diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2015-07-12 10:22:12 -0500 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2015-07-12 10:22:12 -0500 |
commit | 548e85ed63964c38fd450a4ee8753a5be2c956d5 (patch) | |
tree | 0df927a52a8a0edb1ed132a499aa2cc6951c69b9 /src | |
parent | 534846178021b1a2993730409e8a3937b589ea12 (diff) | |
parent | 684e7c1b342a46495e05d5cbd831192534f182f8 (diff) | |
download | cryptography-548e85ed63964c38fd450a4ee8753a5be2c956d5.tar.gz cryptography-548e85ed63964c38fd450a4ee8753a5be2c956d5.tar.bz2 cryptography-548e85ed63964c38fd450a4ee8753a5be2c956d5.zip |
Merge pull request #2095 from reaperhulk/nc-the-hard-part-redux
name constraints - support IP addresses with netmask
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index d78c60fa..096cbc9e 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -141,11 +141,32 @@ 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 = _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 + # 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 = ipaddress.ip_address(data[data_len // 2:]) + bits = bin(int(netmask))[2:] + prefix = bits.find('0') + # If no 0 bits are found it is a /32 or /128 + if prefix == -1: + prefix = len(bits) + + if "1" in bits[prefix:]: + 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) |