summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2023-05-16 08:38:15 +0800
committerGitHub <noreply@github.com>2023-05-16 00:38:15 +0000
commit4b8187f8bc8265ca5aba76994ca8963b845c0705 (patch)
tree2130ea49c66a01cdca0fcd1879ad339d5c61396a
parent16fbebd345460fa173d851b226ecbf74abf9c3ec (diff)
downloadcryptography-4b8187f8bc8265ca5aba76994ca8963b845c0705.tar.gz
don't use a set (#8931)
* don't use a set We don't need one here and it creates ordering instability when iterating over an RDN * add a test
-rw-r--r--src/rust/src/x509/common.rs4
-rw-r--r--tests/x509/test_x509.py41
2 files changed, 43 insertions, 2 deletions
diff --git a/src/rust/src/x509/common.rs b/src/rust/src/x509/common.rs
index bc26dace3..8ceb51884 100644
--- a/src/rust/src/x509/common.rs
+++ b/src/rust/src/x509/common.rs
@@ -238,10 +238,10 @@ pub(crate) fn parse_rdn<'a>(
rdn: &asn1::SetOf<'a, AttributeTypeValue<'a>>,
) -> Result<pyo3::PyObject, CryptographyError> {
let x509_module = py.import(pyo3::intern!(py, "cryptography.x509"))?;
- let py_attrs = pyo3::types::PySet::empty(py)?;
+ let py_attrs = pyo3::types::PyList::empty(py);
for attribute in rdn.clone() {
let na = parse_name_attribute(py, attribute)?;
- py_attrs.add(na)?;
+ py_attrs.append(na)?;
}
Ok(x509_module
.call_method1(pyo3::intern!(py, "RelativeDistinguishedName"), (py_attrs,))?
diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py
index 5fd5265b7..88be1a176 100644
--- a/tests/x509/test_x509.py
+++ b/tests/x509/test_x509.py
@@ -2463,6 +2463,47 @@ class TestCertificateBuilder:
# GENERALIZED TIME
assert parsed.not_after_tag == 0x18
+ def test_rdns_preserve_iteration_order(
+ self, rsa_key_2048: rsa.RSAPrivateKey, backend
+ ):
+ """
+ This test checks that RDN ordering is consistent when loading
+ data from a certificate. Since the underlying RDN is an ASN.1
+ set these values get lexicographically ordered on encode and
+ the parsed value won't necessarily be in the same order as
+ the originally provided list. However, we want to make sure
+ that the order is always consistent since it confuses people
+ when it isn't.
+ """
+ name = x509.Name(
+ [
+ x509.RelativeDistinguishedName(
+ [
+ x509.NameAttribute(NameOID.TITLE, "Test"),
+ x509.NameAttribute(NameOID.COMMON_NAME, "Multivalue"),
+ x509.NameAttribute(NameOID.SURNAME, "RDNs"),
+ ]
+ ),
+ ]
+ )
+
+ cert = (
+ x509.CertificateBuilder()
+ .serial_number(1)
+ .issuer_name(name)
+ .subject_name(name)
+ .public_key(rsa_key_2048.public_key())
+ .not_valid_before(datetime.datetime(2020, 1, 1))
+ .not_valid_after(datetime.datetime(2038, 1, 1))
+ .sign(rsa_key_2048, hashes.SHA256(), backend)
+ )
+ loaded_cert = x509.load_pem_x509_certificate(
+ cert.public_bytes(encoding=serialization.Encoding.PEM)
+ )
+ assert next(iter(loaded_cert.subject.rdns[0])) == x509.NameAttribute(
+ NameOID.SURNAME, "RDNs"
+ )
+
@pytest.mark.parametrize(
("alg", "mgf_alg"),
[