From: Jennifer Sutton Date: Tue, 18 Nov 2025 03:42:03 +0000 (+1300) Subject: tests/krb5: Construct signed_attrs correctly X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a6004b7b3fa9b8540ed0f285697ddda4e015b32;p=thirdparty%2Fsamba.git tests/krb5: Construct signed_attrs correctly signed_attrs is supposed to be a list of key‐value pairs, but we forgot the values. Because the field was not constructed correctly, the pyasn1 encoder simply stripped it out. Also properly separate the signature algorithm and digest algorithms. Signed-off-by: Jennifer Sutton Reviewed-by: Douglas Bagnall Autobuild-User(master): Douglas Bagnall Autobuild-Date(master): Wed Nov 19 00:32:31 UTC 2025 on atb-devel-224 --- diff --git a/python/samba/tests/krb5/key_trust_tests.py b/python/samba/tests/krb5/key_trust_tests.py index 07c62485dea..5ef5d5353dc 100755 --- a/python/samba/tests/krb5/key_trust_tests.py +++ b/python/samba/tests/krb5/key_trust_tests.py @@ -300,6 +300,9 @@ class KeyTrustTests(KDCBaseTest): signature_algorithm = krb5_asn1.sha1WithRSAEncryption signature_algorithm_id = self.AlgorithmIdentifier_create(signature_algorithm) + digest_algorithm = krb5_asn1.id_sha1 + digest_algorithm_id = self.AlgorithmIdentifier_create(digest_algorithm) + private_key = creds.get_private_key() preauth_key = private_key @@ -348,11 +351,11 @@ class KeyTrustTests(KDCBaseTest): auth_pack = self.der_encode(auth_pack_obj, asn1Spec=asn1_spec()) signature_hash = self.hash_from_algorithm(signature_algorithm) + digest_hash = self.hash_from_algorithm(digest_algorithm) - pad = padding.PKCS1v15() - signed = private_key.sign( - auth_pack, padding=pad, algorithm=signature_hash() - ) + digest = hashes.Hash(digest_hash(), default_backend()) + digest.update(auth_pack) + digest = digest.finalize() encap_content_info_obj = self.EncapsulatedContentInfo_create( krb5_asn1.id_pkinit_authData, auth_pack @@ -365,16 +368,36 @@ class KeyTrustTests(KDCBaseTest): subject_key_id=subject_key_id.value.digest ) + auth_data_attr = self.Attribute_create( + krb5_asn1.id_pkinit_authData, [auth_pack] + ) + + message_digest = self.der_encode(digest, asn1Spec=krb5_asn1.MessageDigest()) + + message_digest_attr = self.Attribute_create( + krb5_asn1.id_messageDigest, [message_digest] + ) + + signed_attrs = [ + # Note: these attributes are optional. + auth_data_attr, + message_digest_attr, + ] + encoded_signed_attrs = self.der_encode( + signed_attrs, asn1Spec=krb5_asn1.CMSAttributes() + ) + + pad = padding.PKCS1v15() + signed = private_key.sign( + encoded_signed_attrs, padding=pad, algorithm=signature_hash() + ) + signer_info = self.SignerInfo_create( signer_identifier, - signature_algorithm_id, + digest_algorithm_id, signature_algorithm_id, signed, - signed_attrs=[ - # Note: these attributes are optional. - krb5_asn1.id_pkinit_authData, - krb5_asn1.id_messageDigest, - ], + signed_attrs=signed_attrs, ) encoded_cert = certificate.public_bytes(serialization.Encoding.DER) @@ -383,7 +406,7 @@ class KeyTrustTests(KDCBaseTest): ) signed_auth_pack = self.SignedData_create( - [signature_algorithm_id], + [digest_algorithm_id], encap_content_info_obj, signer_infos=[signer_info], certificates=[decoded_cert], diff --git a/python/samba/tests/krb5/pkinit_certificate_mapping_tests.py b/python/samba/tests/krb5/pkinit_certificate_mapping_tests.py index e6486cc54d2..7802a0cf4ac 100755 --- a/python/samba/tests/krb5/pkinit_certificate_mapping_tests.py +++ b/python/samba/tests/krb5/pkinit_certificate_mapping_tests.py @@ -770,6 +770,7 @@ class PkInitCertificateMappingTests(KDCBaseTest): pk_nonce=None, supported_cms_types=None, signature_algorithm=None, + digest_algorithm=None, certificate_signature=None, freshness_token=None, win2k_variant=False, @@ -785,6 +786,11 @@ class PkInitCertificateMappingTests(KDCBaseTest): signature_algorithm_id = self.AlgorithmIdentifier_create(signature_algorithm) + if digest_algorithm is None: + digest_algorithm = krb5_asn1.id_sha1 + + digest_algorithm_id = self.AlgorithmIdentifier_create(digest_algorithm) + if certificate is None: ca_cert, ca_private_key = self.get_ca_cert_and_private_key() @@ -916,11 +922,11 @@ class PkInitCertificateMappingTests(KDCBaseTest): auth_pack = self.der_encode(auth_pack_obj, asn1Spec=asn1_spec()) signature_hash = self.hash_from_algorithm(signature_algorithm) + digest_hash = self.hash_from_algorithm(digest_algorithm) - pad = padding.PKCS1v15() - signed = private_key.sign( - auth_pack, padding=pad, algorithm=signature_hash() - ) + digest = hashes.Hash(digest_hash(), default_backend()) + digest.update(auth_pack) + digest = digest.finalize() encap_content_info_obj = self.EncapsulatedContentInfo_create( krb5_asn1.id_pkinit_authData, auth_pack @@ -933,16 +939,36 @@ class PkInitCertificateMappingTests(KDCBaseTest): subject_key_id=subject_key_id.value.digest ) + auth_data_attr = self.Attribute_create( + krb5_asn1.id_pkinit_authData, [auth_pack] + ) + + message_digest = self.der_encode(digest, asn1Spec=krb5_asn1.MessageDigest()) + + message_digest_attr = self.Attribute_create( + krb5_asn1.id_messageDigest, [message_digest] + ) + + signed_attrs = [ + # Note: these attributes are optional. + auth_data_attr, + message_digest_attr, + ] + encoded_signed_attrs = self.der_encode( + signed_attrs, asn1Spec=krb5_asn1.CMSAttributes() + ) + + pad = padding.PKCS1v15() + signed = private_key.sign( + encoded_signed_attrs, padding=pad, algorithm=signature_hash() + ) + signer_info = self.SignerInfo_create( signer_identifier, - signature_algorithm_id, + digest_algorithm_id, signature_algorithm_id, signed, - signed_attrs=[ - # Note: these attributes are optional. - krb5_asn1.id_pkinit_authData, - krb5_asn1.id_messageDigest, - ], + signed_attrs=signed_attrs, ) encoded_cert = certificate.public_bytes(serialization.Encoding.DER) @@ -951,7 +977,7 @@ class PkInitCertificateMappingTests(KDCBaseTest): ) signed_auth_pack = self.SignedData_create( - [signature_algorithm_id], + [digest_algorithm_id], encap_content_info_obj, signer_infos=[signer_info], certificates=[decoded_cert], diff --git a/python/samba/tests/krb5/pkinit_tests.py b/python/samba/tests/krb5/pkinit_tests.py index 4928f1ce46e..74f1c489620 100755 --- a/python/samba/tests/krb5/pkinit_tests.py +++ b/python/samba/tests/krb5/pkinit_tests.py @@ -1693,6 +1693,7 @@ class PkInitTests(KDCBaseTest): pk_nonce=None, supported_cms_types=None, signature_algorithm=None, + digest_algorithm=None, certificate_signature=None, freshness_token=None, win2k_variant=False, @@ -1709,6 +1710,11 @@ class PkInitTests(KDCBaseTest): signature_algorithm_id = self.AlgorithmIdentifier_create( signature_algorithm) + if digest_algorithm is None: + digest_algorithm = krb5_asn1.id_sha1 + + digest_algorithm_id = self.AlgorithmIdentifier_create(digest_algorithm) + if certificate is None: ca_cert, ca_private_key = self.get_ca_cert_and_private_key() @@ -1837,11 +1843,11 @@ class PkInitTests(KDCBaseTest): auth_pack = self.der_encode(auth_pack_obj, asn1Spec=asn1_spec()) signature_hash = self.hash_from_algorithm(signature_algorithm) + digest_hash = self.hash_from_algorithm(digest_algorithm) - pad = padding.PKCS1v15() - signed = private_key.sign(auth_pack, - padding=pad, - algorithm=signature_hash()) + digest = hashes.Hash(digest_hash(), default_backend()) + digest.update(auth_pack) + digest = digest.finalize() encap_content_info_obj = self.EncapsulatedContentInfo_create( krb5_asn1.id_pkinit_authData, auth_pack) @@ -1851,23 +1857,44 @@ class PkInitTests(KDCBaseTest): signer_identifier = self.SignerIdentifier_create( subject_key_id=subject_key_id.value.digest) + auth_data_attr = self.Attribute_create( + krb5_asn1.id_pkinit_authData, [auth_pack] + ) + + message_digest = self.der_encode(digest, asn1Spec=krb5_asn1.MessageDigest()) + + message_digest_attr = self.Attribute_create( + krb5_asn1.id_messageDigest, [message_digest] + ) + + signed_attrs = [ + # Note: these attributes are optional. + auth_data_attr, + message_digest_attr, + ] + encoded_signed_attrs = self.der_encode( + signed_attrs, asn1Spec=krb5_asn1.CMSAttributes() + ) + + pad = padding.PKCS1v15() + signed = private_key.sign(encoded_signed_attrs, + padding=pad, + algorithm=signature_hash()) + signer_info = self.SignerInfo_create( signer_identifier, - signature_algorithm_id, + digest_algorithm_id, signature_algorithm_id, signed, - signed_attrs=[ - # Note: these attributes are optional. - krb5_asn1.id_pkinit_authData, - krb5_asn1.id_messageDigest, - ]) + signed_attrs=signed_attrs, + ) encoded_cert = certificate.public_bytes(serialization.Encoding.DER) decoded_cert = self.der_decode( encoded_cert, asn1Spec=krb5_asn1.CertificateChoices()) signed_auth_pack = self.SignedData_create( - [signature_algorithm_id], + [digest_algorithm_id], encap_content_info_obj, signer_infos=[signer_info], certificates=[decoded_cert], diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py index 40ea854b9f7..07bf4490104 100644 --- a/python/samba/tests/krb5/raw_testcase.py +++ b/python/samba/tests/krb5/raw_testcase.py @@ -2521,6 +2521,14 @@ class RawKerberosTest(TestCase): return self.der_encode(pk_as_req_obj, asn1Spec=asn1_spec()) + def Attribute_create(self, + attr_type, + attr_values): + return { + 'type': attr_type, + 'values': attr_values, + } + def SignerInfo_create(self, signer_id, digest_algorithm,