The branch, master has been updated
       via  f1a82801692 librpc:bcrypt_rsakey_blob: exponent and modulus lengths 
can't be zero
      from  c1ee6fe9a48 s3/libsmb: check the negative-conn-cache in 
resolve_ads()

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f1a828016921b4d5852148cdb2b8147ceafd7f69
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Jul 30 21:18:09 2025 +1200

    librpc:bcrypt_rsakey_blob: exponent and modulus lengths can't be zero
    
    Apart from it making no sense, without these ranges we end up
    allocating a NULL buffer and aborting.
    
    We also put a maximum size on the RSA key, in case we could get
    tricked into a DoS by pulling a large buffer and trying crypto maths
    on it.
    
     6 0x572ebce2749a in talloc_abort samba/lib/talloc/talloc.c:506:3
     7 0x572ebce271d4 in talloc_chunk_from_ptr samba/lib/talloc/talloc.c:0
     8 0x572ebce271d4 in __talloc_with_prefix samba/lib/talloc/talloc.c:762:12
     9 0x572ebce235f9 in __talloc samba/lib/talloc/talloc.c:825:9
    10 0x572ebce235f9 in _talloc_named_const samba/lib/talloc/talloc.c:982:8
    11 0x572ebce235f9 in _talloc_memdup samba/lib/talloc/talloc.c:2441:9
    12 0x572ebc8f6a4f in data_blob_talloc_named samba/lib/util/data_blob.c:56:25
    13 0x572ebc7d23bd in pull_BCRYPT_RSAPUBLIC_BLOB 
samba/librpc/ndr/ndr_keycredlink.c:878:17
    14 0x572ebc7d23bd in ndr_pull_KeyMaterialInternal 
samba/librpc/ndr/ndr_keycredlink.c:959:10
    15 0x572ebc788e90 in LLVMFuzzerTestOneInput 
samba/bin/default/lib/fuzzing/fuzz_ndr_keycredlink_TYPE_STRUCT.c:282:13
    
    REF: https://issues.oss-fuzz.com/issues/435039896
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Gary Lockyer <g...@catalyst.net.nz>
    
    Autobuild-User(master): Douglas Bagnall <dbagn...@samba.org>
    Autobuild-Date(master): Thu Jul 31 05:45:07 UTC 2025 on atb-devel-224

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/bcrypt_rsakey_blob.idl        | 15 ++++++++--
 python/samba/tests/bcrypt_rsakey_blob.py | 51 ++++++++++++++------------------
 2 files changed, 35 insertions(+), 31 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/idl/bcrypt_rsakey_blob.idl 
b/librpc/idl/bcrypt_rsakey_blob.idl
index fd5f6134e34..6bd071cf4d4 100644
--- a/librpc/idl/bcrypt_rsakey_blob.idl
+++ b/librpc/idl/bcrypt_rsakey_blob.idl
@@ -21,13 +21,22 @@ interface bcrypt_rsakey_blob
                /* Currently only handle RSA Public Key blobs */
                [value(0x31415352), range(0x31415352, 0x31415352)]
                        uint32 magic; /* RSA1 */
-               uint32 bit_length;
+               /*
+                * In key_credential_links we expect bit_length to be
+                * 2048, but we accept a wider range in part because
+                * testing is much easier with small numbers.
+                */
+               [range(1,65536)]uint32 bit_length;
                /*
                 * As of Windows 10 version 1903, public exponents larger
                 * than (2^64 - 1) are no longer supported.
                 */
-               [range(0x0,0x8)] uint32 public_exponent_len;
-               uint32 modulus_len;
+               [range(0x1,0x8)] uint32 public_exponent_len;
+               /*
+                * modulus_len is the key size in bytes, more or less
+                * bit_length / 8.
+                */
+               [range(0x1, 0x2001)] uint32 modulus_len;
                /*
                 * We're only supporting public keys, so the private
                 * key prime lengths should be zero
diff --git a/python/samba/tests/bcrypt_rsakey_blob.py 
b/python/samba/tests/bcrypt_rsakey_blob.py
index ea984445d24..59e446deec2 100755
--- a/python/samba/tests/bcrypt_rsakey_blob.py
+++ b/python/samba/tests/bcrypt_rsakey_blob.py
@@ -35,7 +35,8 @@ class BcryptRsaKeyBlobTests(TestCase):
     def test_unpack_empty_key_blob(self):
         """
         Ensure that a minimal header only BCRYPT_RSAPUBLIC_BLOB
-        can be unpacked, then packed into identical bytes
+        can't be unpacked, because it would imply zero length modulus
+        and exponent numbers, which is meaningless.
         """
         empty_key_blob = bytes.fromhex(
             "52 53 41 31"  # Magic value RSA1
@@ -45,20 +46,11 @@ class BcryptRsaKeyBlobTests(TestCase):
             "00 00 00 00"  # prime one length"
             "00 00 00 00"  # prime two length"
         )
-        blob = ndr_unpack(
-            bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB, empty_key_blob)
-
-        self.assertEqual(blob.magic, 0x31415352)
-        self.assertEqual(blob.bit_length, 0)
-        self.assertEqual(blob.public_exponent_len, 0)
-        self.assertEqual(blob.modulus_len, 0)
-        self.assertEqual(blob.prime1_len_unused, 0)
-        self.assertEqual(blob.prime2_len_unused, 0)
-        self.assertEqual(len(blob.public_exponent), 0)
-        self.assertEqual(len(blob.modulus), 0)
-
-        packed = ndr_pack(blob)
-        self.assertEqual(empty_key_blob, packed)
+        with self.assertRaises(RuntimeError) as e:
+            ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
+                       empty_key_blob)
+        self.assertEqual(e.exception.args[0], 13)
+        self.assertEqual(e.exception.args[1], "Range Error")
 
     def test_unpack_invalid_magic(self):
         """
@@ -67,11 +59,12 @@ class BcryptRsaKeyBlobTests(TestCase):
         """
         invalid_magic_key_blob = bytes.fromhex(
             "52 53 41 30"  # Magic value RSA0
-            "00 00 00 00"  # bit length
-            "00 00 00 00"  # public exponent length
-            "00 00 00 00"  # modulus length
+            "04 00 00 00"  # bit length
+            "01 00 00 00"  # public exponent length
+            "01 00 00 00"  # modulus length
             "00 00 00 00"  # prime one length
             "00 00 00 00"  # prime two length"
+            "01 02"        # exponent and modulus, one byte each
         )
         with self.assertRaises(RuntimeError) as e:
             ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
@@ -87,11 +80,12 @@ class BcryptRsaKeyBlobTests(TestCase):
         """
         extra_data_key_blob = bytes.fromhex(
             "52 53 41 31"  # Magic value RSA1
-            "00 00 00 00"  # bit length
-            "00 00 00 00"  # public exponent length
-            "00 00 00 00"  # modulus length
+            "04 00 00 00"  # bit length
+            "01 00 00 00"  # public exponent length
+            "01 00 00 00"  # modulus length
             "00 00 00 00"  # prime one length
             "00 00 00 00"  # prime two length
+            "01 02"        # exponent and modulus, one byte each
             "01"           # a trailing byte of data
         )
         with self.assertRaises(RuntimeError) as e:
@@ -127,9 +121,9 @@ class BcryptRsaKeyBlobTests(TestCase):
         """
         invalid_magic_key_blob = bytes.fromhex(
             "52 53 41 31"  # Magic value RSA1
-            "00 00 00 00"  # bit length
+            "08 00 00 00"  # bit length
             "09 00 00 00"  # public exponent length, 9 bytes
-            "00 00 00 00"  # modulus length
+            "01 00 00 00"  # modulus length
             "00 00 00 00"  # prime one length
             "00 00 00 00"  # prime two length"
         )
@@ -147,11 +141,12 @@ class BcryptRsaKeyBlobTests(TestCase):
         """
         invalid_prime1_key_blob = bytes.fromhex(
             "52 53 41 31"  # Magic value RSA1
-            "00 00 00 00"  # bit length
-            "00 00 00 00"  # public exponent length, 9 bytes
-            "00 00 00 00"  # modulus length
+            "04 00 00 00"  # bit length
+            "01 00 00 00"  # public exponent length
+            "01 00 00 00"  # modulus length
             "01 00 00 00"  # prime one length
             "00 00 00 00"  # prime two length"
+            "01 02"        # exponent and modulus, one byte each
         )
         with self.assertRaises(RuntimeError) as e:
             ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
@@ -168,8 +163,8 @@ class BcryptRsaKeyBlobTests(TestCase):
         invalid_prime2_key_blob = bytes.fromhex(
             "52 53 41 31"  # Magic value RSA1
             "00 00 00 00"  # bit length
-            "00 00 00 00"  # public exponent length, 9 bytes
-            "00 00 00 00"  # modulus length
+            "01 00 00 00"  # public exponent length
+            "01 00 00 00"  # modulus length
             "00 00 00 00"  # prime one length
             "01 00 00 00"  # prime two length"
         )


-- 
Samba Shared Repository

Reply via email to