Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/rust/src/x509/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,13 @@ fn parse_name_attribute<'p>(
"Long-form tags are not supported in NameAttribute values",
))
})?;
let py_tag = types::ASN1_TYPE_TO_ENUM.get(py)?.get_item(tag_val)?;
// A value whose tag is not one of the recognised string types is not a
// valid AttributeValue; surface it as a parse error rather than letting the
// dict lookup raise a bare KeyError.
let py_tag = types::ASN1_TYPE_TO_ENUM
.get(py)?
.get_item(tag_val)
.map_err(|_| asn1::ParseError::new(asn1::ParseErrorKind::InvalidValue))?;
let py_data = match attribute.value {
AttributeValue::AnyString(s) => {
if s.tag() == asn1::BitString::TAG {
Expand Down
28 changes: 28 additions & 0 deletions tests/x509/test_x509.py
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,34 @@ def test_invalid_unicode_name(self, backend):
with pytest.raises(ValueError, match="issuer"):
cert.issuer

def test_name_attribute_unsupported_type_tag(self, backend):
# A name attribute value whose ASN.1 tag is not one of the recognised
# string types must raise a ValueError, not a bare KeyError.
key = ec.generate_private_key(ec.SECP256R1())
cert = (
x509.CertificateBuilder()
.subject_name(
x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA")])
)
.issuer_name(
x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, "PyCA")])
)
.public_key(key.public_key())
.serial_number(1)
.not_valid_before(datetime.datetime(2020, 1, 1))
.not_valid_after(datetime.datetime(2030, 1, 1))
.sign(key, hashes.SHA256())
)
der = bytearray(cert.public_bytes(serialization.Encoding.DER))
# Find id-at-commonName (2.5.4.3) and replace the following
# UTF8String tag with an unsupported tag value. The first occurrence
# is the issuer name.
idx = der.index(b"\x06\x03\x55\x04\x03")
der[idx + 5] = 0x69
cert = x509.load_der_x509_certificate(bytes(der))
with pytest.raises(ValueError, match="issuer"):
cert.issuer

def test_non_ascii_dns_name(self, backend):
cert = _load_cert(
os.path.join("x509", "utf8-dnsname.pem"),
Expand Down
Loading