blob: 02e938a79989dd4f91f4f0b832bc928b90bee4e7 [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
Andre Caron9bbfcea2015-05-18 20:55:29 -04008import datetime
Paul Kehrer31bdf792015-03-25 14:11:00 -05009import ipaddress
Paul Kehrer01d5d0b2015-07-12 09:41:21 -050010from email.utils import parseaddr
Paul Kehrer016e08a2014-11-26 09:41:18 -100011from enum import Enum
12
Paul Kehrer01d5d0b2015-07-12 09:41:21 -050013import idna
14
Paul Kehrerb2de9482014-12-11 14:54:48 -060015import six
16
Paul Kehrere28d6c42015-07-12 14:59:37 -050017from six.moves import urllib_parse
18
Paul Kehrer912d3fb2015-01-29 11:19:22 -060019from cryptography import utils
Paul Kehrer8802a5b2015-02-13 12:06:57 -060020from cryptography.hazmat.primitives import hashes
Ian Cordascob3ed4842015-07-01 22:46:03 -050021from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehrer912d3fb2015-01-29 11:19:22 -060022
Paul Kehrer016e08a2014-11-26 09:41:18 -100023
Paul Kehrer806bfb22015-02-02 17:05:24 -060024_OID_NAMES = {
25 "2.5.4.3": "commonName",
26 "2.5.4.6": "countryName",
27 "2.5.4.7": "localityName",
28 "2.5.4.8": "stateOrProvinceName",
29 "2.5.4.10": "organizationName",
30 "2.5.4.11": "organizationalUnitName",
31 "2.5.4.5": "serialNumber",
32 "2.5.4.4": "surname",
33 "2.5.4.42": "givenName",
34 "2.5.4.12": "title",
35 "2.5.4.44": "generationQualifier",
36 "2.5.4.46": "dnQualifier",
37 "2.5.4.65": "pseudonym",
38 "0.9.2342.19200300.100.1.25": "domainComponent",
39 "1.2.840.113549.1.9.1": "emailAddress",
Paul Kehrer71d40c62015-02-19 08:21:04 -060040 "1.2.840.113549.1.1.4": "md5WithRSAEncryption",
41 "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
Paul Kehrer56da2a52015-02-11 23:35:07 -060042 "1.2.840.113549.1.1.14": "sha224WithRSAEncryption",
43 "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
44 "1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
45 "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
Alex Gaynor3aadabf2015-06-23 22:06:21 -040046 "1.2.840.10045.4.1": "ecdsa-with-SHA1",
Paul Kehrer71d40c62015-02-19 08:21:04 -060047 "1.2.840.10045.4.3.1": "ecdsa-with-SHA224",
48 "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
49 "1.2.840.10045.4.3.3": "ecdsa-with-SHA384",
50 "1.2.840.10045.4.3.4": "ecdsa-with-SHA512",
51 "1.2.840.10040.4.3": "dsa-with-sha1",
52 "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
53 "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
Paul Kehrere1513fa2015-03-30 23:08:17 -050054 "1.3.6.1.5.5.7.3.1": "serverAuth",
55 "1.3.6.1.5.5.7.3.2": "clientAuth",
56 "1.3.6.1.5.5.7.3.3": "codeSigning",
57 "1.3.6.1.5.5.7.3.4": "emailProtection",
58 "1.3.6.1.5.5.7.3.8": "timeStamping",
59 "1.3.6.1.5.5.7.3.9": "OCSPSigning",
Paul Kehrerd08b5492015-04-04 15:19:16 -050060 "2.5.29.9": "subjectDirectoryAttributes",
61 "2.5.29.14": "subjectKeyIdentifier",
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050062 "2.5.29.15": "keyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050063 "2.5.29.17": "subjectAltName",
64 "2.5.29.18": "issuerAltName",
65 "2.5.29.19": "basicConstraints",
Erik Trauschkec5a8d172015-05-28 10:24:25 -070066 "2.5.29.21": "cRLReason",
67 "2.5.29.24": "invalidityDate",
68 "2.5.29.29": "certificateIssuer",
Paul Kehrerd08b5492015-04-04 15:19:16 -050069 "2.5.29.30": "nameConstraints",
70 "2.5.29.31": "cRLDistributionPoints",
71 "2.5.29.32": "certificatePolicies",
72 "2.5.29.33": "policyMappings",
73 "2.5.29.35": "authorityKeyIdentifier",
74 "2.5.29.36": "policyConstraints",
Paul Kehrere1513fa2015-03-30 23:08:17 -050075 "2.5.29.37": "extendedKeyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050076 "2.5.29.46": "freshestCRL",
77 "2.5.29.54": "inhibitAnyPolicy",
78 "1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
79 "1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
80 "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
Paul Kehrer3e6d5582015-05-02 21:57:56 -050081 "1.3.6.1.5.5.7.48.1": "OCSP",
Paul Kehrerf506bca2015-05-02 22:31:47 -050082 "1.3.6.1.5.5.7.48.2": "caIssuers",
Paul Kehrer2b622582015-04-15 11:04:29 -040083 "1.3.6.1.5.5.7.2.1": "id-qt-cps",
84 "1.3.6.1.5.5.7.2.2": "id-qt-unotice",
Paul Kehrer806bfb22015-02-02 17:05:24 -060085}
86
87
Paul Kehrer9089c912015-04-20 22:15:20 -050088_GENERAL_NAMES = {
89 0: "otherName",
90 1: "rfc822Name",
91 2: "dNSName",
92 3: "x400Address",
93 4: "directoryName",
94 5: "ediPartyName",
95 6: "uniformResourceIdentifier",
96 7: "iPAddress",
97 8: "registeredID",
98}
99
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500100_UNIX_EPOCH = datetime.datetime(1970, 1, 1)
101
Paul Kehrer9089c912015-04-20 22:15:20 -0500102
Paul Kehrere76cd272014-12-14 19:00:51 -0600103class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -1000104 v1 = 0
105 v3 = 2
106
107
Paul Kehrer016e08a2014-11-26 09:41:18 -1000108def load_pem_x509_certificate(data, backend):
109 return backend.load_pem_x509_certificate(data)
110
111
Paul Kehrer016e08a2014-11-26 09:41:18 -1000112def load_der_x509_certificate(data, backend):
113 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -1000114
115
Paul Kehrer31e39882015-03-11 11:37:04 -0500116def load_pem_x509_csr(data, backend):
117 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600118
119
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500120def load_der_x509_csr(data, backend):
121 return backend.load_der_x509_csr(data)
122
123
Paul Kehrere76cd272014-12-14 19:00:51 -0600124class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600125 def __init__(self, msg, parsed_version):
126 super(InvalidVersion, self).__init__(msg)
127 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600128
129
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500130class DuplicateExtension(Exception):
131 def __init__(self, msg, oid):
132 super(DuplicateExtension, self).__init__(msg)
133 self.oid = oid
134
135
136class UnsupportedExtension(Exception):
137 def __init__(self, msg, oid):
138 super(UnsupportedExtension, self).__init__(msg)
139 self.oid = oid
140
141
Paul Kehrerfa56a232015-03-17 13:14:03 -0500142class ExtensionNotFound(Exception):
143 def __init__(self, msg, oid):
144 super(ExtensionNotFound, self).__init__(msg)
145 self.oid = oid
146
147
Paul Kehrer9089c912015-04-20 22:15:20 -0500148class UnsupportedGeneralNameType(Exception):
Paul Kehrerbed07352015-04-21 08:31:10 -0500149 def __init__(self, msg, type):
150 super(UnsupportedGeneralNameType, self).__init__(msg)
151 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500152
153
Paul Kehrer806bfb22015-02-02 17:05:24 -0600154class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600155 def __init__(self, oid, value):
156 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600157 raise TypeError(
158 "oid argument must be an ObjectIdentifier instance."
159 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600160
Ian Cordasco7618fbe2015-06-16 19:12:17 -0500161 if not isinstance(value, six.text_type):
162 raise TypeError(
163 "value argument must be a text type."
164 )
165
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600166 self._oid = oid
167 self._value = value
168
169 oid = utils.read_only_property("_oid")
170 value = utils.read_only_property("_value")
171
172 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600173 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600174 return NotImplemented
175
176 return (
177 self.oid == other.oid and
178 self.value == other.value
179 )
180
181 def __ne__(self, other):
182 return not self == other
183
Paul Kehrera498be82015-02-12 15:00:56 -0600184 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400185 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600186
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600187
188class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600189 def __init__(self, dotted_string):
190 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600191
192 def __eq__(self, other):
193 if not isinstance(other, ObjectIdentifier):
194 return NotImplemented
195
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600196 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600197
198 def __ne__(self, other):
199 return not self == other
200
201 def __repr__(self):
202 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600203 self._dotted_string,
204 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600205 )
206
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500207 def __hash__(self):
208 return hash(self.dotted_string)
209
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600210 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600211
212
Paul Kehrer719d5362015-01-01 20:03:52 -0600213class Name(object):
214 def __init__(self, attributes):
215 self._attributes = attributes
216
Paul Kehrere901d642015-02-11 18:50:58 -0600217 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800218 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600219
Paul Kehrer719d5362015-01-01 20:03:52 -0600220 def __eq__(self, other):
221 if not isinstance(other, Name):
222 return NotImplemented
223
Paul Kehrer53d8d492015-02-13 18:47:30 -0600224 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600225
226 def __ne__(self, other):
227 return not self == other
228
Paul Kehrer53d8d492015-02-13 18:47:30 -0600229 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600230 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600231
232 def __len__(self):
233 return len(self._attributes)
234
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400235 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400236 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400237
Paul Kehrer719d5362015-01-01 20:03:52 -0600238
Paul Kehrerd08b5492015-04-04 15:19:16 -0500239OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
240OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500241OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500242OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
243OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500244OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Erik Trauschke2dcce902015-05-14 16:12:24 -0700245OID_CRL_REASON = ObjectIdentifier("2.5.29.21")
246OID_INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
247OID_CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500248OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
249OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
250OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
251OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
252OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
253OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
254OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
255OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
256OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
257OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
258OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
259OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500260
261
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500262class Extensions(object):
263 def __init__(self, extensions):
264 self._extensions = extensions
265
Paul Kehrerfa56a232015-03-17 13:14:03 -0500266 def get_extension_for_oid(self, oid):
267 for ext in self:
268 if ext.oid == oid:
269 return ext
270
271 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
272
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500273 def __iter__(self):
274 return iter(self._extensions)
275
276 def __len__(self):
277 return len(self._extensions)
278
279
Paul Kehrer8cf26422015-03-21 09:50:24 -0500280class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500281 def __init__(self, oid, critical, value):
282 if not isinstance(oid, ObjectIdentifier):
283 raise TypeError(
284 "oid argument must be an ObjectIdentifier instance."
285 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500286
287 if not isinstance(critical, bool):
288 raise TypeError("critical must be a boolean value")
289
Paul Kehrer85894662015-03-22 13:19:31 -0500290 self._oid = oid
291 self._critical = critical
292 self._value = value
293
294 oid = utils.read_only_property("_oid")
295 critical = utils.read_only_property("_critical")
296 value = utils.read_only_property("_value")
297
298 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500299 return ("<Extension(oid={0.oid}, critical={0.critical}, "
300 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500301
Paul Kehrer58e870c2015-05-17 09:15:30 -0700302 def __eq__(self, other):
303 if not isinstance(other, Extension):
304 return NotImplemented
305
306 return (
307 self.oid == other.oid and
308 self.critical == other.critical and
309 self.value == other.value
310 )
311
312 def __ne__(self, other):
313 return not self == other
314
Paul Kehrer85894662015-03-22 13:19:31 -0500315
Paul Kehrerffa2a152015-03-31 08:18:25 -0500316class ExtendedKeyUsage(object):
317 def __init__(self, usages):
Paul Kehrerb0476172015-05-02 19:34:51 -0500318 if not all(isinstance(x, ObjectIdentifier) for x in usages):
319 raise TypeError(
320 "Every item in the usages list must be an ObjectIdentifier"
321 )
Paul Kehrerffa2a152015-03-31 08:18:25 -0500322
323 self._usages = usages
324
325 def __iter__(self):
326 return iter(self._usages)
327
328 def __len__(self):
329 return len(self._usages)
330
Paul Kehrer23d10c32015-04-02 23:12:32 -0500331 def __repr__(self):
332 return "<ExtendedKeyUsage({0})>".format(self._usages)
333
Paul Kehrerb0476172015-05-02 19:34:51 -0500334 def __eq__(self, other):
335 if not isinstance(other, ExtendedKeyUsage):
336 return NotImplemented
337
Paul Kehrerf24bad72015-05-02 19:36:20 -0500338 return self._usages == other._usages
Paul Kehrerb0476172015-05-02 19:34:51 -0500339
340 def __ne__(self, other):
341 return not self == other
342
Paul Kehrerffa2a152015-03-31 08:18:25 -0500343
Paul Kehrer4a1038e2015-05-18 10:28:31 -0700344class OCSPNoCheck(object):
345 pass
346
347
Paul Kehrer85894662015-03-22 13:19:31 -0500348class BasicConstraints(object):
349 def __init__(self, ca, path_length):
350 if not isinstance(ca, bool):
351 raise TypeError("ca must be a boolean value")
352
Paul Kehrer611d3d32015-03-22 13:31:18 -0500353 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500354 raise ValueError("path_length must be None when ca is False")
355
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500356 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500357 path_length is not None and
358 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500359 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500360 raise TypeError(
361 "path_length must be a non-negative integer or None"
362 )
363
364 self._ca = ca
365 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500366
367 ca = utils.read_only_property("_ca")
368 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500369
370 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500371 return ("<BasicConstraints(ca={0.ca}, "
372 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500373
Paul Kehrer3a69b132015-05-13 10:03:46 -0500374 def __eq__(self, other):
375 if not isinstance(other, BasicConstraints):
376 return NotImplemented
377
378 return self.ca == other.ca and self.path_length == other.path_length
379
380 def __ne__(self, other):
381 return not self == other
382
Paul Kehrer8cf26422015-03-21 09:50:24 -0500383
Paul Kehrercecbbba2015-03-30 14:58:38 -0500384class KeyUsage(object):
385 def __init__(self, digital_signature, content_commitment, key_encipherment,
386 data_encipherment, key_agreement, key_cert_sign, crl_sign,
387 encipher_only, decipher_only):
388 if not key_agreement and (encipher_only or decipher_only):
389 raise ValueError(
390 "encipher_only and decipher_only can only be true when "
391 "key_agreement is true"
392 )
393
394 self._digital_signature = digital_signature
395 self._content_commitment = content_commitment
396 self._key_encipherment = key_encipherment
397 self._data_encipherment = data_encipherment
398 self._key_agreement = key_agreement
399 self._key_cert_sign = key_cert_sign
400 self._crl_sign = crl_sign
401 self._encipher_only = encipher_only
402 self._decipher_only = decipher_only
403
404 digital_signature = utils.read_only_property("_digital_signature")
405 content_commitment = utils.read_only_property("_content_commitment")
406 key_encipherment = utils.read_only_property("_key_encipherment")
407 data_encipherment = utils.read_only_property("_data_encipherment")
408 key_agreement = utils.read_only_property("_key_agreement")
409 key_cert_sign = utils.read_only_property("_key_cert_sign")
410 crl_sign = utils.read_only_property("_crl_sign")
411
412 @property
413 def encipher_only(self):
414 if not self.key_agreement:
415 raise ValueError(
416 "encipher_only is undefined unless key_agreement is true"
417 )
418 else:
419 return self._encipher_only
420
421 @property
422 def decipher_only(self):
423 if not self.key_agreement:
424 raise ValueError(
425 "decipher_only is undefined unless key_agreement is true"
426 )
427 else:
428 return self._decipher_only
429
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500430 def __repr__(self):
431 try:
432 encipher_only = self.encipher_only
433 decipher_only = self.decipher_only
434 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400435 encipher_only = None
436 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500437
438 return ("<KeyUsage(digital_signature={0.digital_signature}, "
439 "content_commitment={0.content_commitment}, "
440 "key_encipherment={0.key_encipherment}, "
441 "data_encipherment={0.data_encipherment}, "
442 "key_agreement={0.key_agreement}, "
443 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
444 "encipher_only={1}, decipher_only={2})>").format(
445 self, encipher_only, decipher_only)
446
Paul Kehrer8565f5e2015-05-13 09:57:09 -0500447 def __eq__(self, other):
448 if not isinstance(other, KeyUsage):
449 return NotImplemented
450
451 return (
452 self.digital_signature == other.digital_signature and
453 self.content_commitment == other.content_commitment and
454 self.key_encipherment == other.key_encipherment and
455 self.data_encipherment == other.data_encipherment and
456 self.key_agreement == other.key_agreement and
457 self.key_cert_sign == other.key_cert_sign and
458 self.crl_sign == other.crl_sign and
459 self._encipher_only == other._encipher_only and
460 self._decipher_only == other._decipher_only
461 )
462
463 def __ne__(self, other):
464 return not self == other
465
Paul Kehrercecbbba2015-03-30 14:58:38 -0500466
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500467class AuthorityInformationAccess(object):
468 def __init__(self, descriptions):
469 if not all(isinstance(x, AccessDescription) for x in descriptions):
470 raise TypeError(
471 "Every item in the descriptions list must be an "
472 "AccessDescription"
473 )
474
475 self._descriptions = descriptions
476
477 def __iter__(self):
478 return iter(self._descriptions)
479
480 def __len__(self):
481 return len(self._descriptions)
482
483 def __repr__(self):
484 return "<AuthorityInformationAccess({0})>".format(self._descriptions)
485
486 def __eq__(self, other):
487 if not isinstance(other, AuthorityInformationAccess):
488 return NotImplemented
489
490 return self._descriptions == other._descriptions
491
492 def __ne__(self, other):
493 return not self == other
494
495
496class AccessDescription(object):
497 def __init__(self, access_method, access_location):
498 if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
Paul Kehrerf506bca2015-05-02 22:31:47 -0500499 raise ValueError(
500 "access_method must be OID_OCSP or OID_CA_ISSUERS"
501 )
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500502
503 if not isinstance(access_location, GeneralName):
504 raise TypeError("access_location must be a GeneralName")
505
506 self._access_method = access_method
507 self._access_location = access_location
508
509 def __repr__(self):
510 return (
511 "<AccessDescription(access_method={0.access_method}, access_locati"
512 "on={0.access_location})>".format(self)
513 )
514
515 def __eq__(self, other):
516 if not isinstance(other, AccessDescription):
517 return NotImplemented
518
519 return (
520 self.access_method == other.access_method and
521 self.access_location == other.access_location
522 )
523
524 def __ne__(self, other):
525 return not self == other
526
527 access_method = utils.read_only_property("_access_method")
528 access_location = utils.read_only_property("_access_location")
529
530
Paul Kehrer2b622582015-04-15 11:04:29 -0400531class CertificatePolicies(object):
532 def __init__(self, policies):
Paul Kehrerf61ec742015-04-18 20:42:39 -0500533 if not all(isinstance(x, PolicyInformation) for x in policies):
Paul Kehrer2b622582015-04-15 11:04:29 -0400534 raise TypeError(
535 "Every item in the policies list must be a "
536 "PolicyInformation"
537 )
538
539 self._policies = policies
540
541 def __iter__(self):
542 return iter(self._policies)
543
544 def __len__(self):
545 return len(self._policies)
546
547 def __repr__(self):
548 return "<CertificatePolicies({0})>".format(self._policies)
549
Paul Kehrerc56ab622015-05-03 09:56:31 -0500550 def __eq__(self, other):
551 if not isinstance(other, CertificatePolicies):
552 return NotImplemented
553
554 return self._policies == other._policies
555
556 def __ne__(self, other):
557 return not self == other
558
Paul Kehrer2b622582015-04-15 11:04:29 -0400559
560class PolicyInformation(object):
561 def __init__(self, policy_identifier, policy_qualifiers):
562 if not isinstance(policy_identifier, ObjectIdentifier):
563 raise TypeError("policy_identifier must be an ObjectIdentifier")
564
565 self._policy_identifier = policy_identifier
566 if policy_qualifiers and not all(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500567 isinstance(
568 x, (six.text_type, UserNotice)
569 ) for x in policy_qualifiers
Paul Kehrer2b622582015-04-15 11:04:29 -0400570 ):
571 raise TypeError(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500572 "policy_qualifiers must be a list of strings and/or UserNotice"
573 " objects or None"
Paul Kehrer2b622582015-04-15 11:04:29 -0400574 )
575
576 self._policy_qualifiers = policy_qualifiers
577
578 def __repr__(self):
579 return (
580 "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
581 "y_qualifiers={0.policy_qualifiers})>".format(self)
582 )
583
Paul Kehrerc56ab622015-05-03 09:56:31 -0500584 def __eq__(self, other):
585 if not isinstance(other, PolicyInformation):
586 return NotImplemented
587
588 return (
589 self.policy_identifier == other.policy_identifier and
590 self.policy_qualifiers == other.policy_qualifiers
591 )
592
593 def __ne__(self, other):
594 return not self == other
595
Paul Kehrer2b622582015-04-15 11:04:29 -0400596 policy_identifier = utils.read_only_property("_policy_identifier")
597 policy_qualifiers = utils.read_only_property("_policy_qualifiers")
598
599
Paul Kehrer2b622582015-04-15 11:04:29 -0400600class UserNotice(object):
601 def __init__(self, notice_reference, explicit_text):
602 if notice_reference and not isinstance(
603 notice_reference, NoticeReference
604 ):
605 raise TypeError(
606 "notice_reference must be None or a NoticeReference"
607 )
608
609 self._notice_reference = notice_reference
610 self._explicit_text = explicit_text
611
612 def __repr__(self):
613 return (
614 "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
Paul Kehrer9aaef9e2015-05-11 10:49:20 -0500615 "{0.explicit_text!r})>".format(self)
Paul Kehrer2b622582015-04-15 11:04:29 -0400616 )
617
Paul Kehrerc56ab622015-05-03 09:56:31 -0500618 def __eq__(self, other):
619 if not isinstance(other, UserNotice):
620 return NotImplemented
621
622 return (
623 self.notice_reference == other.notice_reference and
624 self.explicit_text == other.explicit_text
625 )
626
627 def __ne__(self, other):
628 return not self == other
629
Paul Kehrer2b622582015-04-15 11:04:29 -0400630 notice_reference = utils.read_only_property("_notice_reference")
631 explicit_text = utils.read_only_property("_explicit_text")
632
633
634class NoticeReference(object):
635 def __init__(self, organization, notice_numbers):
636 self._organization = organization
Paul Kehrer6e198b02015-05-12 15:53:38 -0500637 if not isinstance(notice_numbers, list) or not all(
Paul Kehrerf61ec742015-04-18 20:42:39 -0500638 isinstance(x, int) for x in notice_numbers
Paul Kehrer2b622582015-04-15 11:04:29 -0400639 ):
640 raise TypeError(
Paul Kehrer6e198b02015-05-12 15:53:38 -0500641 "notice_numbers must be a list of integers"
Paul Kehrer2b622582015-04-15 11:04:29 -0400642 )
643
644 self._notice_numbers = notice_numbers
645
646 def __repr__(self):
647 return (
Paul Kehrer73be2ca2015-05-11 21:22:38 -0500648 "<NoticeReference(organization={0.organization!r}, notice_numbers="
Paul Kehrer2b622582015-04-15 11:04:29 -0400649 "{0.notice_numbers})>".format(self)
650 )
651
Paul Kehrerc56ab622015-05-03 09:56:31 -0500652 def __eq__(self, other):
653 if not isinstance(other, NoticeReference):
654 return NotImplemented
655
656 return (
657 self.organization == other.organization and
658 self.notice_numbers == other.notice_numbers
659 )
660
661 def __ne__(self, other):
662 return not self == other
663
Paul Kehrer2b622582015-04-15 11:04:29 -0400664 organization = utils.read_only_property("_organization")
665 notice_numbers = utils.read_only_property("_notice_numbers")
666
667
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500668class SubjectKeyIdentifier(object):
669 def __init__(self, digest):
670 self._digest = digest
671
672 digest = utils.read_only_property("_digest")
673
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500674 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400675 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500676
677 def __eq__(self, other):
678 if not isinstance(other, SubjectKeyIdentifier):
679 return NotImplemented
680
681 return (
682 self.digest == other.digest
683 )
684
685 def __ne__(self, other):
686 return not self == other
687
688
Paul Kehrere0017be2015-05-17 20:39:40 -0600689class NameConstraints(object):
690 def __init__(self, permitted_subtrees, excluded_subtrees):
691 if permitted_subtrees is not None:
692 if not all(
693 isinstance(x, GeneralName) for x in permitted_subtrees
694 ):
695 raise TypeError(
696 "permitted_subtrees must be a list of GeneralName objects "
697 "or None"
698 )
699
700 self._validate_ip_name(permitted_subtrees)
701
702 if excluded_subtrees is not None:
703 if not all(
704 isinstance(x, GeneralName) for x in excluded_subtrees
705 ):
706 raise TypeError(
707 "excluded_subtrees must be a list of GeneralName objects "
708 "or None"
709 )
710
711 self._validate_ip_name(excluded_subtrees)
712
713 if permitted_subtrees is None and excluded_subtrees is None:
714 raise ValueError(
715 "At least one of permitted_subtrees and excluded_subtrees "
716 "must not be None"
717 )
718
719 self._permitted_subtrees = permitted_subtrees
720 self._excluded_subtrees = excluded_subtrees
721
Paul Kehrer31894282015-06-21 21:46:41 -0500722 def __eq__(self, other):
723 if not isinstance(other, NameConstraints):
724 return NotImplemented
725
726 return (
727 self.excluded_subtrees == other.excluded_subtrees and
728 self.permitted_subtrees == other.permitted_subtrees
729 )
730
731 def __ne__(self, other):
732 return not self == other
733
Paul Kehrere0017be2015-05-17 20:39:40 -0600734 def _validate_ip_name(self, tree):
735 if any(isinstance(name, IPAddress) and not isinstance(
736 name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)
737 ) for name in tree):
738 raise TypeError(
739 "IPAddress name constraints must be an IPv4Network or"
740 " IPv6Network object"
741 )
742
743 def __repr__(self):
744 return (
745 u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, "
746 u"excluded_subtrees={0.excluded_subtrees})>".format(self)
747 )
748
749 permitted_subtrees = utils.read_only_property("_permitted_subtrees")
750 excluded_subtrees = utils.read_only_property("_excluded_subtrees")
751
752
Paul Kehrer5a485522015-05-06 00:29:12 -0500753class CRLDistributionPoints(object):
754 def __init__(self, distribution_points):
755 if not all(
756 isinstance(x, DistributionPoint) for x in distribution_points
757 ):
758 raise TypeError(
759 "distribution_points must be a list of DistributionPoint "
760 "objects"
761 )
762
763 self._distribution_points = distribution_points
764
765 def __iter__(self):
766 return iter(self._distribution_points)
767
768 def __len__(self):
769 return len(self._distribution_points)
770
771 def __repr__(self):
772 return "<CRLDistributionPoints({0})>".format(self._distribution_points)
773
774 def __eq__(self, other):
775 if not isinstance(other, CRLDistributionPoints):
776 return NotImplemented
777
778 return self._distribution_points == other._distribution_points
779
780 def __ne__(self, other):
781 return not self == other
782
783
784class DistributionPoint(object):
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500785 def __init__(self, full_name, relative_name, reasons, crl_issuer):
786 if full_name and relative_name:
787 raise ValueError(
788 "At least one of full_name and relative_name must be None"
789 )
790
791 if full_name and not all(
792 isinstance(x, GeneralName) for x in full_name
793 ):
794 raise TypeError(
795 "full_name must be a list of GeneralName objects"
796 )
797
798 if relative_name and not isinstance(relative_name, Name):
799 raise TypeError("relative_name must be a Name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500800
801 if crl_issuer and not all(
802 isinstance(x, GeneralName) for x in crl_issuer
803 ):
804 raise TypeError(
805 "crl_issuer must be None or a list of general names"
806 )
807
Paul Kehrer3fd02602015-05-09 19:46:13 -0500808 if reasons and (not isinstance(reasons, frozenset) or not all(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500809 isinstance(x, ReasonFlags) for x in reasons
Paul Kehrer3fd02602015-05-09 19:46:13 -0500810 )):
811 raise TypeError("reasons must be None or frozenset of ReasonFlags")
Paul Kehrer5a485522015-05-06 00:29:12 -0500812
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500813 if reasons and (
814 ReasonFlags.unspecified in reasons or
815 ReasonFlags.remove_from_crl in reasons
816 ):
Paul Kehrer5a485522015-05-06 00:29:12 -0500817 raise ValueError(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500818 "unspecified and remove_from_crl are not valid reasons in a "
819 "DistributionPoint"
820 )
821
822 if reasons and not crl_issuer and not (full_name or relative_name):
823 raise ValueError(
824 "You must supply crl_issuer, full_name, or relative_name when "
Paul Kehrer5a485522015-05-06 00:29:12 -0500825 "reasons is not None"
826 )
827
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500828 self._full_name = full_name
829 self._relative_name = relative_name
Paul Kehrer5a485522015-05-06 00:29:12 -0500830 self._reasons = reasons
831 self._crl_issuer = crl_issuer
832
833 def __repr__(self):
834 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500835 "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
836 "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
837 "suer})>".format(self)
Paul Kehrer5a485522015-05-06 00:29:12 -0500838 )
839
840 def __eq__(self, other):
841 if not isinstance(other, DistributionPoint):
842 return NotImplemented
843
844 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500845 self.full_name == other.full_name and
846 self.relative_name == other.relative_name and
Paul Kehrer5a485522015-05-06 00:29:12 -0500847 self.reasons == other.reasons and
848 self.crl_issuer == other.crl_issuer
849 )
850
851 def __ne__(self, other):
852 return not self == other
853
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500854 full_name = utils.read_only_property("_full_name")
855 relative_name = utils.read_only_property("_relative_name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500856 reasons = utils.read_only_property("_reasons")
857 crl_issuer = utils.read_only_property("_crl_issuer")
858
859
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500860class ReasonFlags(Enum):
861 unspecified = "unspecified"
862 key_compromise = "keyCompromise"
863 ca_compromise = "cACompromise"
864 affiliation_changed = "affiliationChanged"
865 superseded = "superseded"
866 cessation_of_operation = "cessationOfOperation"
867 certificate_hold = "certificateHold"
868 privilege_withdrawn = "privilegeWithdrawn"
869 aa_compromise = "aACompromise"
870 remove_from_crl = "removeFromCRL"
Paul Kehrer5a485522015-05-06 00:29:12 -0500871
872
Paul Kehrer16fae762015-05-01 23:14:20 -0500873class InhibitAnyPolicy(object):
874 def __init__(self, skip_certs):
875 if not isinstance(skip_certs, six.integer_types):
876 raise TypeError("skip_certs must be an integer")
877
878 if skip_certs < 0:
879 raise ValueError("skip_certs must be a non-negative integer")
880
881 self._skip_certs = skip_certs
882
883 def __repr__(self):
884 return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self)
885
886 def __eq__(self, other):
887 if not isinstance(other, InhibitAnyPolicy):
888 return NotImplemented
889
890 return self.skip_certs == other.skip_certs
891
892 def __ne__(self, other):
893 return not self == other
894
895 skip_certs = utils.read_only_property("_skip_certs")
896
897
Paul Kehrer31bdf792015-03-25 14:11:00 -0500898@six.add_metaclass(abc.ABCMeta)
899class GeneralName(object):
900 @abc.abstractproperty
901 def value(self):
902 """
903 Return the value of the object
904 """
905
906
907@utils.register_interface(GeneralName)
908class RFC822Name(object):
909 def __init__(self, value):
910 if not isinstance(value, six.text_type):
911 raise TypeError("value must be a unicode string")
912
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500913 name, address = parseaddr(value)
914 parts = address.split(u"@")
Paul Kehrer82890862015-07-12 12:08:28 -0500915 if name or not address:
916 # parseaddr has found a name (e.g. Name <email>) or the entire
917 # value is an empty string.
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500918 raise ValueError("Invalid rfc822name value")
919 elif len(parts) == 1:
920 # Single label email name. This is valid for local delivery.
921 # No IDNA encoding needed since there is no domain component.
922 encoded = address.encode("ascii")
923 else:
924 # A normal email of the form user@domain.com. Let's attempt to
925 # encode the domain component and reconstruct the address.
926 encoded = parts[0].encode("ascii") + b"@" + idna.encode(parts[1])
927
Paul Kehrer31bdf792015-03-25 14:11:00 -0500928 self._value = value
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500929 self._encoded = encoded
Paul Kehrer31bdf792015-03-25 14:11:00 -0500930
931 value = utils.read_only_property("_value")
932
933 def __repr__(self):
934 return "<RFC822Name(value={0})>".format(self.value)
935
936 def __eq__(self, other):
937 if not isinstance(other, RFC822Name):
938 return NotImplemented
939
940 return self.value == other.value
941
942 def __ne__(self, other):
943 return not self == other
944
945
946@utils.register_interface(GeneralName)
947class DNSName(object):
948 def __init__(self, value):
949 if not isinstance(value, six.text_type):
950 raise TypeError("value must be a unicode string")
951
952 self._value = value
953
954 value = utils.read_only_property("_value")
955
956 def __repr__(self):
957 return "<DNSName(value={0})>".format(self.value)
958
959 def __eq__(self, other):
960 if not isinstance(other, DNSName):
961 return NotImplemented
962
963 return self.value == other.value
964
965 def __ne__(self, other):
966 return not self == other
967
968
969@utils.register_interface(GeneralName)
970class UniformResourceIdentifier(object):
971 def __init__(self, value):
972 if not isinstance(value, six.text_type):
973 raise TypeError("value must be a unicode string")
974
Paul Kehrere28d6c42015-07-12 14:59:37 -0500975 parsed = urllib_parse.urlparse(value)
976 if not parsed.hostname:
977 netloc = ""
978 elif parsed.port:
979 netloc = (
980 idna.encode(parsed.hostname) +
981 ":{0}".format(parsed.port).encode("ascii")
982 ).decode("ascii")
983 else:
984 netloc = idna.encode(parsed.hostname).decode("ascii")
985
986 # Note that building a URL in this fashion means it should be
987 # semantically indistinguishable from the original but is not
988 # guaranteed to be exactly the same.
989 uri = urllib_parse.urlunparse((
990 parsed.scheme,
991 netloc,
992 parsed.path,
993 parsed.params,
994 parsed.query,
995 parsed.fragment
996 )).encode("ascii")
997
Paul Kehrer31bdf792015-03-25 14:11:00 -0500998 self._value = value
Paul Kehrere28d6c42015-07-12 14:59:37 -0500999 self._encoded = uri
Paul Kehrer31bdf792015-03-25 14:11:00 -05001000
1001 value = utils.read_only_property("_value")
1002
1003 def __repr__(self):
1004 return "<UniformResourceIdentifier(value={0})>".format(self.value)
1005
1006 def __eq__(self, other):
1007 if not isinstance(other, UniformResourceIdentifier):
1008 return NotImplemented
1009
1010 return self.value == other.value
1011
1012 def __ne__(self, other):
1013 return not self == other
1014
1015
1016@utils.register_interface(GeneralName)
1017class DirectoryName(object):
1018 def __init__(self, value):
1019 if not isinstance(value, Name):
1020 raise TypeError("value must be a Name")
1021
1022 self._value = value
1023
1024 value = utils.read_only_property("_value")
1025
1026 def __repr__(self):
1027 return "<DirectoryName(value={0})>".format(self.value)
1028
1029 def __eq__(self, other):
1030 if not isinstance(other, DirectoryName):
1031 return NotImplemented
1032
1033 return self.value == other.value
1034
1035 def __ne__(self, other):
1036 return not self == other
1037
1038
1039@utils.register_interface(GeneralName)
1040class RegisteredID(object):
1041 def __init__(self, value):
1042 if not isinstance(value, ObjectIdentifier):
1043 raise TypeError("value must be an ObjectIdentifier")
1044
1045 self._value = value
1046
1047 value = utils.read_only_property("_value")
1048
1049 def __repr__(self):
1050 return "<RegisteredID(value={0})>".format(self.value)
1051
1052 def __eq__(self, other):
1053 if not isinstance(other, RegisteredID):
1054 return NotImplemented
1055
1056 return self.value == other.value
1057
1058 def __ne__(self, other):
1059 return not self == other
1060
1061
1062@utils.register_interface(GeneralName)
1063class IPAddress(object):
1064 def __init__(self, value):
1065 if not isinstance(
Paul Kehrereb177932015-05-17 18:33:33 -07001066 value,
1067 (
1068 ipaddress.IPv4Address,
1069 ipaddress.IPv6Address,
1070 ipaddress.IPv4Network,
1071 ipaddress.IPv6Network
1072 )
Paul Kehrer31bdf792015-03-25 14:11:00 -05001073 ):
1074 raise TypeError(
Paul Kehrereb177932015-05-17 18:33:33 -07001075 "value must be an instance of ipaddress.IPv4Address, "
1076 "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
1077 "ipaddress.IPv6Network"
Paul Kehrer31bdf792015-03-25 14:11:00 -05001078 )
1079
1080 self._value = value
1081
1082 value = utils.read_only_property("_value")
1083
1084 def __repr__(self):
1085 return "<IPAddress(value={0})>".format(self.value)
1086
1087 def __eq__(self, other):
1088 if not isinstance(other, IPAddress):
1089 return NotImplemented
1090
1091 return self.value == other.value
1092
1093 def __ne__(self, other):
1094 return not self == other
1095
1096
Joshua Tauberer2ee5e3c2015-07-04 20:09:46 +00001097@utils.register_interface(GeneralName)
1098class OtherName(object):
1099 def __init__(self, type_id, value):
1100 if not isinstance(type_id, ObjectIdentifier):
1101 raise TypeError("type_id must be an ObjectIdentifier")
1102 if not isinstance(value, bytes):
1103 raise TypeError("value must be a binary string")
1104
1105 self._type_id = type_id
1106 self._value = value
1107
1108 type_id = utils.read_only_property("_type_id")
1109 value = utils.read_only_property("_value")
1110
1111 def __repr__(self):
1112 return "<OtherName(type_id={0}, value={1!r})>".format(
1113 self.type_id, self.value)
1114
1115 def __eq__(self, other):
1116 if not isinstance(other, OtherName):
1117 return NotImplemented
1118
1119 return self.type_id == other.type_id and self.value == other.value
1120
1121 def __ne__(self, other):
1122 return not self == other
1123
1124
Erik Trauschke2dcce902015-05-14 16:12:24 -07001125class GeneralNames(object):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001126 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -05001127 if not all(isinstance(x, GeneralName) for x in general_names):
1128 raise TypeError(
1129 "Every item in the general_names list must be an "
1130 "object conforming to the GeneralName interface"
1131 )
1132
Paul Kehrer31bdf792015-03-25 14:11:00 -05001133 self._general_names = general_names
1134
1135 def __iter__(self):
1136 return iter(self._general_names)
1137
1138 def __len__(self):
1139 return len(self._general_names)
1140
1141 def get_values_for_type(self, type):
Joshua Taubererd2afad32015-07-06 22:37:53 +00001142 # Return the value of each GeneralName, except for OtherName instances
1143 # which we return directly because it has two important properties not
1144 # just one value.
1145 objs = (i for i in self if isinstance(i, type))
1146 if type != OtherName:
1147 objs = (i.value for i in objs)
1148 return list(objs)
Paul Kehrer31bdf792015-03-25 14:11:00 -05001149
1150 def __repr__(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001151 return "<GeneralNames({0})>".format(self._general_names)
1152
1153 def __eq__(self, other):
1154 if not isinstance(other, GeneralNames):
1155 return NotImplemented
1156
1157 return self._general_names == other._general_names
1158
1159 def __ne__(self, other):
1160 return not self == other
1161
1162
1163class SubjectAlternativeName(object):
1164 def __init__(self, general_names):
1165 self._general_names = GeneralNames(general_names)
1166
1167 def __iter__(self):
1168 return iter(self._general_names)
1169
1170 def __len__(self):
1171 return len(self._general_names)
1172
1173 def get_values_for_type(self, type):
1174 return self._general_names.get_values_for_type(type)
1175
1176 def __repr__(self):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001177 return "<SubjectAlternativeName({0})>".format(self._general_names)
1178
Paul Kehrer58cc3972015-05-13 10:00:41 -05001179 def __eq__(self, other):
1180 if not isinstance(other, SubjectAlternativeName):
1181 return NotImplemented
1182
1183 return self._general_names == other._general_names
1184
1185 def __ne__(self, other):
1186 return not self == other
1187
Paul Kehrer31bdf792015-03-25 14:11:00 -05001188
Paul Kehrer99125c92015-06-07 18:37:10 -05001189class IssuerAlternativeName(object):
1190 def __init__(self, general_names):
1191 self._general_names = GeneralNames(general_names)
1192
1193 def __iter__(self):
1194 return iter(self._general_names)
1195
1196 def __len__(self):
1197 return len(self._general_names)
1198
1199 def get_values_for_type(self, type):
1200 return self._general_names.get_values_for_type(type)
1201
1202 def __repr__(self):
1203 return "<IssuerAlternativeName({0})>".format(self._general_names)
1204
1205 def __eq__(self, other):
1206 if not isinstance(other, IssuerAlternativeName):
1207 return NotImplemented
1208
1209 return self._general_names == other._general_names
1210
1211 def __ne__(self, other):
1212 return not self == other
1213
1214
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001215class AuthorityKeyIdentifier(object):
1216 def __init__(self, key_identifier, authority_cert_issuer,
1217 authority_cert_serial_number):
1218 if authority_cert_issuer or authority_cert_serial_number:
1219 if not authority_cert_issuer or not authority_cert_serial_number:
1220 raise ValueError(
1221 "authority_cert_issuer and authority_cert_serial_number "
1222 "must both be present or both None"
1223 )
1224
Paul Kehrerc6e0f062015-05-03 11:04:34 -05001225 if not all(
1226 isinstance(x, GeneralName) for x in authority_cert_issuer
1227 ):
1228 raise TypeError(
1229 "authority_cert_issuer must be a list of GeneralName "
1230 "objects"
1231 )
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001232
1233 if not isinstance(authority_cert_serial_number, six.integer_types):
1234 raise TypeError(
1235 "authority_cert_serial_number must be an integer"
1236 )
1237
1238 self._key_identifier = key_identifier
1239 self._authority_cert_issuer = authority_cert_issuer
1240 self._authority_cert_serial_number = authority_cert_serial_number
1241
1242 def __repr__(self):
1243 return (
1244 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
1245 "authority_cert_issuer={0.authority_cert_issuer}, "
1246 "authority_cert_serial_number={0.authority_cert_serial_number}"
1247 ")>".format(self)
1248 )
1249
Paul Kehrer2ca2eb32015-05-03 10:04:57 -05001250 def __eq__(self, other):
1251 if not isinstance(other, AuthorityKeyIdentifier):
1252 return NotImplemented
1253
1254 return (
1255 self.key_identifier == other.key_identifier and
1256 self.authority_cert_issuer == other.authority_cert_issuer and
1257 self.authority_cert_serial_number ==
1258 other.authority_cert_serial_number
1259 )
1260
1261 def __ne__(self, other):
1262 return not self == other
1263
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001264 key_identifier = utils.read_only_property("_key_identifier")
1265 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
1266 authority_cert_serial_number = utils.read_only_property(
1267 "_authority_cert_serial_number"
1268 )
1269
1270
Paul Kehrer806bfb22015-02-02 17:05:24 -06001271OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
1272OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
1273OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
1274OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
1275OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
1276OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
1277OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
1278OID_SURNAME = ObjectIdentifier("2.5.4.4")
1279OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
1280OID_TITLE = ObjectIdentifier("2.5.4.12")
1281OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
1282OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
1283OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
1284OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
1285OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001286
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001287OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
1288OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
1289OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
1290OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
1291OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
1292OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001293OID_ECDSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10045.4.1")
Paul Kehrer56da2a52015-02-11 23:35:07 -06001294OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
1295OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
1296OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
1297OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
1298OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
1299OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
1300OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
1301
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001302_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001303 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
1304 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1305 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1306 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1307 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1308 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001309 OID_ECDSA_WITH_SHA1.dotted_string: hashes.SHA1(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -06001310 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1311 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1312 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1313 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
1314 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1315 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1316 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001317}
1318
Paul Kehrere1513fa2015-03-30 23:08:17 -05001319OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
1320OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
1321OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
1322OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
1323OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
1324OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
1325
Paul Kehrer3e6d5582015-05-02 21:57:56 -05001326OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
1327OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
1328
Paul Kehrer2b622582015-04-15 11:04:29 -04001329OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
1330OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
Paul Kehrer16fae762015-05-01 23:14:20 -05001331OID_ANY_POLICY = ObjectIdentifier("2.5.29.32.0")
Paul Kehrer2b622582015-04-15 11:04:29 -04001332
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001333
Paul Kehrerb2de9482014-12-11 14:54:48 -06001334@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -06001335class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -06001336 @abc.abstractmethod
1337 def fingerprint(self, algorithm):
1338 """
1339 Returns bytes using digest passed.
1340 """
1341
1342 @abc.abstractproperty
1343 def serial(self):
1344 """
1345 Returns certificate serial number
1346 """
1347
1348 @abc.abstractproperty
1349 def version(self):
1350 """
1351 Returns the certificate version
1352 """
1353
1354 @abc.abstractmethod
1355 def public_key(self):
1356 """
1357 Returns the public key
1358 """
1359
1360 @abc.abstractproperty
1361 def not_valid_before(self):
1362 """
1363 Not before time (represented as UTC datetime)
1364 """
1365
1366 @abc.abstractproperty
1367 def not_valid_after(self):
1368 """
1369 Not after time (represented as UTC datetime)
1370 """
Paul Kehrer719d5362015-01-01 20:03:52 -06001371
1372 @abc.abstractproperty
1373 def issuer(self):
1374 """
1375 Returns the issuer name object.
1376 """
1377
1378 @abc.abstractproperty
1379 def subject(self):
1380 """
1381 Returns the subject name object.
1382 """
Paul Kehrer56da2a52015-02-11 23:35:07 -06001383
1384 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001385 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -06001386 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001387 Returns a HashAlgorithm corresponding to the type of the digest signed
1388 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -06001389 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001390
Paul Kehrer8c234d12015-05-15 09:27:22 -07001391 @abc.abstractproperty
1392 def extensions(self):
1393 """
1394 Returns an Extensions object.
1395 """
1396
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001397 @abc.abstractmethod
1398 def __eq__(self, other):
1399 """
1400 Checks equality.
1401 """
1402
1403 @abc.abstractmethod
1404 def __ne__(self, other):
1405 """
1406 Checks not equal.
1407 """
1408
Andre Carona8aded62015-05-19 20:11:57 -04001409 @abc.abstractmethod
Alex Gaynor969f3a52015-07-06 18:52:41 -04001410 def __hash__(self):
1411 """
1412 Computes a hash.
1413 """
1414
1415 @abc.abstractmethod
Andre Carona8aded62015-05-19 20:11:57 -04001416 def public_bytes(self, encoding):
Andre Caron18ef34b2015-05-19 21:24:31 -04001417 """
1418 Serializes the certificate to PEM or DER format.
1419 """
Andre Carona8aded62015-05-19 20:11:57 -04001420
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001421
1422@six.add_metaclass(abc.ABCMeta)
Erik Trauschke2dcce902015-05-14 16:12:24 -07001423class CertificateRevocationList(object):
1424
1425 @abc.abstractmethod
1426 def fingerprint(self, algorithm):
1427 """
1428 Returns bytes using digest passed.
1429 """
1430
1431 @abc.abstractproperty
1432 def signature_hash_algorithm(self):
1433 """
1434 Returns a HashAlgorithm corresponding to the type of the digest signed
1435 in the certificate.
1436 """
1437
1438 @abc.abstractproperty
1439 def issuer(self):
1440 """
1441 Returns the X509Name with the issuer of this CRL.
1442 """
1443
1444 @abc.abstractproperty
1445 def next_update(self):
1446 """
1447 Returns the date of next update for this CRL.
1448 """
1449
1450 @abc.abstractproperty
1451 def last_update(self):
1452 """
1453 Returns the date of last update for this CRL.
1454 """
1455
1456 @abc.abstractproperty
Erik Trauschkeabb7b6e2015-05-27 15:07:35 -07001457 def revoked_certificates(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001458 """
1459 Returns a list of RevokedCertificate objects for this CRL.
1460 """
1461
1462 @abc.abstractproperty
1463 def extensions(self):
1464 """
1465 Returns an Extensions object containing a list of CRL extensions.
1466 """
1467
1468 @abc.abstractmethod
Erik Trauschke2dcce902015-05-14 16:12:24 -07001469 def __eq__(self, other):
1470 """
1471 Checks equality.
1472 """
1473
1474 @abc.abstractmethod
1475 def __ne__(self, other):
1476 """
1477 Checks not equal.
1478 """
1479
1480
1481@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -05001482class CertificateSigningRequest(object):
Alex Gaynor935f6ca2015-07-06 21:03:46 -04001483 @abc.abstractmethod
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001484 def __eq__(self, other):
1485 """
1486 Checks equality.
1487 """
1488
1489 @abc.abstractmethod
1490 def __ne__(self, other):
1491 """
1492 Checks not equal.
1493 """
1494
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001495 @abc.abstractmethod
Alex Gaynor978137d2015-07-08 20:59:16 -04001496 def __hash__(self):
1497 """
1498 Computes a hash.
1499 """
1500
1501 @abc.abstractmethod
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001502 def public_key(self):
1503 """
1504 Returns the public key
1505 """
1506
1507 @abc.abstractproperty
1508 def subject(self):
1509 """
1510 Returns the subject name object.
1511 """
1512
1513 @abc.abstractproperty
1514 def signature_hash_algorithm(self):
1515 """
1516 Returns a HashAlgorithm corresponding to the type of the digest signed
1517 in the certificate.
1518 """
Andre Caron6e721a92015-05-17 15:08:48 -04001519
1520 @abc.abstractproperty
1521 def extensions(self):
1522 """
1523 Returns the extensions in the signing request.
1524 """
Andre Caron476c5df2015-05-18 10:23:28 -04001525
1526 @abc.abstractmethod
1527 def public_bytes(self, encoding):
1528 """
1529 Encodes the request to PEM or DER format.
1530 """
Erik Trauschke2dcce902015-05-14 16:12:24 -07001531
1532
1533@six.add_metaclass(abc.ABCMeta)
1534class RevokedCertificate(object):
1535 @abc.abstractproperty
1536 def serial_number(self):
1537 """
1538 Returns the serial number of the revoked certificate.
1539 """
1540
1541 @abc.abstractproperty
1542 def revocation_date(self):
1543 """
1544 Returns the date of when this certificate was revoked.
1545 """
1546
1547 @abc.abstractproperty
1548 def extensions(self):
1549 """
1550 Returns an Extensions object containing a list of Revoked extensions.
1551 """
Andre Caron0ef595f2015-05-18 13:53:43 -04001552
1553
1554class CertificateSigningRequestBuilder(object):
Andre Caron99d0f902015-06-01 08:36:59 -04001555 def __init__(self, subject_name=None, extensions=[]):
Andre Caron0ef595f2015-05-18 13:53:43 -04001556 """
1557 Creates an empty X.509 certificate request (v1).
1558 """
Andre Caronfc164c52015-05-31 17:36:18 -04001559 self._subject_name = subject_name
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001560 self._extensions = extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001561
Andre Carona9a51172015-06-06 20:18:44 -04001562 def subject_name(self, name):
Andre Caron0ef595f2015-05-18 13:53:43 -04001563 """
1564 Sets the certificate requestor's distinguished name.
1565 """
1566 if not isinstance(name, Name):
1567 raise TypeError('Expecting x509.Name object.')
Ian Cordascod09ec372015-06-17 21:37:51 -05001568 if self._subject_name is not None:
1569 raise ValueError('The subject name may only be set once.')
Andre Caron99d0f902015-06-01 08:36:59 -04001570 return CertificateSigningRequestBuilder(name, self._extensions)
Andre Caron0ef595f2015-05-18 13:53:43 -04001571
Ian Cordascof06b6be2015-06-21 10:09:18 -05001572 def add_extension(self, extension, critical):
Andre Caron0ef595f2015-05-18 13:53:43 -04001573 """
1574 Adds an X.509 extension to the certificate request.
1575 """
Andre Caron472fd692015-06-06 20:04:44 -04001576 if isinstance(extension, BasicConstraints):
1577 extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
Paul Kehrer0b8f3272015-07-23 21:46:21 +01001578 elif isinstance(extension, ExtendedKeyUsage):
1579 extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001580 elif isinstance(extension, SubjectAlternativeName):
1581 extension = Extension(
1582 OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
1583 )
Alex Gaynor887a4082015-07-03 04:29:03 -04001584 elif isinstance(extension, KeyUsage):
1585 extension = Extension(OID_KEY_USAGE, critical, extension)
Paul Kehrerdce91f02015-07-23 20:31:12 +01001586 elif isinstance(extension, InhibitAnyPolicy):
1587 extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension)
Andre Caron472fd692015-06-06 20:04:44 -04001588 else:
Ian Cordascof06b6be2015-06-21 10:09:18 -05001589 raise NotImplementedError('Unsupported X.509 extension.')
1590 # TODO: This is quadratic in the number of extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001591 for e in self._extensions:
1592 if e.oid == extension.oid:
1593 raise ValueError('This extension has already been set.')
Andre Caronfc164c52015-05-31 17:36:18 -04001594 return CertificateSigningRequestBuilder(
Andre Caron99d0f902015-06-01 08:36:59 -04001595 self._subject_name, self._extensions + [extension]
Andre Caronfc164c52015-05-31 17:36:18 -04001596 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001597
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001598 def sign(self, private_key, algorithm, backend):
Andre Caron0ef595f2015-05-18 13:53:43 -04001599 """
1600 Signs the request using the requestor's private key.
1601 """
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001602 if self._subject_name is None:
1603 raise ValueError("A CertificateSigningRequest must have a subject")
Andre Carona33ea282015-05-31 16:32:26 -04001604 return backend.create_x509_csr(self, private_key, algorithm)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001605
1606
1607class CertificateBuilder(object):
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001608 def __init__(self, issuer_name=None, subject_name=None,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001609 public_key=None, serial_number=None, not_valid_before=None,
1610 not_valid_after=None, extensions=[]):
Ian Cordasco893246f2015-07-24 14:52:18 -05001611 self._version = Version.v3
Ian Cordascob3ed4842015-07-01 22:46:03 -05001612 self._issuer_name = issuer_name
1613 self._subject_name = subject_name
1614 self._public_key = public_key
1615 self._serial_number = serial_number
1616 self._not_valid_before = not_valid_before
1617 self._not_valid_after = not_valid_after
1618 self._extensions = extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -04001619
Ian Cordascob3ed4842015-07-01 22:46:03 -05001620 def issuer_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001621 """
1622 Sets the CA's distinguished name.
1623 """
1624 if not isinstance(name, Name):
1625 raise TypeError('Expecting x509.Name object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001626 if self._issuer_name is not None:
1627 raise ValueError('The issuer name may only be set once.')
1628 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001629 name, self._subject_name, self._public_key,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001630 self._serial_number, self._not_valid_before,
1631 self._not_valid_after, self._extensions
1632 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001633
Ian Cordascob3ed4842015-07-01 22:46:03 -05001634 def subject_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001635 """
1636 Sets the requestor's distinguished name.
1637 """
1638 if not isinstance(name, Name):
1639 raise TypeError('Expecting x509.Name object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001640 if self._subject_name is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001641 raise ValueError('The subject name may only be set once.')
1642 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001643 self._issuer_name, name, self._public_key,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001644 self._serial_number, self._not_valid_before,
1645 self._not_valid_after, self._extensions
1646 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001647
Ian Cordascob3ed4842015-07-01 22:46:03 -05001648 def public_key(self, key):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001649 """
1650 Sets the requestor's public key (as found in the signing request).
1651 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001652 if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
1653 ec.EllipticCurvePublicKey)):
1654 raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
1655 ' or EllipticCurvePublicKey.')
1656 if self._public_key is not None:
1657 raise ValueError('The public key may only be set once.')
1658 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001659 self._issuer_name, self._subject_name, key,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001660 self._serial_number, self._not_valid_before,
1661 self._not_valid_after, self._extensions
1662 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001663
Ian Cordascob3ed4842015-07-01 22:46:03 -05001664 def serial_number(self, number):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001665 """
1666 Sets the certificate serial number.
1667 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001668 if not isinstance(number, six.integer_types):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001669 raise TypeError('Serial number must be of integral type.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001670 if self._serial_number is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001671 raise ValueError('The serial number may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001672 if number < 0:
1673 raise ValueError('The serial number should be non-negative.')
1674 if utils.bit_length(number) > 160: # As defined in RFC 5280
1675 raise ValueError('The serial number should not be more than 160 '
1676 'bits.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001677 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001678 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001679 self._public_key, number, self._not_valid_before,
1680 self._not_valid_after, self._extensions
1681 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001682
Ian Cordascob3ed4842015-07-01 22:46:03 -05001683 def not_valid_before(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001684 """
1685 Sets the certificate activation time.
1686 """
Andre Caron9bbfcea2015-05-18 20:55:29 -04001687 if not isinstance(time, datetime.datetime):
1688 raise TypeError('Expecting datetime object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001689 if self._not_valid_before is not None:
1690 raise ValueError('The not valid before may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001691 if time <= _UNIX_EPOCH:
1692 raise ValueError('The not valid before date must be after the unix'
1693 ' epoch (1970 January 1).')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001694 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001695 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001696 self._public_key, self._serial_number, time,
1697 self._not_valid_after, self._extensions
1698 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001699
Ian Cordascob3ed4842015-07-01 22:46:03 -05001700 def not_valid_after(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001701 """
1702 Sets the certificate expiration time.
1703 """
Andre Caron9bbfcea2015-05-18 20:55:29 -04001704 if not isinstance(time, datetime.datetime):
1705 raise TypeError('Expecting datetime object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001706 if self._not_valid_after is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001707 raise ValueError('The not valid after may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001708 if time <= _UNIX_EPOCH:
1709 raise ValueError('The not valid after date must be after the unix'
1710 ' epoch (1970 January 1).')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001711 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001712 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001713 self._public_key, self._serial_number, self._not_valid_before,
1714 time, self._extensions
1715 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001716
Ian Cordascob3ed4842015-07-01 22:46:03 -05001717 def add_extension(self, extension, critical):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001718 """
1719 Adds an X.509 extension to the certificate.
1720 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001721 if isinstance(extension, BasicConstraints):
1722 extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001723 elif isinstance(extension, KeyUsage):
1724 extension = Extension(OID_KEY_USAGE, critical, extension)
1725 elif isinstance(extension, ExtendedKeyUsage):
1726 extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001727 elif isinstance(extension, SubjectAlternativeName):
1728 extension = Extension(
1729 OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
1730 )
Paul Kehrer3b54ce22015-08-03 16:44:57 +01001731 elif isinstance(extension, AuthorityInformationAccess):
1732 extension = Extension(
1733 OID_AUTHORITY_INFORMATION_ACCESS, critical, extension
1734 )
Ian Cordasco17c89002015-08-02 21:13:59 -05001735 elif isinstance(extension, InhibitAnyPolicy):
1736 extension = Extension(OID_INHIBIT_ANY_POLICY, critical, extension)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001737 else:
1738 raise NotImplementedError('Unsupported X.509 extension.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001739
1740 # TODO: This is quadratic in the number of extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -04001741 for e in self._extensions:
1742 if e.oid == extension.oid:
1743 raise ValueError('This extension has already been set.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001744
1745 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -05001746 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001747 self._public_key, self._serial_number, self._not_valid_before,
1748 self._not_valid_after, self._extensions + [extension]
1749 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001750
Paul Kehrer9add80e2015-08-03 17:53:14 +01001751 def sign(self, private_key, algorithm, backend):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001752 """
1753 Signs the certificate using the CA's private key.
1754 """
Paul Kehrer25f19222015-08-04 23:05:09 +01001755 if self._subject_name is None:
1756 raise ValueError("A certificate must have a subject name")
1757
1758 if self._issuer_name is None:
1759 raise ValueError("A certificate must have an issuer name")
1760
1761 if self._serial_number is None:
1762 raise ValueError("A certificate must have a serial number")
1763
1764 if self._not_valid_before is None:
1765 raise ValueError("A certificate must have a not valid before time")
1766
1767 if self._not_valid_after is None:
1768 raise ValueError("A certificate must have a not valid after time")
1769
1770 if self._public_key is None:
1771 raise ValueError("A certificate must have a public key")
1772
Paul Kehrer1ae76532015-08-06 12:37:10 +01001773 return backend.create_x509_certificate(self, private_key, algorithm)