]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
tests/krb5: Construct signed_attrs correctly
authorJennifer Sutton <jennifersutton@catalyst.net.nz>
Tue, 18 Nov 2025 03:42:03 +0000 (16:42 +1300)
committerDouglas Bagnall <dbagnall@samba.org>
Wed, 19 Nov 2025 00:32:31 +0000 (00:32 +0000)
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 <jennifersutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Autobuild-User(master): Douglas Bagnall <dbagnall@samba.org>
Autobuild-Date(master): Wed Nov 19 00:32:31 UTC 2025 on atb-devel-224

python/samba/tests/krb5/key_trust_tests.py
python/samba/tests/krb5/pkinit_certificate_mapping_tests.py
python/samba/tests/krb5/pkinit_tests.py
python/samba/tests/krb5/raw_testcase.py

index 07c62485dea28e5293049537185425783f5e2cc7..5ef5d5353dc8d3eb2519357f34d5eee1e5fe2bf4 100755 (executable)
@@ -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],
index e6486cc54d2a5463f23e195607b4db4dc5d64b53..7802a0cf4ac110f13359290ae49242abb01436a8 100755 (executable)
@@ -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],
index 4928f1ce46e5883086c226586f6fefb5c6a4944d..74f1c48962099e1ef1ec1b16e1e0146eaabd586a 100755 (executable)
@@ -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],
index 40ea854b9f740acd7a1978ebc6f196185a3144cd..07bf4490104a7144d6fd34c89179ffd9deb9fc92 100644 (file)
@@ -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,