From f199042f9e9796cd9c500346ff37353401fb22b2 Mon Sep 17 00:00:00 2001
From: DimitriZhurkin <dimitri.zhurkin@noblis.org>
Date: Fri, 10 Jan 2025 14:19:22 -0700
Subject: [PATCH] Add the interconnection-component-linked-has-protocol
 constraint

---
 features/fedramp_extensions.feature           |  3 ++
 .../ssp/xml/fedramp-ssp-example.oscal.xml     | 43 ++++++++++++++++++
 ...-component-linked-has-protocol-INVALID.xml | 45 +++++++++++++++++++
 .../fedramp-external-constraints.xml          |  6 +++
 ...on-component-linked-has-protocol-FAIL.yaml |  8 ++++
 ...on-component-linked-has-protocol-PASS.yaml |  8 ++++
 6 files changed, 113 insertions(+)
 create mode 100644 src/validations/constraints/content/ssp-interconnection-component-linked-has-protocol-INVALID.xml
 create mode 100644 src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-FAIL.yaml
 create mode 100644 src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-PASS.yaml

diff --git a/features/fedramp_extensions.feature b/features/fedramp_extensions.feature
index 7aced5bef..329a86895 100644
--- a/features/fedramp_extensions.feature
+++ b/features/fedramp_extensions.feature
@@ -120,6 +120,7 @@ Examples:
   | information-type-has-integrity-impact |
   | information-type-system |
   | inter-boundary-component-has-information-type |
+  | interconnection-component-linked-has-protocol |
   | interconnection-direction |
   | interconnection-security |
   | inventory-item-allows-authenticated-scan |
@@ -380,6 +381,8 @@ Examples:
   | information-type-system-PASS.yaml |
   | inter-boundary-component-has-information-type-FAIL.yaml |
   | inter-boundary-component-has-information-type-PASS.yaml |
+  | interconnection-component-linked-has-protocol-FAIL.yaml |
+  | interconnection-component-linked-has-protocol-PASS.yaml |
   | interconnection-direction-FAIL.yaml |
   | interconnection-direction-PASS.yaml |
   | interconnection-security-FAIL.yaml |
diff --git a/src/content/rev5/examples/ssp/xml/fedramp-ssp-example.oscal.xml b/src/content/rev5/examples/ssp/xml/fedramp-ssp-example.oscal.xml
index 171d69de9..744990551 100644
--- a/src/content/rev5/examples/ssp/xml/fedramp-ssp-example.oscal.xml
+++ b/src/content/rev5/examples/ssp/xml/fedramp-ssp-example.oscal.xml
@@ -2305,6 +2305,49 @@ approved.</p>
       </protocol>
     </component>
 
+    <component uuid="11111111-2222-4000-8000-009000200005" type="interconnection">
+       <title>Authorized Connection Information System Name</title>
+       <description>
+          <p>Describe the purpose of the external system or service.</p>
+       </description>
+       <prop name="nature-of-agreement" value="contract" ns="http://fedramp.gov/ns/oscal"/>
+       <prop name="authentication-method" value="yes" ns="http://fedramp.gov/ns/oscal">
+          <remarks>
+             <p>If 'yes', describe the authentication method in the remarks.</p>
+             <p>If 'no', explain why no authentication is used in the remarks.</p>
+             <p>If 'not-applicable', attest explain why authentication is not applicable in the remarks.</p>
+          </remarks>
+       </prop>
+       <prop name="information-type" class="incoming" value="C.3.5.1" ns="http://fedramp.gov/ns/oscal"/>
+       <prop name="information-type" class="incoming" value="C.3.5.8" ns="http://fedramp.gov/ns/oscal"/>
+       <prop name="ipv4-address" class="local" value="10.1.1.1"/>
+       <prop name="ipv6-address" class="local" value="::ffff:10.1.1.1"/>
+       <prop name="ipv4-address" class="remote" value="10.2.2.2"/>
+       <prop name="ipv6-address" class="remote" value="::ffff:10.2.2.2"/>
+       <prop name="connection-security" value="tls-1.3" ns="http://fedramp.gov/ns/oscal"/>
+       <link rel="used-by" href="#11111111-2222-4000-8000-009000100002">
+          <text>UUID of remote system</text>
+       </link>
+       <status state="operational"/>
+       <responsible-role role-id="provider">
+          <party-uuid>44444444-2222-4000-8000-004000000001</party-uuid>
+       </responsible-role>
+       <responsible-role role-id="isa-poc-remote">
+          <party-uuid>11111111-2222-4000-8000-004000000008</party-uuid>
+       </responsible-role>
+       <responsible-role role-id="isa-poc-local">
+          <party-uuid>11111111-2222-4000-8000-004000000008</party-uuid>
+       </responsible-role>
+       <responsible-role role-id="administrator">
+          <prop name="privilege-uuid" value="11111111-2222-4000-8000-008000000004" ns="http://fedramp.gov/ns/oscal"/>
+          <party-uuid>11111111-2222-4000-8000-004000000010</party-uuid>
+          <party-uuid>11111111-2222-4000-8000-004000000011</party-uuid>
+          <party-uuid>11111111-2222-4000-8000-004000000012</party-uuid>
+       </responsible-role>
+    </component>
+
+
+
     <!-- Appendix M - Inventory -->
     <inventory-item uuid="11111111-2222-4000-8000-011000000001">
       <description>
diff --git a/src/validations/constraints/content/ssp-interconnection-component-linked-has-protocol-INVALID.xml b/src/validations/constraints/content/ssp-interconnection-component-linked-has-protocol-INVALID.xml
new file mode 100644
index 000000000..ef0e7b06b
--- /dev/null
+++ b/src/validations/constraints/content/ssp-interconnection-component-linked-has-protocol-INVALID.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-model href="https://github.com/usnistgov/OSCAL/releases/download/v1.1.3/oscal_ssp_schema.xsd" schematypens="http://www.w3.org/2001/XMLSchema" title="OSCAL complete schema"?>
+<system-security-plan xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="df903c4c-6bb5-4b78-8a71-c5baa06a9f2e">
+    <system-implementation>
+        <component uuid="11111111-2222-4000-8000-009000200002" type="interconnection">
+           <title>Authorized Connection Information System Name</title>
+           <description>
+              <p>Describe the purpose of the external system/service; specifically, provide reasons for connectivity (e.g., system monitoring, system alerting, download updates, etc.)</p>
+           </description>
+           <prop name="nature-of-agreement" value="contract" ns="http://fedramp.gov/ns/oscal"/>
+           <prop name="authentication-method" value="yes" ns="http://fedramp.gov/ns/oscal">
+              <remarks>
+                 <p>If 'yes', describe the authentication method in the remarks.</p>
+                 <p>If 'no', explain why no authentication is used in the remarks.</p>
+                 <p>If 'not-applicable', attest explain why authentication is not applicable in the remarks.</p>
+              </remarks>
+           </prop>
+           <prop name="information-type" class="incoming" value="C.3.5.1" ns="http://fedramp.gov/ns/oscal"/>
+           <prop name="information-type" class="incoming" value="C.3.5.8" ns="http://fedramp.gov/ns/oscal"/>
+           <prop name="ipv4-address" class="local" value="10.1.1.1"/>
+           <prop name="ipv6-address" class="local" value="::ffff:10.1.1.1"/>
+           <prop name="ipv4-address" class="remote" value="10.2.2.2"/>
+           <prop name="ipv6-address" class="remote" value="::ffff:10.2.2.2"/>
+           <link rel="used-by" href="#none">
+              <text>UUID of remote system</text>
+           </link>
+           <status state="operational"/>
+           <responsible-role role-id="provider">
+              <party-uuid>44444444-2222-4000-8000-004000000001</party-uuid>
+           </responsible-role>
+           <responsible-role role-id="isa-poc-remote">
+              <party-uuid>11111111-2222-4000-8000-004000000008</party-uuid>
+           </responsible-role>
+           <responsible-role role-id="isa-poc-local">
+              <party-uuid>11111111-2222-4000-8000-004000000008</party-uuid>
+           </responsible-role>
+           <responsible-role role-id="administrator">
+              <prop name="privilege-uuid" value="11111111-2222-4000-8000-008000000004" ns="http://fedramp.gov/ns/oscal"/>
+              <party-uuid>11111111-2222-4000-8000-004000000010</party-uuid>
+              <party-uuid>11111111-2222-4000-8000-004000000011</party-uuid>
+              <party-uuid>11111111-2222-4000-8000-004000000012</party-uuid>
+           </responsible-role>
+        </component>
+    </system-implementation>
+</system-security-plan>
\ No newline at end of file
diff --git a/src/validations/constraints/fedramp-external-constraints.xml b/src/validations/constraints/fedramp-external-constraints.xml
index af1baef6b..9607cbf43 100644
--- a/src/validations/constraints/fedramp-external-constraints.xml
+++ b/src/validations/constraints/fedramp-external-constraints.xml
@@ -586,6 +586,7 @@
         <metapath target="/system-security-plan/system-implementation"/>
         <constraints>
             <let var="inter-boundary-component" expression="component[(@type=('service','software') and not(prop[@name='leveraged-authorization-uuid']) and prop[@name='implementation-point' and @value='external']) or (@type='interconnection') or (@type=('service','software') and prop[@name='implementation-point' and @value='internal'] and (prop[@name='communicates-externally' and @value='yes' and @ns='http://fedramp.gov/ns/oscal']))]"/>
+            <let var="interconnection-component" expression="component[@type='interconnection']"/>
             <expect id="authentication-method-has-remarks" target="//component[(@type='system' and ./prop[@name='leveraged-authorization-uuid']) or (@type='service' and not(./prop[@name='leveraged-authorization-uuid']) and ./prop[@name='implementation-point' and @value='external']) or (@type='interconnection') or (@type='service' and ./prop[@name='implementation-point' and @value='internal'] and ./prop[@name='direction']) or (@type='software' and ./prop[@name='asset-type' and @value='cli'] and ./prop[@name='direction'])]" test="count(./prop[@name='authentication-method' and @ns='http://fedramp.gov/ns/oscal'])  = count(./prop[@name='authentication-method' and @ns='http://fedramp.gov/ns/oscal']/remarks)" level="ERROR">
                 <formal-name>Authentication Method Has Remarks</formal-name>
                 <prop namespace="https://docs.oasis-open.org/sarif/sarif/v2.1.0" name="help-url" value="https://automate.fedramp.gov/documentation/ssp/4-ssp-template-to-oscal-mapping/#leveraged-fedramp-authorized-services"/>
@@ -616,6 +617,11 @@
                 <prop namespace="https://docs.oasis-open.org/sarif/sarif/v2.1.0" name="help-url" value="https://automate.fedramp.gov/documentation/ssp/4-ssp-template-to-oscal-mapping/#system-information-and-information-types"/>
                 <message>An inter-boundary communication component {@uuid} ({path(.)}) MUST have at least one information-type property.</message>
             </expect>
+            <expect id="interconnection-component-linked-has-protocol" target="." test="count(component[@uuid=$interconnection-component/link[@rel='used-by']/substring-after(@href,'#')]/protocol) >= 1" level="ERROR">
+                <formal-name>Linked Interconnection Component Has Protocol</formal-name>
+                <prop namespace="https://docs.oasis-open.org/sarif/sarif/v2.1.0" name="help-url" value="https://automate.fedramp.gov/documentation/ssp/4-ssp-template-to-oscal-mapping/#ports-protocols-and-services"/>
+                <message>In a FedRAMP SSP, at least one of the interconnection "used-by" linked components MUST have at least one protocol assembly.</message>
+            </expect>
             <expect id="inventory-item-and-component-has-public" target="(inventory-item | component[@type='service' and prop[@name='implementation-point' and @value='internal']])" test="count(prop[@name='public']) = 1" level="ERROR">
                 <formal-name>Inventory Item and Component Has Public</formal-name>
                 <prop namespace="https://docs.oasis-open.org/sarif/sarif/v2.1.0" name="help-url" value="https://automate.fedramp.gov/documentation/ssp/5-attachments/#system-inventory-approach"/>
diff --git a/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-FAIL.yaml b/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-FAIL.yaml
new file mode 100644
index 000000000..486bafceb
--- /dev/null
+++ b/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-FAIL.yaml
@@ -0,0 +1,8 @@
+# Driver for the invalid interconnection-component-linked-has-protocol constraint unit test.
+test-case:
+  name: The invalid interconnection-component-linked-has-protocol constraint unit test.
+  description: Test that the FedRAMP SSP interconnection "used-by" linked component does not have a protocol assembly.
+  content: ../content/ssp-interconnection-component-linked-has-protocol-INVALID.xml
+  expectations:
+  - constraint-id: interconnection-component-linked-has-protocol
+    result: fail
\ No newline at end of file
diff --git a/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-PASS.yaml b/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-PASS.yaml
new file mode 100644
index 000000000..486e1de1a
--- /dev/null
+++ b/src/validations/constraints/unit-tests/interconnection-component-linked-has-protocol-PASS.yaml
@@ -0,0 +1,8 @@
+# Driver for the valid interconnection-component-linked-has-protocol constraint unit test.
+test-case:
+  name: The valid interconnection-component-linked-has-protocol constraint unit test.
+  description: Test that the FedRAMP SSP interconnection "used-by" linked component has a protocol assembly.
+  content: ../../../content/rev5/examples/ssp/xml/fedramp-ssp-example.oscal.xml
+  expectations:
+  - constraint-id: interconnection-component-linked-has-protocol
+    result: pass
\ No newline at end of file