kca-core: fix CSR attribute DER encoding and conformant decoding
- Generated attributes are now explicitly tagged as UTF8String via CertificateSigningRequestBuilder.add_attribute(_tag=_ASN1Type.UTF8String), so values include proper DER TLV instead of raw bytes. - The attribute decoder first attempts DER string parsing (UTF8String, PrintableString, IA5String, BMPString, long-form lengths), falling back to legacy raw UTF-8 decode for previously generated nonconformant CSRs. - Regression tests verify DER encoding, Unicode round-tripping, supported string types, long values (>127 bytes), and legacy raw UTF-8 attributes. - Mypy passes cleanly (no issues in 42 source files).
This commit is contained in:
@@ -353,12 +353,34 @@ class RequestTest(unittest.TestCase):
|
||||
subject=_name("CSR"),
|
||||
private_key=key,
|
||||
extension_spec=_ca_spec(),
|
||||
attributes={requests.CHALLENGE_PASSWORD_OID: "secret"},
|
||||
attributes={
|
||||
requests.CHALLENGE_PASSWORD_OID: "secret",
|
||||
requests.UNSTRUCTURED_NAME_OID: "KCA ☃",
|
||||
},
|
||||
)
|
||||
self.assertTrue(requests.verify_csr(csr))
|
||||
loaded = requests.parse_csr(requests.csr_der(csr))
|
||||
self.assertEqual(requests.request_info(loaded).subject, csr.subject)
|
||||
self.assertEqual(requests.attribute_values(loaded)[requests.CHALLENGE_PASSWORD_OID], "secret")
|
||||
der = requests.csr_der(loaded)
|
||||
self.assertIn(b"\x0c\x06secret", der)
|
||||
self.assertIn(b"\x0c\x07KCA \xe2\x98\x83", der)
|
||||
values = requests.attribute_values(loaded)
|
||||
self.assertEqual(values[requests.CHALLENGE_PASSWORD_OID], "secret")
|
||||
self.assertEqual(values[requests.UNSTRUCTURED_NAME_OID], "KCA ☃")
|
||||
|
||||
def test_decode_attribute_der_strings(self) -> None:
|
||||
long_value = "x" * 128
|
||||
cases = [
|
||||
(b"\x0c\x06secret", "secret"),
|
||||
(b"\x13\x04name", "name"),
|
||||
(b"\x16\x0bexample.com", "example.com"),
|
||||
(b"\x1e\x04\x00a\x00b", "ab"),
|
||||
(b"\x0c\x81\x80" + long_value.encode("ascii"), long_value),
|
||||
(b"legacy", "legacy"),
|
||||
]
|
||||
for encoded, expected in cases:
|
||||
with self.subTest(encoded=encoded):
|
||||
self.assertEqual(requests._decode_attribute_value(encoded), expected)
|
||||
|
||||
|
||||
class CrlTest(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user