aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2016-10-01 07:12:27 -0500
committerAlex Gaynor <alex.gaynor@gmail.com>2016-10-01 08:12:27 -0400
commit3feeec87b370958ea24595aa30d8d8e953a601f5 (patch)
tree7d51baa75e060f4d0cb00358db4f781ae06638cd
parent9e66d10732f96eb24861b1a252c8783e75121929 (diff)
downloadcryptography-3feeec87b370958ea24595aa30d8d8e953a601f5.tar.gz
cryptography-3feeec87b370958ea24595aa30d8d8e953a601f5.tar.bz2
cryptography-3feeec87b370958ea24595aa30d8d8e953a601f5.zip
support encoding IPv4Network and IPv6Network, useful for NameConstraints (#3182)
* support encoding IPv4Network and IPv6Network, useful for NameConstraints * add changelog entry * add more networks with full and no masking (/32, /128, /0) * parametrize the nc tests to fix coverage
-rw-r--r--CHANGELOG.rst2
-rw-r--r--src/cryptography/hazmat/backends/openssl/encode_asn1.py19
-rw-r--r--tests/test_x509.py38
3 files changed, 49 insertions, 10 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 328c4301..c9fa42cb 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -24,6 +24,8 @@ Changelog
when using OpenSSL 1.1.0.
* Added support for generating a
:meth:`~cryptography.x509.random_serial_number`.
+* Added support for encoding ``IPv4Network`` and ``IPv6Network`` in X.509
+ certificates for use with :class:`~cryptography.x509.NameConstraints`.
1.5.2 - 2016-09-26
~~~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
index 467aa88e..284c760c 100644
--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
@@ -5,12 +5,13 @@
from __future__ import absolute_import, division, print_function
import calendar
+import ipaddress
import idna
import six
-from cryptography import x509
+from cryptography import utils, x509
from cryptography.hazmat.backends.openssl.decode_asn1 import (
_CRL_ENTRY_REASON_ENUM_TO_CODE, _DISTPOINT_TYPE_FULLNAME,
_DISTPOINT_TYPE_RELATIVENAME
@@ -402,9 +403,19 @@ def _encode_general_name(backend, name):
elif isinstance(name, x509.IPAddress):
gn = backend._lib.GENERAL_NAME_new()
backend.openssl_assert(gn != backend._ffi.NULL)
- ipaddr = _encode_asn1_str(
- backend, name.value.packed, len(name.value.packed)
- )
+ if isinstance(name.value, ipaddress.IPv4Network):
+ packed = (
+ name.value.network_address.packed +
+ utils.int_to_bytes(((1 << 32) - name.value.num_addresses), 4)
+ )
+ elif isinstance(name.value, ipaddress.IPv6Network):
+ packed = (
+ name.value.network_address.packed +
+ utils.int_to_bytes((1 << 128) - name.value.num_addresses, 16)
+ )
+ else:
+ packed = name.value.packed
+ ipaddr = _encode_asn1_str(backend, packed, len(packed))
gn.type = backend._lib.GEN_IPADD
gn.d.iPAddress = ipaddr
elif isinstance(name, x509.OtherName):
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 7fd0e04c..d3b24ecc 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -2405,18 +2405,44 @@ class TestCertificateBuilder(object):
@pytest.mark.requires_backend_interface(interface=RSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
- def test_name_constraints(self, backend):
+ @pytest.mark.parametrize(
+ "nc",
+ [
+ x509.NameConstraints(
+ permitted_subtrees=[
+ x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/24")),
+ x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/29")),
+ x509.IPAddress(ipaddress.IPv4Network(u"127.0.0.1/32")),
+ x509.IPAddress(ipaddress.IPv4Network(u"8.0.0.0/8")),
+ x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
+ x509.IPAddress(
+ ipaddress.IPv6Network(u"FF:0:0:0:0:0:0:0/96")
+ ),
+ x509.IPAddress(
+ ipaddress.IPv6Network(u"FF:FF:0:0:0:0:0:0/128")
+ ),
+ ],
+ excluded_subtrees=[x509.DNSName(u"name.local")]
+ ),
+ x509.NameConstraints(
+ permitted_subtrees=[
+ x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
+ ],
+ excluded_subtrees=None
+ ),
+ x509.NameConstraints(
+ permitted_subtrees=None,
+ excluded_subtrees=[x509.DNSName(u"name.local")]
+ ),
+ ]
+ )
+ def test_name_constraints(self, nc, backend):
issuer_private_key = RSA_KEY_2048.private_key(backend)
subject_private_key = RSA_KEY_2048.private_key(backend)
not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
- excluded = [x509.DNSName(u"name.local")]
- nc = x509.NameConstraints(
- permitted_subtrees=None, excluded_subtrees=excluded
- )
-
cert = x509.CertificateBuilder().subject_name(
x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
).issuer_name(