blob: 75552fc1bdea844942e796cbcf1c730a32bf1619 [file] [log] [blame]
Paul Kehrer016e08a2014-11-26 09:41:18 -10001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
Paul Kehrerb2de9482014-12-11 14:54:48 -06007import abc
Paul Kehrer31bdf792015-03-25 14:11:00 -05008import ipaddress
Paul Kehrer01d5d0b2015-07-12 09:41:21 -05009from email.utils import parseaddr
Paul Kehrer016e08a2014-11-26 09:41:18 -100010from enum import Enum
11
Paul Kehrer01d5d0b2015-07-12 09:41:21 -050012import idna
13
Paul Kehrerb2de9482014-12-11 14:54:48 -060014import six
15
Paul Kehrere28d6c42015-07-12 14:59:37 -050016from six.moves import urllib_parse
17
Paul Kehrer912d3fb2015-01-29 11:19:22 -060018from cryptography import utils
Paul Kehrer8802a5b2015-02-13 12:06:57 -060019from cryptography.hazmat.primitives import hashes
Paul Kehrer912d3fb2015-01-29 11:19:22 -060020
Paul Kehrer016e08a2014-11-26 09:41:18 -100021
Paul Kehrer806bfb22015-02-02 17:05:24 -060022_OID_NAMES = {
23 "2.5.4.3": "commonName",
24 "2.5.4.6": "countryName",
25 "2.5.4.7": "localityName",
26 "2.5.4.8": "stateOrProvinceName",
27 "2.5.4.10": "organizationName",
28 "2.5.4.11": "organizationalUnitName",
29 "2.5.4.5": "serialNumber",
30 "2.5.4.4": "surname",
31 "2.5.4.42": "givenName",
32 "2.5.4.12": "title",
33 "2.5.4.44": "generationQualifier",
34 "2.5.4.46": "dnQualifier",
35 "2.5.4.65": "pseudonym",
36 "0.9.2342.19200300.100.1.25": "domainComponent",
37 "1.2.840.113549.1.9.1": "emailAddress",
Paul Kehrer71d40c62015-02-19 08:21:04 -060038 "1.2.840.113549.1.1.4": "md5WithRSAEncryption",
39 "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
Paul Kehrer56da2a52015-02-11 23:35:07 -060040 "1.2.840.113549.1.1.14": "sha224WithRSAEncryption",
41 "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
42 "1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
43 "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
Alex Gaynor3aadabf2015-06-23 22:06:21 -040044 "1.2.840.10045.4.1": "ecdsa-with-SHA1",
Paul Kehrer71d40c62015-02-19 08:21:04 -060045 "1.2.840.10045.4.3.1": "ecdsa-with-SHA224",
46 "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
47 "1.2.840.10045.4.3.3": "ecdsa-with-SHA384",
48 "1.2.840.10045.4.3.4": "ecdsa-with-SHA512",
49 "1.2.840.10040.4.3": "dsa-with-sha1",
50 "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
51 "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
Paul Kehrere1513fa2015-03-30 23:08:17 -050052 "1.3.6.1.5.5.7.3.1": "serverAuth",
53 "1.3.6.1.5.5.7.3.2": "clientAuth",
54 "1.3.6.1.5.5.7.3.3": "codeSigning",
55 "1.3.6.1.5.5.7.3.4": "emailProtection",
56 "1.3.6.1.5.5.7.3.8": "timeStamping",
57 "1.3.6.1.5.5.7.3.9": "OCSPSigning",
Paul Kehrerd08b5492015-04-04 15:19:16 -050058 "2.5.29.9": "subjectDirectoryAttributes",
59 "2.5.29.14": "subjectKeyIdentifier",
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050060 "2.5.29.15": "keyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050061 "2.5.29.17": "subjectAltName",
62 "2.5.29.18": "issuerAltName",
63 "2.5.29.19": "basicConstraints",
Erik Trauschkec5a8d172015-05-28 10:24:25 -070064 "2.5.29.21": "cRLReason",
65 "2.5.29.24": "invalidityDate",
66 "2.5.29.29": "certificateIssuer",
Paul Kehrerd08b5492015-04-04 15:19:16 -050067 "2.5.29.30": "nameConstraints",
68 "2.5.29.31": "cRLDistributionPoints",
69 "2.5.29.32": "certificatePolicies",
70 "2.5.29.33": "policyMappings",
71 "2.5.29.35": "authorityKeyIdentifier",
72 "2.5.29.36": "policyConstraints",
Paul Kehrere1513fa2015-03-30 23:08:17 -050073 "2.5.29.37": "extendedKeyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050074 "2.5.29.46": "freshestCRL",
75 "2.5.29.54": "inhibitAnyPolicy",
76 "1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
77 "1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
78 "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
Paul Kehrer3e6d5582015-05-02 21:57:56 -050079 "1.3.6.1.5.5.7.48.1": "OCSP",
Paul Kehrerf506bca2015-05-02 22:31:47 -050080 "1.3.6.1.5.5.7.48.2": "caIssuers",
Paul Kehrer2b622582015-04-15 11:04:29 -040081 "1.3.6.1.5.5.7.2.1": "id-qt-cps",
82 "1.3.6.1.5.5.7.2.2": "id-qt-unotice",
Paul Kehrer806bfb22015-02-02 17:05:24 -060083}
84
85
Paul Kehrer9089c912015-04-20 22:15:20 -050086_GENERAL_NAMES = {
87 0: "otherName",
88 1: "rfc822Name",
89 2: "dNSName",
90 3: "x400Address",
91 4: "directoryName",
92 5: "ediPartyName",
93 6: "uniformResourceIdentifier",
94 7: "iPAddress",
95 8: "registeredID",
96}
97
98
Paul Kehrere76cd272014-12-14 19:00:51 -060099class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -1000100 v1 = 0
101 v3 = 2
102
103
Paul Kehrer016e08a2014-11-26 09:41:18 -1000104def load_pem_x509_certificate(data, backend):
105 return backend.load_pem_x509_certificate(data)
106
107
Paul Kehrer016e08a2014-11-26 09:41:18 -1000108def load_der_x509_certificate(data, backend):
109 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -1000110
111
Paul Kehrer31e39882015-03-11 11:37:04 -0500112def load_pem_x509_csr(data, backend):
113 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600114
115
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500116def load_der_x509_csr(data, backend):
117 return backend.load_der_x509_csr(data)
118
119
Paul Kehrere76cd272014-12-14 19:00:51 -0600120class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600121 def __init__(self, msg, parsed_version):
122 super(InvalidVersion, self).__init__(msg)
123 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600124
125
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500126class DuplicateExtension(Exception):
127 def __init__(self, msg, oid):
128 super(DuplicateExtension, self).__init__(msg)
129 self.oid = oid
130
131
132class UnsupportedExtension(Exception):
133 def __init__(self, msg, oid):
134 super(UnsupportedExtension, self).__init__(msg)
135 self.oid = oid
136
137
Paul Kehrerfa56a232015-03-17 13:14:03 -0500138class ExtensionNotFound(Exception):
139 def __init__(self, msg, oid):
140 super(ExtensionNotFound, self).__init__(msg)
141 self.oid = oid
142
143
Paul Kehrer9089c912015-04-20 22:15:20 -0500144class UnsupportedGeneralNameType(Exception):
Paul Kehrerbed07352015-04-21 08:31:10 -0500145 def __init__(self, msg, type):
146 super(UnsupportedGeneralNameType, self).__init__(msg)
147 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500148
149
Paul Kehrer806bfb22015-02-02 17:05:24 -0600150class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600151 def __init__(self, oid, value):
152 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600153 raise TypeError(
154 "oid argument must be an ObjectIdentifier instance."
155 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600156
Ian Cordasco7618fbe2015-06-16 19:12:17 -0500157 if not isinstance(value, six.text_type):
158 raise TypeError(
159 "value argument must be a text type."
160 )
161
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600162 self._oid = oid
163 self._value = value
164
165 oid = utils.read_only_property("_oid")
166 value = utils.read_only_property("_value")
167
168 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600169 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600170 return NotImplemented
171
172 return (
173 self.oid == other.oid and
174 self.value == other.value
175 )
176
177 def __ne__(self, other):
178 return not self == other
179
Paul Kehrera498be82015-02-12 15:00:56 -0600180 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400181 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600182
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600183
184class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600185 def __init__(self, dotted_string):
186 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600187
188 def __eq__(self, other):
189 if not isinstance(other, ObjectIdentifier):
190 return NotImplemented
191
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600192 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600193
194 def __ne__(self, other):
195 return not self == other
196
197 def __repr__(self):
198 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600199 self._dotted_string,
200 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600201 )
202
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500203 def __hash__(self):
204 return hash(self.dotted_string)
205
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600206 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600207
208
Paul Kehrer719d5362015-01-01 20:03:52 -0600209class Name(object):
210 def __init__(self, attributes):
211 self._attributes = attributes
212
Paul Kehrere901d642015-02-11 18:50:58 -0600213 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800214 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600215
Paul Kehrer719d5362015-01-01 20:03:52 -0600216 def __eq__(self, other):
217 if not isinstance(other, Name):
218 return NotImplemented
219
Paul Kehrer53d8d492015-02-13 18:47:30 -0600220 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600221
222 def __ne__(self, other):
223 return not self == other
224
Paul Kehrer53d8d492015-02-13 18:47:30 -0600225 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600226 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600227
228 def __len__(self):
229 return len(self._attributes)
230
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400231 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400232 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400233
Paul Kehrer719d5362015-01-01 20:03:52 -0600234
Paul Kehrerd08b5492015-04-04 15:19:16 -0500235OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
236OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500237OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500238OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
239OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500240OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Erik Trauschke2dcce902015-05-14 16:12:24 -0700241OID_CRL_REASON = ObjectIdentifier("2.5.29.21")
242OID_INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
243OID_CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500244OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
245OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
246OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
247OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
248OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
249OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
250OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
251OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
252OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
253OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
254OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
255OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500256
257
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500258class Extensions(object):
259 def __init__(self, extensions):
260 self._extensions = extensions
261
Paul Kehrerfa56a232015-03-17 13:14:03 -0500262 def get_extension_for_oid(self, oid):
263 for ext in self:
264 if ext.oid == oid:
265 return ext
266
267 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
268
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500269 def __iter__(self):
270 return iter(self._extensions)
271
272 def __len__(self):
273 return len(self._extensions)
274
275
Paul Kehrer8cf26422015-03-21 09:50:24 -0500276class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500277 def __init__(self, oid, critical, value):
278 if not isinstance(oid, ObjectIdentifier):
279 raise TypeError(
280 "oid argument must be an ObjectIdentifier instance."
281 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500282
283 if not isinstance(critical, bool):
284 raise TypeError("critical must be a boolean value")
285
Paul Kehrer85894662015-03-22 13:19:31 -0500286 self._oid = oid
287 self._critical = critical
288 self._value = value
289
290 oid = utils.read_only_property("_oid")
291 critical = utils.read_only_property("_critical")
292 value = utils.read_only_property("_value")
293
294 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500295 return ("<Extension(oid={0.oid}, critical={0.critical}, "
296 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500297
Paul Kehrer58e870c2015-05-17 09:15:30 -0700298 def __eq__(self, other):
299 if not isinstance(other, Extension):
300 return NotImplemented
301
302 return (
303 self.oid == other.oid and
304 self.critical == other.critical and
305 self.value == other.value
306 )
307
308 def __ne__(self, other):
309 return not self == other
310
Paul Kehrer85894662015-03-22 13:19:31 -0500311
Paul Kehrerffa2a152015-03-31 08:18:25 -0500312class ExtendedKeyUsage(object):
313 def __init__(self, usages):
Paul Kehrerb0476172015-05-02 19:34:51 -0500314 if not all(isinstance(x, ObjectIdentifier) for x in usages):
315 raise TypeError(
316 "Every item in the usages list must be an ObjectIdentifier"
317 )
Paul Kehrerffa2a152015-03-31 08:18:25 -0500318
319 self._usages = usages
320
321 def __iter__(self):
322 return iter(self._usages)
323
324 def __len__(self):
325 return len(self._usages)
326
Paul Kehrer23d10c32015-04-02 23:12:32 -0500327 def __repr__(self):
328 return "<ExtendedKeyUsage({0})>".format(self._usages)
329
Paul Kehrerb0476172015-05-02 19:34:51 -0500330 def __eq__(self, other):
331 if not isinstance(other, ExtendedKeyUsage):
332 return NotImplemented
333
Paul Kehrerf24bad72015-05-02 19:36:20 -0500334 return self._usages == other._usages
Paul Kehrerb0476172015-05-02 19:34:51 -0500335
336 def __ne__(self, other):
337 return not self == other
338
Paul Kehrerffa2a152015-03-31 08:18:25 -0500339
Paul Kehrer4a1038e2015-05-18 10:28:31 -0700340class OCSPNoCheck(object):
341 pass
342
343
Paul Kehrer85894662015-03-22 13:19:31 -0500344class BasicConstraints(object):
345 def __init__(self, ca, path_length):
346 if not isinstance(ca, bool):
347 raise TypeError("ca must be a boolean value")
348
Paul Kehrer611d3d32015-03-22 13:31:18 -0500349 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500350 raise ValueError("path_length must be None when ca is False")
351
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500352 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500353 path_length is not None and
354 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500355 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500356 raise TypeError(
357 "path_length must be a non-negative integer or None"
358 )
359
360 self._ca = ca
361 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500362
363 ca = utils.read_only_property("_ca")
364 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500365
366 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500367 return ("<BasicConstraints(ca={0.ca}, "
368 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500369
Paul Kehrer3a69b132015-05-13 10:03:46 -0500370 def __eq__(self, other):
371 if not isinstance(other, BasicConstraints):
372 return NotImplemented
373
374 return self.ca == other.ca and self.path_length == other.path_length
375
376 def __ne__(self, other):
377 return not self == other
378
Paul Kehrer8cf26422015-03-21 09:50:24 -0500379
Paul Kehrercecbbba2015-03-30 14:58:38 -0500380class KeyUsage(object):
381 def __init__(self, digital_signature, content_commitment, key_encipherment,
382 data_encipherment, key_agreement, key_cert_sign, crl_sign,
383 encipher_only, decipher_only):
384 if not key_agreement and (encipher_only or decipher_only):
385 raise ValueError(
386 "encipher_only and decipher_only can only be true when "
387 "key_agreement is true"
388 )
389
390 self._digital_signature = digital_signature
391 self._content_commitment = content_commitment
392 self._key_encipherment = key_encipherment
393 self._data_encipherment = data_encipherment
394 self._key_agreement = key_agreement
395 self._key_cert_sign = key_cert_sign
396 self._crl_sign = crl_sign
397 self._encipher_only = encipher_only
398 self._decipher_only = decipher_only
399
400 digital_signature = utils.read_only_property("_digital_signature")
401 content_commitment = utils.read_only_property("_content_commitment")
402 key_encipherment = utils.read_only_property("_key_encipherment")
403 data_encipherment = utils.read_only_property("_data_encipherment")
404 key_agreement = utils.read_only_property("_key_agreement")
405 key_cert_sign = utils.read_only_property("_key_cert_sign")
406 crl_sign = utils.read_only_property("_crl_sign")
407
408 @property
409 def encipher_only(self):
410 if not self.key_agreement:
411 raise ValueError(
412 "encipher_only is undefined unless key_agreement is true"
413 )
414 else:
415 return self._encipher_only
416
417 @property
418 def decipher_only(self):
419 if not self.key_agreement:
420 raise ValueError(
421 "decipher_only is undefined unless key_agreement is true"
422 )
423 else:
424 return self._decipher_only
425
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500426 def __repr__(self):
427 try:
428 encipher_only = self.encipher_only
429 decipher_only = self.decipher_only
430 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400431 encipher_only = None
432 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500433
434 return ("<KeyUsage(digital_signature={0.digital_signature}, "
435 "content_commitment={0.content_commitment}, "
436 "key_encipherment={0.key_encipherment}, "
437 "data_encipherment={0.data_encipherment}, "
438 "key_agreement={0.key_agreement}, "
439 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
440 "encipher_only={1}, decipher_only={2})>").format(
441 self, encipher_only, decipher_only)
442
Paul Kehrer8565f5e2015-05-13 09:57:09 -0500443 def __eq__(self, other):
444 if not isinstance(other, KeyUsage):
445 return NotImplemented
446
447 return (
448 self.digital_signature == other.digital_signature and
449 self.content_commitment == other.content_commitment and
450 self.key_encipherment == other.key_encipherment and
451 self.data_encipherment == other.data_encipherment and
452 self.key_agreement == other.key_agreement and
453 self.key_cert_sign == other.key_cert_sign and
454 self.crl_sign == other.crl_sign and
455 self._encipher_only == other._encipher_only and
456 self._decipher_only == other._decipher_only
457 )
458
459 def __ne__(self, other):
460 return not self == other
461
Paul Kehrercecbbba2015-03-30 14:58:38 -0500462
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500463class AuthorityInformationAccess(object):
464 def __init__(self, descriptions):
465 if not all(isinstance(x, AccessDescription) for x in descriptions):
466 raise TypeError(
467 "Every item in the descriptions list must be an "
468 "AccessDescription"
469 )
470
471 self._descriptions = descriptions
472
473 def __iter__(self):
474 return iter(self._descriptions)
475
476 def __len__(self):
477 return len(self._descriptions)
478
479 def __repr__(self):
480 return "<AuthorityInformationAccess({0})>".format(self._descriptions)
481
482 def __eq__(self, other):
483 if not isinstance(other, AuthorityInformationAccess):
484 return NotImplemented
485
486 return self._descriptions == other._descriptions
487
488 def __ne__(self, other):
489 return not self == other
490
491
492class AccessDescription(object):
493 def __init__(self, access_method, access_location):
494 if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
Paul Kehrerf506bca2015-05-02 22:31:47 -0500495 raise ValueError(
496 "access_method must be OID_OCSP or OID_CA_ISSUERS"
497 )
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500498
499 if not isinstance(access_location, GeneralName):
500 raise TypeError("access_location must be a GeneralName")
501
502 self._access_method = access_method
503 self._access_location = access_location
504
505 def __repr__(self):
506 return (
507 "<AccessDescription(access_method={0.access_method}, access_locati"
508 "on={0.access_location})>".format(self)
509 )
510
511 def __eq__(self, other):
512 if not isinstance(other, AccessDescription):
513 return NotImplemented
514
515 return (
516 self.access_method == other.access_method and
517 self.access_location == other.access_location
518 )
519
520 def __ne__(self, other):
521 return not self == other
522
523 access_method = utils.read_only_property("_access_method")
524 access_location = utils.read_only_property("_access_location")
525
526
Paul Kehrer2b622582015-04-15 11:04:29 -0400527class CertificatePolicies(object):
528 def __init__(self, policies):
Paul Kehrerf61ec742015-04-18 20:42:39 -0500529 if not all(isinstance(x, PolicyInformation) for x in policies):
Paul Kehrer2b622582015-04-15 11:04:29 -0400530 raise TypeError(
531 "Every item in the policies list must be a "
532 "PolicyInformation"
533 )
534
535 self._policies = policies
536
537 def __iter__(self):
538 return iter(self._policies)
539
540 def __len__(self):
541 return len(self._policies)
542
543 def __repr__(self):
544 return "<CertificatePolicies({0})>".format(self._policies)
545
Paul Kehrerc56ab622015-05-03 09:56:31 -0500546 def __eq__(self, other):
547 if not isinstance(other, CertificatePolicies):
548 return NotImplemented
549
550 return self._policies == other._policies
551
552 def __ne__(self, other):
553 return not self == other
554
Paul Kehrer2b622582015-04-15 11:04:29 -0400555
556class PolicyInformation(object):
557 def __init__(self, policy_identifier, policy_qualifiers):
558 if not isinstance(policy_identifier, ObjectIdentifier):
559 raise TypeError("policy_identifier must be an ObjectIdentifier")
560
561 self._policy_identifier = policy_identifier
562 if policy_qualifiers and not all(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500563 isinstance(
564 x, (six.text_type, UserNotice)
565 ) for x in policy_qualifiers
Paul Kehrer2b622582015-04-15 11:04:29 -0400566 ):
567 raise TypeError(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500568 "policy_qualifiers must be a list of strings and/or UserNotice"
569 " objects or None"
Paul Kehrer2b622582015-04-15 11:04:29 -0400570 )
571
572 self._policy_qualifiers = policy_qualifiers
573
574 def __repr__(self):
575 return (
576 "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
577 "y_qualifiers={0.policy_qualifiers})>".format(self)
578 )
579
Paul Kehrerc56ab622015-05-03 09:56:31 -0500580 def __eq__(self, other):
581 if not isinstance(other, PolicyInformation):
582 return NotImplemented
583
584 return (
585 self.policy_identifier == other.policy_identifier and
586 self.policy_qualifiers == other.policy_qualifiers
587 )
588
589 def __ne__(self, other):
590 return not self == other
591
Paul Kehrer2b622582015-04-15 11:04:29 -0400592 policy_identifier = utils.read_only_property("_policy_identifier")
593 policy_qualifiers = utils.read_only_property("_policy_qualifiers")
594
595
Paul Kehrer2b622582015-04-15 11:04:29 -0400596class UserNotice(object):
597 def __init__(self, notice_reference, explicit_text):
598 if notice_reference and not isinstance(
599 notice_reference, NoticeReference
600 ):
601 raise TypeError(
602 "notice_reference must be None or a NoticeReference"
603 )
604
605 self._notice_reference = notice_reference
606 self._explicit_text = explicit_text
607
608 def __repr__(self):
609 return (
610 "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
Paul Kehrer9aaef9e2015-05-11 10:49:20 -0500611 "{0.explicit_text!r})>".format(self)
Paul Kehrer2b622582015-04-15 11:04:29 -0400612 )
613
Paul Kehrerc56ab622015-05-03 09:56:31 -0500614 def __eq__(self, other):
615 if not isinstance(other, UserNotice):
616 return NotImplemented
617
618 return (
619 self.notice_reference == other.notice_reference and
620 self.explicit_text == other.explicit_text
621 )
622
623 def __ne__(self, other):
624 return not self == other
625
Paul Kehrer2b622582015-04-15 11:04:29 -0400626 notice_reference = utils.read_only_property("_notice_reference")
627 explicit_text = utils.read_only_property("_explicit_text")
628
629
630class NoticeReference(object):
631 def __init__(self, organization, notice_numbers):
632 self._organization = organization
Paul Kehrer6e198b02015-05-12 15:53:38 -0500633 if not isinstance(notice_numbers, list) or not all(
Paul Kehrerf61ec742015-04-18 20:42:39 -0500634 isinstance(x, int) for x in notice_numbers
Paul Kehrer2b622582015-04-15 11:04:29 -0400635 ):
636 raise TypeError(
Paul Kehrer6e198b02015-05-12 15:53:38 -0500637 "notice_numbers must be a list of integers"
Paul Kehrer2b622582015-04-15 11:04:29 -0400638 )
639
640 self._notice_numbers = notice_numbers
641
642 def __repr__(self):
643 return (
Paul Kehrer73be2ca2015-05-11 21:22:38 -0500644 "<NoticeReference(organization={0.organization!r}, notice_numbers="
Paul Kehrer2b622582015-04-15 11:04:29 -0400645 "{0.notice_numbers})>".format(self)
646 )
647
Paul Kehrerc56ab622015-05-03 09:56:31 -0500648 def __eq__(self, other):
649 if not isinstance(other, NoticeReference):
650 return NotImplemented
651
652 return (
653 self.organization == other.organization and
654 self.notice_numbers == other.notice_numbers
655 )
656
657 def __ne__(self, other):
658 return not self == other
659
Paul Kehrer2b622582015-04-15 11:04:29 -0400660 organization = utils.read_only_property("_organization")
661 notice_numbers = utils.read_only_property("_notice_numbers")
662
663
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500664class SubjectKeyIdentifier(object):
665 def __init__(self, digest):
666 self._digest = digest
667
668 digest = utils.read_only_property("_digest")
669
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500670 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400671 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500672
673 def __eq__(self, other):
674 if not isinstance(other, SubjectKeyIdentifier):
675 return NotImplemented
676
677 return (
678 self.digest == other.digest
679 )
680
681 def __ne__(self, other):
682 return not self == other
683
684
Paul Kehrere0017be2015-05-17 20:39:40 -0600685class NameConstraints(object):
686 def __init__(self, permitted_subtrees, excluded_subtrees):
687 if permitted_subtrees is not None:
688 if not all(
689 isinstance(x, GeneralName) for x in permitted_subtrees
690 ):
691 raise TypeError(
692 "permitted_subtrees must be a list of GeneralName objects "
693 "or None"
694 )
695
696 self._validate_ip_name(permitted_subtrees)
697
698 if excluded_subtrees is not None:
699 if not all(
700 isinstance(x, GeneralName) for x in excluded_subtrees
701 ):
702 raise TypeError(
703 "excluded_subtrees must be a list of GeneralName objects "
704 "or None"
705 )
706
707 self._validate_ip_name(excluded_subtrees)
708
709 if permitted_subtrees is None and excluded_subtrees is None:
710 raise ValueError(
711 "At least one of permitted_subtrees and excluded_subtrees "
712 "must not be None"
713 )
714
715 self._permitted_subtrees = permitted_subtrees
716 self._excluded_subtrees = excluded_subtrees
717
Paul Kehrer31894282015-06-21 21:46:41 -0500718 def __eq__(self, other):
719 if not isinstance(other, NameConstraints):
720 return NotImplemented
721
722 return (
723 self.excluded_subtrees == other.excluded_subtrees and
724 self.permitted_subtrees == other.permitted_subtrees
725 )
726
727 def __ne__(self, other):
728 return not self == other
729
Paul Kehrere0017be2015-05-17 20:39:40 -0600730 def _validate_ip_name(self, tree):
731 if any(isinstance(name, IPAddress) and not isinstance(
732 name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)
733 ) for name in tree):
734 raise TypeError(
735 "IPAddress name constraints must be an IPv4Network or"
736 " IPv6Network object"
737 )
738
739 def __repr__(self):
740 return (
741 u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, "
742 u"excluded_subtrees={0.excluded_subtrees})>".format(self)
743 )
744
745 permitted_subtrees = utils.read_only_property("_permitted_subtrees")
746 excluded_subtrees = utils.read_only_property("_excluded_subtrees")
747
748
Paul Kehrer5a485522015-05-06 00:29:12 -0500749class CRLDistributionPoints(object):
750 def __init__(self, distribution_points):
751 if not all(
752 isinstance(x, DistributionPoint) for x in distribution_points
753 ):
754 raise TypeError(
755 "distribution_points must be a list of DistributionPoint "
756 "objects"
757 )
758
759 self._distribution_points = distribution_points
760
761 def __iter__(self):
762 return iter(self._distribution_points)
763
764 def __len__(self):
765 return len(self._distribution_points)
766
767 def __repr__(self):
768 return "<CRLDistributionPoints({0})>".format(self._distribution_points)
769
770 def __eq__(self, other):
771 if not isinstance(other, CRLDistributionPoints):
772 return NotImplemented
773
774 return self._distribution_points == other._distribution_points
775
776 def __ne__(self, other):
777 return not self == other
778
779
780class DistributionPoint(object):
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500781 def __init__(self, full_name, relative_name, reasons, crl_issuer):
782 if full_name and relative_name:
783 raise ValueError(
784 "At least one of full_name and relative_name must be None"
785 )
786
787 if full_name and not all(
788 isinstance(x, GeneralName) for x in full_name
789 ):
790 raise TypeError(
791 "full_name must be a list of GeneralName objects"
792 )
793
794 if relative_name and not isinstance(relative_name, Name):
795 raise TypeError("relative_name must be a Name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500796
797 if crl_issuer and not all(
798 isinstance(x, GeneralName) for x in crl_issuer
799 ):
800 raise TypeError(
801 "crl_issuer must be None or a list of general names"
802 )
803
Paul Kehrer3fd02602015-05-09 19:46:13 -0500804 if reasons and (not isinstance(reasons, frozenset) or not all(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500805 isinstance(x, ReasonFlags) for x in reasons
Paul Kehrer3fd02602015-05-09 19:46:13 -0500806 )):
807 raise TypeError("reasons must be None or frozenset of ReasonFlags")
Paul Kehrer5a485522015-05-06 00:29:12 -0500808
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500809 if reasons and (
810 ReasonFlags.unspecified in reasons or
811 ReasonFlags.remove_from_crl in reasons
812 ):
Paul Kehrer5a485522015-05-06 00:29:12 -0500813 raise ValueError(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500814 "unspecified and remove_from_crl are not valid reasons in a "
815 "DistributionPoint"
816 )
817
818 if reasons and not crl_issuer and not (full_name or relative_name):
819 raise ValueError(
820 "You must supply crl_issuer, full_name, or relative_name when "
Paul Kehrer5a485522015-05-06 00:29:12 -0500821 "reasons is not None"
822 )
823
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500824 self._full_name = full_name
825 self._relative_name = relative_name
Paul Kehrer5a485522015-05-06 00:29:12 -0500826 self._reasons = reasons
827 self._crl_issuer = crl_issuer
828
829 def __repr__(self):
830 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500831 "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
832 "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
833 "suer})>".format(self)
Paul Kehrer5a485522015-05-06 00:29:12 -0500834 )
835
836 def __eq__(self, other):
837 if not isinstance(other, DistributionPoint):
838 return NotImplemented
839
840 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500841 self.full_name == other.full_name and
842 self.relative_name == other.relative_name and
Paul Kehrer5a485522015-05-06 00:29:12 -0500843 self.reasons == other.reasons and
844 self.crl_issuer == other.crl_issuer
845 )
846
847 def __ne__(self, other):
848 return not self == other
849
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500850 full_name = utils.read_only_property("_full_name")
851 relative_name = utils.read_only_property("_relative_name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500852 reasons = utils.read_only_property("_reasons")
853 crl_issuer = utils.read_only_property("_crl_issuer")
854
855
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500856class ReasonFlags(Enum):
857 unspecified = "unspecified"
858 key_compromise = "keyCompromise"
859 ca_compromise = "cACompromise"
860 affiliation_changed = "affiliationChanged"
861 superseded = "superseded"
862 cessation_of_operation = "cessationOfOperation"
863 certificate_hold = "certificateHold"
864 privilege_withdrawn = "privilegeWithdrawn"
865 aa_compromise = "aACompromise"
866 remove_from_crl = "removeFromCRL"
Paul Kehrer5a485522015-05-06 00:29:12 -0500867
868
Paul Kehrer16fae762015-05-01 23:14:20 -0500869class InhibitAnyPolicy(object):
870 def __init__(self, skip_certs):
871 if not isinstance(skip_certs, six.integer_types):
872 raise TypeError("skip_certs must be an integer")
873
874 if skip_certs < 0:
875 raise ValueError("skip_certs must be a non-negative integer")
876
877 self._skip_certs = skip_certs
878
879 def __repr__(self):
880 return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self)
881
882 def __eq__(self, other):
883 if not isinstance(other, InhibitAnyPolicy):
884 return NotImplemented
885
886 return self.skip_certs == other.skip_certs
887
888 def __ne__(self, other):
889 return not self == other
890
891 skip_certs = utils.read_only_property("_skip_certs")
892
893
Paul Kehrer31bdf792015-03-25 14:11:00 -0500894@six.add_metaclass(abc.ABCMeta)
895class GeneralName(object):
896 @abc.abstractproperty
897 def value(self):
898 """
899 Return the value of the object
900 """
901
902
903@utils.register_interface(GeneralName)
904class RFC822Name(object):
905 def __init__(self, value):
906 if not isinstance(value, six.text_type):
907 raise TypeError("value must be a unicode string")
908
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500909 name, address = parseaddr(value)
910 parts = address.split(u"@")
Paul Kehrer82890862015-07-12 12:08:28 -0500911 if name or not address:
912 # parseaddr has found a name (e.g. Name <email>) or the entire
913 # value is an empty string.
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500914 raise ValueError("Invalid rfc822name value")
915 elif len(parts) == 1:
916 # Single label email name. This is valid for local delivery.
917 # No IDNA encoding needed since there is no domain component.
918 encoded = address.encode("ascii")
919 else:
920 # A normal email of the form user@domain.com. Let's attempt to
921 # encode the domain component and reconstruct the address.
922 encoded = parts[0].encode("ascii") + b"@" + idna.encode(parts[1])
923
Paul Kehrer31bdf792015-03-25 14:11:00 -0500924 self._value = value
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500925 self._encoded = encoded
Paul Kehrer31bdf792015-03-25 14:11:00 -0500926
927 value = utils.read_only_property("_value")
928
929 def __repr__(self):
930 return "<RFC822Name(value={0})>".format(self.value)
931
932 def __eq__(self, other):
933 if not isinstance(other, RFC822Name):
934 return NotImplemented
935
936 return self.value == other.value
937
938 def __ne__(self, other):
939 return not self == other
940
941
942@utils.register_interface(GeneralName)
943class DNSName(object):
944 def __init__(self, value):
945 if not isinstance(value, six.text_type):
946 raise TypeError("value must be a unicode string")
947
948 self._value = value
949
950 value = utils.read_only_property("_value")
951
952 def __repr__(self):
953 return "<DNSName(value={0})>".format(self.value)
954
955 def __eq__(self, other):
956 if not isinstance(other, DNSName):
957 return NotImplemented
958
959 return self.value == other.value
960
961 def __ne__(self, other):
962 return not self == other
963
964
965@utils.register_interface(GeneralName)
966class UniformResourceIdentifier(object):
967 def __init__(self, value):
968 if not isinstance(value, six.text_type):
969 raise TypeError("value must be a unicode string")
970
Paul Kehrere28d6c42015-07-12 14:59:37 -0500971 parsed = urllib_parse.urlparse(value)
972 if not parsed.hostname:
973 netloc = ""
974 elif parsed.port:
975 netloc = (
976 idna.encode(parsed.hostname) +
977 ":{0}".format(parsed.port).encode("ascii")
978 ).decode("ascii")
979 else:
980 netloc = idna.encode(parsed.hostname).decode("ascii")
981
982 # Note that building a URL in this fashion means it should be
983 # semantically indistinguishable from the original but is not
984 # guaranteed to be exactly the same.
985 uri = urllib_parse.urlunparse((
986 parsed.scheme,
987 netloc,
988 parsed.path,
989 parsed.params,
990 parsed.query,
991 parsed.fragment
992 )).encode("ascii")
993
Paul Kehrer31bdf792015-03-25 14:11:00 -0500994 self._value = value
Paul Kehrere28d6c42015-07-12 14:59:37 -0500995 self._encoded = uri
Paul Kehrer31bdf792015-03-25 14:11:00 -0500996
997 value = utils.read_only_property("_value")
998
999 def __repr__(self):
1000 return "<UniformResourceIdentifier(value={0})>".format(self.value)
1001
1002 def __eq__(self, other):
1003 if not isinstance(other, UniformResourceIdentifier):
1004 return NotImplemented
1005
1006 return self.value == other.value
1007
1008 def __ne__(self, other):
1009 return not self == other
1010
1011
1012@utils.register_interface(GeneralName)
1013class DirectoryName(object):
1014 def __init__(self, value):
1015 if not isinstance(value, Name):
1016 raise TypeError("value must be a Name")
1017
1018 self._value = value
1019
1020 value = utils.read_only_property("_value")
1021
1022 def __repr__(self):
1023 return "<DirectoryName(value={0})>".format(self.value)
1024
1025 def __eq__(self, other):
1026 if not isinstance(other, DirectoryName):
1027 return NotImplemented
1028
1029 return self.value == other.value
1030
1031 def __ne__(self, other):
1032 return not self == other
1033
1034
1035@utils.register_interface(GeneralName)
1036class RegisteredID(object):
1037 def __init__(self, value):
1038 if not isinstance(value, ObjectIdentifier):
1039 raise TypeError("value must be an ObjectIdentifier")
1040
1041 self._value = value
1042
1043 value = utils.read_only_property("_value")
1044
1045 def __repr__(self):
1046 return "<RegisteredID(value={0})>".format(self.value)
1047
1048 def __eq__(self, other):
1049 if not isinstance(other, RegisteredID):
1050 return NotImplemented
1051
1052 return self.value == other.value
1053
1054 def __ne__(self, other):
1055 return not self == other
1056
1057
1058@utils.register_interface(GeneralName)
1059class IPAddress(object):
1060 def __init__(self, value):
1061 if not isinstance(
Paul Kehrereb177932015-05-17 18:33:33 -07001062 value,
1063 (
1064 ipaddress.IPv4Address,
1065 ipaddress.IPv6Address,
1066 ipaddress.IPv4Network,
1067 ipaddress.IPv6Network
1068 )
Paul Kehrer31bdf792015-03-25 14:11:00 -05001069 ):
1070 raise TypeError(
Paul Kehrereb177932015-05-17 18:33:33 -07001071 "value must be an instance of ipaddress.IPv4Address, "
1072 "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
1073 "ipaddress.IPv6Network"
Paul Kehrer31bdf792015-03-25 14:11:00 -05001074 )
1075
1076 self._value = value
1077
1078 value = utils.read_only_property("_value")
1079
1080 def __repr__(self):
1081 return "<IPAddress(value={0})>".format(self.value)
1082
1083 def __eq__(self, other):
1084 if not isinstance(other, IPAddress):
1085 return NotImplemented
1086
1087 return self.value == other.value
1088
1089 def __ne__(self, other):
1090 return not self == other
1091
1092
Joshua Tauberer2ee5e3c2015-07-04 20:09:46 +00001093@utils.register_interface(GeneralName)
1094class OtherName(object):
1095 def __init__(self, type_id, value):
1096 if not isinstance(type_id, ObjectIdentifier):
1097 raise TypeError("type_id must be an ObjectIdentifier")
1098 if not isinstance(value, bytes):
1099 raise TypeError("value must be a binary string")
1100
1101 self._type_id = type_id
1102 self._value = value
1103
1104 type_id = utils.read_only_property("_type_id")
1105 value = utils.read_only_property("_value")
1106
1107 def __repr__(self):
1108 return "<OtherName(type_id={0}, value={1!r})>".format(
1109 self.type_id, self.value)
1110
1111 def __eq__(self, other):
1112 if not isinstance(other, OtherName):
1113 return NotImplemented
1114
1115 return self.type_id == other.type_id and self.value == other.value
1116
1117 def __ne__(self, other):
1118 return not self == other
1119
1120
Erik Trauschke2dcce902015-05-14 16:12:24 -07001121class GeneralNames(object):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001122 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -05001123 if not all(isinstance(x, GeneralName) for x in general_names):
1124 raise TypeError(
1125 "Every item in the general_names list must be an "
1126 "object conforming to the GeneralName interface"
1127 )
1128
Paul Kehrer31bdf792015-03-25 14:11:00 -05001129 self._general_names = general_names
1130
1131 def __iter__(self):
1132 return iter(self._general_names)
1133
1134 def __len__(self):
1135 return len(self._general_names)
1136
1137 def get_values_for_type(self, type):
Joshua Taubererd2afad32015-07-06 22:37:53 +00001138 # Return the value of each GeneralName, except for OtherName instances
1139 # which we return directly because it has two important properties not
1140 # just one value.
1141 objs = (i for i in self if isinstance(i, type))
1142 if type != OtherName:
1143 objs = (i.value for i in objs)
1144 return list(objs)
Paul Kehrer31bdf792015-03-25 14:11:00 -05001145
1146 def __repr__(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001147 return "<GeneralNames({0})>".format(self._general_names)
1148
1149 def __eq__(self, other):
1150 if not isinstance(other, GeneralNames):
1151 return NotImplemented
1152
1153 return self._general_names == other._general_names
1154
1155 def __ne__(self, other):
1156 return not self == other
1157
1158
1159class SubjectAlternativeName(object):
1160 def __init__(self, general_names):
1161 self._general_names = GeneralNames(general_names)
1162
1163 def __iter__(self):
1164 return iter(self._general_names)
1165
1166 def __len__(self):
1167 return len(self._general_names)
1168
1169 def get_values_for_type(self, type):
1170 return self._general_names.get_values_for_type(type)
1171
1172 def __repr__(self):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001173 return "<SubjectAlternativeName({0})>".format(self._general_names)
1174
Paul Kehrer58cc3972015-05-13 10:00:41 -05001175 def __eq__(self, other):
1176 if not isinstance(other, SubjectAlternativeName):
1177 return NotImplemented
1178
1179 return self._general_names == other._general_names
1180
1181 def __ne__(self, other):
1182 return not self == other
1183
Paul Kehrer31bdf792015-03-25 14:11:00 -05001184
Paul Kehrer99125c92015-06-07 18:37:10 -05001185class IssuerAlternativeName(object):
1186 def __init__(self, general_names):
1187 self._general_names = GeneralNames(general_names)
1188
1189 def __iter__(self):
1190 return iter(self._general_names)
1191
1192 def __len__(self):
1193 return len(self._general_names)
1194
1195 def get_values_for_type(self, type):
1196 return self._general_names.get_values_for_type(type)
1197
1198 def __repr__(self):
1199 return "<IssuerAlternativeName({0})>".format(self._general_names)
1200
1201 def __eq__(self, other):
1202 if not isinstance(other, IssuerAlternativeName):
1203 return NotImplemented
1204
1205 return self._general_names == other._general_names
1206
1207 def __ne__(self, other):
1208 return not self == other
1209
1210
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001211class AuthorityKeyIdentifier(object):
1212 def __init__(self, key_identifier, authority_cert_issuer,
1213 authority_cert_serial_number):
1214 if authority_cert_issuer or authority_cert_serial_number:
1215 if not authority_cert_issuer or not authority_cert_serial_number:
1216 raise ValueError(
1217 "authority_cert_issuer and authority_cert_serial_number "
1218 "must both be present or both None"
1219 )
1220
Paul Kehrerc6e0f062015-05-03 11:04:34 -05001221 if not all(
1222 isinstance(x, GeneralName) for x in authority_cert_issuer
1223 ):
1224 raise TypeError(
1225 "authority_cert_issuer must be a list of GeneralName "
1226 "objects"
1227 )
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001228
1229 if not isinstance(authority_cert_serial_number, six.integer_types):
1230 raise TypeError(
1231 "authority_cert_serial_number must be an integer"
1232 )
1233
1234 self._key_identifier = key_identifier
1235 self._authority_cert_issuer = authority_cert_issuer
1236 self._authority_cert_serial_number = authority_cert_serial_number
1237
1238 def __repr__(self):
1239 return (
1240 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
1241 "authority_cert_issuer={0.authority_cert_issuer}, "
1242 "authority_cert_serial_number={0.authority_cert_serial_number}"
1243 ")>".format(self)
1244 )
1245
Paul Kehrer2ca2eb32015-05-03 10:04:57 -05001246 def __eq__(self, other):
1247 if not isinstance(other, AuthorityKeyIdentifier):
1248 return NotImplemented
1249
1250 return (
1251 self.key_identifier == other.key_identifier and
1252 self.authority_cert_issuer == other.authority_cert_issuer and
1253 self.authority_cert_serial_number ==
1254 other.authority_cert_serial_number
1255 )
1256
1257 def __ne__(self, other):
1258 return not self == other
1259
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001260 key_identifier = utils.read_only_property("_key_identifier")
1261 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
1262 authority_cert_serial_number = utils.read_only_property(
1263 "_authority_cert_serial_number"
1264 )
1265
1266
Paul Kehrer806bfb22015-02-02 17:05:24 -06001267OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
1268OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
1269OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
1270OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
1271OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
1272OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
1273OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
1274OID_SURNAME = ObjectIdentifier("2.5.4.4")
1275OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
1276OID_TITLE = ObjectIdentifier("2.5.4.12")
1277OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
1278OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
1279OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
1280OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
1281OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001282
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001283OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
1284OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
1285OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
1286OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
1287OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
1288OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001289OID_ECDSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10045.4.1")
Paul Kehrer56da2a52015-02-11 23:35:07 -06001290OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
1291OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
1292OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
1293OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
1294OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
1295OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
1296OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
1297
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001298_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001299 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
1300 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1301 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1302 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1303 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1304 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001305 OID_ECDSA_WITH_SHA1.dotted_string: hashes.SHA1(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -06001306 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1307 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1308 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1309 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
1310 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1311 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1312 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001313}
1314
Paul Kehrere1513fa2015-03-30 23:08:17 -05001315OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
1316OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
1317OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
1318OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
1319OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
1320OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
1321
Paul Kehrer3e6d5582015-05-02 21:57:56 -05001322OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
1323OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
1324
Paul Kehrer2b622582015-04-15 11:04:29 -04001325OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
1326OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
Paul Kehrer16fae762015-05-01 23:14:20 -05001327OID_ANY_POLICY = ObjectIdentifier("2.5.29.32.0")
Paul Kehrer2b622582015-04-15 11:04:29 -04001328
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001329
Paul Kehrerb2de9482014-12-11 14:54:48 -06001330@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -06001331class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -06001332 @abc.abstractmethod
1333 def fingerprint(self, algorithm):
1334 """
1335 Returns bytes using digest passed.
1336 """
1337
1338 @abc.abstractproperty
1339 def serial(self):
1340 """
1341 Returns certificate serial number
1342 """
1343
1344 @abc.abstractproperty
1345 def version(self):
1346 """
1347 Returns the certificate version
1348 """
1349
1350 @abc.abstractmethod
1351 def public_key(self):
1352 """
1353 Returns the public key
1354 """
1355
1356 @abc.abstractproperty
1357 def not_valid_before(self):
1358 """
1359 Not before time (represented as UTC datetime)
1360 """
1361
1362 @abc.abstractproperty
1363 def not_valid_after(self):
1364 """
1365 Not after time (represented as UTC datetime)
1366 """
Paul Kehrer719d5362015-01-01 20:03:52 -06001367
1368 @abc.abstractproperty
1369 def issuer(self):
1370 """
1371 Returns the issuer name object.
1372 """
1373
1374 @abc.abstractproperty
1375 def subject(self):
1376 """
1377 Returns the subject name object.
1378 """
Paul Kehrer56da2a52015-02-11 23:35:07 -06001379
1380 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001381 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -06001382 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001383 Returns a HashAlgorithm corresponding to the type of the digest signed
1384 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -06001385 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001386
Paul Kehrer8c234d12015-05-15 09:27:22 -07001387 @abc.abstractproperty
1388 def extensions(self):
1389 """
1390 Returns an Extensions object.
1391 """
1392
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001393 @abc.abstractmethod
1394 def __eq__(self, other):
1395 """
1396 Checks equality.
1397 """
1398
1399 @abc.abstractmethod
1400 def __ne__(self, other):
1401 """
1402 Checks not equal.
1403 """
1404
Andre Carona8aded62015-05-19 20:11:57 -04001405 @abc.abstractmethod
Alex Gaynor969f3a52015-07-06 18:52:41 -04001406 def __hash__(self):
1407 """
1408 Computes a hash.
1409 """
1410
1411 @abc.abstractmethod
Andre Carona8aded62015-05-19 20:11:57 -04001412 def public_bytes(self, encoding):
Andre Caron18ef34b2015-05-19 21:24:31 -04001413 """
1414 Serializes the certificate to PEM or DER format.
1415 """
Andre Carona8aded62015-05-19 20:11:57 -04001416
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001417
1418@six.add_metaclass(abc.ABCMeta)
Erik Trauschke2dcce902015-05-14 16:12:24 -07001419class CertificateRevocationList(object):
1420
1421 @abc.abstractmethod
1422 def fingerprint(self, algorithm):
1423 """
1424 Returns bytes using digest passed.
1425 """
1426
1427 @abc.abstractproperty
1428 def signature_hash_algorithm(self):
1429 """
1430 Returns a HashAlgorithm corresponding to the type of the digest signed
1431 in the certificate.
1432 """
1433
1434 @abc.abstractproperty
1435 def issuer(self):
1436 """
1437 Returns the X509Name with the issuer of this CRL.
1438 """
1439
1440 @abc.abstractproperty
1441 def next_update(self):
1442 """
1443 Returns the date of next update for this CRL.
1444 """
1445
1446 @abc.abstractproperty
1447 def last_update(self):
1448 """
1449 Returns the date of last update for this CRL.
1450 """
1451
1452 @abc.abstractproperty
Erik Trauschkeabb7b6e2015-05-27 15:07:35 -07001453 def revoked_certificates(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001454 """
1455 Returns a list of RevokedCertificate objects for this CRL.
1456 """
1457
1458 @abc.abstractproperty
1459 def extensions(self):
1460 """
1461 Returns an Extensions object containing a list of CRL extensions.
1462 """
1463
1464 @abc.abstractmethod
Erik Trauschke2dcce902015-05-14 16:12:24 -07001465 def __eq__(self, other):
1466 """
1467 Checks equality.
1468 """
1469
1470 @abc.abstractmethod
1471 def __ne__(self, other):
1472 """
1473 Checks not equal.
1474 """
1475
1476
1477@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -05001478class CertificateSigningRequest(object):
Alex Gaynor935f6ca2015-07-06 21:03:46 -04001479 @abc.abstractmethod
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001480 def __eq__(self, other):
1481 """
1482 Checks equality.
1483 """
1484
1485 @abc.abstractmethod
1486 def __ne__(self, other):
1487 """
1488 Checks not equal.
1489 """
1490
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001491 @abc.abstractmethod
Alex Gaynor978137d2015-07-08 20:59:16 -04001492 def __hash__(self):
1493 """
1494 Computes a hash.
1495 """
1496
1497 @abc.abstractmethod
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001498 def public_key(self):
1499 """
1500 Returns the public key
1501 """
1502
1503 @abc.abstractproperty
1504 def subject(self):
1505 """
1506 Returns the subject name object.
1507 """
1508
1509 @abc.abstractproperty
1510 def signature_hash_algorithm(self):
1511 """
1512 Returns a HashAlgorithm corresponding to the type of the digest signed
1513 in the certificate.
1514 """
Andre Caron6e721a92015-05-17 15:08:48 -04001515
1516 @abc.abstractproperty
1517 def extensions(self):
1518 """
1519 Returns the extensions in the signing request.
1520 """
Andre Caron476c5df2015-05-18 10:23:28 -04001521
1522 @abc.abstractmethod
1523 def public_bytes(self, encoding):
1524 """
1525 Encodes the request to PEM or DER format.
1526 """
Erik Trauschke2dcce902015-05-14 16:12:24 -07001527
1528
1529@six.add_metaclass(abc.ABCMeta)
1530class RevokedCertificate(object):
1531 @abc.abstractproperty
1532 def serial_number(self):
1533 """
1534 Returns the serial number of the revoked certificate.
1535 """
1536
1537 @abc.abstractproperty
1538 def revocation_date(self):
1539 """
1540 Returns the date of when this certificate was revoked.
1541 """
1542
1543 @abc.abstractproperty
1544 def extensions(self):
1545 """
1546 Returns an Extensions object containing a list of Revoked extensions.
1547 """
Andre Caron0ef595f2015-05-18 13:53:43 -04001548
1549
1550class CertificateSigningRequestBuilder(object):
Andre Caron99d0f902015-06-01 08:36:59 -04001551 def __init__(self, subject_name=None, extensions=[]):
Andre Caron0ef595f2015-05-18 13:53:43 -04001552 """
1553 Creates an empty X.509 certificate request (v1).
1554 """
Andre Caronfc164c52015-05-31 17:36:18 -04001555 self._subject_name = subject_name
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001556 self._extensions = extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001557
Andre Carona9a51172015-06-06 20:18:44 -04001558 def subject_name(self, name):
Andre Caron0ef595f2015-05-18 13:53:43 -04001559 """
1560 Sets the certificate requestor's distinguished name.
1561 """
1562 if not isinstance(name, Name):
1563 raise TypeError('Expecting x509.Name object.')
Ian Cordascod09ec372015-06-17 21:37:51 -05001564 if self._subject_name is not None:
1565 raise ValueError('The subject name may only be set once.')
Andre Caron99d0f902015-06-01 08:36:59 -04001566 return CertificateSigningRequestBuilder(name, self._extensions)
Andre Caron0ef595f2015-05-18 13:53:43 -04001567
Ian Cordascof06b6be2015-06-21 10:09:18 -05001568 def add_extension(self, extension, critical):
Andre Caron0ef595f2015-05-18 13:53:43 -04001569 """
1570 Adds an X.509 extension to the certificate request.
1571 """
Andre Caron472fd692015-06-06 20:04:44 -04001572 if isinstance(extension, BasicConstraints):
1573 extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
Paul Kehrer0b8f3272015-07-23 21:46:21 +01001574 elif isinstance(extension, ExtendedKeyUsage):
1575 extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001576 elif isinstance(extension, SubjectAlternativeName):
1577 extension = Extension(
1578 OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
1579 )
Alex Gaynor887a4082015-07-03 04:29:03 -04001580 elif isinstance(extension, KeyUsage):
1581 extension = Extension(OID_KEY_USAGE, critical, extension)
Paul Kehrerdce91f02015-07-23 20:31:12 +01001582 elif isinstance(extension, InhibitAnyPolicy):
1583 extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension)
Andre Caron472fd692015-06-06 20:04:44 -04001584 else:
Ian Cordascof06b6be2015-06-21 10:09:18 -05001585 raise NotImplementedError('Unsupported X.509 extension.')
1586 # TODO: This is quadratic in the number of extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001587 for e in self._extensions:
1588 if e.oid == extension.oid:
1589 raise ValueError('This extension has already been set.')
Andre Caronfc164c52015-05-31 17:36:18 -04001590 return CertificateSigningRequestBuilder(
Andre Caron99d0f902015-06-01 08:36:59 -04001591 self._subject_name, self._extensions + [extension]
Andre Caronfc164c52015-05-31 17:36:18 -04001592 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001593
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001594 def sign(self, private_key, algorithm, backend):
Andre Caron0ef595f2015-05-18 13:53:43 -04001595 """
1596 Signs the request using the requestor's private key.
1597 """
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001598 if self._subject_name is None:
1599 raise ValueError("A CertificateSigningRequest must have a subject")
Andre Carona33ea282015-05-31 16:32:26 -04001600 return backend.create_x509_csr(self, private_key, algorithm)