From cfb8aa2f39095d33d19b17123aed065dd5e9efd3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 19:16:36 -0500 Subject: name constraints - support IP addresses with netmask --- src/cryptography/hazmat/backends/openssl/x509.py | 29 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index d78c60fa..c2a32b2a 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -141,11 +141,30 @@ def _decode_general_name(backend, gn): oid = _obj2txt(backend, gn.d.registeredID) return x509.RegisteredID(x509.ObjectIdentifier(oid)) elif gn.type == backend._lib.GEN_IPADD: - return x509.IPAddress( - ipaddress.ip_address( - _asn1_string_to_bytes(backend, gn.d.iPAddress) - ) - ) + data = backend._ffi.buffer( + gn.d.iPAddress.data, gn.d.iPAddress.length + )[:] + data_len = len(data) + if data_len == 8 or data_len == 32: + # This is an IPv4 or IPv6 Network and not a single IP. This + # type of data appears in Name Constraints. Unfortunately, + # ipaddress doesn't support packed bytes + netmask. Additionally, + # IPv6Network can only handle CIDR rather than the full 16 byte + # netmask. To handle this we convert the netmask to integer, then + # find the first 0 bit, which will be the prefix. If another 1 + # bit is present after that the netmask is invalid. + base = ipaddress.ip_address(data[:data_len // 2]) + netmask = utils.int_from_bytes(data[data_len // 2:], 'big') + bits = bin(netmask)[2:] + prefix = bits.find('0') + if bits[prefix:].find('1') != -1: + raise ValueError("Invalid netmask") + + ip = ipaddress.ip_network(base.exploded + u"/{0}".format(prefix)) + else: + ip = ipaddress.ip_address(data) + + return x509.IPAddress(ip) elif gn.type == backend._lib.GEN_DIRNAME: return x509.DirectoryName( _decode_x509_name(backend, gn.d.directoryName) -- cgit v1.2.3 From a72ebaf84b9f41dcd9535ce9481ecc1966a7a930 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 21:07:37 -0500 Subject: simplify and handle /32 and /128 --- src/cryptography/hazmat/backends/openssl/x509.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index c2a32b2a..0aa2e2da 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -154,10 +154,14 @@ def _decode_general_name(backend, gn): # find the first 0 bit, which will be the prefix. If another 1 # bit is present after that the netmask is invalid. base = ipaddress.ip_address(data[:data_len // 2]) - netmask = utils.int_from_bytes(data[data_len // 2:], 'big') - bits = bin(netmask)[2:] + netmask = ipaddress.ip_address(data[data_len // 2:]) + bits = bin(int(netmask))[2:] prefix = bits.find('0') - if bits[prefix:].find('1') != -1: + # If no 0 bits are found it is a /32 or /128 + if prefix == -1: + prefix = len(bits) + + if b"1" in bits[prefix:]: raise ValueError("Invalid netmask") ip = ipaddress.ip_network(base.exploded + u"/{0}".format(prefix)) -- cgit v1.2.3 From 684362650a101109af681baecec8d454d9f9287e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Wed, 1 Jul 2015 23:13:05 -0500 Subject: not bytes --- src/cryptography/hazmat/backends/openssl/x509.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 0aa2e2da..ca6d2bcb 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -161,7 +161,7 @@ def _decode_general_name(backend, gn): if prefix == -1: prefix = len(bits) - if b"1" in bits[prefix:]: + if "1" in bits[prefix:]: raise ValueError("Invalid netmask") ip = ipaddress.ip_network(base.exploded + u"/{0}".format(prefix)) -- cgit v1.2.3 From 684e7c1b342a46495e05d5cbd831192534f182f8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sun, 12 Jul 2015 09:58:30 -0500 Subject: use helper method _asn1_string_to_bytes --- src/cryptography/hazmat/backends/openssl/x509.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index ca6d2bcb..096cbc9e 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -141,9 +141,7 @@ def _decode_general_name(backend, gn): oid = _obj2txt(backend, gn.d.registeredID) return x509.RegisteredID(x509.ObjectIdentifier(oid)) elif gn.type == backend._lib.GEN_IPADD: - data = backend._ffi.buffer( - gn.d.iPAddress.data, gn.d.iPAddress.length - )[:] + data = _asn1_string_to_bytes(backend, gn.d.iPAddress) data_len = len(data) if data_len == 8 or data_len == 32: # This is an IPv4 or IPv6 Network and not a single IP. This -- cgit v1.2.3