aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-05-14 23:16:53 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-05-14 23:16:53 -0400
commit388f92ab5cfd5c60fcd8712e5889c4ded300959b (patch)
tree4ed919a89157fbf80ef9fbfd7abe56bc58dddd91 /src
parent4e1dd2e0e35ce3880380af2c6fa278de87b0df2f (diff)
parentf9531ada2f09accdb42156bca7917af5266220c6 (diff)
downloadcryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.tar.gz
cryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.tar.bz2
cryptography-388f92ab5cfd5c60fcd8712e5889c4ded300959b.zip
Merge branch 'master' into macstadium-travis
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/__about__.py2
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py343
-rw-r--r--src/cryptography/hazmat/bindings/openssl/ec.py15
-rw-r--r--src/cryptography/hazmat/bindings/openssl/evp.py4
-rw-r--r--src/cryptography/hazmat/bindings/openssl/ssl.py37
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509.py14
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509_vfy.py16
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509name.py5
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509v3.py85
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/dsa.py22
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/ec.py29
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/rsa.py22
-rw-r--r--src/cryptography/hazmat/primitives/interfaces/__init__.py351
-rw-r--r--src/cryptography/hazmat/primitives/kdf/hkdf.py4
-rw-r--r--src/cryptography/utils.py3
-rw-r--r--src/cryptography/x509.py409
16 files changed, 894 insertions, 467 deletions
diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py
index 0f8d4871..359cd819 100644
--- a/src/cryptography/__about__.py
+++ b/src/cryptography/__about__.py
@@ -14,7 +14,7 @@ __summary__ = ("cryptography is a package which provides cryptographic recipes"
" and primitives to Python developers.")
__uri__ = "https://github.com/pyca/cryptography"
-__version__ = "0.9.dev1"
+__version__ = "0.10.dev1"
__author__ = "The cryptography developers"
__email__ = "cryptography-dev@python.org"
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 7f633c76..07e54baa 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function
import datetime
import ipaddress
+from email.utils import parseaddr
import idna
@@ -37,33 +38,56 @@ def _obj2txt(backend, obj):
return backend._ffi.buffer(buf, res)[:].decode()
+def _asn1_integer_to_int(backend, asn1_int):
+ bn = backend._lib.ASN1_INTEGER_to_BN(asn1_int, backend._ffi.NULL)
+ assert bn != backend._ffi.NULL
+ bn = backend._ffi.gc(bn, backend._lib.BN_free)
+ return backend._bn_to_int(bn)
+
+
+def _asn1_string_to_utf8(backend, asn1_string):
+ buf = backend._ffi.new("unsigned char **")
+ res = backend._lib.ASN1_STRING_to_UTF8(buf, asn1_string)
+ assert res >= 0
+ assert buf[0] != backend._ffi.NULL
+ buf = backend._ffi.gc(
+ buf, lambda buffer: backend._lib.OPENSSL_free(buffer[0])
+ )
+ return backend._ffi.buffer(buf[0], res)[:].decode('utf8')
+
+
+def _build_x509_name_entry(backend, x509_name_entry):
+ obj = backend._lib.X509_NAME_ENTRY_get_object(x509_name_entry)
+ assert obj != backend._ffi.NULL
+ data = backend._lib.X509_NAME_ENTRY_get_data(x509_name_entry)
+ assert data != backend._ffi.NULL
+ value = _asn1_string_to_utf8(backend, data)
+ oid = _obj2txt(backend, obj)
+
+ return x509.NameAttribute(x509.ObjectIdentifier(oid), value)
+
+
def _build_x509_name(backend, x509_name):
count = backend._lib.X509_NAME_entry_count(x509_name)
attributes = []
for x in range(count):
entry = backend._lib.X509_NAME_get_entry(x509_name, x)
- obj = backend._lib.X509_NAME_ENTRY_get_object(entry)
- assert obj != backend._ffi.NULL
- data = backend._lib.X509_NAME_ENTRY_get_data(entry)
- assert data != backend._ffi.NULL
- buf = backend._ffi.new("unsigned char **")
- res = backend._lib.ASN1_STRING_to_UTF8(buf, data)
- assert res >= 0
- assert buf[0] != backend._ffi.NULL
- buf = backend._ffi.gc(
- buf, lambda buffer: backend._lib.OPENSSL_free(buffer[0])
- )
- value = backend._ffi.buffer(buf[0], res)[:].decode('utf8')
- oid = _obj2txt(backend, obj)
- attributes.append(
- x509.NameAttribute(
- x509.ObjectIdentifier(oid), value
- )
- )
+ attributes.append(_build_x509_name_entry(backend, entry))
return x509.Name(attributes)
+def _build_general_names(backend, gns):
+ num = backend._lib.sk_GENERAL_NAME_num(gns)
+ names = []
+ for i in range(num):
+ gn = backend._lib.sk_GENERAL_NAME_value(gns, i)
+ assert gn != backend._ffi.NULL
+ names.append(_build_general_name(backend, gn))
+
+ return names
+
+
def _build_general_name(backend, gn):
if gn.type == backend._lib.GEN_DNS:
data = backend._ffi.buffer(gn.d.dNSName.data, gn.d.dNSName.length)[:]
@@ -107,6 +131,27 @@ def _build_general_name(backend, gn):
return x509.DirectoryName(
_build_x509_name(backend, gn.d.directoryName)
)
+ elif gn.type == backend._lib.GEN_EMAIL:
+ data = backend._ffi.buffer(
+ gn.d.rfc822Name.data, gn.d.rfc822Name.length
+ )[:].decode("ascii")
+ name, address = parseaddr(data)
+ parts = address.split(u"@")
+ if name or len(parts) > 2 or not address:
+ # parseaddr has found a name (e.g. Name <email>) or the split
+ # has found more than 2 parts (which means more than one @ sign)
+ # or the entire value is an empty string.
+ raise ValueError("Invalid rfc822name value")
+ elif len(parts) == 1:
+ # Single label email name. This is valid for local delivery. No
+ # IDNA decoding can be done since there is no domain component.
+ return x509.RFC822Name(address)
+ else:
+ # A normal email of the form user@domain.com. Let's attempt to
+ # decode the domain component and return the entire address.
+ return x509.RFC822Name(
+ parts[0] + u"@" + idna.decode(parts[1])
+ )
else:
# otherName, x400Address or ediPartyName
raise x509.UnsupportedGeneralNameType(
@@ -160,12 +205,7 @@ class _Certificate(object):
def serial(self):
asn1_int = self._backend._lib.X509_get_serialNumber(self._x509)
assert asn1_int != self._backend._ffi.NULL
- bn = self._backend._lib.ASN1_INTEGER_to_BN(
- asn1_int, self._backend._ffi.NULL
- )
- assert bn != self._backend._ffi.NULL
- bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free)
- return self._backend._bn_to_int(bn)
+ return _asn1_integer_to_int(self._backend, asn1_int)
def public_key(self):
pkey = self._backend._lib.X509_get_pubkey(self._x509)
@@ -245,6 +285,16 @@ class _Certificate(object):
value = self._build_key_usage(ext)
elif oid == x509.OID_SUBJECT_ALTERNATIVE_NAME:
value = self._build_subject_alt_name(ext)
+ elif oid == x509.OID_EXTENDED_KEY_USAGE:
+ value = self._build_extended_key_usage(ext)
+ elif oid == x509.OID_AUTHORITY_KEY_IDENTIFIER:
+ value = self._build_authority_key_identifier(ext)
+ elif oid == x509.OID_AUTHORITY_INFORMATION_ACCESS:
+ value = self._build_authority_information_access(ext)
+ elif oid == x509.OID_CERTIFICATE_POLICIES:
+ value = self._build_certificate_policies(ext)
+ elif oid == x509.OID_CRL_DISTRIBUTION_POINTS:
+ value = self._build_crl_distribution_points(ext)
elif critical:
raise x509.UnsupportedExtension(
"{0} is not currently supported".format(oid), oid
@@ -259,6 +309,75 @@ class _Certificate(object):
return x509.Extensions(extensions)
+ def _build_certificate_policies(self, ext):
+ cp = self._backend._ffi.cast(
+ "Cryptography_STACK_OF_POLICYINFO *",
+ self._backend._lib.X509V3_EXT_d2i(ext)
+ )
+ assert cp != self._backend._ffi.NULL
+ cp = self._backend._ffi.gc(cp, self._backend._lib.sk_POLICYINFO_free)
+ num = self._backend._lib.sk_POLICYINFO_num(cp)
+ certificate_policies = []
+ for i in range(num):
+ qualifiers = None
+ pi = self._backend._lib.sk_POLICYINFO_value(cp, i)
+ oid = x509.ObjectIdentifier(_obj2txt(self._backend, pi.policyid))
+ if pi.qualifiers != self._backend._ffi.NULL:
+ qnum = self._backend._lib.sk_POLICYQUALINFO_num(pi.qualifiers)
+ qualifiers = []
+ for j in range(qnum):
+ pqi = self._backend._lib.sk_POLICYQUALINFO_value(
+ pi.qualifiers, j
+ )
+ pqualid = x509.ObjectIdentifier(
+ _obj2txt(self._backend, pqi.pqualid)
+ )
+ if pqualid == x509.OID_CPS_QUALIFIER:
+ cpsuri = self._backend._ffi.buffer(
+ pqi.d.cpsuri.data, pqi.d.cpsuri.length
+ )[:].decode('ascii')
+ qualifiers.append(cpsuri)
+ elif pqualid == x509.OID_CPS_USER_NOTICE:
+ user_notice = self._build_user_notice(pqi.d.usernotice)
+ qualifiers.append(user_notice)
+
+ certificate_policies.append(
+ x509.PolicyInformation(oid, qualifiers)
+ )
+
+ return x509.CertificatePolicies(certificate_policies)
+
+ def _build_user_notice(self, un):
+ explicit_text = None
+ notice_reference = None
+
+ if un.exptext != self._backend._ffi.NULL:
+ explicit_text = _asn1_string_to_utf8(self._backend, un.exptext)
+
+ if un.noticeref != self._backend._ffi.NULL:
+ organization = _asn1_string_to_utf8(
+ self._backend, un.noticeref.organization
+ )
+
+ num = self._backend._lib.sk_ASN1_INTEGER_num(
+ un.noticeref.noticenos
+ )
+ notice_numbers = []
+ for i in range(num):
+ asn1_int = self._backend._lib.sk_ASN1_INTEGER_value(
+ un.noticeref.noticenos, i
+ )
+ notice_num = _asn1_integer_to_int(
+ self._backend, asn1_int
+ )
+ notice_numbers.append(notice_num)
+
+ notice_reference = x509.NoticeReference(
+ organization, notice_numbers
+ )
+
+ return x509.UserNotice(notice_reference, explicit_text)
+
def _build_basic_constraints(self, ext):
bc_st = self._backend._lib.X509V3_EXT_d2i(ext)
assert bc_st != self._backend._ffi.NULL
@@ -275,12 +394,9 @@ class _Certificate(object):
if basic_constraints.pathlen == self._backend._ffi.NULL:
path_length = None
else:
- bn = self._backend._lib.ASN1_INTEGER_to_BN(
- basic_constraints.pathlen, self._backend._ffi.NULL
+ path_length = _asn1_integer_to_int(
+ self._backend, basic_constraints.pathlen
)
- assert bn != self._backend._ffi.NULL
- bn = self._backend._ffi.gc(bn, self._backend._lib.BN_free)
- path_length = self._backend._bn_to_int(bn)
return x509.BasicConstraints(ca, path_length)
@@ -297,6 +413,57 @@ class _Certificate(object):
self._backend._ffi.buffer(asn1_string.data, asn1_string.length)[:]
)
+ def _build_authority_key_identifier(self, ext):
+ akid = self._backend._lib.X509V3_EXT_d2i(ext)
+ assert akid != self._backend._ffi.NULL
+ akid = self._backend._ffi.cast("AUTHORITY_KEYID *", akid)
+ akid = self._backend._ffi.gc(
+ akid, self._backend._lib.AUTHORITY_KEYID_free
+ )
+ key_identifier = None
+ authority_cert_issuer = None
+ authority_cert_serial_number = None
+
+ if akid.keyid != self._backend._ffi.NULL:
+ key_identifier = self._backend._ffi.buffer(
+ akid.keyid.data, akid.keyid.length
+ )[:]
+
+ if akid.issuer != self._backend._ffi.NULL:
+ authority_cert_issuer = _build_general_names(
+ self._backend, akid.issuer
+ )
+
+ if akid.serial != self._backend._ffi.NULL:
+ authority_cert_serial_number = _asn1_integer_to_int(
+ self._backend, akid.serial
+ )
+
+ return x509.AuthorityKeyIdentifier(
+ key_identifier, authority_cert_issuer, authority_cert_serial_number
+ )
+
+ def _build_authority_information_access(self, ext):
+ aia = self._backend._lib.X509V3_EXT_d2i(ext)
+ assert aia != self._backend._ffi.NULL
+ aia = self._backend._ffi.cast(
+ "Cryptography_STACK_OF_ACCESS_DESCRIPTION *", aia
+ )
+ aia = self._backend._ffi.gc(
+ aia, self._backend._lib.sk_ACCESS_DESCRIPTION_free
+ )
+ num = self._backend._lib.sk_ACCESS_DESCRIPTION_num(aia)
+ access_descriptions = []
+ for i in range(num):
+ ad = self._backend._lib.sk_ACCESS_DESCRIPTION_value(aia, i)
+ assert ad.method != self._backend._ffi.NULL
+ oid = x509.ObjectIdentifier(_obj2txt(self._backend, ad.method))
+ assert ad.location != self._backend._ffi.NULL
+ gn = _build_general_name(self._backend, ad.location)
+ access_descriptions.append(x509.AccessDescription(oid, gn))
+
+ return x509.AuthorityInformationAccess(access_descriptions)
+
def _build_key_usage(self, ext):
bit_string = self._backend._lib.X509V3_EXT_d2i(ext)
assert bit_string != self._backend._ffi.NULL
@@ -332,17 +499,121 @@ class _Certificate(object):
)
assert gns != self._backend._ffi.NULL
gns = self._backend._ffi.gc(gns, self._backend._lib.GENERAL_NAMES_free)
- num = self._backend._lib.sk_GENERAL_NAME_num(gns)
- general_names = []
+ general_names = _build_general_names(self._backend, gns)
+
+ return x509.SubjectAlternativeName(general_names)
+
+ def _build_extended_key_usage(self, ext):
+ sk = self._backend._ffi.cast(
+ "Cryptography_STACK_OF_ASN1_OBJECT *",
+ self._backend._lib.X509V3_EXT_d2i(ext)
+ )
+ assert sk != self._backend._ffi.NULL
+ sk = self._backend._ffi.gc(sk, self._backend._lib.sk_ASN1_OBJECT_free)
+ num = self._backend._lib.sk_ASN1_OBJECT_num(sk)
+ ekus = []
for i in range(num):
- gn = self._backend._lib.sk_GENERAL_NAME_value(gns, i)
- assert gn != self._backend._ffi.NULL
- value = _build_general_name(self._backend, gn)
+ obj = self._backend._lib.sk_ASN1_OBJECT_value(sk, i)
+ assert obj != self._backend._ffi.NULL
+ oid = x509.ObjectIdentifier(_obj2txt(self._backend, obj))
+ ekus.append(oid)
- general_names.append(value)
+ return x509.ExtendedKeyUsage(ekus)
- return x509.SubjectAlternativeName(general_names)
+ def _build_crl_distribution_points(self, ext):
+ cdps = self._backend._ffi.cast(
+ "Cryptography_STACK_OF_DIST_POINT *",
+ self._backend._lib.X509V3_EXT_d2i(ext)
+ )
+ assert cdps != self._backend._ffi.NULL
+ cdps = self._backend._ffi.gc(
+ cdps, self._backend._lib.sk_DIST_POINT_free)
+ num = self._backend._lib.sk_DIST_POINT_num(cdps)
+
+ dist_points = []
+ for i in range(num):
+ full_name = None
+ relative_name = None
+ crl_issuer = None
+ reasons = None
+ cdp = self._backend._lib.sk_DIST_POINT_value(cdps, i)
+ if cdp.reasons != self._backend._ffi.NULL:
+ # We will check each bit from RFC 5280
+ # ReasonFlags ::= BIT STRING {
+ # unused (0),
+ # keyCompromise (1),
+ # cACompromise (2),
+ # affiliationChanged (3),
+ # superseded (4),
+ # cessationOfOperation (5),
+ # certificateHold (6),
+ # privilegeWithdrawn (7),
+ # aACompromise (8) }
+ reasons = []
+ get_bit = self._backend._lib.ASN1_BIT_STRING_get_bit
+ if get_bit(cdp.reasons, 1):
+ reasons.append(x509.ReasonFlags.key_compromise)
+
+ if get_bit(cdp.reasons, 2):
+ reasons.append(x509.ReasonFlags.ca_compromise)
+
+ if get_bit(cdp.reasons, 3):
+ reasons.append(x509.ReasonFlags.affiliation_changed)
+
+ if get_bit(cdp.reasons, 4):
+ reasons.append(x509.ReasonFlags.superseded)
+
+ if get_bit(cdp.reasons, 5):
+ reasons.append(x509.ReasonFlags.cessation_of_operation)
+
+ if get_bit(cdp.reasons, 6):
+ reasons.append(x509.ReasonFlags.certificate_hold)
+
+ if get_bit(cdp.reasons, 7):
+ reasons.append(x509.ReasonFlags.privilege_withdrawn)
+
+ if get_bit(cdp.reasons, 8):
+ reasons.append(x509.ReasonFlags.aa_compromise)
+
+ reasons = frozenset(reasons)
+
+ if cdp.CRLissuer != self._backend._ffi.NULL:
+ crl_issuer = _build_general_names(self._backend, cdp.CRLissuer)
+
+ # Certificates may have a crl_issuer/reasons and no distribution
+ # point so make sure it's not null.
+ if cdp.distpoint != self._backend._ffi.NULL:
+ # Type 0 is fullName, there is no #define for it in the code.
+ if cdp.distpoint.type == 0:
+ full_name = _build_general_names(
+ self._backend, cdp.distpoint.name.fullname
+ )
+ # OpenSSL code doesn't test for a specific type for
+ # relativename, everything that isn't fullname is considered
+ # relativename.
+ else:
+ rns = cdp.distpoint.name.relativename
+ rnum = self._backend._lib.sk_X509_NAME_ENTRY_num(rns)
+ attributes = []
+ for i in range(rnum):
+ rn = self._backend._lib.sk_X509_NAME_ENTRY_value(
+ rns, i
+ )
+ assert rn != self._backend._ffi.NULL
+ attributes.append(
+ _build_x509_name_entry(self._backend, rn)
+ )
+
+ relative_name = x509.Name(attributes)
+
+ dist_points.append(
+ x509.DistributionPoint(
+ full_name, relative_name, reasons, crl_issuer
+ )
+ )
+
+ return x509.CRLDistributionPoints(dist_points)
@utils.register_interface(x509.CertificateSigningRequest)
diff --git a/src/cryptography/hazmat/bindings/openssl/ec.py b/src/cryptography/hazmat/bindings/openssl/ec.py
index 84a596eb..c5052d36 100644
--- a/src/cryptography/hazmat/bindings/openssl/ec.py
+++ b/src/cryptography/hazmat/bindings/openssl/ec.py
@@ -17,6 +17,7 @@ static const int Cryptography_HAS_EC;
static const int Cryptography_HAS_EC_1_0_1;
static const int Cryptography_HAS_EC_NISTP_64_GCC_128;
static const int Cryptography_HAS_EC2M;
+static const int Cryptography_HAS_EC_1_0_2;
static const int OPENSSL_EC_NAMED_CURVE;
@@ -188,6 +189,8 @@ const EC_METHOD *EC_GFp_nistp521_method();
const EC_METHOD *EC_GF2m_simple_method();
int EC_METHOD_get_field_type(const EC_METHOD *);
+
+const char *EC_curve_nid2nist(int);
"""
CUSTOMIZATIONS = """
@@ -385,6 +388,14 @@ EC_GROUP *(*EC_GROUP_new_curve_GF2m)(
#else
static const long Cryptography_HAS_EC2M = 1;
#endif
+
+#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000200f || \
+ defined(LIBRESSL_VERSION_NUMBER)
+static const long Cryptography_HAS_EC_1_0_2 = 0;
+const char *(*EC_curve_nid2nist)(int) = NULL;
+#else
+static const long Cryptography_HAS_EC_1_0_2 = 1;
+#endif
"""
CONDITIONAL_NAMES = {
@@ -478,4 +489,8 @@ CONDITIONAL_NAMES = {
"EC_GROUP_get_curve_GF2m",
"EC_GROUP_new_curve_GF2m",
],
+
+ "Cryptography_HAS_EC_1_0_2": [
+ "EC_curve_nid2nist",
+ ],
}
diff --git a/src/cryptography/hazmat/bindings/openssl/evp.py b/src/cryptography/hazmat/bindings/openssl/evp.py
index 780ce900..93aa83de 100644
--- a/src/cryptography/hazmat/bindings/openssl/evp.py
+++ b/src/cryptography/hazmat/bindings/openssl/evp.py
@@ -28,6 +28,7 @@ typedef struct evp_pkey_st {
typedef ... EVP_PKEY_CTX;
static const int EVP_PKEY_RSA;
static const int EVP_PKEY_DSA;
+static const int EVP_PKEY_DH;
static const int EVP_PKEY_EC;
static const int EVP_MAX_MD_SIZE;
static const int EVP_CTRL_GCM_SET_IVLEN;
@@ -154,6 +155,7 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t,
const unsigned char *, size_t);
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *);
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *);
+int EVP_PKEY_id(const EVP_PKEY *);
/* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5
we should move these back to FUNCTIONS. */
@@ -221,6 +223,7 @@ int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
const unsigned char *, size_t) = NULL;
int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
const unsigned char *, size_t) = NULL;
+int (*EVP_PKEY_id)(const EVP_PKEY *) = NULL;
#endif
#ifdef OPENSSL_NO_EC
int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL;
@@ -252,6 +255,7 @@ CONDITIONAL_NAMES = {
"Cryptography_EVP_PKEY_decrypt",
"EVP_PKEY_decrypt_init",
"EVP_PKEY_CTX_set_signature_md",
+ "EVP_PKEY_id",
],
"Cryptography_HAS_EC": [
"EVP_PKEY_assign_EC_KEY",
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
index 4a824ae5..5445f3c9 100644
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -22,6 +22,8 @@ static const long Cryptography_HAS_SECURE_RENEGOTIATION;
static const long Cryptography_HAS_COMPRESSION;
static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB;
static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP;
+static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE;
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY;
/* Internally invented symbol to tell us if SNI is supported */
static const long Cryptography_HAS_TLSEXT_HOSTNAME;
@@ -164,6 +166,7 @@ const char *SSL_state_string_long(const SSL *);
SSL_SESSION *SSL_get1_session(SSL *);
int SSL_set_session(SSL *, SSL_SESSION *);
int SSL_get_verify_mode(const SSL *);
+void SSL_set_verify(SSL *, int, int (*)(int, X509_STORE_CTX *));
void SSL_set_verify_depth(SSL *, int);
int SSL_get_verify_depth(const SSL *);
int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *);
@@ -325,7 +328,10 @@ void SSL_CTX_set_tlsext_servername_callback(
is fraught with peril thanks to OS distributions we check some constants
to determine if they are supported or not */
long SSL_set_tlsext_status_ocsp_resp(SSL *, unsigned char *, int);
+long SSL_get_tlsext_status_ocsp_resp(SSL *, const unsigned char **);
+long SSL_set_tlsext_status_type(SSL *, long);
long SSL_CTX_set_tlsext_status_cb(SSL_CTX *, int(*)(SSL *, void *));
+long SSL_CTX_set_tlsext_status_arg(SSL_CTX *, void *);
long SSL_session_reused(SSL *);
@@ -379,6 +385,8 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX *,
void *),
void *);
void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *);
+
+long SSL_get_server_tmp_key(SSL *, EVP_PKEY **);
"""
CUSTOMIZATIONS = """
@@ -427,6 +435,7 @@ static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB = 1;
#else
static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB = 0;
long (*SSL_CTX_set_tlsext_status_cb)(SSL_CTX *, int(*)(SSL *, void *)) = NULL;
+long (*SSL_CTX_set_tlsext_status_arg)(SSL_CTX *, void *) = NULL;
#endif
#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP
@@ -434,6 +443,14 @@ static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP = 1;
#else
static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP = 0;
long (*SSL_set_tlsext_status_ocsp_resp)(SSL *, unsigned char *, int) = NULL;
+long (*SSL_get_tlsext_status_ocsp_resp)(SSL *, const unsigned char **) = NULL;
+#endif
+
+#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE
+static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE = 1;
+#else
+static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE = 0;
+long (*SSL_set_tlsext_status_type)(SSL *, long) = NULL;
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
@@ -572,6 +589,7 @@ static const long Cryptography_HAS_ALPN = 0;
#else
static const long Cryptography_HAS_ALPN = 1;
#endif
+
#if defined(OPENSSL_NO_COMP) || defined(LIBRESSL_VERSION_NUMBER)
static const long Cryptography_HAS_COMPRESSION = 0;
typedef void COMP_METHOD;
@@ -579,6 +597,13 @@ typedef void COMP_METHOD;
static const long Cryptography_HAS_COMPRESSION = 1;
#endif
+#if defined(SSL_CTRL_GET_SERVER_TMP_KEY)
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 1;
+#else
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 0;
+long (*SSL_get_server_tmp_key)(SSL *, EVP_PKEY **) = NULL;
+#endif
+
"""
CONDITIONAL_NAMES = {
@@ -616,10 +641,16 @@ CONDITIONAL_NAMES = {
"Cryptography_HAS_TLSEXT_STATUS_REQ_CB": [
"SSL_CTX_set_tlsext_status_cb",
+ "SSL_CTX_set_tlsext_status_arg"
],
"Cryptography_HAS_STATUS_REQ_OCSP_RESP": [
"SSL_set_tlsext_status_ocsp_resp",
+ "SSL_get_tlsext_status_ocsp_resp",
+ ],
+
+ "Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE": [
+ "SSL_set_tlsext_status_type",
],
"Cryptography_HAS_RELEASE_BUFFERS": [
@@ -675,5 +706,9 @@ CONDITIONAL_NAMES = {
"SSL_get_current_compression",
"SSL_get_current_expansion",
"SSL_COMP_get_name",
- ]
+ ],
+
+ "Cryptography_HAS_GET_SERVER_TMP_KEY": [
+ "SSL_get_server_tmp_key",
+ ],
}
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index a1fb7ffb..caa33969 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -64,6 +64,7 @@ typedef struct {
typedef struct {
X509_CRL_INFO *crl;
+ X509_ALGOR *sig_alg;
...;
} X509_CRL;
@@ -145,9 +146,13 @@ X509_EXTENSION *X509_delete_ext(X509 *, int);
X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *);
X509_EXTENSION *X509_get_ext(X509 *, int);
int X509_get_ext_by_NID(X509 *, int, int);
+
int X509_EXTENSION_get_critical(X509_EXTENSION *);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *);
void X509_EXTENSION_free(X509_EXTENSION *);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **,
+ ASN1_OBJECT *, int,
+ ASN1_OCTET_STRING *);
int i2d_X509(X509 *, unsigned char **);
@@ -155,11 +160,13 @@ int X509_REQ_set_version(X509_REQ *, long);
X509_REQ *X509_REQ_new(void);
void X509_REQ_free(X509_REQ *);
int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);
+int X509_REQ_set_subject_name(X509_REQ *, X509_NAME *);
int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);
int X509_REQ_verify(X509_REQ *, EVP_PKEY *);
int X509_REQ_digest(const X509_REQ *, const EVP_MD *,
unsigned char *, unsigned int *);
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);
+int X509_REQ_print(BIO *, X509_REQ *);
int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long);
int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int);
@@ -183,6 +190,7 @@ int i2d_X509_CRL_bio(BIO *, X509_CRL *);
int X509_CRL_print(BIO *, X509_CRL *);
int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *);
int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *);
+int X509_CRL_verify(X509_CRL *, EVP_PKEY *);
int X509_CRL_get_ext_count(X509_CRL *);
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int);
int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int);
@@ -285,6 +293,7 @@ int X509_CRL_get_version(X509_CRL *);
ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *);
ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *);
X509_NAME *X509_CRL_get_issuer(X509_CRL *);
+Cryptography_STACK_OF_X509_REVOKED *X509_CRL_get_REVOKED(X509_CRL *);
/* These aren't macros these arguments are all const X on openssl > 1.0.x */
int X509_CRL_set_lastUpdate(X509_CRL *, ASN1_TIME *);
@@ -303,6 +312,11 @@ EC_KEY *d2i_EC_PUBKEY_bio(BIO *, EC_KEY **);
int i2d_EC_PUBKEY_bio(BIO *, EC_KEY *);
EC_KEY *d2i_ECPrivateKey_bio(BIO *, EC_KEY **);
int i2d_ECPrivateKey_bio(BIO *, EC_KEY *);
+
+// declared in safestack
+int sk_ASN1_OBJECT_num(Cryptography_STACK_OF_ASN1_OBJECT *);
+ASN1_OBJECT *sk_ASN1_OBJECT_value(Cryptography_STACK_OF_ASN1_OBJECT *, int);
+void sk_ASN1_OBJECT_free(Cryptography_STACK_OF_ASN1_OBJECT *);
"""
CUSTOMIZATIONS = """
diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
index 1f75b86f..02631409 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
@@ -29,9 +29,23 @@ static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE;
typedef ... Cryptography_STACK_OF_ASN1_OBJECT;
typedef ... X509_STORE;
-typedef ... X509_STORE_CTX;
typedef ... X509_VERIFY_PARAM;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+struct x509_store_ctx_st {
+ X509_STORE *ctx;
+ int current_method;
+ X509 *cert;
+ Cryptography_STACK_OF_X509 *untrusted;
+ Cryptography_STACK_OF_X509_CRL *crls;
+ X509_VERIFY_PARAM *param;
+ void *other_ctx;
+ int (*verify)(X509_STORE_CTX *);
+ int (*verify_cb)(int, X509_STORE_CTX *);
+ int (*get_issuer)(X509 **, X509_STORE_CTX *, X509 *);
+ ...;
+};
+
/* While these are defined in the source as ints, they're tagged here
as longs, just in case they ever grow to large, such as what we saw
with OP_ALL. */
diff --git a/src/cryptography/hazmat/bindings/openssl/x509name.py b/src/cryptography/hazmat/bindings/openssl/x509name.py
index bda92eb7..a7dde87c 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509name.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509name.py
@@ -11,12 +11,14 @@ INCLUDES = """
* See the comment above Cryptography_STACK_OF_X509 in x509.py
*/
typedef STACK_OF(X509_NAME) Cryptography_STACK_OF_X509_NAME;
+typedef STACK_OF(X509_NAME_ENTRY) Cryptography_STACK_OF_X509_NAME_ENTRY;
"""
TYPES = """
typedef ... X509_NAME;
typedef ... X509_NAME_ENTRY;
typedef ... Cryptography_STACK_OF_X509_NAME;
+typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY;
"""
FUNCTIONS = """
@@ -48,6 +50,9 @@ int sk_X509_NAME_num(Cryptography_STACK_OF_X509_NAME *);
int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *);
X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
+int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *);
+X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value(
+ Cryptography_STACK_OF_X509_NAME_ENTRY *, int);
"""
CUSTOMIZATIONS = """
diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py
index 28dd7f32..054ab624 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509v3.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py
@@ -19,9 +19,19 @@ typedef LHASH_OF(CONF_VALUE) Cryptography_LHASH_OF_CONF_VALUE;
#else
typedef LHASH Cryptography_LHASH_OF_CONF_VALUE;
#endif
+typedef STACK_OF(ACCESS_DESCRIPTION) Cryptography_STACK_OF_ACCESS_DESCRIPTION;
+typedef STACK_OF(DIST_POINT) Cryptography_STACK_OF_DIST_POINT;
+typedef STACK_OF(POLICYQUALINFO) Cryptography_STACK_OF_POLICYQUALINFO;
+typedef STACK_OF(POLICYINFO) Cryptography_STACK_OF_POLICYINFO;
+typedef STACK_OF(ASN1_INTEGER) Cryptography_STACK_OF_ASN1_INTEGER;
"""
TYPES = """
+typedef ... Cryptography_STACK_OF_ACCESS_DESCRIPTION;
+typedef ... Cryptography_STACK_OF_POLICYQUALINFO;
+typedef ... Cryptography_STACK_OF_POLICYINFO;
+typedef ... Cryptography_STACK_OF_ASN1_INTEGER;
+
typedef struct {
X509 *issuer_cert;
X509 *subject_cert;
@@ -92,7 +102,55 @@ typedef struct {
ASN1_INTEGER *serial;
} AUTHORITY_KEYID;
+typedef struct {
+ ASN1_OBJECT *method;
+ GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
typedef ... Cryptography_LHASH_OF_CONF_VALUE;
+
+
+typedef ... Cryptography_STACK_OF_DIST_POINT;
+
+typedef struct {
+ int type;
+ union {
+ GENERAL_NAMES *fullname;
+ Cryptography_STACK_OF_X509_NAME_ENTRY *relativename;
+ } name;
+ ...;
+} DIST_POINT_NAME;
+
+typedef struct {
+ DIST_POINT_NAME *distpoint;
+ ASN1_BIT_STRING *reasons;
+ GENERAL_NAMES *CRLissuer;
+ ...;
+} DIST_POINT;
+
+typedef struct {
+ ASN1_STRING *organization;
+ Cryptography_STACK_OF_ASN1_INTEGER *noticenos;
+} NOTICEREF;
+
+typedef struct {
+ NOTICEREF *noticeref;
+ ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct {
+ ASN1_OBJECT *pqualid;
+ union {
+ ASN1_IA5STRING *cpsuri;
+ USERNOTICE *usernotice;
+ ASN1_TYPE *other;
+ } d;
+} POLICYQUALINFO;
+
+typedef struct {
+ ASN1_OBJECT *policyid;
+ Cryptography_STACK_OF_POLICYQUALINFO *qualifiers;
+} POLICYINFO;
"""
@@ -108,12 +166,23 @@ void *X509V3_EXT_d2i(X509_EXTENSION *);
MACROS = """
/* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the
x509v3.h header. */
+int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **);
+BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void);
void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *);
+/* This is a macro defined by a call to DECLARE_ASN1_FUNCTIONS in the
+ x509v3.h header. */
+void AUTHORITY_KEYID_free(AUTHORITY_KEYID *);
void *X509V3_set_ctx_nodb(X509V3_CTX *);
int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
+int sk_ACCESS_DESCRIPTION_num(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
+ACCESS_DESCRIPTION *sk_ACCESS_DESCRIPTION_value(
+ Cryptography_STACK_OF_ACCESS_DESCRIPTION *, int
+);
+void sk_ACCESS_DESCRIPTION_free(Cryptography_STACK_OF_ACCESS_DESCRIPTION *);
+
X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *,
X509V3_CTX *, int, char *);
@@ -121,6 +190,22 @@ X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *,
const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *);
const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int);
+void sk_DIST_POINT_free(Cryptography_STACK_OF_DIST_POINT *);
+int sk_DIST_POINT_num(Cryptography_STACK_OF_DIST_POINT *);
+DIST_POINT *sk_DIST_POINT_value(Cryptography_STACK_OF_DIST_POINT *, int);
+
+void sk_POLICYINFO_free(Cryptography_STACK_OF_POLICYINFO *);
+int sk_POLICYINFO_num(Cryptography_STACK_OF_POLICYINFO *);
+POLICYINFO *sk_POLICYINFO_value(Cryptography_STACK_OF_POLICYINFO *, int);
+
+void sk_POLICYQUALINFO_free(Cryptography_STACK_OF_POLICYQUALINFO *);
+int sk_POLICYQUALINFO_num(Cryptography_STACK_OF_POLICYQUALINFO *);
+POLICYQUALINFO *sk_POLICYQUALINFO_value(Cryptography_STACK_OF_POLICYQUALINFO *,
+ int);
+
+void sk_ASN1_INTEGER_free(Cryptography_STACK_OF_ASN1_INTEGER *);
+int sk_ASN1_INTEGER_num(Cryptography_STACK_OF_ASN1_INTEGER *);
+ASN1_INTEGER *sk_ASN1_INTEGER_value(Cryptography_STACK_OF_ASN1_INTEGER *, int);
"""
CUSTOMIZATIONS = """
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
index 4d332f2a..733a967c 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -71,17 +71,6 @@ class DSAPrivateKeyWithSerialization(DSAPrivateKey):
"""
-DSAPrivateKeyWithNumbers = utils.deprecated(
- DSAPrivateKeyWithSerialization,
- __name__,
- (
- "The DSAPrivateKeyWithNumbers interface has been renamed to "
- "DSAPrivateKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
@six.add_metaclass(abc.ABCMeta)
class DSAPublicKey(object):
@abc.abstractproperty
@@ -118,17 +107,6 @@ class DSAPublicKeyWithSerialization(DSAPublicKey):
"""
-DSAPublicKeyWithNumbers = utils.deprecated(
- DSAPublicKeyWithSerialization,
- __name__,
- (
- "The DSAPublicKeyWithNumbers interface has been renamed to "
- "DSAPublicKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
def generate_parameters(key_size, backend):
return backend.generate_dsa_parameters(key_size)
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index bf1705db..631fcbf7 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -71,17 +71,6 @@ class EllipticCurvePrivateKeyWithSerialization(EllipticCurvePrivateKey):
"""
-EllipticCurvePrivateKeyWithNumbers = utils.deprecated(
- EllipticCurvePrivateKeyWithSerialization,
- __name__,
- (
- "The EllipticCurvePrivateKeyWithNumbers interface has been renamed to "
- "EllipticCurvePrivateKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
@six.add_metaclass(abc.ABCMeta)
class EllipticCurvePublicKey(object):
@abc.abstractmethod
@@ -112,17 +101,6 @@ class EllipticCurvePublicKeyWithSerialization(EllipticCurvePublicKey):
"""
-EllipticCurvePublicKeyWithNumbers = utils.deprecated(
- EllipticCurvePublicKeyWithSerialization,
- __name__,
- (
- "The EllipticCurvePublicKeyWithNumbers interface has been renamed to "
- "EllipticCurvePublicKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
@utils.register_interface(EllipticCurve)
class SECT571R1(object):
name = "sect571r1"
@@ -202,6 +180,12 @@ class SECP256R1(object):
@utils.register_interface(EllipticCurve)
+class SECP256K1(object):
+ name = "secp256k1"
+ key_size = 256
+
+
+@utils.register_interface(EllipticCurve)
class SECP224R1(object):
name = "secp224r1"
key_size = 224
@@ -222,6 +206,7 @@ _CURVE_TYPES = {
"secp256r1": SECP256R1,
"secp384r1": SECP384R1,
"secp521r1": SECP521R1,
+ "secp256k1": SECP256K1,
"sect163k1": SECT163K1,
"sect233k1": SECT233K1,
diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
index ae00184f..772473fd 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -56,17 +56,6 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey):
"""
-RSAPrivateKeyWithNumbers = utils.deprecated(
- RSAPrivateKeyWithSerialization,
- __name__,
- (
- "The RSAPrivateKeyWithNumbers interface has been renamed to "
- "RSAPrivateKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
@six.add_metaclass(abc.ABCMeta)
class RSAPublicKey(object):
@abc.abstractmethod
@@ -103,17 +92,6 @@ class RSAPublicKeyWithSerialization(RSAPublicKey):
"""
-RSAPublicKeyWithNumbers = utils.deprecated(
- RSAPublicKeyWithSerialization,
- __name__,
- (
- "The RSAPublicKeyWithNumbers interface has been renamed to "
- "RSAPublicKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-
def generate_private_key(public_exponent, key_size, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
diff --git a/src/cryptography/hazmat/primitives/interfaces/__init__.py b/src/cryptography/hazmat/primitives/interfaces/__init__.py
index c980e5a5..4c95190b 100644
--- a/src/cryptography/hazmat/primitives/interfaces/__init__.py
+++ b/src/cryptography/hazmat/primitives/interfaces/__init__.py
@@ -8,357 +8,6 @@ import abc
import six
-from cryptography import utils
-from cryptography.hazmat.primitives import ciphers, hashes
-from cryptography.hazmat.primitives.asymmetric import (
- AsymmetricSignatureContext, AsymmetricVerificationContext, dsa, ec,
- padding, rsa
-)
-from cryptography.hazmat.primitives.ciphers import modes
-from cryptography.hazmat.primitives.kdf import KeyDerivationFunction
-from cryptography.hazmat.primitives.padding import PaddingContext
-
-
-BlockCipherAlgorithm = utils.deprecated(
- ciphers.BlockCipherAlgorithm,
- __name__,
- (
- "The BlockCipherAlgorithm interface has moved to the "
- "cryptography.hazmat.primitives.ciphers module"
- ),
- utils.DeprecatedIn08
-)
-
-
-CipherAlgorithm = utils.deprecated(
- ciphers.CipherAlgorithm,
- __name__,
- (
- "The CipherAlgorithm interface has moved to the "
- "cryptography.hazmat.primitives.ciphers module"
- ),
- utils.DeprecatedIn08
-)
-
-
-Mode = utils.deprecated(
- modes.Mode,
- __name__,
- (
- "The Mode interface has moved to the "
- "cryptography.hazmat.primitives.ciphers.modes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-ModeWithAuthenticationTag = utils.deprecated(
- modes.ModeWithAuthenticationTag,
- __name__,
- (
- "The ModeWithAuthenticationTag interface has moved to the "
- "cryptography.hazmat.primitives.ciphers.modes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-ModeWithInitializationVector = utils.deprecated(
- modes.ModeWithInitializationVector,
- __name__,
- (
- "The ModeWithInitializationVector interface has moved to the "
- "cryptography.hazmat.primitives.ciphers.modes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-ModeWithNonce = utils.deprecated(
- modes.ModeWithNonce,
- __name__,
- (
- "The ModeWithNonce interface has moved to the "
- "cryptography.hazmat.primitives.ciphers.modes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-CipherContext = utils.deprecated(
- ciphers.CipherContext,
- __name__,
- (
- "The CipherContext interface has moved to the "
- "cryptography.hazmat.primitives.ciphers module"
- ),
- utils.DeprecatedIn08
-)
-
-
-AEADCipherContext = utils.deprecated(
- ciphers.AEADCipherContext,
- __name__,
- (
- "The AEADCipherContext interface has moved to the "
- "cryptography.hazmat.primitives.ciphers module"
- ),
- utils.DeprecatedIn08
-)
-
-
-AEADEncryptionContext = utils.deprecated(
- ciphers.AEADEncryptionContext,
- __name__,
- (
- "The AEADEncryptionContext interface has moved to the "
- "cryptography.hazmat.primitives.ciphers module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurve = utils.deprecated(
- ec.EllipticCurve,
- __name__,
- (
- "The EllipticCurve interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurvePrivateKey = utils.deprecated(
- ec.EllipticCurvePrivateKey,
- __name__,
- (
- "The EllipticCurvePrivateKey interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurvePrivateKeyWithNumbers = utils.deprecated(
- ec.EllipticCurvePrivateKeyWithSerialization,
- __name__,
- (
- "The EllipticCurvePrivateKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurvePublicKey = utils.deprecated(
- ec.EllipticCurvePublicKey,
- __name__,
- (
- "The EllipticCurvePublicKey interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurvePublicKeyWithNumbers = utils.deprecated(
- ec.EllipticCurvePublicKeyWithSerialization,
- __name__,
- (
- "The EllipticCurvePublicKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-EllipticCurveSignatureAlgorithm = utils.deprecated(
- ec.EllipticCurveSignatureAlgorithm,
- __name__,
- (
- "The EllipticCurveSignatureAlgorithm interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.ec module"
- ),
- utils.DeprecatedIn08
-)
-
-
-DSAParameters = utils.deprecated(
- dsa.DSAParameters,
- __name__,
- (
- "The DSAParameters interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-DSAParametersWithNumbers = utils.deprecated(
- dsa.DSAParametersWithNumbers,
- __name__,
- (
- "The DSAParametersWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-DSAPrivateKey = utils.deprecated(
- dsa.DSAPrivateKey,
- __name__,
- (
- "The DSAPrivateKey interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-DSAPrivateKeyWithNumbers = utils.deprecated(
- dsa.DSAPrivateKeyWithSerialization,
- __name__,
- (
- "The DSAPrivateKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-DSAPublicKey = utils.deprecated(
- dsa.DSAPublicKey,
- __name__,
- (
- "The DSAPublicKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-DSAPublicKeyWithNumbers = utils.deprecated(
- dsa.DSAPublicKeyWithSerialization,
- __name__,
- (
- "The DSAPublicKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.dsa.module"
- ),
- utils.DeprecatedIn08
-)
-
-
-PaddingContext = utils.deprecated(
- PaddingContext,
- __name__,
- (
- "The PaddingContext interface has moved to the "
- "cryptography.hazmat.primitives.padding module"
- ),
- utils.DeprecatedIn08
-)
-
-
-HashContext = utils.deprecated(
- hashes.HashContext,
- __name__,
- (
- "The HashContext interface has moved to the "
- "cryptography.hazmat.primitives.hashes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-HashAlgorithm = utils.deprecated(
- hashes.HashAlgorithm,
- __name__,
- (
- "The HashAlgorithm interface has moved to the "
- "cryptography.hazmat.primitives.hashes module"
- ),
- utils.DeprecatedIn08
-)
-
-
-RSAPrivateKey = utils.deprecated(
- rsa.RSAPrivateKey,
- __name__,
- (
- "The RSAPrivateKey interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.rsa module"
- ),
- utils.DeprecatedIn08
-)
-
-RSAPrivateKeyWithNumbers = utils.deprecated(
- rsa.RSAPrivateKeyWithSerialization,
- __name__,
- (
- "The RSAPrivateKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.rsa module and has been "
- "renamed RSAPrivateKeyWithSerialization"
- ),
- utils.DeprecatedIn08
-)
-
-RSAPublicKey = utils.deprecated(
- rsa.RSAPublicKey,
- __name__,
- (
- "The RSAPublicKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.rsa module"
- ),
- utils.DeprecatedIn08
-)
-
-RSAPublicKeyWithNumbers = utils.deprecated(
- rsa.RSAPublicKeyWithSerialization,
- __name__,
- (
- "The RSAPublicKeyWithNumbers interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.rsa module"
- ),
- utils.DeprecatedIn08
-)
-
-AsymmetricPadding = utils.deprecated(
- padding.AsymmetricPadding,
- __name__,
- (
- "The AsymmetricPadding interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric.padding module"
- ),
- utils.DeprecatedIn08
-)
-
-AsymmetricSignatureContext = utils.deprecated(
- AsymmetricSignatureContext,
- __name__,
- (
- "The AsymmetricPadding interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric module"
- ),
- utils.DeprecatedIn08
-)
-
-AsymmetricVerificationContext = utils.deprecated(
- AsymmetricVerificationContext,
- __name__,
- (
- "The AsymmetricVerificationContext interface has moved to the "
- "cryptography.hazmat.primitives.asymmetric module"
- ),
- utils.DeprecatedIn08
-)
-
-KeyDerivationFunction = utils.deprecated(
- KeyDerivationFunction,
- __name__,
- (
- "The KeyDerivationFunction interface has moved to the "
- "cryptography.hazmat.primitives.kdf module"
- ),
- utils.DeprecatedIn08
-)
-
@six.add_metaclass(abc.ABCMeta)
class MACContext(object):
diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py
index 65b7091a..f738bbdc 100644
--- a/src/cryptography/hazmat/primitives/kdf/hkdf.py
+++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py
@@ -26,7 +26,7 @@ class HKDF(object):
self._algorithm = algorithm
- if not isinstance(salt, bytes) and salt is not None:
+ if not (salt is None or isinstance(salt, bytes)):
raise TypeError("salt must be bytes.")
if salt is None:
@@ -77,7 +77,7 @@ class HKDFExpand(object):
self._length = length
- if not isinstance(info, bytes) and info is not None:
+ if not (info is None or isinstance(info, bytes)):
raise TypeError("info must be bytes.")
if info is None:
diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py
index 445554ec..0bf8c0ea 100644
--- a/src/cryptography/utils.py
+++ b/src/cryptography/utils.py
@@ -10,8 +10,7 @@ import sys
import warnings
-DeprecatedIn08 = DeprecationWarning
-DeprecatedIn09 = PendingDeprecationWarning
+DeprecatedIn09 = DeprecationWarning
def read_only_property(name):
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index b22ac8be..71ba9042 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -67,6 +67,10 @@ _OID_NAMES = {
"1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
"1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
"1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
+ "1.3.6.1.5.5.7.48.1": "OCSP",
+ "1.3.6.1.5.5.7.48.2": "caIssuers",
+ "1.3.6.1.5.5.7.2.1": "id-qt-cps",
+ "1.3.6.1.5.5.7.2.2": "id-qt-unotice",
}
@@ -277,11 +281,10 @@ class Extension(object):
class ExtendedKeyUsage(object):
def __init__(self, usages):
- for oid in usages:
- if not isinstance(oid, ObjectIdentifier):
- raise TypeError(
- "Every item in the usages list must be an ObjectIdentifier"
- )
+ if not all(isinstance(x, ObjectIdentifier) for x in usages):
+ raise TypeError(
+ "Every item in the usages list must be an ObjectIdentifier"
+ )
self._usages = usages
@@ -294,6 +297,15 @@ class ExtendedKeyUsage(object):
def __repr__(self):
return "<ExtendedKeyUsage({0})>".format(self._usages)
+ def __eq__(self, other):
+ if not isinstance(other, ExtendedKeyUsage):
+ return NotImplemented
+
+ return self._usages == other._usages
+
+ def __ne__(self, other):
+ return not self == other
+
class BasicConstraints(object):
def __init__(self, ca, path_length):
@@ -321,6 +333,15 @@ class BasicConstraints(object):
return ("<BasicConstraints(ca={0.ca}, "
"path_length={0.path_length})>").format(self)
+ def __eq__(self, other):
+ if not isinstance(other, BasicConstraints):
+ return NotImplemented
+
+ return self.ca == other.ca and self.path_length == other.path_length
+
+ def __ne__(self, other):
+ return not self == other
+
class KeyUsage(object):
def __init__(self, digital_signature, content_commitment, key_encipherment,
@@ -385,6 +406,226 @@ class KeyUsage(object):
"encipher_only={1}, decipher_only={2})>").format(
self, encipher_only, decipher_only)
+ def __eq__(self, other):
+ if not isinstance(other, KeyUsage):
+ return NotImplemented
+
+ return (
+ self.digital_signature == other.digital_signature and
+ self.content_commitment == other.content_commitment and
+ self.key_encipherment == other.key_encipherment and
+ self.data_encipherment == other.data_encipherment and
+ self.key_agreement == other.key_agreement and
+ self.key_cert_sign == other.key_cert_sign and
+ self.crl_sign == other.crl_sign and
+ self._encipher_only == other._encipher_only and
+ self._decipher_only == other._decipher_only
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class AuthorityInformationAccess(object):
+ def __init__(self, descriptions):
+ if not all(isinstance(x, AccessDescription) for x in descriptions):
+ raise TypeError(
+ "Every item in the descriptions list must be an "
+ "AccessDescription"
+ )
+
+ self._descriptions = descriptions
+
+ def __iter__(self):
+ return iter(self._descriptions)
+
+ def __len__(self):
+ return len(self._descriptions)
+
+ def __repr__(self):
+ return "<AuthorityInformationAccess({0})>".format(self._descriptions)
+
+ def __eq__(self, other):
+ if not isinstance(other, AuthorityInformationAccess):
+ return NotImplemented
+
+ return self._descriptions == other._descriptions
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class AccessDescription(object):
+ def __init__(self, access_method, access_location):
+ if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
+ raise ValueError(
+ "access_method must be OID_OCSP or OID_CA_ISSUERS"
+ )
+
+ if not isinstance(access_location, GeneralName):
+ raise TypeError("access_location must be a GeneralName")
+
+ self._access_method = access_method
+ self._access_location = access_location
+
+ def __repr__(self):
+ return (
+ "<AccessDescription(access_method={0.access_method}, access_locati"
+ "on={0.access_location})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, AccessDescription):
+ return NotImplemented
+
+ return (
+ self.access_method == other.access_method and
+ self.access_location == other.access_location
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ access_method = utils.read_only_property("_access_method")
+ access_location = utils.read_only_property("_access_location")
+
+
+class CertificatePolicies(object):
+ def __init__(self, policies):
+ if not all(isinstance(x, PolicyInformation) for x in policies):
+ raise TypeError(
+ "Every item in the policies list must be a "
+ "PolicyInformation"
+ )
+
+ self._policies = policies
+
+ def __iter__(self):
+ return iter(self._policies)
+
+ def __len__(self):
+ return len(self._policies)
+
+ def __repr__(self):
+ return "<CertificatePolicies({0})>".format(self._policies)
+
+ def __eq__(self, other):
+ if not isinstance(other, CertificatePolicies):
+ return NotImplemented
+
+ return self._policies == other._policies
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class PolicyInformation(object):
+ def __init__(self, policy_identifier, policy_qualifiers):
+ if not isinstance(policy_identifier, ObjectIdentifier):
+ raise TypeError("policy_identifier must be an ObjectIdentifier")
+
+ self._policy_identifier = policy_identifier
+ if policy_qualifiers and not all(
+ isinstance(
+ x, (six.text_type, UserNotice)
+ ) for x in policy_qualifiers
+ ):
+ raise TypeError(
+ "policy_qualifiers must be a list of strings and/or UserNotice"
+ " objects or None"
+ )
+
+ self._policy_qualifiers = policy_qualifiers
+
+ def __repr__(self):
+ return (
+ "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
+ "y_qualifiers={0.policy_qualifiers})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, PolicyInformation):
+ return NotImplemented
+
+ return (
+ self.policy_identifier == other.policy_identifier and
+ self.policy_qualifiers == other.policy_qualifiers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ policy_identifier = utils.read_only_property("_policy_identifier")
+ policy_qualifiers = utils.read_only_property("_policy_qualifiers")
+
+
+class UserNotice(object):
+ def __init__(self, notice_reference, explicit_text):
+ if notice_reference and not isinstance(
+ notice_reference, NoticeReference
+ ):
+ raise TypeError(
+ "notice_reference must be None or a NoticeReference"
+ )
+
+ self._notice_reference = notice_reference
+ self._explicit_text = explicit_text
+
+ def __repr__(self):
+ return (
+ "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
+ "{0.explicit_text!r})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, UserNotice):
+ return NotImplemented
+
+ return (
+ self.notice_reference == other.notice_reference and
+ self.explicit_text == other.explicit_text
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ notice_reference = utils.read_only_property("_notice_reference")
+ explicit_text = utils.read_only_property("_explicit_text")
+
+
+class NoticeReference(object):
+ def __init__(self, organization, notice_numbers):
+ self._organization = organization
+ if not isinstance(notice_numbers, list) or not all(
+ isinstance(x, int) for x in notice_numbers
+ ):
+ raise TypeError(
+ "notice_numbers must be a list of integers"
+ )
+
+ self._notice_numbers = notice_numbers
+
+ def __repr__(self):
+ return (
+ "<NoticeReference(organization={0.organization!r}, notice_numbers="
+ "{0.notice_numbers})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, NoticeReference):
+ return NotImplemented
+
+ return (
+ self.organization == other.organization and
+ self.notice_numbers == other.notice_numbers
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ organization = utils.read_only_property("_organization")
+ notice_numbers = utils.read_only_property("_notice_numbers")
+
class SubjectKeyIdentifier(object):
def __init__(self, digest):
@@ -407,6 +648,126 @@ class SubjectKeyIdentifier(object):
return not self == other
+class CRLDistributionPoints(object):
+ def __init__(self, distribution_points):
+ if not all(
+ isinstance(x, DistributionPoint) for x in distribution_points
+ ):
+ raise TypeError(
+ "distribution_points must be a list of DistributionPoint "
+ "objects"
+ )
+
+ self._distribution_points = distribution_points
+
+ def __iter__(self):
+ return iter(self._distribution_points)
+
+ def __len__(self):
+ return len(self._distribution_points)
+
+ def __repr__(self):
+ return "<CRLDistributionPoints({0})>".format(self._distribution_points)
+
+ def __eq__(self, other):
+ if not isinstance(other, CRLDistributionPoints):
+ return NotImplemented
+
+ return self._distribution_points == other._distribution_points
+
+ def __ne__(self, other):
+ return not self == other
+
+
+class DistributionPoint(object):
+ def __init__(self, full_name, relative_name, reasons, crl_issuer):
+ if full_name and relative_name:
+ raise ValueError(
+ "At least one of full_name and relative_name must be None"
+ )
+
+ if full_name and not all(
+ isinstance(x, GeneralName) for x in full_name
+ ):
+ raise TypeError(
+ "full_name must be a list of GeneralName objects"
+ )
+
+ if relative_name and not isinstance(relative_name, Name):
+ raise TypeError("relative_name must be a Name")
+
+ if crl_issuer and not all(
+ isinstance(x, GeneralName) for x in crl_issuer
+ ):
+ raise TypeError(
+ "crl_issuer must be None or a list of general names"
+ )
+
+ if reasons and (not isinstance(reasons, frozenset) or not all(
+ isinstance(x, ReasonFlags) for x in reasons
+ )):
+ raise TypeError("reasons must be None or frozenset of ReasonFlags")
+
+ if reasons and (
+ ReasonFlags.unspecified in reasons or
+ ReasonFlags.remove_from_crl in reasons
+ ):
+ raise ValueError(
+ "unspecified and remove_from_crl are not valid reasons in a "
+ "DistributionPoint"
+ )
+
+ if reasons and not crl_issuer and not (full_name or relative_name):
+ raise ValueError(
+ "You must supply crl_issuer, full_name, or relative_name when "
+ "reasons is not None"
+ )
+
+ self._full_name = full_name
+ self._relative_name = relative_name
+ self._reasons = reasons
+ self._crl_issuer = crl_issuer
+
+ def __repr__(self):
+ return (
+ "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
+ "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
+ "suer})>".format(self)
+ )
+
+ def __eq__(self, other):
+ if not isinstance(other, DistributionPoint):
+ return NotImplemented
+
+ return (
+ self.full_name == other.full_name and
+ self.relative_name == other.relative_name and
+ self.reasons == other.reasons and
+ self.crl_issuer == other.crl_issuer
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ full_name = utils.read_only_property("_full_name")
+ relative_name = utils.read_only_property("_relative_name")
+ reasons = utils.read_only_property("_reasons")
+ crl_issuer = utils.read_only_property("_crl_issuer")
+
+
+class ReasonFlags(Enum):
+ unspecified = "unspecified"
+ key_compromise = "keyCompromise"
+ ca_compromise = "cACompromise"
+ affiliation_changed = "affiliationChanged"
+ superseded = "superseded"
+ cessation_of_operation = "cessationOfOperation"
+ certificate_hold = "certificateHold"
+ privilege_withdrawn = "privilegeWithdrawn"
+ aa_compromise = "aACompromise"
+ remove_from_crl = "removeFromCRL"
+
+
@six.add_metaclass(abc.ABCMeta)
class GeneralName(object):
@abc.abstractproperty
@@ -581,6 +942,15 @@ class SubjectAlternativeName(object):
def __repr__(self):
return "<SubjectAlternativeName({0})>".format(self._general_names)
+ def __eq__(self, other):
+ if not isinstance(other, SubjectAlternativeName):
+ return NotImplemented
+
+ return self._general_names == other._general_names
+
+ def __ne__(self, other):
+ return not self == other
+
class AuthorityKeyIdentifier(object):
def __init__(self, key_identifier, authority_cert_issuer,
@@ -592,8 +962,13 @@ class AuthorityKeyIdentifier(object):
"must both be present or both None"
)
- if not isinstance(authority_cert_issuer, Name):
- raise TypeError("authority_cert_issuer must be a Name")
+ if not all(
+ isinstance(x, GeneralName) for x in authority_cert_issuer
+ ):
+ raise TypeError(
+ "authority_cert_issuer must be a list of GeneralName "
+ "objects"
+ )
if not isinstance(authority_cert_serial_number, six.integer_types):
raise TypeError(
@@ -612,6 +987,20 @@ class AuthorityKeyIdentifier(object):
")>".format(self)
)
+ def __eq__(self, other):
+ if not isinstance(other, AuthorityKeyIdentifier):
+ return NotImplemented
+
+ return (
+ self.key_identifier == other.key_identifier and
+ self.authority_cert_issuer == other.authority_cert_issuer and
+ self.authority_cert_serial_number ==
+ other.authority_cert_serial_number
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
key_identifier = utils.read_only_property("_key_identifier")
authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
authority_cert_serial_number = utils.read_only_property(
@@ -672,6 +1061,12 @@ OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
+OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
+OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
+
+OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
+OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
+
@six.add_metaclass(abc.ABCMeta)
class Certificate(object):