blob: 0aeafa74fc1fb18f62a6a9c9936b094e38c46051 [file] [log] [blame]
Paul Kehrer016e08a2014-11-26 09:41:18 -10001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
Paul Kehrerb2de9482014-12-11 14:54:48 -06007import abc
Paul Kehrer31bdf792015-03-25 14:11:00 -05008import ipaddress
Paul Kehrer016e08a2014-11-26 09:41:18 -10009from enum import Enum
10
Paul Kehrerb2de9482014-12-11 14:54:48 -060011import six
12
Paul Kehrer912d3fb2015-01-29 11:19:22 -060013from cryptography import utils
Paul Kehrer8802a5b2015-02-13 12:06:57 -060014from cryptography.hazmat.primitives import hashes
Paul Kehrer912d3fb2015-01-29 11:19:22 -060015
Paul Kehrer016e08a2014-11-26 09:41:18 -100016
Paul Kehrer806bfb22015-02-02 17:05:24 -060017_OID_NAMES = {
18 "2.5.4.3": "commonName",
19 "2.5.4.6": "countryName",
20 "2.5.4.7": "localityName",
21 "2.5.4.8": "stateOrProvinceName",
22 "2.5.4.10": "organizationName",
23 "2.5.4.11": "organizationalUnitName",
24 "2.5.4.5": "serialNumber",
25 "2.5.4.4": "surname",
26 "2.5.4.42": "givenName",
27 "2.5.4.12": "title",
28 "2.5.4.44": "generationQualifier",
29 "2.5.4.46": "dnQualifier",
30 "2.5.4.65": "pseudonym",
31 "0.9.2342.19200300.100.1.25": "domainComponent",
32 "1.2.840.113549.1.9.1": "emailAddress",
Paul Kehrer71d40c62015-02-19 08:21:04 -060033 "1.2.840.113549.1.1.4": "md5WithRSAEncryption",
34 "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
Paul Kehrer56da2a52015-02-11 23:35:07 -060035 "1.2.840.113549.1.1.14": "sha224WithRSAEncryption",
36 "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
37 "1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
38 "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
Paul Kehrer71d40c62015-02-19 08:21:04 -060039 "1.2.840.10045.4.3.1": "ecdsa-with-SHA224",
40 "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
41 "1.2.840.10045.4.3.3": "ecdsa-with-SHA384",
42 "1.2.840.10045.4.3.4": "ecdsa-with-SHA512",
43 "1.2.840.10040.4.3": "dsa-with-sha1",
44 "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
45 "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
Paul Kehrere1513fa2015-03-30 23:08:17 -050046 "1.3.6.1.5.5.7.3.1": "serverAuth",
47 "1.3.6.1.5.5.7.3.2": "clientAuth",
48 "1.3.6.1.5.5.7.3.3": "codeSigning",
49 "1.3.6.1.5.5.7.3.4": "emailProtection",
50 "1.3.6.1.5.5.7.3.8": "timeStamping",
51 "1.3.6.1.5.5.7.3.9": "OCSPSigning",
Paul Kehrerd08b5492015-04-04 15:19:16 -050052 "2.5.29.9": "subjectDirectoryAttributes",
53 "2.5.29.14": "subjectKeyIdentifier",
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050054 "2.5.29.15": "keyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050055 "2.5.29.17": "subjectAltName",
56 "2.5.29.18": "issuerAltName",
57 "2.5.29.19": "basicConstraints",
Erik Trauschkec5a8d172015-05-28 10:24:25 -070058 "2.5.29.21": "cRLReason",
59 "2.5.29.24": "invalidityDate",
60 "2.5.29.29": "certificateIssuer",
Paul Kehrerd08b5492015-04-04 15:19:16 -050061 "2.5.29.30": "nameConstraints",
62 "2.5.29.31": "cRLDistributionPoints",
63 "2.5.29.32": "certificatePolicies",
64 "2.5.29.33": "policyMappings",
65 "2.5.29.35": "authorityKeyIdentifier",
66 "2.5.29.36": "policyConstraints",
Paul Kehrere1513fa2015-03-30 23:08:17 -050067 "2.5.29.37": "extendedKeyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050068 "2.5.29.46": "freshestCRL",
69 "2.5.29.54": "inhibitAnyPolicy",
70 "1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
71 "1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
72 "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
Paul Kehrer3e6d5582015-05-02 21:57:56 -050073 "1.3.6.1.5.5.7.48.1": "OCSP",
Paul Kehrerf506bca2015-05-02 22:31:47 -050074 "1.3.6.1.5.5.7.48.2": "caIssuers",
Paul Kehrer2b622582015-04-15 11:04:29 -040075 "1.3.6.1.5.5.7.2.1": "id-qt-cps",
76 "1.3.6.1.5.5.7.2.2": "id-qt-unotice",
Paul Kehrer806bfb22015-02-02 17:05:24 -060077}
78
79
Paul Kehrer9089c912015-04-20 22:15:20 -050080_GENERAL_NAMES = {
81 0: "otherName",
82 1: "rfc822Name",
83 2: "dNSName",
84 3: "x400Address",
85 4: "directoryName",
86 5: "ediPartyName",
87 6: "uniformResourceIdentifier",
88 7: "iPAddress",
89 8: "registeredID",
90}
91
92
Paul Kehrere76cd272014-12-14 19:00:51 -060093class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100094 v1 = 0
95 v3 = 2
96
97
Paul Kehrer016e08a2014-11-26 09:41:18 -100098def load_pem_x509_certificate(data, backend):
99 return backend.load_pem_x509_certificate(data)
100
101
Paul Kehrer016e08a2014-11-26 09:41:18 -1000102def load_der_x509_certificate(data, backend):
103 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -1000104
105
Paul Kehrer31e39882015-03-11 11:37:04 -0500106def load_pem_x509_csr(data, backend):
107 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600108
109
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500110def load_der_x509_csr(data, backend):
111 return backend.load_der_x509_csr(data)
112
113
Paul Kehrere76cd272014-12-14 19:00:51 -0600114class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600115 def __init__(self, msg, parsed_version):
116 super(InvalidVersion, self).__init__(msg)
117 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600118
119
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500120class DuplicateExtension(Exception):
121 def __init__(self, msg, oid):
122 super(DuplicateExtension, self).__init__(msg)
123 self.oid = oid
124
125
126class UnsupportedExtension(Exception):
127 def __init__(self, msg, oid):
128 super(UnsupportedExtension, self).__init__(msg)
129 self.oid = oid
130
131
Paul Kehrerfa56a232015-03-17 13:14:03 -0500132class ExtensionNotFound(Exception):
133 def __init__(self, msg, oid):
134 super(ExtensionNotFound, self).__init__(msg)
135 self.oid = oid
136
137
Paul Kehrer9089c912015-04-20 22:15:20 -0500138class UnsupportedGeneralNameType(Exception):
Paul Kehrerbed07352015-04-21 08:31:10 -0500139 def __init__(self, msg, type):
140 super(UnsupportedGeneralNameType, self).__init__(msg)
141 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500142
143
Paul Kehrer806bfb22015-02-02 17:05:24 -0600144class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600145 def __init__(self, oid, value):
146 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600147 raise TypeError(
148 "oid argument must be an ObjectIdentifier instance."
149 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600150
151 self._oid = oid
152 self._value = value
153
154 oid = utils.read_only_property("_oid")
155 value = utils.read_only_property("_value")
156
157 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600158 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600159 return NotImplemented
160
161 return (
162 self.oid == other.oid and
163 self.value == other.value
164 )
165
166 def __ne__(self, other):
167 return not self == other
168
Paul Kehrera498be82015-02-12 15:00:56 -0600169 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400170 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600171
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600172
173class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600174 def __init__(self, dotted_string):
175 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600176
177 def __eq__(self, other):
178 if not isinstance(other, ObjectIdentifier):
179 return NotImplemented
180
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600181 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600182
183 def __ne__(self, other):
184 return not self == other
185
186 def __repr__(self):
187 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600188 self._dotted_string,
189 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600190 )
191
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500192 def __hash__(self):
193 return hash(self.dotted_string)
194
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600195 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600196
197
Paul Kehrer719d5362015-01-01 20:03:52 -0600198class Name(object):
199 def __init__(self, attributes):
200 self._attributes = attributes
201
Paul Kehrere901d642015-02-11 18:50:58 -0600202 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800203 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600204
Paul Kehrer719d5362015-01-01 20:03:52 -0600205 def __eq__(self, other):
206 if not isinstance(other, Name):
207 return NotImplemented
208
Paul Kehrer53d8d492015-02-13 18:47:30 -0600209 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600210
211 def __ne__(self, other):
212 return not self == other
213
Paul Kehrer53d8d492015-02-13 18:47:30 -0600214 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600215 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600216
217 def __len__(self):
218 return len(self._attributes)
219
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400220 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400221 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400222
Paul Kehrer719d5362015-01-01 20:03:52 -0600223
Paul Kehrerd08b5492015-04-04 15:19:16 -0500224OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
225OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500226OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500227OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
228OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500229OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Erik Trauschke2dcce902015-05-14 16:12:24 -0700230OID_CRL_REASON = ObjectIdentifier("2.5.29.21")
231OID_INVALIDITY_DATE = ObjectIdentifier("2.5.29.24")
232OID_CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500233OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
234OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
235OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
236OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
237OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
238OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
239OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
240OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
241OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
242OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
243OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
244OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500245
246
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500247class Extensions(object):
248 def __init__(self, extensions):
249 self._extensions = extensions
250
Paul Kehrerfa56a232015-03-17 13:14:03 -0500251 def get_extension_for_oid(self, oid):
252 for ext in self:
253 if ext.oid == oid:
254 return ext
255
256 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
257
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500258 def __iter__(self):
259 return iter(self._extensions)
260
261 def __len__(self):
262 return len(self._extensions)
263
264
Paul Kehrer8cf26422015-03-21 09:50:24 -0500265class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500266 def __init__(self, oid, critical, value):
267 if not isinstance(oid, ObjectIdentifier):
268 raise TypeError(
269 "oid argument must be an ObjectIdentifier instance."
270 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500271
272 if not isinstance(critical, bool):
273 raise TypeError("critical must be a boolean value")
274
Paul Kehrer85894662015-03-22 13:19:31 -0500275 self._oid = oid
276 self._critical = critical
277 self._value = value
278
279 oid = utils.read_only_property("_oid")
280 critical = utils.read_only_property("_critical")
281 value = utils.read_only_property("_value")
282
283 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500284 return ("<Extension(oid={0.oid}, critical={0.critical}, "
285 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500286
Paul Kehrer58e870c2015-05-17 09:15:30 -0700287 def __eq__(self, other):
288 if not isinstance(other, Extension):
289 return NotImplemented
290
291 return (
292 self.oid == other.oid and
293 self.critical == other.critical and
294 self.value == other.value
295 )
296
297 def __ne__(self, other):
298 return not self == other
299
Paul Kehrer85894662015-03-22 13:19:31 -0500300
Paul Kehrerffa2a152015-03-31 08:18:25 -0500301class ExtendedKeyUsage(object):
302 def __init__(self, usages):
Paul Kehrerb0476172015-05-02 19:34:51 -0500303 if not all(isinstance(x, ObjectIdentifier) for x in usages):
304 raise TypeError(
305 "Every item in the usages list must be an ObjectIdentifier"
306 )
Paul Kehrerffa2a152015-03-31 08:18:25 -0500307
308 self._usages = usages
309
310 def __iter__(self):
311 return iter(self._usages)
312
313 def __len__(self):
314 return len(self._usages)
315
Paul Kehrer23d10c32015-04-02 23:12:32 -0500316 def __repr__(self):
317 return "<ExtendedKeyUsage({0})>".format(self._usages)
318
Paul Kehrerb0476172015-05-02 19:34:51 -0500319 def __eq__(self, other):
320 if not isinstance(other, ExtendedKeyUsage):
321 return NotImplemented
322
Paul Kehrerf24bad72015-05-02 19:36:20 -0500323 return self._usages == other._usages
Paul Kehrerb0476172015-05-02 19:34:51 -0500324
325 def __ne__(self, other):
326 return not self == other
327
Paul Kehrerffa2a152015-03-31 08:18:25 -0500328
Paul Kehrer4a1038e2015-05-18 10:28:31 -0700329class OCSPNoCheck(object):
330 pass
331
332
Paul Kehrer85894662015-03-22 13:19:31 -0500333class BasicConstraints(object):
334 def __init__(self, ca, path_length):
335 if not isinstance(ca, bool):
336 raise TypeError("ca must be a boolean value")
337
Paul Kehrer611d3d32015-03-22 13:31:18 -0500338 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500339 raise ValueError("path_length must be None when ca is False")
340
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500341 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500342 path_length is not None and
343 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500344 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500345 raise TypeError(
346 "path_length must be a non-negative integer or None"
347 )
348
349 self._ca = ca
350 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500351
352 ca = utils.read_only_property("_ca")
353 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500354
355 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500356 return ("<BasicConstraints(ca={0.ca}, "
357 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500358
Paul Kehrer3a69b132015-05-13 10:03:46 -0500359 def __eq__(self, other):
360 if not isinstance(other, BasicConstraints):
361 return NotImplemented
362
363 return self.ca == other.ca and self.path_length == other.path_length
364
365 def __ne__(self, other):
366 return not self == other
367
Paul Kehrer8cf26422015-03-21 09:50:24 -0500368
Paul Kehrercecbbba2015-03-30 14:58:38 -0500369class KeyUsage(object):
370 def __init__(self, digital_signature, content_commitment, key_encipherment,
371 data_encipherment, key_agreement, key_cert_sign, crl_sign,
372 encipher_only, decipher_only):
373 if not key_agreement and (encipher_only or decipher_only):
374 raise ValueError(
375 "encipher_only and decipher_only can only be true when "
376 "key_agreement is true"
377 )
378
379 self._digital_signature = digital_signature
380 self._content_commitment = content_commitment
381 self._key_encipherment = key_encipherment
382 self._data_encipherment = data_encipherment
383 self._key_agreement = key_agreement
384 self._key_cert_sign = key_cert_sign
385 self._crl_sign = crl_sign
386 self._encipher_only = encipher_only
387 self._decipher_only = decipher_only
388
389 digital_signature = utils.read_only_property("_digital_signature")
390 content_commitment = utils.read_only_property("_content_commitment")
391 key_encipherment = utils.read_only_property("_key_encipherment")
392 data_encipherment = utils.read_only_property("_data_encipherment")
393 key_agreement = utils.read_only_property("_key_agreement")
394 key_cert_sign = utils.read_only_property("_key_cert_sign")
395 crl_sign = utils.read_only_property("_crl_sign")
396
397 @property
398 def encipher_only(self):
399 if not self.key_agreement:
400 raise ValueError(
401 "encipher_only is undefined unless key_agreement is true"
402 )
403 else:
404 return self._encipher_only
405
406 @property
407 def decipher_only(self):
408 if not self.key_agreement:
409 raise ValueError(
410 "decipher_only is undefined unless key_agreement is true"
411 )
412 else:
413 return self._decipher_only
414
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500415 def __repr__(self):
416 try:
417 encipher_only = self.encipher_only
418 decipher_only = self.decipher_only
419 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400420 encipher_only = None
421 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500422
423 return ("<KeyUsage(digital_signature={0.digital_signature}, "
424 "content_commitment={0.content_commitment}, "
425 "key_encipherment={0.key_encipherment}, "
426 "data_encipherment={0.data_encipherment}, "
427 "key_agreement={0.key_agreement}, "
428 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
429 "encipher_only={1}, decipher_only={2})>").format(
430 self, encipher_only, decipher_only)
431
Paul Kehrer8565f5e2015-05-13 09:57:09 -0500432 def __eq__(self, other):
433 if not isinstance(other, KeyUsage):
434 return NotImplemented
435
436 return (
437 self.digital_signature == other.digital_signature and
438 self.content_commitment == other.content_commitment and
439 self.key_encipherment == other.key_encipherment and
440 self.data_encipherment == other.data_encipherment and
441 self.key_agreement == other.key_agreement and
442 self.key_cert_sign == other.key_cert_sign and
443 self.crl_sign == other.crl_sign and
444 self._encipher_only == other._encipher_only and
445 self._decipher_only == other._decipher_only
446 )
447
448 def __ne__(self, other):
449 return not self == other
450
Paul Kehrercecbbba2015-03-30 14:58:38 -0500451
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500452class AuthorityInformationAccess(object):
453 def __init__(self, descriptions):
454 if not all(isinstance(x, AccessDescription) for x in descriptions):
455 raise TypeError(
456 "Every item in the descriptions list must be an "
457 "AccessDescription"
458 )
459
460 self._descriptions = descriptions
461
462 def __iter__(self):
463 return iter(self._descriptions)
464
465 def __len__(self):
466 return len(self._descriptions)
467
468 def __repr__(self):
469 return "<AuthorityInformationAccess({0})>".format(self._descriptions)
470
471 def __eq__(self, other):
472 if not isinstance(other, AuthorityInformationAccess):
473 return NotImplemented
474
475 return self._descriptions == other._descriptions
476
477 def __ne__(self, other):
478 return not self == other
479
480
481class AccessDescription(object):
482 def __init__(self, access_method, access_location):
483 if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
Paul Kehrerf506bca2015-05-02 22:31:47 -0500484 raise ValueError(
485 "access_method must be OID_OCSP or OID_CA_ISSUERS"
486 )
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500487
488 if not isinstance(access_location, GeneralName):
489 raise TypeError("access_location must be a GeneralName")
490
491 self._access_method = access_method
492 self._access_location = access_location
493
494 def __repr__(self):
495 return (
496 "<AccessDescription(access_method={0.access_method}, access_locati"
497 "on={0.access_location})>".format(self)
498 )
499
500 def __eq__(self, other):
501 if not isinstance(other, AccessDescription):
502 return NotImplemented
503
504 return (
505 self.access_method == other.access_method and
506 self.access_location == other.access_location
507 )
508
509 def __ne__(self, other):
510 return not self == other
511
512 access_method = utils.read_only_property("_access_method")
513 access_location = utils.read_only_property("_access_location")
514
515
Paul Kehrer2b622582015-04-15 11:04:29 -0400516class CertificatePolicies(object):
517 def __init__(self, policies):
Paul Kehrerf61ec742015-04-18 20:42:39 -0500518 if not all(isinstance(x, PolicyInformation) for x in policies):
Paul Kehrer2b622582015-04-15 11:04:29 -0400519 raise TypeError(
520 "Every item in the policies list must be a "
521 "PolicyInformation"
522 )
523
524 self._policies = policies
525
526 def __iter__(self):
527 return iter(self._policies)
528
529 def __len__(self):
530 return len(self._policies)
531
532 def __repr__(self):
533 return "<CertificatePolicies({0})>".format(self._policies)
534
Paul Kehrerc56ab622015-05-03 09:56:31 -0500535 def __eq__(self, other):
536 if not isinstance(other, CertificatePolicies):
537 return NotImplemented
538
539 return self._policies == other._policies
540
541 def __ne__(self, other):
542 return not self == other
543
Paul Kehrer2b622582015-04-15 11:04:29 -0400544
545class PolicyInformation(object):
546 def __init__(self, policy_identifier, policy_qualifiers):
547 if not isinstance(policy_identifier, ObjectIdentifier):
548 raise TypeError("policy_identifier must be an ObjectIdentifier")
549
550 self._policy_identifier = policy_identifier
551 if policy_qualifiers and not all(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500552 isinstance(
553 x, (six.text_type, UserNotice)
554 ) for x in policy_qualifiers
Paul Kehrer2b622582015-04-15 11:04:29 -0400555 ):
556 raise TypeError(
Paul Kehrerba35b3b2015-05-10 13:07:59 -0500557 "policy_qualifiers must be a list of strings and/or UserNotice"
558 " objects or None"
Paul Kehrer2b622582015-04-15 11:04:29 -0400559 )
560
561 self._policy_qualifiers = policy_qualifiers
562
563 def __repr__(self):
564 return (
565 "<PolicyInformation(policy_identifier={0.policy_identifier}, polic"
566 "y_qualifiers={0.policy_qualifiers})>".format(self)
567 )
568
Paul Kehrerc56ab622015-05-03 09:56:31 -0500569 def __eq__(self, other):
570 if not isinstance(other, PolicyInformation):
571 return NotImplemented
572
573 return (
574 self.policy_identifier == other.policy_identifier and
575 self.policy_qualifiers == other.policy_qualifiers
576 )
577
578 def __ne__(self, other):
579 return not self == other
580
Paul Kehrer2b622582015-04-15 11:04:29 -0400581 policy_identifier = utils.read_only_property("_policy_identifier")
582 policy_qualifiers = utils.read_only_property("_policy_qualifiers")
583
584
Paul Kehrer2b622582015-04-15 11:04:29 -0400585class UserNotice(object):
586 def __init__(self, notice_reference, explicit_text):
587 if notice_reference and not isinstance(
588 notice_reference, NoticeReference
589 ):
590 raise TypeError(
591 "notice_reference must be None or a NoticeReference"
592 )
593
594 self._notice_reference = notice_reference
595 self._explicit_text = explicit_text
596
597 def __repr__(self):
598 return (
599 "<UserNotice(notice_reference={0.notice_reference}, explicit_text="
Paul Kehrer9aaef9e2015-05-11 10:49:20 -0500600 "{0.explicit_text!r})>".format(self)
Paul Kehrer2b622582015-04-15 11:04:29 -0400601 )
602
Paul Kehrerc56ab622015-05-03 09:56:31 -0500603 def __eq__(self, other):
604 if not isinstance(other, UserNotice):
605 return NotImplemented
606
607 return (
608 self.notice_reference == other.notice_reference and
609 self.explicit_text == other.explicit_text
610 )
611
612 def __ne__(self, other):
613 return not self == other
614
Paul Kehrer2b622582015-04-15 11:04:29 -0400615 notice_reference = utils.read_only_property("_notice_reference")
616 explicit_text = utils.read_only_property("_explicit_text")
617
618
619class NoticeReference(object):
620 def __init__(self, organization, notice_numbers):
621 self._organization = organization
Paul Kehrer6e198b02015-05-12 15:53:38 -0500622 if not isinstance(notice_numbers, list) or not all(
Paul Kehrerf61ec742015-04-18 20:42:39 -0500623 isinstance(x, int) for x in notice_numbers
Paul Kehrer2b622582015-04-15 11:04:29 -0400624 ):
625 raise TypeError(
Paul Kehrer6e198b02015-05-12 15:53:38 -0500626 "notice_numbers must be a list of integers"
Paul Kehrer2b622582015-04-15 11:04:29 -0400627 )
628
629 self._notice_numbers = notice_numbers
630
631 def __repr__(self):
632 return (
Paul Kehrer73be2ca2015-05-11 21:22:38 -0500633 "<NoticeReference(organization={0.organization!r}, notice_numbers="
Paul Kehrer2b622582015-04-15 11:04:29 -0400634 "{0.notice_numbers})>".format(self)
635 )
636
Paul Kehrerc56ab622015-05-03 09:56:31 -0500637 def __eq__(self, other):
638 if not isinstance(other, NoticeReference):
639 return NotImplemented
640
641 return (
642 self.organization == other.organization and
643 self.notice_numbers == other.notice_numbers
644 )
645
646 def __ne__(self, other):
647 return not self == other
648
Paul Kehrer2b622582015-04-15 11:04:29 -0400649 organization = utils.read_only_property("_organization")
650 notice_numbers = utils.read_only_property("_notice_numbers")
651
652
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500653class SubjectKeyIdentifier(object):
654 def __init__(self, digest):
655 self._digest = digest
656
657 digest = utils.read_only_property("_digest")
658
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500659 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400660 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500661
662 def __eq__(self, other):
663 if not isinstance(other, SubjectKeyIdentifier):
664 return NotImplemented
665
666 return (
667 self.digest == other.digest
668 )
669
670 def __ne__(self, other):
671 return not self == other
672
673
Paul Kehrer5a485522015-05-06 00:29:12 -0500674class CRLDistributionPoints(object):
675 def __init__(self, distribution_points):
676 if not all(
677 isinstance(x, DistributionPoint) for x in distribution_points
678 ):
679 raise TypeError(
680 "distribution_points must be a list of DistributionPoint "
681 "objects"
682 )
683
684 self._distribution_points = distribution_points
685
686 def __iter__(self):
687 return iter(self._distribution_points)
688
689 def __len__(self):
690 return len(self._distribution_points)
691
692 def __repr__(self):
693 return "<CRLDistributionPoints({0})>".format(self._distribution_points)
694
695 def __eq__(self, other):
696 if not isinstance(other, CRLDistributionPoints):
697 return NotImplemented
698
699 return self._distribution_points == other._distribution_points
700
701 def __ne__(self, other):
702 return not self == other
703
704
705class DistributionPoint(object):
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500706 def __init__(self, full_name, relative_name, reasons, crl_issuer):
707 if full_name and relative_name:
708 raise ValueError(
709 "At least one of full_name and relative_name must be None"
710 )
711
712 if full_name and not all(
713 isinstance(x, GeneralName) for x in full_name
714 ):
715 raise TypeError(
716 "full_name must be a list of GeneralName objects"
717 )
718
719 if relative_name and not isinstance(relative_name, Name):
720 raise TypeError("relative_name must be a Name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500721
722 if crl_issuer and not all(
723 isinstance(x, GeneralName) for x in crl_issuer
724 ):
725 raise TypeError(
726 "crl_issuer must be None or a list of general names"
727 )
728
Paul Kehrer3fd02602015-05-09 19:46:13 -0500729 if reasons and (not isinstance(reasons, frozenset) or not all(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500730 isinstance(x, ReasonFlags) for x in reasons
Paul Kehrer3fd02602015-05-09 19:46:13 -0500731 )):
732 raise TypeError("reasons must be None or frozenset of ReasonFlags")
Paul Kehrer5a485522015-05-06 00:29:12 -0500733
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500734 if reasons and (
735 ReasonFlags.unspecified in reasons or
736 ReasonFlags.remove_from_crl in reasons
737 ):
Paul Kehrer5a485522015-05-06 00:29:12 -0500738 raise ValueError(
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500739 "unspecified and remove_from_crl are not valid reasons in a "
740 "DistributionPoint"
741 )
742
743 if reasons and not crl_issuer and not (full_name or relative_name):
744 raise ValueError(
745 "You must supply crl_issuer, full_name, or relative_name when "
Paul Kehrer5a485522015-05-06 00:29:12 -0500746 "reasons is not None"
747 )
748
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500749 self._full_name = full_name
750 self._relative_name = relative_name
Paul Kehrer5a485522015-05-06 00:29:12 -0500751 self._reasons = reasons
752 self._crl_issuer = crl_issuer
753
754 def __repr__(self):
755 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500756 "<DistributionPoint(full_name={0.full_name}, relative_name={0.rela"
757 "tive_name}, reasons={0.reasons}, crl_issuer={0.crl_is"
758 "suer})>".format(self)
Paul Kehrer5a485522015-05-06 00:29:12 -0500759 )
760
761 def __eq__(self, other):
762 if not isinstance(other, DistributionPoint):
763 return NotImplemented
764
765 return (
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500766 self.full_name == other.full_name and
767 self.relative_name == other.relative_name and
Paul Kehrer5a485522015-05-06 00:29:12 -0500768 self.reasons == other.reasons and
769 self.crl_issuer == other.crl_issuer
770 )
771
772 def __ne__(self, other):
773 return not self == other
774
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500775 full_name = utils.read_only_property("_full_name")
776 relative_name = utils.read_only_property("_relative_name")
Paul Kehrer5a485522015-05-06 00:29:12 -0500777 reasons = utils.read_only_property("_reasons")
778 crl_issuer = utils.read_only_property("_crl_issuer")
779
780
Paul Kehrer4e8dacd2015-05-09 10:38:23 -0500781class ReasonFlags(Enum):
782 unspecified = "unspecified"
783 key_compromise = "keyCompromise"
784 ca_compromise = "cACompromise"
785 affiliation_changed = "affiliationChanged"
786 superseded = "superseded"
787 cessation_of_operation = "cessationOfOperation"
788 certificate_hold = "certificateHold"
789 privilege_withdrawn = "privilegeWithdrawn"
790 aa_compromise = "aACompromise"
791 remove_from_crl = "removeFromCRL"
Paul Kehrer5a485522015-05-06 00:29:12 -0500792
793
Paul Kehrer31bdf792015-03-25 14:11:00 -0500794@six.add_metaclass(abc.ABCMeta)
795class GeneralName(object):
796 @abc.abstractproperty
797 def value(self):
798 """
799 Return the value of the object
800 """
801
802
803@utils.register_interface(GeneralName)
804class RFC822Name(object):
805 def __init__(self, value):
806 if not isinstance(value, six.text_type):
807 raise TypeError("value must be a unicode string")
808
809 self._value = value
810
811 value = utils.read_only_property("_value")
812
813 def __repr__(self):
814 return "<RFC822Name(value={0})>".format(self.value)
815
816 def __eq__(self, other):
817 if not isinstance(other, RFC822Name):
818 return NotImplemented
819
820 return self.value == other.value
821
822 def __ne__(self, other):
823 return not self == other
824
825
826@utils.register_interface(GeneralName)
827class DNSName(object):
828 def __init__(self, value):
829 if not isinstance(value, six.text_type):
830 raise TypeError("value must be a unicode string")
831
832 self._value = value
833
834 value = utils.read_only_property("_value")
835
836 def __repr__(self):
837 return "<DNSName(value={0})>".format(self.value)
838
839 def __eq__(self, other):
840 if not isinstance(other, DNSName):
841 return NotImplemented
842
843 return self.value == other.value
844
845 def __ne__(self, other):
846 return not self == other
847
848
849@utils.register_interface(GeneralName)
850class UniformResourceIdentifier(object):
851 def __init__(self, value):
852 if not isinstance(value, six.text_type):
853 raise TypeError("value must be a unicode string")
854
855 self._value = value
856
857 value = utils.read_only_property("_value")
858
859 def __repr__(self):
860 return "<UniformResourceIdentifier(value={0})>".format(self.value)
861
862 def __eq__(self, other):
863 if not isinstance(other, UniformResourceIdentifier):
864 return NotImplemented
865
866 return self.value == other.value
867
868 def __ne__(self, other):
869 return not self == other
870
871
872@utils.register_interface(GeneralName)
873class DirectoryName(object):
874 def __init__(self, value):
875 if not isinstance(value, Name):
876 raise TypeError("value must be a Name")
877
878 self._value = value
879
880 value = utils.read_only_property("_value")
881
882 def __repr__(self):
883 return "<DirectoryName(value={0})>".format(self.value)
884
885 def __eq__(self, other):
886 if not isinstance(other, DirectoryName):
887 return NotImplemented
888
889 return self.value == other.value
890
891 def __ne__(self, other):
892 return not self == other
893
894
895@utils.register_interface(GeneralName)
896class RegisteredID(object):
897 def __init__(self, value):
898 if not isinstance(value, ObjectIdentifier):
899 raise TypeError("value must be an ObjectIdentifier")
900
901 self._value = value
902
903 value = utils.read_only_property("_value")
904
905 def __repr__(self):
906 return "<RegisteredID(value={0})>".format(self.value)
907
908 def __eq__(self, other):
909 if not isinstance(other, RegisteredID):
910 return NotImplemented
911
912 return self.value == other.value
913
914 def __ne__(self, other):
915 return not self == other
916
917
918@utils.register_interface(GeneralName)
919class IPAddress(object):
920 def __init__(self, value):
921 if not isinstance(
Paul Kehrereb177932015-05-17 18:33:33 -0700922 value,
923 (
924 ipaddress.IPv4Address,
925 ipaddress.IPv6Address,
926 ipaddress.IPv4Network,
927 ipaddress.IPv6Network
928 )
Paul Kehrer31bdf792015-03-25 14:11:00 -0500929 ):
930 raise TypeError(
Paul Kehrereb177932015-05-17 18:33:33 -0700931 "value must be an instance of ipaddress.IPv4Address, "
932 "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
933 "ipaddress.IPv6Network"
Paul Kehrer31bdf792015-03-25 14:11:00 -0500934 )
935
936 self._value = value
937
938 value = utils.read_only_property("_value")
939
940 def __repr__(self):
941 return "<IPAddress(value={0})>".format(self.value)
942
943 def __eq__(self, other):
944 if not isinstance(other, IPAddress):
945 return NotImplemented
946
947 return self.value == other.value
948
949 def __ne__(self, other):
950 return not self == other
951
952
Erik Trauschke2dcce902015-05-14 16:12:24 -0700953class GeneralNames(object):
Paul Kehrer31bdf792015-03-25 14:11:00 -0500954 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500955 if not all(isinstance(x, GeneralName) for x in general_names):
956 raise TypeError(
957 "Every item in the general_names list must be an "
958 "object conforming to the GeneralName interface"
959 )
960
Paul Kehrer31bdf792015-03-25 14:11:00 -0500961 self._general_names = general_names
962
963 def __iter__(self):
964 return iter(self._general_names)
965
966 def __len__(self):
967 return len(self._general_names)
968
969 def get_values_for_type(self, type):
970 return [i.value for i in self if isinstance(i, type)]
971
972 def __repr__(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -0700973 return "<GeneralNames({0})>".format(self._general_names)
974
975 def __eq__(self, other):
976 if not isinstance(other, GeneralNames):
977 return NotImplemented
978
979 return self._general_names == other._general_names
980
981 def __ne__(self, other):
982 return not self == other
983
984
985class SubjectAlternativeName(object):
986 def __init__(self, general_names):
987 self._general_names = GeneralNames(general_names)
988
989 def __iter__(self):
990 return iter(self._general_names)
991
992 def __len__(self):
993 return len(self._general_names)
994
995 def get_values_for_type(self, type):
996 return self._general_names.get_values_for_type(type)
997
998 def __repr__(self):
Paul Kehrer31bdf792015-03-25 14:11:00 -0500999 return "<SubjectAlternativeName({0})>".format(self._general_names)
1000
Paul Kehrer58cc3972015-05-13 10:00:41 -05001001 def __eq__(self, other):
1002 if not isinstance(other, SubjectAlternativeName):
1003 return NotImplemented
1004
1005 return self._general_names == other._general_names
1006
1007 def __ne__(self, other):
1008 return not self == other
1009
Paul Kehrer31bdf792015-03-25 14:11:00 -05001010
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001011class AuthorityKeyIdentifier(object):
1012 def __init__(self, key_identifier, authority_cert_issuer,
1013 authority_cert_serial_number):
1014 if authority_cert_issuer or authority_cert_serial_number:
1015 if not authority_cert_issuer or not authority_cert_serial_number:
1016 raise ValueError(
1017 "authority_cert_issuer and authority_cert_serial_number "
1018 "must both be present or both None"
1019 )
1020
Paul Kehrerc6e0f062015-05-03 11:04:34 -05001021 if not all(
1022 isinstance(x, GeneralName) for x in authority_cert_issuer
1023 ):
1024 raise TypeError(
1025 "authority_cert_issuer must be a list of GeneralName "
1026 "objects"
1027 )
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001028
1029 if not isinstance(authority_cert_serial_number, six.integer_types):
1030 raise TypeError(
1031 "authority_cert_serial_number must be an integer"
1032 )
1033
1034 self._key_identifier = key_identifier
1035 self._authority_cert_issuer = authority_cert_issuer
1036 self._authority_cert_serial_number = authority_cert_serial_number
1037
1038 def __repr__(self):
1039 return (
1040 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
1041 "authority_cert_issuer={0.authority_cert_issuer}, "
1042 "authority_cert_serial_number={0.authority_cert_serial_number}"
1043 ")>".format(self)
1044 )
1045
Paul Kehrer2ca2eb32015-05-03 10:04:57 -05001046 def __eq__(self, other):
1047 if not isinstance(other, AuthorityKeyIdentifier):
1048 return NotImplemented
1049
1050 return (
1051 self.key_identifier == other.key_identifier and
1052 self.authority_cert_issuer == other.authority_cert_issuer and
1053 self.authority_cert_serial_number ==
1054 other.authority_cert_serial_number
1055 )
1056
1057 def __ne__(self, other):
1058 return not self == other
1059
Paul Kehrer2eb4ed92015-04-11 15:33:45 -04001060 key_identifier = utils.read_only_property("_key_identifier")
1061 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
1062 authority_cert_serial_number = utils.read_only_property(
1063 "_authority_cert_serial_number"
1064 )
1065
1066
Paul Kehrer806bfb22015-02-02 17:05:24 -06001067OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
1068OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
1069OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
1070OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
1071OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
1072OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
1073OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
1074OID_SURNAME = ObjectIdentifier("2.5.4.4")
1075OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
1076OID_TITLE = ObjectIdentifier("2.5.4.12")
1077OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
1078OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
1079OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
1080OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
1081OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001082
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001083OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
1084OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
1085OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
1086OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
1087OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
1088OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -06001089OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
1090OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
1091OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
1092OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
1093OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
1094OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
1095OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
1096
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001097_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -06001098 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
1099 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1100 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1101 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1102 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1103 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -06001104 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1105 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
1106 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
1107 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
1108 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
1109 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
1110 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001111}
1112
Paul Kehrere1513fa2015-03-30 23:08:17 -05001113OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
1114OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
1115OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
1116OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
1117OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
1118OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
1119
Paul Kehrer3e6d5582015-05-02 21:57:56 -05001120OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
1121OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
1122
Paul Kehrer2b622582015-04-15 11:04:29 -04001123OID_CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1")
1124OID_CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2")
1125
Paul Kehrer912d3fb2015-01-29 11:19:22 -06001126
Paul Kehrerb2de9482014-12-11 14:54:48 -06001127@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -06001128class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -06001129 @abc.abstractmethod
1130 def fingerprint(self, algorithm):
1131 """
1132 Returns bytes using digest passed.
1133 """
1134
1135 @abc.abstractproperty
1136 def serial(self):
1137 """
1138 Returns certificate serial number
1139 """
1140
1141 @abc.abstractproperty
1142 def version(self):
1143 """
1144 Returns the certificate version
1145 """
1146
1147 @abc.abstractmethod
1148 def public_key(self):
1149 """
1150 Returns the public key
1151 """
1152
1153 @abc.abstractproperty
1154 def not_valid_before(self):
1155 """
1156 Not before time (represented as UTC datetime)
1157 """
1158
1159 @abc.abstractproperty
1160 def not_valid_after(self):
1161 """
1162 Not after time (represented as UTC datetime)
1163 """
Paul Kehrer719d5362015-01-01 20:03:52 -06001164
1165 @abc.abstractproperty
1166 def issuer(self):
1167 """
1168 Returns the issuer name object.
1169 """
1170
1171 @abc.abstractproperty
1172 def subject(self):
1173 """
1174 Returns the subject name object.
1175 """
Paul Kehrer56da2a52015-02-11 23:35:07 -06001176
1177 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001178 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -06001179 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001180 Returns a HashAlgorithm corresponding to the type of the digest signed
1181 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -06001182 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001183
Paul Kehrer8c234d12015-05-15 09:27:22 -07001184 @abc.abstractproperty
1185 def extensions(self):
1186 """
1187 Returns an Extensions object.
1188 """
1189
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001190 @abc.abstractmethod
1191 def __eq__(self, other):
1192 """
1193 Checks equality.
1194 """
1195
1196 @abc.abstractmethod
1197 def __ne__(self, other):
1198 """
1199 Checks not equal.
1200 """
1201
Andre Carona8aded62015-05-19 20:11:57 -04001202 @abc.abstractmethod
1203 def public_bytes(self, encoding):
Andre Caron18ef34b2015-05-19 21:24:31 -04001204 """
1205 Serializes the certificate to PEM or DER format.
1206 """
Andre Carona8aded62015-05-19 20:11:57 -04001207
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001208
1209@six.add_metaclass(abc.ABCMeta)
Erik Trauschke2dcce902015-05-14 16:12:24 -07001210class CertificateRevocationList(object):
1211
1212 @abc.abstractmethod
1213 def fingerprint(self, algorithm):
1214 """
1215 Returns bytes using digest passed.
1216 """
1217
1218 @abc.abstractproperty
1219 def signature_hash_algorithm(self):
1220 """
1221 Returns a HashAlgorithm corresponding to the type of the digest signed
1222 in the certificate.
1223 """
1224
1225 @abc.abstractproperty
1226 def issuer(self):
1227 """
1228 Returns the X509Name with the issuer of this CRL.
1229 """
1230
1231 @abc.abstractproperty
1232 def next_update(self):
1233 """
1234 Returns the date of next update for this CRL.
1235 """
1236
1237 @abc.abstractproperty
1238 def last_update(self):
1239 """
1240 Returns the date of last update for this CRL.
1241 """
1242
1243 @abc.abstractproperty
Erik Trauschkeabb7b6e2015-05-27 15:07:35 -07001244 def revoked_certificates(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -07001245 """
1246 Returns a list of RevokedCertificate objects for this CRL.
1247 """
1248
1249 @abc.abstractproperty
1250 def extensions(self):
1251 """
1252 Returns an Extensions object containing a list of CRL extensions.
1253 """
1254
1255 @abc.abstractmethod
Erik Trauschke2dcce902015-05-14 16:12:24 -07001256 def __eq__(self, other):
1257 """
1258 Checks equality.
1259 """
1260
1261 @abc.abstractmethod
1262 def __ne__(self, other):
1263 """
1264 Checks not equal.
1265 """
1266
1267
1268@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -05001269class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001270 @abc.abstractmethod
1271 def public_key(self):
1272 """
1273 Returns the public key
1274 """
1275
1276 @abc.abstractproperty
1277 def subject(self):
1278 """
1279 Returns the subject name object.
1280 """
1281
1282 @abc.abstractproperty
1283 def signature_hash_algorithm(self):
1284 """
1285 Returns a HashAlgorithm corresponding to the type of the digest signed
1286 in the certificate.
1287 """
Andre Caron6e721a92015-05-17 15:08:48 -04001288
1289 @abc.abstractproperty
1290 def extensions(self):
1291 """
1292 Returns the extensions in the signing request.
1293 """
Andre Caron476c5df2015-05-18 10:23:28 -04001294
1295 @abc.abstractmethod
1296 def public_bytes(self, encoding):
1297 """
1298 Encodes the request to PEM or DER format.
1299 """
Erik Trauschke2dcce902015-05-14 16:12:24 -07001300
1301
1302@six.add_metaclass(abc.ABCMeta)
1303class RevokedCertificate(object):
1304 @abc.abstractproperty
1305 def serial_number(self):
1306 """
1307 Returns the serial number of the revoked certificate.
1308 """
1309
1310 @abc.abstractproperty
1311 def revocation_date(self):
1312 """
1313 Returns the date of when this certificate was revoked.
1314 """
1315
1316 @abc.abstractproperty
1317 def extensions(self):
1318 """
1319 Returns an Extensions object containing a list of Revoked extensions.
1320 """