blob: e73721b515bff5261083a71dda5ffb70e03c4cb9 [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
100
Paul Kehrere76cd272014-12-14 19:00:51 -0600101class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -1000102 v1 = 0
103 v3 = 2
104
105
Paul Kehrer016e08a2014-11-26 09:41:18 -1000106def load_pem_x509_certificate(data, backend):
107 return backend.load_pem_x509_certificate(data)
108
109
Paul Kehrer016e08a2014-11-26 09:41:18 -1000110def load_der_x509_certificate(data, backend):
111 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -1000112
113
Paul Kehrer31e39882015-03-11 11:37:04 -0500114def load_pem_x509_csr(data, backend):
115 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600116
117
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500118def load_der_x509_csr(data, backend):
119 return backend.load_der_x509_csr(data)
120
121
Paul Kehrere76cd272014-12-14 19:00:51 -0600122class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600123 def __init__(self, msg, parsed_version):
124 super(InvalidVersion, self).__init__(msg)
125 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600126
127
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500128class DuplicateExtension(Exception):
129 def __init__(self, msg, oid):
130 super(DuplicateExtension, self).__init__(msg)
131 self.oid = oid
132
133
134class UnsupportedExtension(Exception):
135 def __init__(self, msg, oid):
136 super(UnsupportedExtension, self).__init__(msg)
137 self.oid = oid
138
139
Paul Kehrerfa56a232015-03-17 13:14:03 -0500140class ExtensionNotFound(Exception):
141 def __init__(self, msg, oid):
142 super(ExtensionNotFound, self).__init__(msg)
143 self.oid = oid
144
145
Paul Kehrer9089c912015-04-20 22:15:20 -0500146class UnsupportedGeneralNameType(Exception):
Paul Kehrerbed07352015-04-21 08:31:10 -0500147 def __init__(self, msg, type):
148 super(UnsupportedGeneralNameType, self).__init__(msg)
149 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500150
151
Paul Kehrer806bfb22015-02-02 17:05:24 -0600152class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600153 def __init__(self, oid, value):
154 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600155 raise TypeError(
156 "oid argument must be an ObjectIdentifier instance."
157 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600158
Ian Cordasco7618fbe2015-06-16 19:12:17 -0500159 if not isinstance(value, six.text_type):
160 raise TypeError(
161 "value argument must be a text type."
162 )
163
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600164 self._oid = oid
165 self._value = value
166
167 oid = utils.read_only_property("_oid")
168 value = utils.read_only_property("_value")
169
170 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600171 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600172 return NotImplemented
173
174 return (
175 self.oid == other.oid and
176 self.value == other.value
177 )
178
179 def __ne__(self, other):
180 return not self == other
181
Paul Kehrera498be82015-02-12 15:00:56 -0600182 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400183 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600184
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600185
186class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600187 def __init__(self, dotted_string):
188 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600189
190 def __eq__(self, other):
191 if not isinstance(other, ObjectIdentifier):
192 return NotImplemented
193
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600194 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600195
196 def __ne__(self, other):
197 return not self == other
198
199 def __repr__(self):
200 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600201 self._dotted_string,
202 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600203 )
204
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500205 def __hash__(self):
206 return hash(self.dotted_string)
207
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600208 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600209
210
Paul Kehrer719d5362015-01-01 20:03:52 -0600211class Name(object):
212 def __init__(self, attributes):
213 self._attributes = attributes
214
Paul Kehrere901d642015-02-11 18:50:58 -0600215 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800216 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600217
Paul Kehrer719d5362015-01-01 20:03:52 -0600218 def __eq__(self, other):
219 if not isinstance(other, Name):
220 return NotImplemented
221
Paul Kehrer53d8d492015-02-13 18:47:30 -0600222 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600223
224 def __ne__(self, other):
225 return not self == other
226
Paul Kehrer53d8d492015-02-13 18:47:30 -0600227 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600228 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600229
230 def __len__(self):
231 return len(self._attributes)
232
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400233 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400234 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400235
Paul Kehrer719d5362015-01-01 20:03:52 -0600236
Paul Kehrerd08b5492015-04-04 15:19:16 -0500237OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
238OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500239OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500240OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
241OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500242OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Erik Trauschke2dcce902015-05-14 16:12:24 -0700243OID_CRL_REASON = ObjectIdentifier("2.5.29.21")
244OID_INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
245OID_CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500246OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
247OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
248OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
249OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
250OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
251OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
252OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
253OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
254OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
255OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
256OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
257OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500258
259
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500260class Extensions(object):
261 def __init__(self, extensions):
262 self._extensions = extensions
263
Paul Kehrerfa56a232015-03-17 13:14:03 -0500264 def get_extension_for_oid(self, oid):
265 for ext in self:
266 if ext.oid == oid:
267 return ext
268
269 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
270
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500271 def __iter__(self):
272 return iter(self._extensions)
273
274 def __len__(self):
275 return len(self._extensions)
276
277
Paul Kehrer8cf26422015-03-21 09:50:24 -0500278class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500279 def __init__(self, oid, critical, value):
280 if not isinstance(oid, ObjectIdentifier):
281 raise TypeError(
282 "oid argument must be an ObjectIdentifier instance."
283 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500284
285 if not isinstance(critical, bool):
286 raise TypeError("critical must be a boolean value")
287
Paul Kehrer85894662015-03-22 13:19:31 -0500288 self._oid = oid
289 self._critical = critical
290 self._value = value
291
292 oid = utils.read_only_property("_oid")
293 critical = utils.read_only_property("_critical")
294 value = utils.read_only_property("_value")
295
296 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500297 return ("<Extension(oid={0.oid}, critical={0.critical}, "
298 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500299
Paul Kehrer58e870c2015-05-17 09:15:30 -0700300 def __eq__(self, other):
301 if not isinstance(other, Extension):
302 return NotImplemented
303
304 return (
305 self.oid == other.oid and
306 self.critical == other.critical and
307 self.value == other.value
308 )
309
310 def __ne__(self, other):
311 return not self == other
312
Paul Kehrer85894662015-03-22 13:19:31 -0500313
Paul Kehrerffa2a152015-03-31 08:18:25 -0500314class ExtendedKeyUsage(object):
315 def __init__(self, usages):
Paul Kehrerb0476172015-05-02 19:34:51 -0500316 if not all(isinstance(x, ObjectIdentifier) for x in usages):
317 raise TypeError(
318 "Every item in the usages list must be an ObjectIdentifier"
319 )
Paul Kehrerffa2a152015-03-31 08:18:25 -0500320
321 self._usages = usages
322
323 def __iter__(self):
324 return iter(self._usages)
325
326 def __len__(self):
327 return len(self._usages)
328
Paul Kehrer23d10c32015-04-02 23:12:32 -0500329 def __repr__(self):
330 return "<ExtendedKeyUsage({0})>".format(self._usages)
331
Paul Kehrerb0476172015-05-02 19:34:51 -0500332 def __eq__(self, other):
333 if not isinstance(other, ExtendedKeyUsage):
334 return NotImplemented
335
Paul Kehrerf24bad72015-05-02 19:36:20 -0500336 return self._usages == other._usages
Paul Kehrerb0476172015-05-02 19:34:51 -0500337
338 def __ne__(self, other):
339 return not self == other
340
Paul Kehrerffa2a152015-03-31 08:18:25 -0500341
Paul Kehrer4a1038e2015-05-18 10:28:31 -0700342class OCSPNoCheck(object):
343 pass
344
345
Paul Kehrer85894662015-03-22 13:19:31 -0500346class BasicConstraints(object):
347 def __init__(self, ca, path_length):
348 if not isinstance(ca, bool):
349 raise TypeError("ca must be a boolean value")
350
Paul Kehrer611d3d32015-03-22 13:31:18 -0500351 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500352 raise ValueError("path_length must be None when ca is False")
353
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500354 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500355 path_length is not None and
356 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500357 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500358 raise TypeError(
359 "path_length must be a non-negative integer or None"
360 )
361
362 self._ca = ca
363 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500364
365 ca = utils.read_only_property("_ca")
366 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500367
368 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500369 return ("<BasicConstraints(ca={0.ca}, "
370 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500371
Paul Kehrer3a69b132015-05-13 10:03:46 -0500372 def __eq__(self, other):
373 if not isinstance(other, BasicConstraints):
374 return NotImplemented
375
376 return self.ca == other.ca and self.path_length == other.path_length
377
378 def __ne__(self, other):
379 return not self == other
380
Paul Kehrer8cf26422015-03-21 09:50:24 -0500381
Paul Kehrercecbbba2015-03-30 14:58:38 -0500382class KeyUsage(object):
383 def __init__(self, digital_signature, content_commitment, key_encipherment,
384 data_encipherment, key_agreement, key_cert_sign, crl_sign,
385 encipher_only, decipher_only):
386 if not key_agreement and (encipher_only or decipher_only):
387 raise ValueError(
388 "encipher_only and decipher_only can only be true when "
389 "key_agreement is true"
390 )
391
392 self._digital_signature = digital_signature
393 self._content_commitment = content_commitment
394 self._key_encipherment = key_encipherment
395 self._data_encipherment = data_encipherment
396 self._key_agreement = key_agreement
397 self._key_cert_sign = key_cert_sign
398 self._crl_sign = crl_sign
399 self._encipher_only = encipher_only
400 self._decipher_only = decipher_only
401
402 digital_signature = utils.read_only_property("_digital_signature")
403 content_commitment = utils.read_only_property("_content_commitment")
404 key_encipherment = utils.read_only_property("_key_encipherment")
405 data_encipherment = utils.read_only_property("_data_encipherment")
406 key_agreement = utils.read_only_property("_key_agreement")
407 key_cert_sign = utils.read_only_property("_key_cert_sign")
408 crl_sign = utils.read_only_property("_crl_sign")
409
410 @property
411 def encipher_only(self):
412 if not self.key_agreement:
413 raise ValueError(
414 "encipher_only is undefined unless key_agreement is true"
415 )
416 else:
417 return self._encipher_only
418
419 @property
420 def decipher_only(self):
421 if not self.key_agreement:
422 raise ValueError(
423 "decipher_only is undefined unless key_agreement is true"
424 )
425 else:
426 return self._decipher_only
427
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500428 def __repr__(self):
429 try:
430 encipher_only = self.encipher_only
431 decipher_only = self.decipher_only
432 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400433 encipher_only = None
434 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500435
436 return ("<KeyUsage(digital_signature={0.digital_signature}, "
437 "content_commitment={0.content_commitment}, "
438 "key_encipherment={0.key_encipherment}, "
439 "data_encipherment={0.data_encipherment}, "
440 "key_agreement={0.key_agreement}, "
441 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
442 "encipher_only={1}, decipher_only={2})>").format(
443 self, encipher_only, decipher_only)
444
Paul Kehrer8565f5e2015-05-13 09:57:09 -0500445 def __eq__(self, other):
446 if not isinstance(other, KeyUsage):
447 return NotImplemented
448
449 return (
450 self.digital_signature == other.digital_signature and
451 self.content_commitment == other.content_commitment and
452 self.key_encipherment == other.key_encipherment and
453 self.data_encipherment == other.data_encipherment and
454 self.key_agreement == other.key_agreement and
455 self.key_cert_sign == other.key_cert_sign and
456 self.crl_sign == other.crl_sign and
457 self._encipher_only == other._encipher_only and
458 self._decipher_only == other._decipher_only
459 )
460
461 def __ne__(self, other):
462 return not self == other
463
Paul Kehrercecbbba2015-03-30 14:58:38 -0500464
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500465class AuthorityInformationAccess(object):
466 def __init__(self, descriptions):
467 if not all(isinstance(x, AccessDescription) for x in descriptions):
468 raise TypeError(
469 "Every item in the descriptions list must be an "
470 "AccessDescription"
471 )
472
473 self._descriptions = descriptions
474
475 def __iter__(self):
476 return iter(self._descriptions)
477
478 def __len__(self):
479 return len(self._descriptions)
480
481 def __repr__(self):
482 return "<AuthorityInformationAccess({0})>".format(self._descriptions)
483
484 def __eq__(self, other):
485 if not isinstance(other, AuthorityInformationAccess):
486 return NotImplemented
487
488 return self._descriptions == other._descriptions
489
490 def __ne__(self, other):
491 return not self == other
492
493
494class AccessDescription(object):
495 def __init__(self, access_method, access_location):
496 if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
Paul Kehrerf506bca2015-05-02 22:31:47 -0500497 raise ValueError(
498 "access_method must be OID_OCSP or OID_CA_ISSUERS"
499 )
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500500
501 if not isinstance(access_location, GeneralName):
502 raise TypeError("access_location must be a GeneralName")
503
504 self._access_method = access_method
505 self._access_location = access_location
506
507 def __repr__(self):
508 return (
509 "<AccessDescription(access_method={0.access_method}, access_locati"
510 "on={0.access_location})>".format(self)
511 )
512
513 def __eq__(self, other):
514 if not isinstance(other, AccessDescription):
515 return NotImplemented
516
517 return (
518 self.access_method == other.access_method and
519 self.access_location == other.access_location
520 )
521
522 def __ne__(self, other):
523 return not self == other
524
525 access_method = utils.read_only_property("_access_method")
526 access_location = utils.read_only_property("_access_location")
527
528
Paul Kehrer2b622582015-04-15 11:04:29 -0400529class CertificatePolicies(object):
530 def __init__(self, policies):
Paul Kehrerf61ec742015-04-18 20:42:39 -0500531 if not all(isinstance(x, PolicyInformation) for x in policies):
Paul Kehrer2b622582015-04-15 11:04:29 -0400532 raise TypeError(
533 "Every item in the policies list must be a "
534 "PolicyInformation"
535 )
536
537 self._policies = policies
538
539 def __iter__(self):
540 return iter(self._policies)
541
542 def __len__(self):
543 return len(self._policies)
544
545 def __repr__(self):
546 return "<CertificatePolicies({0})>".format(self._policies)
547
Paul Kehrerc56ab622015-05-03 09:56:31 -0500548 def __eq__(self, other):
549 if not isinstance(other, CertificatePolicies):
550 return NotImplemented
551
552 return self._policies == other._policies
553
554 def __ne__(self, other):
555 return not self == other
556
Paul Kehrer2b622582015-04-15 11:04:29 -0400557
558class PolicyInformation(object):
559 def __init__(self, policy_identifier, policy_qualifiers):
560 if not isinstance(policy_identifier, ObjectIdentifier):
561 raise TypeError("policy_identifier must be an ObjectIdentifier")
562
563 self._policy_identifier = policy_identifier
564 if policy_qualifiers and not all(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500565 isinstance(
566 x, (six.text_type, UserNotice)
567 ) for x in policy_qualifiers
Paul Kehrer2b622582015-04-15 11:04:29 -0400568 ):
569 raise TypeError(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500570 "policy_qualifiers must be a list of strings and/or UserNotice"
571 " objects or None"
Paul Kehrer2b622582015-04-15 11:04:29 -0400572 )
573
574 self._policy_qualifiers = policy_qualifiers
575
576 def __repr__(self):
577 return (
578 "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
579 "y_qualifiers={0.policy_qualifiers})>".format(self)
580 )
581
Paul Kehrerc56ab622015-05-03 09:56:31 -0500582 def __eq__(self, other):
583 if not isinstance(other, PolicyInformation):
584 return NotImplemented
585
586 return (
587 self.policy_identifier == other.policy_identifier and
588 self.policy_qualifiers == other.policy_qualifiers
589 )
590
591 def __ne__(self, other):
592 return not self == other
593
Paul Kehrer2b622582015-04-15 11:04:29 -0400594 policy_identifier = utils.read_only_property("_policy_identifier")
595 policy_qualifiers = utils.read_only_property("_policy_qualifiers")
596
597
Paul Kehrer2b622582015-04-15 11:04:29 -0400598class UserNotice(object):
599 def __init__(self, notice_reference, explicit_text):
600 if notice_reference and not isinstance(
601 notice_reference, NoticeReference
602 ):
603 raise TypeError(
604 "notice_reference must be None or a NoticeReference"
605 )
606
607 self._notice_reference = notice_reference
608 self._explicit_text = explicit_text
609
610 def __repr__(self):
611 return (
612 "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
Paul Kehrer9aaef9e2015-05-11 10:49:20 -0500613 "{0.explicit_text!r})>".format(self)
Paul Kehrer2b622582015-04-15 11:04:29 -0400614 )
615
Paul Kehrerc56ab622015-05-03 09:56:31 -0500616 def __eq__(self, other):
617 if not isinstance(other, UserNotice):
618 return NotImplemented
619
620 return (
621 self.notice_reference == other.notice_reference and
622 self.explicit_text == other.explicit_text
623 )
624
625 def __ne__(self, other):
626 return not self == other
627
Paul Kehrer2b622582015-04-15 11:04:29 -0400628 notice_reference = utils.read_only_property("_notice_reference")
629 explicit_text = utils.read_only_property("_explicit_text")
630
631
632class NoticeReference(object):
633 def __init__(self, organization, notice_numbers):
634 self._organization = organization
Paul Kehrer6e198b02015-05-12 15:53:38 -0500635 if not isinstance(notice_numbers, list) or not all(
Paul Kehrerf61ec742015-04-18 20:42:39 -0500636 isinstance(x, int) for x in notice_numbers
Paul Kehrer2b622582015-04-15 11:04:29 -0400637 ):
638 raise TypeError(
Paul Kehrer6e198b02015-05-12 15:53:38 -0500639 "notice_numbers must be a list of integers"
Paul Kehrer2b622582015-04-15 11:04:29 -0400640 )
641
642 self._notice_numbers = notice_numbers
643
644 def __repr__(self):
645 return (
Paul Kehrer73be2ca2015-05-11 21:22:38 -0500646 "<NoticeReference(organization={0.organization!r}, notice_numbers="
Paul Kehrer2b622582015-04-15 11:04:29 -0400647 "{0.notice_numbers})>".format(self)
648 )
649
Paul Kehrerc56ab622015-05-03 09:56:31 -0500650 def __eq__(self, other):
651 if not isinstance(other, NoticeReference):
652 return NotImplemented
653
654 return (
655 self.organization == other.organization and
656 self.notice_numbers == other.notice_numbers
657 )
658
659 def __ne__(self, other):
660 return not self == other
661
Paul Kehrer2b622582015-04-15 11:04:29 -0400662 organization = utils.read_only_property("_organization")
663 notice_numbers = utils.read_only_property("_notice_numbers")
664
665
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500666class SubjectKeyIdentifier(object):
667 def __init__(self, digest):
668 self._digest = digest
669
670 digest = utils.read_only_property("_digest")
671
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500672 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400673 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500674
675 def __eq__(self, other):
676 if not isinstance(other, SubjectKeyIdentifier):
677 return NotImplemented
678
679 return (
680 self.digest == other.digest
681 )
682
683 def __ne__(self, other):
684 return not self == other
685
686
Paul Kehrere0017be2015-05-17 20:39:40 -0600687class NameConstraints(object):
688 def __init__(self, permitted_subtrees, excluded_subtrees):
689 if permitted_subtrees is not None:
690 if not all(
691 isinstance(x, GeneralName) for x in permitted_subtrees
692 ):
693 raise TypeError(
694 "permitted_subtrees must be a list of GeneralName objects "
695 "or None"
696 )
697
698 self._validate_ip_name(permitted_subtrees)
699
700 if excluded_subtrees is not None:
701 if not all(
702 isinstance(x, GeneralName) for x in excluded_subtrees
703 ):
704 raise TypeError(
705 "excluded_subtrees must be a list of GeneralName objects "
706 "or None"
707 )
708
709 self._validate_ip_name(excluded_subtrees)
710
711 if permitted_subtrees is None and excluded_subtrees is None:
712 raise ValueError(
713 "At least one of permitted_subtrees and excluded_subtrees "
714 "must not be None"
715 )
716
717 self._permitted_subtrees = permitted_subtrees
718 self._excluded_subtrees = excluded_subtrees
719
Paul Kehrer31894282015-06-21 21:46:41 -0500720 def __eq__(self, other):
721 if not isinstance(other, NameConstraints):
722 return NotImplemented
723
724 return (
725 self.excluded_subtrees == other.excluded_subtrees and
726 self.permitted_subtrees == other.permitted_subtrees
727 )
728
729 def __ne__(self, other):
730 return not self == other
731
Paul Kehrere0017be2015-05-17 20:39:40 -0600732 def _validate_ip_name(self, tree):
733 if any(isinstance(name, IPAddress) and not isinstance(
734 name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network)
735 ) for name in tree):
736 raise TypeError(
737 "IPAddress name constraints must be an IPv4Network or"
738 " IPv6Network object"
739 )
740
741 def __repr__(self):
742 return (
743 u"<NameConstraints(permitted_subtrees={0.permitted_subtrees}, "
744 u"excluded_subtrees={0.excluded_subtrees})>".format(self)
745 )
746
747 permitted_subtrees = utils.read_only_property("_permitted_subtrees")
748 excluded_subtrees = utils.read_only_property("_excluded_subtrees")
749
750
Paul Kehrer5a485522015-05-06 00:29:12 -0500751class CRLDistributionPoints(object):
752 def __init__(self, distribution_points):
753 if not all(
754 isinstance(x, DistributionPoint) for x in distribution_points
755 ):
756 raise TypeError(
757 "distribution_points must be a list of DistributionPoint "
758 "objects"
759 )
760
761 self._distribution_points = distribution_points
762
763 def __iter__(self):
764 return iter(self._distribution_points)
765
766 def __len__(self):
767 return len(self._distribution_points)
768
769 def __repr__(self):
770 return "<CRLDistributionPoints({0})>".format(self._distribution_points)
771
772 def __eq__(self, other):
773 if not isinstance(other, CRLDistributionPoints):
774 return NotImplemented
775
776 return self._distribution_points == other._distribution_points
777
778 def __ne__(self, other):
779 return not self == other
780
781
782class DistributionPoint(object):
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500783 def __init__(self, full_name, relative_name, reasons, crl_issuer):
784 if full_name and relative_name:
785 raise ValueError(
786 "At least one of full_name and relative_name must be None"
787 )
788
789 if full_name and not all(
790 isinstance(x, GeneralName) for x in full_name
791 ):
792 raise TypeError(
793 "full_name must be a list of GeneralName objects"
794 )
795
796 if relative_name and not isinstance(relative_name, Name):
797 raise TypeError("relative_name must be a Name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500798
799 if crl_issuer and not all(
800 isinstance(x, GeneralName) for x in crl_issuer
801 ):
802 raise TypeError(
803 "crl_issuer must be None or a list of general names"
804 )
805
Paul Kehrer3fd02602015-05-09 19:46:13 -0500806 if reasons and (not isinstance(reasons, frozenset) or not all(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500807 isinstance(x, ReasonFlags) for x in reasons
Paul Kehrer3fd02602015-05-09 19:46:13 -0500808 )):
809 raise TypeError("reasons must be None or frozenset of ReasonFlags")
Paul Kehrer5a485522015-05-06 00:29:12 -0500810
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500811 if reasons and (
812 ReasonFlags.unspecified in reasons or
813 ReasonFlags.remove_from_crl in reasons
814 ):
Paul Kehrer5a485522015-05-06 00:29:12 -0500815 raise ValueError(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500816 "unspecified and remove_from_crl are not valid reasons in a "
817 "DistributionPoint"
818 )
819
820 if reasons and not crl_issuer and not (full_name or relative_name):
821 raise ValueError(
822 "You must supply crl_issuer, full_name, or relative_name when "
Paul Kehrer5a485522015-05-06 00:29:12 -0500823 "reasons is not None"
824 )
825
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500826 self._full_name = full_name
827 self._relative_name = relative_name
Paul Kehrer5a485522015-05-06 00:29:12 -0500828 self._reasons = reasons
829 self._crl_issuer = crl_issuer
830
831 def __repr__(self):
832 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500833 "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
834 "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
835 "suer})>".format(self)
Paul Kehrer5a485522015-05-06 00:29:12 -0500836 )
837
838 def __eq__(self, other):
839 if not isinstance(other, DistributionPoint):
840 return NotImplemented
841
842 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500843 self.full_name == other.full_name and
844 self.relative_name == other.relative_name and
Paul Kehrer5a485522015-05-06 00:29:12 -0500845 self.reasons == other.reasons and
846 self.crl_issuer == other.crl_issuer
847 )
848
849 def __ne__(self, other):
850 return not self == other
851
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500852 full_name = utils.read_only_property("_full_name")
853 relative_name = utils.read_only_property("_relative_name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500854 reasons = utils.read_only_property("_reasons")
855 crl_issuer = utils.read_only_property("_crl_issuer")
856
857
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500858class ReasonFlags(Enum):
859 unspecified = "unspecified"
860 key_compromise = "keyCompromise"
861 ca_compromise = "cACompromise"
862 affiliation_changed = "affiliationChanged"
863 superseded = "superseded"
864 cessation_of_operation = "cessationOfOperation"
865 certificate_hold = "certificateHold"
866 privilege_withdrawn = "privilegeWithdrawn"
867 aa_compromise = "aACompromise"
868 remove_from_crl = "removeFromCRL"
Paul Kehrer5a485522015-05-06 00:29:12 -0500869
870
Paul Kehrer16fae762015-05-01 23:14:20 -0500871class InhibitAnyPolicy(object):
872 def __init__(self, skip_certs):
873 if not isinstance(skip_certs, six.integer_types):
874 raise TypeError("skip_certs must be an integer")
875
876 if skip_certs < 0:
877 raise ValueError("skip_certs must be a non-negative integer")
878
879 self._skip_certs = skip_certs
880
881 def __repr__(self):
882 return "<InhibitAnyPolicy(skip_certs={0.skip_certs})>".format(self)
883
884 def __eq__(self, other):
885 if not isinstance(other, InhibitAnyPolicy):
886 return NotImplemented
887
888 return self.skip_certs == other.skip_certs
889
890 def __ne__(self, other):
891 return not self == other
892
893 skip_certs = utils.read_only_property("_skip_certs")
894
895
Paul Kehrer31bdf792015-03-25 14:11:00 -0500896@six.add_metaclass(abc.ABCMeta)
897class GeneralName(object):
898 @abc.abstractproperty
899 def value(self):
900 """
901 Return the value of the object
902 """
903
904
905@utils.register_interface(GeneralName)
906class RFC822Name(object):
907 def __init__(self, value):
908 if not isinstance(value, six.text_type):
909 raise TypeError("value must be a unicode string")
910
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500911 name, address = parseaddr(value)
912 parts = address.split(u"@")
Paul Kehrer82890862015-07-12 12:08:28 -0500913 if name or not address:
914 # parseaddr has found a name (e.g. Name <email>) or the entire
915 # value is an empty string.
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500916 raise ValueError("Invalid rfc822name value")
917 elif len(parts) == 1:
918 # Single label email name. This is valid for local delivery.
919 # No IDNA encoding needed since there is no domain component.
920 encoded = address.encode("ascii")
921 else:
922 # A normal email of the form user@domain.com. Let's attempt to
923 # encode the domain component and reconstruct the address.
924 encoded = parts[0].encode("ascii") + b"@" + idna.encode(parts[1])
925
Paul Kehrer31bdf792015-03-25 14:11:00 -0500926 self._value = value
Paul Kehrer01d5d0b2015-07-12 09:41:21 -0500927 self._encoded = encoded
Paul Kehrer31bdf792015-03-25 14:11:00 -0500928
929 value = utils.read_only_property("_value")
930
931 def __repr__(self):
932 return "<RFC822Name(value={0})>".format(self.value)
933
934 def __eq__(self, other):
935 if not isinstance(other, RFC822Name):
936 return NotImplemented
937
938 return self.value == other.value
939
940 def __ne__(self, other):
941 return not self == other
942
943
944@utils.register_interface(GeneralName)
945class DNSName(object):
946 def __init__(self, value):
947 if not isinstance(value, six.text_type):
948 raise TypeError("value must be a unicode string")
949
950 self._value = value
951
952 value = utils.read_only_property("_value")
953
954 def __repr__(self):
955 return "<DNSName(value={0})>".format(self.value)
956
957 def __eq__(self, other):
958 if not isinstance(other, DNSName):
959 return NotImplemented
960
961 return self.value == other.value
962
963 def __ne__(self, other):
964 return not self == other
965
966
967@utils.register_interface(GeneralName)
968class UniformResourceIdentifier(object):
969 def __init__(self, value):
970 if not isinstance(value, six.text_type):
971 raise TypeError("value must be a unicode string")
972
Paul Kehrere28d6c42015-07-12 14:59:37 -0500973 parsed = urllib_parse.urlparse(value)
974 if not parsed.hostname:
975 netloc = ""
976 elif parsed.port:
977 netloc = (
978 idna.encode(parsed.hostname) +
979 ":{0}".format(parsed.port).encode("ascii")
980 ).decode("ascii")
981 else:
982 netloc = idna.encode(parsed.hostname).decode("ascii")
983
984 # Note that building a URL in this fashion means it should be
985 # semantically indistinguishable from the original but is not
986 # guaranteed to be exactly the same.
987 uri = urllib_parse.urlunparse((
988 parsed.scheme,
989 netloc,
990 parsed.path,
991 parsed.params,
992 parsed.query,
993 parsed.fragment
994 )).encode("ascii")
995
Paul Kehrer31bdf792015-03-25 14:11:00 -0500996 self._value = value
Paul Kehrere28d6c42015-07-12 14:59:37 -0500997 self._encoded = uri
Paul Kehrer31bdf792015-03-25 14:11:00 -0500998
999 value = utils.read_only_property("_value")
1000
1001 def __repr__(self):
1002 return "<UniformResourceIdentifier(value={0})>".format(self.value)
1003
1004 def __eq__(self, other):
1005 if not isinstance(other, UniformResourceIdentifier):
1006 return NotImplemented
1007
1008 return self.value == other.value
1009
1010 def __ne__(self, other):
1011 return not self == other
1012
1013
1014@utils.register_interface(GeneralName)
1015class DirectoryName(object):
1016 def __init__(self, value):
1017 if not isinstance(value, Name):
1018 raise TypeError("value must be a Name")
1019
1020 self._value = value
1021
1022 value = utils.read_only_property("_value")
1023
1024 def __repr__(self):
1025 return "<DirectoryName(value={0})>".format(self.value)
1026
1027 def __eq__(self, other):
1028 if not isinstance(other, DirectoryName):
1029 return NotImplemented
1030
1031 return self.value == other.value
1032
1033 def __ne__(self, other):
1034 return not self == other
1035
1036
1037@utils.register_interface(GeneralName)
1038class RegisteredID(object):
1039 def __init__(self, value):
1040 if not isinstance(value, ObjectIdentifier):
1041 raise TypeError("value must be an ObjectIdentifier")
1042
1043 self._value = value
1044
1045 value = utils.read_only_property("_value")
1046
1047 def __repr__(self):
1048 return "<RegisteredID(value={0})>".format(self.value)
1049
1050 def __eq__(self, other):
1051 if not isinstance(other, RegisteredID):
1052 return NotImplemented
1053
1054 return self.value == other.value
1055
1056 def __ne__(self, other):
1057 return not self == other
1058
1059
1060@utils.register_interface(GeneralName)
1061class IPAddress(object):
1062 def __init__(self, value):
1063 if not isinstance(
Paul Kehrereb177932015-05-17 18:33:33 -07001064 value,
1065 (
1066 ipaddress.IPv4Address,
1067 ipaddress.IPv6Address,
1068 ipaddress.IPv4Network,
1069 ipaddress.IPv6Network
1070 )
Paul Kehrer31bdf792015-03-25 14:11:00 -05001071 ):
1072 raise TypeError(
Paul Kehrereb177932015-05-17 18:33:33 -07001073 "value must be an instance of ipaddress.IPv4Address, "
1074 "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
1075 "ipaddress.IPv6Network"
Paul Kehrer31bdf792015-03-25 14:11:00 -05001076 )
1077
1078 self._value = value
1079
1080 value = utils.read_only_property("_value")
1081
1082 def __repr__(self):
1083 return "<IPAddress(value={0})>".format(self.value)
1084
1085 def __eq__(self, other):
1086 if not isinstance(other, IPAddress):
1087 return NotImplemented
1088
1089 return self.value == other.value
1090
1091 def __ne__(self, other):
1092 return not self == other
1093
1094
Joshua Tauberer2ee5e3c2015-07-04 20:09:46 +00001095@utils.register_interface(GeneralName)
1096class OtherName(object):
1097 def __init__(self, type_id, value):
1098 if not isinstance(type_id, ObjectIdentifier):
1099 raise TypeError("type_id must be an ObjectIdentifier")
1100 if not isinstance(value, bytes):
1101 raise TypeError("value must be a binary string")
1102
1103 self._type_id = type_id
1104 self._value = value
1105
1106 type_id = utils.read_only_property("_type_id")
1107 value = utils.read_only_property("_value")
1108
1109 def __repr__(self):
1110 return "<OtherName(type_id={0}, value={1!r})>".format(
1111 self.type_id, self.value)
1112
1113 def __eq__(self, other):
1114 if not isinstance(other, OtherName):
1115 return NotImplemented
1116
1117 return self.type_id == other.type_id and self.value == other.value
1118
1119 def __ne__(self, other):
1120 return not self == other
1121
1122
Erik Trauschke2dcce902015-05-14 16:12:24 -07001123class GeneralNames(object):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001124 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -05001125 if not all(isinstance(x, GeneralName) for x in general_names):
1126 raise TypeError(
1127 "Every item in the general_names list must be an "
1128 "object conforming to the GeneralName interface"
1129 )
1130
Paul Kehrer31bdf792015-03-25 14:11:00 -05001131 self._general_names = general_names
1132
1133 def __iter__(self):
1134 return iter(self._general_names)
1135
1136 def __len__(self):
1137 return len(self._general_names)
1138
1139 def get_values_for_type(self, type):
Joshua Taubererd2afad32015-07-06 22:37:53 +00001140 # Return the value of each GeneralName, except for OtherName instances
1141 # which we return directly because it has two important properties not
1142 # just one value.
1143 objs = (i for i in self if isinstance(i, type))
1144 if type != OtherName:
1145 objs = (i.value for i in objs)
1146 return list(objs)
Paul Kehrer31bdf792015-03-25 14:11:00 -05001147
1148 def __repr__(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001149 return "<GeneralNames({0})>".format(self._general_names)
1150
1151 def __eq__(self, other):
1152 if not isinstance(other, GeneralNames):
1153 return NotImplemented
1154
1155 return self._general_names == other._general_names
1156
1157 def __ne__(self, other):
1158 return not self == other
1159
1160
1161class SubjectAlternativeName(object):
1162 def __init__(self, general_names):
1163 self._general_names = GeneralNames(general_names)
1164
1165 def __iter__(self):
1166 return iter(self._general_names)
1167
1168 def __len__(self):
1169 return len(self._general_names)
1170
1171 def get_values_for_type(self, type):
1172 return self._general_names.get_values_for_type(type)
1173
1174 def __repr__(self):
Paul Kehrer31bdf792015-03-25 14:11:00 -05001175 return "<SubjectAlternativeName({0})>".format(self._general_names)
1176
Paul Kehrer58cc3972015-05-13 10:00:41 -05001177 def __eq__(self, other):
1178 if not isinstance(other, SubjectAlternativeName):
1179 return NotImplemented
1180
1181 return self._general_names == other._general_names
1182
1183 def __ne__(self, other):
1184 return not self == other
1185
Paul Kehrer31bdf792015-03-25 14:11:00 -05001186
Paul Kehrer99125c92015-06-07 18:37:10 -05001187class IssuerAlternativeName(object):
1188 def __init__(self, general_names):
1189 self._general_names = GeneralNames(general_names)
1190
1191 def __iter__(self):
1192 return iter(self._general_names)
1193
1194 def __len__(self):
1195 return len(self._general_names)
1196
1197 def get_values_for_type(self, type):
1198 return self._general_names.get_values_for_type(type)
1199
1200 def __repr__(self):
1201 return "<IssuerAlternativeName({0})>".format(self._general_names)
1202
1203 def __eq__(self, other):
1204 if not isinstance(other, IssuerAlternativeName):
1205 return NotImplemented
1206
1207 return self._general_names == other._general_names
1208
1209 def __ne__(self, other):
1210 return not self == other
1211
1212
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001213class AuthorityKeyIdentifier(object):
1214 def __init__(self, key_identifier, authority_cert_issuer,
1215 authority_cert_serial_number):
1216 if authority_cert_issuer or authority_cert_serial_number:
1217 if not authority_cert_issuer or not authority_cert_serial_number:
1218 raise ValueError(
1219 "authority_cert_issuer and authority_cert_serial_number "
1220 "must both be present or both None"
1221 )
1222
Paul Kehrerc6e0f062015-05-03 11:04:34 -05001223 if not all(
1224 isinstance(x, GeneralName) for x in authority_cert_issuer
1225 ):
1226 raise TypeError(
1227 "authority_cert_issuer must be a list of GeneralName "
1228 "objects"
1229 )
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001230
1231 if not isinstance(authority_cert_serial_number, six.integer_types):
1232 raise TypeError(
1233 "authority_cert_serial_number must be an integer"
1234 )
1235
1236 self._key_identifier = key_identifier
1237 self._authority_cert_issuer = authority_cert_issuer
1238 self._authority_cert_serial_number = authority_cert_serial_number
1239
1240 def __repr__(self):
1241 return (
1242 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
1243 "authority_cert_issuer={0.authority_cert_issuer}, "
1244 "authority_cert_serial_number={0.authority_cert_serial_number}"
1245 ")>".format(self)
1246 )
1247
Paul Kehrer2ca2eb32015-05-03 10:04:57 -05001248 def __eq__(self, other):
1249 if not isinstance(other, AuthorityKeyIdentifier):
1250 return NotImplemented
1251
1252 return (
1253 self.key_identifier == other.key_identifier and
1254 self.authority_cert_issuer == other.authority_cert_issuer and
1255 self.authority_cert_serial_number ==
1256 other.authority_cert_serial_number
1257 )
1258
1259 def __ne__(self, other):
1260 return not self == other
1261
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001262 key_identifier = utils.read_only_property("_key_identifier")
1263 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
1264 authority_cert_serial_number = utils.read_only_property(
1265 "_authority_cert_serial_number"
1266 )
1267
1268
Paul Kehrer806bfb22015-02-02 17:05:24 -06001269OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
1270OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
1271OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
1272OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
1273OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
1274OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
1275OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
1276OID_SURNAME = ObjectIdentifier("2.5.4.4")
1277OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
1278OID_TITLE = ObjectIdentifier("2.5.4.12")
1279OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
1280OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
1281OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
1282OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
1283OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001284
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001285OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
1286OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
1287OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
1288OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
1289OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
1290OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001291OID_ECDSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10045.4.1")
Paul Kehrer56da2a52015-02-11 23:35:07 -06001292OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
1293OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
1294OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
1295OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
1296OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
1297OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
1298OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
1299
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001300_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001301 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
1302 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1303 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1304 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1305 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1306 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Alex Gaynor3aadabf2015-06-23 22:06:21 -04001307 OID_ECDSA_WITH_SHA1.dotted_string: hashes.SHA1(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -06001308 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1309 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1310 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1311 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
1312 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1313 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1314 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001315}
1316
Paul Kehrere1513fa2015-03-30 23:08:17 -05001317OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
1318OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
1319OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
1320OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
1321OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
1322OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
1323
Paul Kehrer3e6d5582015-05-02 21:57:56 -05001324OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
1325OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
1326
Paul Kehrer2b622582015-04-15 11:04:29 -04001327OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
1328OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
Paul Kehrer16fae762015-05-01 23:14:20 -05001329OID_ANY_POLICY = ObjectIdentifier("2.5.29.32.0")
Paul Kehrer2b622582015-04-15 11:04:29 -04001330
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001331
Paul Kehrerb2de9482014-12-11 14:54:48 -06001332@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -06001333class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -06001334 @abc.abstractmethod
1335 def fingerprint(self, algorithm):
1336 """
1337 Returns bytes using digest passed.
1338 """
1339
1340 @abc.abstractproperty
1341 def serial(self):
1342 """
1343 Returns certificate serial number
1344 """
1345
1346 @abc.abstractproperty
1347 def version(self):
1348 """
1349 Returns the certificate version
1350 """
1351
1352 @abc.abstractmethod
1353 def public_key(self):
1354 """
1355 Returns the public key
1356 """
1357
1358 @abc.abstractproperty
1359 def not_valid_before(self):
1360 """
1361 Not before time (represented as UTC datetime)
1362 """
1363
1364 @abc.abstractproperty
1365 def not_valid_after(self):
1366 """
1367 Not after time (represented as UTC datetime)
1368 """
Paul Kehrer719d5362015-01-01 20:03:52 -06001369
1370 @abc.abstractproperty
1371 def issuer(self):
1372 """
1373 Returns the issuer name object.
1374 """
1375
1376 @abc.abstractproperty
1377 def subject(self):
1378 """
1379 Returns the subject name object.
1380 """
Paul Kehrer56da2a52015-02-11 23:35:07 -06001381
1382 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001383 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -06001384 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001385 Returns a HashAlgorithm corresponding to the type of the digest signed
1386 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -06001387 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001388
Paul Kehrer8c234d12015-05-15 09:27:22 -07001389 @abc.abstractproperty
1390 def extensions(self):
1391 """
1392 Returns an Extensions object.
1393 """
1394
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001395 @abc.abstractmethod
1396 def __eq__(self, other):
1397 """
1398 Checks equality.
1399 """
1400
1401 @abc.abstractmethod
1402 def __ne__(self, other):
1403 """
1404 Checks not equal.
1405 """
1406
Andre Carona8aded62015-05-19 20:11:57 -04001407 @abc.abstractmethod
Alex Gaynor969f3a52015-07-06 18:52:41 -04001408 def __hash__(self):
1409 """
1410 Computes a hash.
1411 """
1412
1413 @abc.abstractmethod
Andre Carona8aded62015-05-19 20:11:57 -04001414 def public_bytes(self, encoding):
Andre Caron18ef34b2015-05-19 21:24:31 -04001415 """
1416 Serializes the certificate to PEM or DER format.
1417 """
Andre Carona8aded62015-05-19 20:11:57 -04001418
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001419
1420@six.add_metaclass(abc.ABCMeta)
Erik Trauschke2dcce902015-05-14 16:12:24 -07001421class CertificateRevocationList(object):
1422
1423 @abc.abstractmethod
1424 def fingerprint(self, algorithm):
1425 """
1426 Returns bytes using digest passed.
1427 """
1428
1429 @abc.abstractproperty
1430 def signature_hash_algorithm(self):
1431 """
1432 Returns a HashAlgorithm corresponding to the type of the digest signed
1433 in the certificate.
1434 """
1435
1436 @abc.abstractproperty
1437 def issuer(self):
1438 """
1439 Returns the X509Name with the issuer of this CRL.
1440 """
1441
1442 @abc.abstractproperty
1443 def next_update(self):
1444 """
1445 Returns the date of next update for this CRL.
1446 """
1447
1448 @abc.abstractproperty
1449 def last_update(self):
1450 """
1451 Returns the date of last update for this CRL.
1452 """
1453
1454 @abc.abstractproperty
Erik Trauschkeabb7b6e2015-05-27 15:07:35 -07001455 def revoked_certificates(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001456 """
1457 Returns a list of RevokedCertificate objects for this CRL.
1458 """
1459
1460 @abc.abstractproperty
1461 def extensions(self):
1462 """
1463 Returns an Extensions object containing a list of CRL extensions.
1464 """
1465
1466 @abc.abstractmethod
Erik Trauschke2dcce902015-05-14 16:12:24 -07001467 def __eq__(self, other):
1468 """
1469 Checks equality.
1470 """
1471
1472 @abc.abstractmethod
1473 def __ne__(self, other):
1474 """
1475 Checks not equal.
1476 """
1477
1478
1479@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -05001480class CertificateSigningRequest(object):
Alex Gaynor935f6ca2015-07-06 21:03:46 -04001481 @abc.abstractmethod
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001482 def __eq__(self, other):
1483 """
1484 Checks equality.
1485 """
1486
1487 @abc.abstractmethod
1488 def __ne__(self, other):
1489 """
1490 Checks not equal.
1491 """
1492
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001493 @abc.abstractmethod
Alex Gaynor978137d2015-07-08 20:59:16 -04001494 def __hash__(self):
1495 """
1496 Computes a hash.
1497 """
1498
1499 @abc.abstractmethod
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001500 def public_key(self):
1501 """
1502 Returns the public key
1503 """
1504
1505 @abc.abstractproperty
1506 def subject(self):
1507 """
1508 Returns the subject name object.
1509 """
1510
1511 @abc.abstractproperty
1512 def signature_hash_algorithm(self):
1513 """
1514 Returns a HashAlgorithm corresponding to the type of the digest signed
1515 in the certificate.
1516 """
Andre Caron6e721a92015-05-17 15:08:48 -04001517
1518 @abc.abstractproperty
1519 def extensions(self):
1520 """
1521 Returns the extensions in the signing request.
1522 """
Andre Caron476c5df2015-05-18 10:23:28 -04001523
1524 @abc.abstractmethod
1525 def public_bytes(self, encoding):
1526 """
1527 Encodes the request to PEM or DER format.
1528 """
Erik Trauschke2dcce902015-05-14 16:12:24 -07001529
1530
1531@six.add_metaclass(abc.ABCMeta)
1532class RevokedCertificate(object):
1533 @abc.abstractproperty
1534 def serial_number(self):
1535 """
1536 Returns the serial number of the revoked certificate.
1537 """
1538
1539 @abc.abstractproperty
1540 def revocation_date(self):
1541 """
1542 Returns the date of when this certificate was revoked.
1543 """
1544
1545 @abc.abstractproperty
1546 def extensions(self):
1547 """
1548 Returns an Extensions object containing a list of Revoked extensions.
1549 """
Andre Caron0ef595f2015-05-18 13:53:43 -04001550
1551
1552class CertificateSigningRequestBuilder(object):
Andre Caron99d0f902015-06-01 08:36:59 -04001553 def __init__(self, subject_name=None, extensions=[]):
Andre Caron0ef595f2015-05-18 13:53:43 -04001554 """
1555 Creates an empty X.509 certificate request (v1).
1556 """
Andre Caronfc164c52015-05-31 17:36:18 -04001557 self._subject_name = subject_name
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001558 self._extensions = extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001559
Andre Carona9a51172015-06-06 20:18:44 -04001560 def subject_name(self, name):
Andre Caron0ef595f2015-05-18 13:53:43 -04001561 """
1562 Sets the certificate requestor's distinguished name.
1563 """
1564 if not isinstance(name, Name):
1565 raise TypeError('Expecting x509.Name object.')
Ian Cordascod09ec372015-06-17 21:37:51 -05001566 if self._subject_name is not None:
1567 raise ValueError('The subject name may only be set once.')
Andre Caron99d0f902015-06-01 08:36:59 -04001568 return CertificateSigningRequestBuilder(name, self._extensions)
Andre Caron0ef595f2015-05-18 13:53:43 -04001569
Ian Cordascof06b6be2015-06-21 10:09:18 -05001570 def add_extension(self, extension, critical):
Andre Caron0ef595f2015-05-18 13:53:43 -04001571 """
1572 Adds an X.509 extension to the certificate request.
1573 """
Andre Caron472fd692015-06-06 20:04:44 -04001574 if isinstance(extension, BasicConstraints):
1575 extension = Extension(OID_BASIC_CONSTRAINTS, 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)
Andre Caron472fd692015-06-06 20:04:44 -04001582 else:
Ian Cordascof06b6be2015-06-21 10:09:18 -05001583 raise NotImplementedError('Unsupported X.509 extension.')
1584 # TODO: This is quadratic in the number of extensions
Andre Caron0ef595f2015-05-18 13:53:43 -04001585 for e in self._extensions:
1586 if e.oid == extension.oid:
1587 raise ValueError('This extension has already been set.')
Andre Caronfc164c52015-05-31 17:36:18 -04001588 return CertificateSigningRequestBuilder(
Andre Caron99d0f902015-06-01 08:36:59 -04001589 self._subject_name, self._extensions + [extension]
Andre Caronfc164c52015-05-31 17:36:18 -04001590 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001591
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001592 def sign(self, private_key, algorithm, backend):
Andre Caron0ef595f2015-05-18 13:53:43 -04001593 """
1594 Signs the request using the requestor's private key.
1595 """
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001596 if self._subject_name is None:
1597 raise ValueError("A CertificateSigningRequest must have a subject")
Andre Carona33ea282015-05-31 16:32:26 -04001598 return backend.create_x509_csr(self, private_key, algorithm)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001599
1600
1601class CertificateBuilder(object):
Ian Cordascob3ed4842015-07-01 22:46:03 -05001602 def __init__(self, version=None, issuer_name=None, subject_name=None,
1603 public_key=None, serial_number=None, not_valid_before=None,
1604 not_valid_after=None, extensions=[]):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001605 """
1606 Creates an empty X.509 certificate (version 1).
1607 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001608 self._version = version
1609 self._issuer_name = issuer_name
1610 self._subject_name = subject_name
1611 self._public_key = public_key
1612 self._serial_number = serial_number
1613 self._not_valid_before = not_valid_before
1614 self._not_valid_after = not_valid_after
1615 self._extensions = extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -04001616
Ian Cordascob3ed4842015-07-01 22:46:03 -05001617 def version(self, version):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001618 """
1619 Sets the X.509 version required by decoders.
1620 """
1621 if not isinstance(version, Version):
1622 raise TypeError('Expecting x509.Version object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001623 if self._version is not None:
1624 raise ValueError('The version may only be set once.')
1625 return CertificateBuilder(
1626 version, self._issuer_name, self._subject_name, self._public_key,
1627 self._serial_number, self._not_valid_before,
1628 self._not_valid_after, self._extensions
1629 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001630
Ian Cordascob3ed4842015-07-01 22:46:03 -05001631 def issuer_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001632 """
1633 Sets the CA's distinguished name.
1634 """
1635 if not isinstance(name, Name):
1636 raise TypeError('Expecting x509.Name object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001637 if self._issuer_name is not None:
1638 raise ValueError('The issuer name may only be set once.')
1639 return CertificateBuilder(
1640 self._version, name, self._subject_name, self._public_key,
1641 self._serial_number, self._not_valid_before,
1642 self._not_valid_after, self._extensions
1643 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001644
Ian Cordascob3ed4842015-07-01 22:46:03 -05001645 def subject_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001646 """
1647 Sets the requestor's distinguished name.
1648 """
1649 if not isinstance(name, Name):
1650 raise TypeError('Expecting x509.Name object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001651 if self._subject_name is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001652 raise ValueError('The subject name may only be set once.')
1653 return CertificateBuilder(
1654 self._version, self._issuer_name, name, self._public_key,
1655 self._serial_number, self._not_valid_before,
1656 self._not_valid_after, self._extensions
1657 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001658
Ian Cordascob3ed4842015-07-01 22:46:03 -05001659 def public_key(self, key):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001660 """
1661 Sets the requestor's public key (as found in the signing request).
1662 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001663 if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
1664 ec.EllipticCurvePublicKey)):
1665 raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
1666 ' or EllipticCurvePublicKey.')
1667 if self._public_key is not None:
1668 raise ValueError('The public key may only be set once.')
1669 return CertificateBuilder(
1670 self._version, self._issuer_name, self._subject_name, key,
1671 self._serial_number, self._not_valid_before,
1672 self._not_valid_after, self._extensions
1673 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001674
Ian Cordascob3ed4842015-07-01 22:46:03 -05001675 def serial_number(self, number):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001676 """
1677 Sets the certificate serial number.
1678 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001679 if not isinstance(number, six.integer_types):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001680 raise TypeError('Serial number must be of integral type.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001681 if self._serial_number is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001682 raise ValueError('The serial number may only be set once.')
1683 return CertificateBuilder(
1684 self._version, self._issuer_name, self._subject_name,
1685 self._public_key, number, self._not_valid_before,
1686 self._not_valid_after, self._extensions
1687 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001688
Ian Cordascob3ed4842015-07-01 22:46:03 -05001689 def not_valid_before(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001690 """
1691 Sets the certificate activation time.
1692 """
1693 # TODO: require UTC datetime?
1694 if not isinstance(time, datetime.datetime):
1695 raise TypeError('Expecting datetime object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001696 if self._not_valid_before is not None:
1697 raise ValueError('The not valid before may only be set once.')
1698 return CertificateBuilder(
1699 self._version, self._issuer_name, self._subject_name,
1700 self._public_key, self._serial_number, time,
1701 self._not_valid_after, self._extensions
1702 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001703
Ian Cordascob3ed4842015-07-01 22:46:03 -05001704 def not_valid_after(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001705 """
1706 Sets the certificate expiration time.
1707 """
1708 # TODO: require UTC datetime?
1709 if not isinstance(time, datetime.datetime):
1710 raise TypeError('Expecting datetime object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -05001711 if self._not_valid_after is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -05001712 raise ValueError('The not valid after may only be set once.')
1713 return CertificateBuilder(
1714 self._version, self._issuer_name, self._subject_name,
1715 self._public_key, self._serial_number, self._not_valid_before,
1716 time, self._extensions
1717 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001718
Ian Cordascob3ed4842015-07-01 22:46:03 -05001719 def add_extension(self, extension, critical):
Andre Caron9bbfcea2015-05-18 20:55:29 -04001720 """
1721 Adds an X.509 extension to the certificate.
1722 """
Ian Cordascob3ed4842015-07-01 22:46:03 -05001723 if isinstance(extension, BasicConstraints):
1724 extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
1725 elif isinstance(extension, SubjectAlternativeName):
1726 extension = Extension(
1727 OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
1728 )
1729 else:
1730 raise NotImplementedError('Unsupported X.509 extension.')
Andre Caron9bbfcea2015-05-18 20:55:29 -04001731 if not isinstance(extension, Extension):
1732 raise TypeError('Expecting x509.Extension object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001733
1734 # TODO: This is quadratic in the number of extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -04001735 for e in self._extensions:
1736 if e.oid == extension.oid:
1737 raise ValueError('This extension has already been set.')
Ian Cordascob3ed4842015-07-01 22:46:03 -05001738
1739 return CertificateBuilder(
1740 self._version, self._issuer_name, self._subject_name,
1741 self._public_key, self._serial_number, self._not_valid_before,
1742 self._not_valid_after, self._extensions + [extension]
1743 )
Andre Caron9bbfcea2015-05-18 20:55:29 -04001744
1745 def sign(self, backend, private_key, algorithm):
1746 """
1747 Signs the certificate using the CA's private key.
1748 """
Ian Cordasco0092a0b2015-07-18 21:46:41 -05001749 builder = self
Ian Cordascob3ed4842015-07-01 22:46:03 -05001750 if self._version is None:
Ian Cordasco0092a0b2015-07-18 21:46:41 -05001751 builder = self.version(Version.v3)
1752 return backend.sign_x509_certificate(builder, private_key, algorithm)