aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-10-24 22:33:53 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-10-24 22:33:53 -0400
commit9bbf778b7dde2fab6d957f3b5b4422d5bb3ce5a0 (patch)
treeff17201a7be26481682fbd23ca140df94b4b6b59 /src
parentc6af93903be97612314cbd9a8d8e3264059419df (diff)
parenta82136f29d3d727b9449c73bb0d0d064c4b95c41 (diff)
downloadcryptography-9bbf778b7dde2fab6d957f3b5b4422d5bb3ce5a0.tar.gz
cryptography-9bbf778b7dde2fab6d957f3b5b4422d5bb3ce5a0.tar.bz2
cryptography-9bbf778b7dde2fab6d957f3b5b4422d5bb3ce5a0.zip
Merge pull request #2220 from reaperhulk/encode-cp
support encoding certificate policies in CertificateBuilder
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 58587b94..f7b5408a 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -94,6 +94,20 @@ def _encode_asn1_str(backend, data, length):
return s
+def _encode_asn1_utf8_str(backend, string):
+ """
+ Create an ASN1_UTF8STRING from a Python unicode string.
+ This object will be a ASN1_STRING with UTF8 type in OpenSSL and
+ can be decoded with ASN1_STRING_to_UTF8.
+ """
+ s = backend._lib.ASN1_UTF8STRING_new()
+ res = backend._lib.ASN1_STRING_set(
+ s, string.encode("utf8"), len(string.encode("utf8"))
+ )
+ backend.openssl_assert(res == 1)
+ return s
+
+
def _encode_asn1_str_gc(backend, data, length):
s = _encode_asn1_str(backend, data, length)
s = backend._ffi.gc(s, backend._lib.ASN1_OCTET_STRING_free)
@@ -136,6 +150,81 @@ def _encode_name_gc(backend, attributes):
return subject
+def _encode_certificate_policies(backend, certificate_policies):
+ cp = backend._lib.sk_POLICYINFO_new_null()
+ backend.openssl_assert(cp != backend._ffi.NULL)
+ cp = backend._ffi.gc(cp, backend._lib.sk_POLICYINFO_free)
+ for policy_info in certificate_policies:
+ pi = backend._lib.POLICYINFO_new()
+ backend.openssl_assert(pi != backend._ffi.NULL)
+ res = backend._lib.sk_POLICYINFO_push(cp, pi)
+ backend.openssl_assert(res >= 1)
+ oid = _txt2obj(backend, policy_info.policy_identifier.dotted_string)
+ pi.policyid = oid
+ if policy_info.policy_qualifiers:
+ pqis = backend._lib.sk_POLICYQUALINFO_new_null()
+ backend.openssl_assert(pqis != backend._ffi.NULL)
+ for qualifier in policy_info.policy_qualifiers:
+ pqi = backend._lib.POLICYQUALINFO_new()
+ backend.openssl_assert(pqi != backend._ffi.NULL)
+ res = backend._lib.sk_POLICYQUALINFO_push(pqis, pqi)
+ backend.openssl_assert(res >= 1)
+ if isinstance(qualifier, six.text_type):
+ pqi.pqualid = _txt2obj(
+ backend, x509.OID_CPS_QUALIFIER.dotted_string
+ )
+ pqi.d.cpsuri = _encode_asn1_str(
+ backend,
+ qualifier.encode("ascii"),
+ len(qualifier.encode("ascii"))
+ )
+ else:
+ assert isinstance(qualifier, x509.UserNotice)
+ pqi.pqualid = _txt2obj(
+ backend, x509.OID_CPS_USER_NOTICE.dotted_string
+ )
+ un = backend._lib.USERNOTICE_new()
+ backend.openssl_assert(un != backend._ffi.NULL)
+ pqi.d.usernotice = un
+ if qualifier.explicit_text:
+ un.exptext = _encode_asn1_utf8_str(
+ backend, qualifier.explicit_text
+ )
+
+ un.noticeref = _encode_notice_reference(
+ backend, qualifier.notice_reference
+ )
+
+ pi.qualifiers = pqis
+
+ pp = backend._ffi.new('unsigned char **')
+ r = backend._lib.i2d_CERTIFICATEPOLICIES(cp, pp)
+ backend.openssl_assert(r > 0)
+ pp = backend._ffi.gc(
+ pp, lambda pointer: backend._lib.OPENSSL_free(pointer[0])
+ )
+ return pp, r
+
+
+def _encode_notice_reference(backend, notice):
+ if notice is None:
+ return backend._ffi.NULL
+ else:
+ nr = backend._lib.NOTICEREF_new()
+ backend.openssl_assert(nr != backend._ffi.NULL)
+ # organization is a required field
+ nr.organization = _encode_asn1_utf8_str(backend, notice.organization)
+
+ notice_stack = backend._lib.sk_ASN1_INTEGER_new_null()
+ nr.noticenos = notice_stack
+ for number in notice.notice_numbers:
+ num = _encode_asn1_int(backend, number)
+ res = backend._lib.sk_ASN1_INTEGER_push(notice_stack, num)
+ backend.openssl_assert(res >= 1)
+
+ return nr
+
+
def _txt2obj(backend, name):
"""
Converts a Python string with an ASN.1 object ID in dotted form to a
@@ -487,6 +576,7 @@ _EXTENSION_ENCODE_HANDLERS = {
ExtensionOID.ISSUER_ALTERNATIVE_NAME: _encode_alt_name,
ExtensionOID.EXTENDED_KEY_USAGE: _encode_extended_key_usage,
ExtensionOID.AUTHORITY_KEY_IDENTIFIER: _encode_authority_key_identifier,
+ ExtensionOID.CERTIFICATE_POLICIES: _encode_certificate_policies,
ExtensionOID.AUTHORITY_INFORMATION_ACCESS: (
_encode_authority_information_access
),