/* 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
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
"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):
"""
"""
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,
"""
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:
"""
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"
)
"""
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,
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"
)