Fix issue #7513 - parsing of RFC4514 strings should reverse the order of RDNs (#7514)

* Fix issue #7513 - parsing of RFC4514 strings should reverse the order of RDNs

* Solving code formating issues

* Adding comment justifing the reversal of rdns on the RFC4514 parser

* Comment changes on CHANGELOG.rst

* fixing a typo on method link at CHANGELOG.rst

* Removing reference to protected class _RFC4514NameParser from CHANGELOG.rst

Co-authored-by: Alexandre Machado <alexandre@softnex.com.br>
This commit is contained in:
Alexandre Machado 2022-08-16 16:57:20 -03:00 committed by GitHub
parent 2477a09405
commit 2adfeb5684
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 26 deletions

View file

@ -46,7 +46,9 @@ Changelog
:class:`~cryptography.hazmat.primitives.kdf.kbkdf.KBKDFCMAC` now support
:attr:`~cryptography.hazmat.primitives.kdf.kbkdf.CounterLocation.MiddleFixed`
counter location.
* Fixed :rfc:`4514` name parsing to reverse the order of the RDNs according
to the section 2.1 of the RFC, affecting method :meth:`~cryptography.x509.Name.from_rfc4514_string`
.. _v37-0-4:
37.0.4 - 2022-07-05

View file

@ -414,13 +414,21 @@ class _RFC4514NameParser:
return val
def parse(self) -> Name:
"""
Parses the `data` string and converts it to a Name.
According to RFC4514 section 2.1 the RDNSequence must be
reversed when converting to string representation. So, when
we parse it, we need to reverse again to get the RDNs on the
correct order.
"""
rdns = [self._parse_rdn()]
while self._has_data():
self._read_char(",")
rdns.append(self._parse_rdn())
return Name(rdns)
return Name(reversed(rdns))
def _parse_rdn(self) -> RelativeDistinguishedName:
nas = [self._parse_na()]

View file

@ -59,14 +59,7 @@ class TestRFC4514:
Name(
[
RelativeDistinguishedName(
[
NameAttribute(
NameOID.ORGANIZATIONAL_UNIT_NAME, "Sales"
),
NameAttribute(
NameOID.COMMON_NAME, "J. Smith"
),
]
[NameAttribute(NameOID.DOMAIN_COMPONENT, "net")]
),
RelativeDistinguishedName(
[
@ -76,7 +69,14 @@ class TestRFC4514:
]
),
RelativeDistinguishedName(
[NameAttribute(NameOID.DOMAIN_COMPONENT, "net")]
[
NameAttribute(
NameOID.ORGANIZATIONAL_UNIT_NAME, "Sales"
),
NameAttribute(
NameOID.COMMON_NAME, "J. Smith"
),
]
),
]
),
@ -85,11 +85,11 @@ class TestRFC4514:
"CN=cryptography.io,O=PyCA,L=,ST=,C=US",
Name(
[
NameAttribute(NameOID.COMMON_NAME, "cryptography.io"),
NameAttribute(NameOID.ORGANIZATION_NAME, "PyCA"),
NameAttribute(NameOID.LOCALITY_NAME, ""),
NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, ""),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, ""),
NameAttribute(NameOID.LOCALITY_NAME, ""),
NameAttribute(NameOID.ORGANIZATION_NAME, "PyCA"),
NameAttribute(NameOID.COMMON_NAME, "cryptography.io"),
]
),
),
@ -97,9 +97,9 @@ class TestRFC4514:
r"C=US,CN=Joe \, Smith,DC=example",
Name(
[
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.COMMON_NAME, "Joe , Smith"),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(NameOID.COMMON_NAME, "Joe , Smith"),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
]
),
),
@ -107,9 +107,9 @@ class TestRFC4514:
r"C=US,CN=Jane \"J\,S\" Smith,DC=example",
Name(
[
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.COMMON_NAME, 'Jane "J,S" Smith'),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(NameOID.COMMON_NAME, 'Jane "J,S" Smith'),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
]
),
),
@ -117,9 +117,9 @@ class TestRFC4514:
'C=US,CN=\\"Jane J\\,S Smith\\",DC=example',
Name(
[
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.COMMON_NAME, '"Jane J,S Smith"'),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(NameOID.COMMON_NAME, '"Jane J,S Smith"'),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
]
),
),
@ -127,11 +127,11 @@ class TestRFC4514:
'C=US,CN=\\"Jane \\"J\\,S\\" Smith\\",DC=example',
Name(
[
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(
NameOID.COMMON_NAME, '"Jane "J,S" Smith"'
),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
]
),
),
@ -139,9 +139,9 @@ class TestRFC4514:
r"C=US,CN=Jane=Smith,DC=example",
Name(
[
NameAttribute(NameOID.COUNTRY_NAME, "US"),
NameAttribute(NameOID.COMMON_NAME, "Jane=Smith"),
NameAttribute(NameOID.DOMAIN_COMPONENT, "example"),
NameAttribute(NameOID.COMMON_NAME, "Jane=Smith"),
NameAttribute(NameOID.COUNTRY_NAME, "US"),
]
),
),
@ -170,8 +170,8 @@ class TestRFC4514:
"CN=Santa Claus,E=santa@north.pole", {"E": NameOID.EMAIL_ADDRESS}
) == Name(
[
NameAttribute(NameOID.COMMON_NAME, "Santa Claus"),
NameAttribute(NameOID.EMAIL_ADDRESS, "santa@north.pole"),
NameAttribute(NameOID.COMMON_NAME, "Santa Claus"),
]
)
@ -182,3 +182,24 @@ class TestRFC4514:
NameAttribute(NameOID.EMAIL_ADDRESS, "Santa Claus"),
]
)
def test_generate_parse(self):
name_value = Name(
[
NameAttribute(NameOID.COMMON_NAME, "Common Name 1"),
NameAttribute(NameOID.LOCALITY_NAME, "City for Name 1"),
NameAttribute(
NameOID.ORGANIZATION_NAME, "Name 1 Organization"
),
]
)
assert (
Name.from_rfc4514_string(name_value.rfc4514_string()) == name_value
)
name_string = "O=Organization,L=City,CN=Common Name"
assert (
Name.from_rfc4514_string(name_string).rfc4514_string()
== name_string
)