From b0fe01dd436c1d74ce8de91b57c8a7d1467efa81 Mon Sep 17 00:00:00 2001 From: Z0050KEW Date: Thu, 12 Mar 2026 08:50:05 +0100 Subject: [PATCH 1/5] feat(test, batch): Add test case to check the correct handling of the outer batch PKIMessage version. --- tests/pki_mgmt_entity_op.robot | 92 ++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/tests/pki_mgmt_entity_op.robot b/tests/pki_mgmt_entity_op.robot index b4007c4d..0908ec6c 100644 --- a/tests/pki_mgmt_entity_op.robot +++ b/tests/pki_mgmt_entity_op.robot @@ -194,6 +194,28 @@ CA MUST Respond with MAC To Added Protection For MAC Inner Request Fail The response to the wrapped protected message was not MAC-based protected. END +CA MUST Respond with A Correct PVNO For Inner Added Protection + [Documentation] According to RFC 9483 Section 3.1 and RFC 9480 Section 7 the `pvno` field in the header of a + ... PKIMessage MUST be set to the request message's `pvno` value when the response is returned. We send a + ... added protection nested PKIMessage with pvno set to 2 and a inner PKIMessage with pvno set to 3. The CA + ... MUST respond with a message that has the `pvno` value set to 3. + [Tags] adding-protection nested positive added-protection pvno + Skip If Cert Or Key Not Set + ${protected_ir}= Default Build Inner IR Message pvno=3 + ${nested}= Build Nested PKIMessage + ... exclude_fields=${None} + ... sender=${SENDER} + ... recipient=${RECIPIENT} + ... other_messages=${protected_ir} + ... for_added_protection=True + ... pvno=3 + ${prot_nested}= Default Protect With Trusted Cert ${nested} + ${response}= Exchange PKIMessage ${prot_nested} + PKIMessage Body Type Must Be ${response} ip + PKIStatus Must Be ${response} status=accepted + ${response_pvno}= Get Asn1 Value As Number ${response} header.pvno + Should Be Equal As Integers ${response_pvno} 3 + ## Section 5.2.2.2. Batching Messages CA MUST Accept Valid Nested Batch Message @@ -263,6 +285,76 @@ CA MUST Check The Protection Of All Inner Messages PKIStatus Must Be ${response} status=rejection PKIStatusInfo Failinfo Bit Must Be ${response} failinfo=badMessageCheck exclusive=True +CA MUST Respond With Correct PVNO For Outer And Inner Batch Message + [Documentation] According to RFC 9483 Section 3.1 and RFC 9480 Section 7, the `pvno` field in the + ... response MUST match the `pvno` of the corresponding request. We send a nested batch PKIMessage + ... where the outer message has `pvno` set to 3 and all three inner IR messages have `pvno` set to 2. + ... The CA MUST respond with a nested message where the outer response has `pvno` 3 and each inner + ... `ip` response has `pvno` 2. + [Tags] batching nested positive batch pvno + Skip If Cert Or Key Not Set + ${nonces}= Generate Unique Byte Values length=4 + ${ids}= Generate Unique Byte Values length=4 + VAR @{inner_irs} + FOR ${i} IN RANGE 3 + ${ir}= Default Build Inner IR Message + ... pvno=2 + ... transaction_id=${ids}[${i}] + ... sender_nonce=${nonces}[${i}] + Append To List ${inner_irs} ${ir} + END + ${nested}= Build Nested PKIMessage + ... recipient=${RECIPIENT} + ... other_messages=${inner_irs} + ... sender_nonce=${nonces}[3] + ... transaction_id=${ids}[3] + ... pvno=3 + ${prot_nested}= Default Protect With Trusted Cert ${nested} + ${response}= Exchange PKIMessage ${prot_nested} + PKIMessage Body Type Must Be ${response} nested + ${outer_pvno}= Get Asn1 Value As Number ${response} header.pvno + Should Be Equal As Integers ${outer_pvno} 3 + FOR ${i} IN RANGE 3 + ${inner_response}= Get Inner PKIMessage ${response} index=${i} + ${inner_pvno}= Get Asn1 Value As Number ${inner_response} header.pvno + Should Be Equal As Integers ${inner_pvno} 2 + END + +CA MUST Respond With Correct PVNO For Outer And Inner Batch Message Reversed + [Documentation] According to RFC 9483 Section 3.1 and RFC 9480 Section 7, the `pvno` field in the + ... response MUST match the `pvno` of the corresponding request. We send a nested batch PKIMessage + ... where the outer message has `pvno` set to 2 and all three inner IR messages have `pvno` set to 3. + ... The CA MUST respond with a nested message where the outer response has `pvno` 2 and each inner + ... `ip` response has `pvno` 3. + [Tags] batching nested positive batch pvno + Skip If Cert Or Key Not Set + ${nonces}= Generate Unique Byte Values length=4 + ${ids}= Generate Unique Byte Values length=4 + VAR @{inner_irs} + FOR ${i} IN RANGE 3 + ${ir}= Default Build Inner IR Message + ... pvno=3 + ... transaction_id=${ids}[${i}] + ... sender_nonce=${nonces}[${i}] + Append To List ${inner_irs} ${ir} + END + ${nested}= Build Nested PKIMessage + ... recipient=${RECIPIENT} + ... other_messages=${inner_irs} + ... sender_nonce=${nonces}[3] + ... transaction_id=${ids}[3] + ... pvno=2 + ${prot_nested}= Default Protect With Trusted Cert ${nested} + ${response}= Exchange PKIMessage ${prot_nested} + PKIMessage Body Type Must Be ${response} nested + ${outer_pvno}= Get Asn1 Value As Number ${response} header.pvno + Should Be Equal As Integers ${outer_pvno} 2 + FOR ${i} IN RANGE 3 + ${inner_response}= Get Inner PKIMessage ${response} index=${i} + ${inner_pvno}= Get Asn1 Value As Number ${inner_response} header.pvno + Should Be Equal As Integers ${inner_pvno} 3 + END + ### Section 5.2.3 Replacing Protection # According to Section 5.2.3, when an intermediate PKI management entity modifies a message, From f295da31ecfca249f0f1e8aa76ed97bc880fac88 Mon Sep 17 00:00:00 2001 From: Z0050KEW Date: Thu, 12 Mar 2026 08:50:45 +0100 Subject: [PATCH 2/5] test(batch, pvno): Add tests for correct PVNO responses in nested batch messages, which includes mixed versions. --- tests/pki_mgmt_entity_op.robot | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/pki_mgmt_entity_op.robot b/tests/pki_mgmt_entity_op.robot index 0908ec6c..9ede7112 100644 --- a/tests/pki_mgmt_entity_op.robot +++ b/tests/pki_mgmt_entity_op.robot @@ -355,6 +355,42 @@ CA MUST Respond With Correct PVNO For Outer And Inner Batch Message Reversed Should Be Equal As Integers ${inner_pvno} 3 END +CA MUST Respond With Correct PVNO For Outer And Inner Batch Message Mixed + [Documentation] According to RFC 9483 Section 3.1 and RFC 9480 Section 7, the `pvno` field in the + ... response MUST match the `pvno` of the corresponding request. We send a nested batch PKIMessage + ... where the outer message has `pvno` set to 3 and three inner IR messages have `pvno` set to 2, 3, and 2. + ... The CA MUST respond with a nested message where the outer response has `pvno` 3 and each inner + ... `ip` response has the corresponding `pvno` (2, 3, 2). + [Tags] batching nested positive batch pvno + Skip If Cert Or Key Not Set + ${nonces}= Generate Unique Byte Values length=4 + ${ids}= Generate Unique Byte Values length=4 + VAR @{inner_irs} + VAR @{expected_pvnos} ${2} ${3} ${2} + FOR ${i} IN RANGE 3 + ${ir}= Default Build Inner IR Message + ... pvno=${expected_pvnos}[${i}] + ... transaction_id=${ids}[${i}] + ... sender_nonce=${nonces}[${i}] + Append To List ${inner_irs} ${ir} + END + ${nested}= Build Nested PKIMessage + ... recipient=${RECIPIENT} + ... other_messages=${inner_irs} + ... sender_nonce=${nonces}[3] + ... transaction_id=${ids}[3] + ... pvno=3 + ${prot_nested}= Default Protect With Trusted Cert ${nested} + ${response}= Exchange PKIMessage ${prot_nested} + PKIMessage Body Type Must Be ${response} nested + ${outer_pvno}= Get Asn1 Value As Number ${response} header.pvno + Should Be Equal As Integers ${outer_pvno} 3 + FOR ${i} IN RANGE 3 + ${inner_response}= Get Inner PKIMessage ${response} index=${i} + ${inner_pvno}= Get Asn1 Value As Number ${inner_response} header.pvno + Should Be Equal As Integers ${inner_pvno} ${expected_pvnos}[${i}] + END + ### Section 5.2.3 Replacing Protection # According to Section 5.2.3, when an intermediate PKI management entity modifies a message, From a8dd90f56388bed37dbc47cdb2718e76515254ea Mon Sep 17 00:00:00 2001 From: Guiliano99 Date: Wed, 11 Mar 2026 09:31:17 +0100 Subject: [PATCH 3/5] test(batch-message): Add PVNO checks in batch message processing tests. --- .../tests_mock_ca/test_process_batch_message.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py b/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py index 146be0fc..6e02396d 100644 --- a/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py +++ b/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py @@ -82,6 +82,7 @@ def _generate_nested_message( transaction_id=trans_id[2], sender_nonce=sender_nonce[2], recip_nonce=recip_nonce[2] if include_recip_nonce else None, + pvno=3 ) return protect_pkimessage( pki_message=nested, @@ -93,6 +94,7 @@ def _generate_nested_message( def test_process_batch_message(self): """Test processing a batch message.""" nested = self._generate_nested_message(False, False) + self.assertEqual(3, int(nested["header"]["pvno"])) self.assertEqual(nested["body"].getName(), "nested") self.assertEqual(len(nested["body"]["nested"]), 2) self.assertEqual(nested["body"]["nested"][0]["body"].getName(), "ir") @@ -105,6 +107,7 @@ def test_process_batch_message(self): self.assertEqual(response["body"]["nested"][0]["header"]["protectionAlg"]["algorithm"], rfc9481.id_PBMAC1) self.assertEqual(response["body"]["nested"][1]["header"]["protectionAlg"]["algorithm"], rfc9481.id_PBMAC1) + self.assertEqual(3, int(response["header"]["pvno"])) def test_process_batch_message_bad_message_check(self): """Test processing a batch message with bad message check.""" @@ -118,3 +121,7 @@ def test_process_batch_message_bad_message_check(self): texts = [x.prettyPrint() for x in pki_status_info["statusString"]] self.assertIn("Invalid inner batch PKIMessage protection at index 1.", texts) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 90ae1a6acfc8934a4ca5ef1431d4d35bba2aaaa4 Mon Sep 17 00:00:00 2001 From: Guiliano99 Date: Wed, 11 Mar 2026 09:40:45 +0100 Subject: [PATCH 4/5] fix(nested-handler): Fix the returned pvno to return teh version of the sender. --- mock_ca/nested_handler.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mock_ca/nested_handler.py b/mock_ca/nested_handler.py index 4a97cf99..bbe62371 100644 --- a/mock_ca/nested_handler.py +++ b/mock_ca/nested_handler.py @@ -319,5 +319,6 @@ def process_batched_request( recip_nonce=request["header"]["senderNonce"].asOctets(), sender=prot_handler.sender, recipient=request["header"]["sender"], + pvno=request["header"]["pvno"], ) return prot_handler.protect_pkimessage(response=pki_message, request=request) From 7d669a3ff3e286de23179a20f16d2d4b52ee9838 Mon Sep 17 00:00:00 2001 From: Guiliano99 Date: Mon, 13 Apr 2026 14:37:50 +0200 Subject: [PATCH 5/5] fix(batch-message): Add pvno parameter to batch message processing --- .../tests_mock_ca/test_process_batch_message.py | 1 + 1 file changed, 1 insertion(+) diff --git a/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py b/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py index 6e02396d..5ec08f96 100644 --- a/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py +++ b/unit_tests/tests_experimental_and_mock_ca/tests_mock_ca/test_process_batch_message.py @@ -55,6 +55,7 @@ def _generate_nested_message( sender_nonce=sender_nonce[0], recip_nonce=recip_nonce[0] if include_recip_nonce else None, for_mac=True, + pvno=2 ) ir = build_ir_from_key(