blob: cdc0e430e82e65741c20622ffa17f95e4a96e9d1 [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",
58 "2.5.29.30": "nameConstraints",
59 "2.5.29.31": "cRLDistributionPoints",
60 "2.5.29.32": "certificatePolicies",
61 "2.5.29.33": "policyMappings",
62 "2.5.29.35": "authorityKeyIdentifier",
63 "2.5.29.36": "policyConstraints",
Paul Kehrere1513fa2015-03-30 23:08:17 -050064 "2.5.29.37": "extendedKeyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050065 "2.5.29.46": "freshestCRL",
66 "2.5.29.54": "inhibitAnyPolicy",
67 "1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
68 "1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
69 "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
Paul Kehrer806bfb22015-02-02 17:05:24 -060070}
71
72
Paul Kehrere76cd272014-12-14 19:00:51 -060073class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100074 v1 = 0
75 v3 = 2
76
77
Paul Kehrer016e08a2014-11-26 09:41:18 -100078def load_pem_x509_certificate(data, backend):
79 return backend.load_pem_x509_certificate(data)
80
81
Paul Kehrer016e08a2014-11-26 09:41:18 -100082def load_der_x509_certificate(data, backend):
83 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100084
85
Paul Kehrer31e39882015-03-11 11:37:04 -050086def load_pem_x509_csr(data, backend):
87 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -060088
89
Paul Kehrer1effb6e2015-03-30 15:05:59 -050090def load_der_x509_csr(data, backend):
91 return backend.load_der_x509_csr(data)
92
93
Paul Kehrere76cd272014-12-14 19:00:51 -060094class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -060095 def __init__(self, msg, parsed_version):
96 super(InvalidVersion, self).__init__(msg)
97 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -060098
99
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500100class DuplicateExtension(Exception):
101 def __init__(self, msg, oid):
102 super(DuplicateExtension, self).__init__(msg)
103 self.oid = oid
104
105
106class UnsupportedExtension(Exception):
107 def __init__(self, msg, oid):
108 super(UnsupportedExtension, self).__init__(msg)
109 self.oid = oid
110
111
Paul Kehrerfa56a232015-03-17 13:14:03 -0500112class ExtensionNotFound(Exception):
113 def __init__(self, msg, oid):
114 super(ExtensionNotFound, self).__init__(msg)
115 self.oid = oid
116
117
Paul Kehrer806bfb22015-02-02 17:05:24 -0600118class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600119 def __init__(self, oid, value):
120 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600121 raise TypeError(
122 "oid argument must be an ObjectIdentifier instance."
123 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600124
125 self._oid = oid
126 self._value = value
127
128 oid = utils.read_only_property("_oid")
129 value = utils.read_only_property("_value")
130
131 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600132 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600133 return NotImplemented
134
135 return (
136 self.oid == other.oid and
137 self.value == other.value
138 )
139
140 def __ne__(self, other):
141 return not self == other
142
Paul Kehrera498be82015-02-12 15:00:56 -0600143 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400144 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600145
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600146
147class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600148 def __init__(self, dotted_string):
149 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600150
151 def __eq__(self, other):
152 if not isinstance(other, ObjectIdentifier):
153 return NotImplemented
154
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600155 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600156
157 def __ne__(self, other):
158 return not self == other
159
160 def __repr__(self):
161 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600162 self._dotted_string,
163 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600164 )
165
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500166 def __hash__(self):
167 return hash(self.dotted_string)
168
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600169 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600170
171
Paul Kehrer719d5362015-01-01 20:03:52 -0600172class Name(object):
173 def __init__(self, attributes):
174 self._attributes = attributes
175
Paul Kehrere901d642015-02-11 18:50:58 -0600176 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800177 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600178
Paul Kehrer719d5362015-01-01 20:03:52 -0600179 def __eq__(self, other):
180 if not isinstance(other, Name):
181 return NotImplemented
182
Paul Kehrer53d8d492015-02-13 18:47:30 -0600183 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600184
185 def __ne__(self, other):
186 return not self == other
187
Paul Kehrer53d8d492015-02-13 18:47:30 -0600188 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600189 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600190
191 def __len__(self):
192 return len(self._attributes)
193
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400194 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400195 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400196
Paul Kehrer719d5362015-01-01 20:03:52 -0600197
Paul Kehrerd08b5492015-04-04 15:19:16 -0500198OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
199OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500200OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500201OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
202OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500203OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500204OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
205OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
206OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
207OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
208OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
209OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
210OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
211OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
212OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
213OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
214OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
215OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500216
217
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500218class Extensions(object):
219 def __init__(self, extensions):
220 self._extensions = extensions
221
Paul Kehrerfa56a232015-03-17 13:14:03 -0500222 def get_extension_for_oid(self, oid):
223 for ext in self:
224 if ext.oid == oid:
225 return ext
226
227 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
228
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500229 def __iter__(self):
230 return iter(self._extensions)
231
232 def __len__(self):
233 return len(self._extensions)
234
235
Paul Kehrer8cf26422015-03-21 09:50:24 -0500236class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500237 def __init__(self, oid, critical, value):
238 if not isinstance(oid, ObjectIdentifier):
239 raise TypeError(
240 "oid argument must be an ObjectIdentifier instance."
241 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500242
243 if not isinstance(critical, bool):
244 raise TypeError("critical must be a boolean value")
245
Paul Kehrer85894662015-03-22 13:19:31 -0500246 self._oid = oid
247 self._critical = critical
248 self._value = value
249
250 oid = utils.read_only_property("_oid")
251 critical = utils.read_only_property("_critical")
252 value = utils.read_only_property("_value")
253
254 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500255 return ("<Extension(oid={0.oid}, critical={0.critical}, "
256 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500257
258
Paul Kehrerffa2a152015-03-31 08:18:25 -0500259class ExtendedKeyUsage(object):
260 def __init__(self, usages):
261 for oid in usages:
262 if not isinstance(oid, ObjectIdentifier):
263 raise TypeError(
264 "Every item in the usages list must be an ObjectIdentifier"
265 )
266
267 self._usages = usages
268
269 def __iter__(self):
270 return iter(self._usages)
271
272 def __len__(self):
273 return len(self._usages)
274
Paul Kehrer23d10c32015-04-02 23:12:32 -0500275 def __repr__(self):
276 return "<ExtendedKeyUsage({0})>".format(self._usages)
277
Paul Kehrerffa2a152015-03-31 08:18:25 -0500278
Paul Kehrer85894662015-03-22 13:19:31 -0500279class BasicConstraints(object):
280 def __init__(self, ca, path_length):
281 if not isinstance(ca, bool):
282 raise TypeError("ca must be a boolean value")
283
Paul Kehrer611d3d32015-03-22 13:31:18 -0500284 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500285 raise ValueError("path_length must be None when ca is False")
286
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500287 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500288 path_length is not None and
289 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500290 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500291 raise TypeError(
292 "path_length must be a non-negative integer or None"
293 )
294
295 self._ca = ca
296 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500297
298 ca = utils.read_only_property("_ca")
299 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500300
301 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500302 return ("<BasicConstraints(ca={0.ca}, "
303 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500304
305
Paul Kehrercecbbba2015-03-30 14:58:38 -0500306class KeyUsage(object):
307 def __init__(self, digital_signature, content_commitment, key_encipherment,
308 data_encipherment, key_agreement, key_cert_sign, crl_sign,
309 encipher_only, decipher_only):
310 if not key_agreement and (encipher_only or decipher_only):
311 raise ValueError(
312 "encipher_only and decipher_only can only be true when "
313 "key_agreement is true"
314 )
315
316 self._digital_signature = digital_signature
317 self._content_commitment = content_commitment
318 self._key_encipherment = key_encipherment
319 self._data_encipherment = data_encipherment
320 self._key_agreement = key_agreement
321 self._key_cert_sign = key_cert_sign
322 self._crl_sign = crl_sign
323 self._encipher_only = encipher_only
324 self._decipher_only = decipher_only
325
326 digital_signature = utils.read_only_property("_digital_signature")
327 content_commitment = utils.read_only_property("_content_commitment")
328 key_encipherment = utils.read_only_property("_key_encipherment")
329 data_encipherment = utils.read_only_property("_data_encipherment")
330 key_agreement = utils.read_only_property("_key_agreement")
331 key_cert_sign = utils.read_only_property("_key_cert_sign")
332 crl_sign = utils.read_only_property("_crl_sign")
333
334 @property
335 def encipher_only(self):
336 if not self.key_agreement:
337 raise ValueError(
338 "encipher_only is undefined unless key_agreement is true"
339 )
340 else:
341 return self._encipher_only
342
343 @property
344 def decipher_only(self):
345 if not self.key_agreement:
346 raise ValueError(
347 "decipher_only is undefined unless key_agreement is true"
348 )
349 else:
350 return self._decipher_only
351
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500352 def __repr__(self):
353 try:
354 encipher_only = self.encipher_only
355 decipher_only = self.decipher_only
356 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400357 encipher_only = None
358 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500359
360 return ("<KeyUsage(digital_signature={0.digital_signature}, "
361 "content_commitment={0.content_commitment}, "
362 "key_encipherment={0.key_encipherment}, "
363 "data_encipherment={0.data_encipherment}, "
364 "key_agreement={0.key_agreement}, "
365 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
366 "encipher_only={1}, decipher_only={2})>").format(
367 self, encipher_only, decipher_only)
368
Paul Kehrercecbbba2015-03-30 14:58:38 -0500369
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500370class SubjectKeyIdentifier(object):
371 def __init__(self, digest):
372 self._digest = digest
373
374 digest = utils.read_only_property("_digest")
375
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500376 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400377 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500378
379 def __eq__(self, other):
380 if not isinstance(other, SubjectKeyIdentifier):
381 return NotImplemented
382
383 return (
384 self.digest == other.digest
385 )
386
387 def __ne__(self, other):
388 return not self == other
389
390
Paul Kehrer31bdf792015-03-25 14:11:00 -0500391@six.add_metaclass(abc.ABCMeta)
392class GeneralName(object):
393 @abc.abstractproperty
394 def value(self):
395 """
396 Return the value of the object
397 """
398
399
400@utils.register_interface(GeneralName)
401class RFC822Name(object):
402 def __init__(self, value):
403 if not isinstance(value, six.text_type):
404 raise TypeError("value must be a unicode string")
405
406 self._value = value
407
408 value = utils.read_only_property("_value")
409
410 def __repr__(self):
411 return "<RFC822Name(value={0})>".format(self.value)
412
413 def __eq__(self, other):
414 if not isinstance(other, RFC822Name):
415 return NotImplemented
416
417 return self.value == other.value
418
419 def __ne__(self, other):
420 return not self == other
421
422
423@utils.register_interface(GeneralName)
424class DNSName(object):
425 def __init__(self, value):
426 if not isinstance(value, six.text_type):
427 raise TypeError("value must be a unicode string")
428
429 self._value = value
430
431 value = utils.read_only_property("_value")
432
433 def __repr__(self):
434 return "<DNSName(value={0})>".format(self.value)
435
436 def __eq__(self, other):
437 if not isinstance(other, DNSName):
438 return NotImplemented
439
440 return self.value == other.value
441
442 def __ne__(self, other):
443 return not self == other
444
445
446@utils.register_interface(GeneralName)
447class UniformResourceIdentifier(object):
448 def __init__(self, value):
449 if not isinstance(value, six.text_type):
450 raise TypeError("value must be a unicode string")
451
452 self._value = value
453
454 value = utils.read_only_property("_value")
455
456 def __repr__(self):
457 return "<UniformResourceIdentifier(value={0})>".format(self.value)
458
459 def __eq__(self, other):
460 if not isinstance(other, UniformResourceIdentifier):
461 return NotImplemented
462
463 return self.value == other.value
464
465 def __ne__(self, other):
466 return not self == other
467
468
469@utils.register_interface(GeneralName)
470class DirectoryName(object):
471 def __init__(self, value):
472 if not isinstance(value, Name):
473 raise TypeError("value must be a Name")
474
475 self._value = value
476
477 value = utils.read_only_property("_value")
478
479 def __repr__(self):
480 return "<DirectoryName(value={0})>".format(self.value)
481
482 def __eq__(self, other):
483 if not isinstance(other, DirectoryName):
484 return NotImplemented
485
486 return self.value == other.value
487
488 def __ne__(self, other):
489 return not self == other
490
491
492@utils.register_interface(GeneralName)
493class RegisteredID(object):
494 def __init__(self, value):
495 if not isinstance(value, ObjectIdentifier):
496 raise TypeError("value must be an ObjectIdentifier")
497
498 self._value = value
499
500 value = utils.read_only_property("_value")
501
502 def __repr__(self):
503 return "<RegisteredID(value={0})>".format(self.value)
504
505 def __eq__(self, other):
506 if not isinstance(other, RegisteredID):
507 return NotImplemented
508
509 return self.value == other.value
510
511 def __ne__(self, other):
512 return not self == other
513
514
515@utils.register_interface(GeneralName)
516class IPAddress(object):
517 def __init__(self, value):
518 if not isinstance(
519 value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
520 ):
521 raise TypeError(
522 "value must be an instance of ipaddress.IPv4Address or "
523 "ipaddress.IPv6Address"
524 )
525
526 self._value = value
527
528 value = utils.read_only_property("_value")
529
530 def __repr__(self):
531 return "<IPAddress(value={0})>".format(self.value)
532
533 def __eq__(self, other):
534 if not isinstance(other, IPAddress):
535 return NotImplemented
536
537 return self.value == other.value
538
539 def __ne__(self, other):
540 return not self == other
541
542
543class SubjectAlternativeName(object):
544 def __init__(self, general_names):
545 self._general_names = general_names
546
547 def __iter__(self):
548 return iter(self._general_names)
549
550 def __len__(self):
551 return len(self._general_names)
552
553 def get_values_for_type(self, type):
554 return [i.value for i in self if isinstance(i, type)]
555
556 def __repr__(self):
557 return "<SubjectAlternativeName({0})>".format(self._general_names)
558
559
Paul Kehrer2eb4ed92015-04-11 15:33:45 -0400560class AuthorityKeyIdentifier(object):
561 def __init__(self, key_identifier, authority_cert_issuer,
562 authority_cert_serial_number):
563 if authority_cert_issuer or authority_cert_serial_number:
564 if not authority_cert_issuer or not authority_cert_serial_number:
565 raise ValueError(
566 "authority_cert_issuer and authority_cert_serial_number "
567 "must both be present or both None"
568 )
569
570 if not isinstance(authority_cert_issuer, Name):
571 raise TypeError("authority_cert_issuer must be a Name")
572
573 if not isinstance(authority_cert_serial_number, six.integer_types):
574 raise TypeError(
575 "authority_cert_serial_number must be an integer"
576 )
577
578 self._key_identifier = key_identifier
579 self._authority_cert_issuer = authority_cert_issuer
580 self._authority_cert_serial_number = authority_cert_serial_number
581
582 def __repr__(self):
583 return (
584 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
585 "authority_cert_issuer={0.authority_cert_issuer}, "
586 "authority_cert_serial_number={0.authority_cert_serial_number}"
587 ")>".format(self)
588 )
589
590 key_identifier = utils.read_only_property("_key_identifier")
591 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
592 authority_cert_serial_number = utils.read_only_property(
593 "_authority_cert_serial_number"
594 )
595
596
Paul Kehrer806bfb22015-02-02 17:05:24 -0600597OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
598OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
599OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
600OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
601OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
602OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
603OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
604OID_SURNAME = ObjectIdentifier("2.5.4.4")
605OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
606OID_TITLE = ObjectIdentifier("2.5.4.12")
607OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
608OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
609OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
610OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
611OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600612
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600613OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
614OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
615OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
616OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
617OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
618OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -0600619OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
620OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
621OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
622OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
623OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
624OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
625OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
626
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600627_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600628 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
629 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
630 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
631 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
632 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
633 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -0600634 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
635 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
636 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
637 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
638 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
639 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
640 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600641}
642
Paul Kehrere1513fa2015-03-30 23:08:17 -0500643OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
644OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
645OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
646OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
647OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
648OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
649
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600650
Paul Kehrerb2de9482014-12-11 14:54:48 -0600651@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600652class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600653 @abc.abstractmethod
654 def fingerprint(self, algorithm):
655 """
656 Returns bytes using digest passed.
657 """
658
659 @abc.abstractproperty
660 def serial(self):
661 """
662 Returns certificate serial number
663 """
664
665 @abc.abstractproperty
666 def version(self):
667 """
668 Returns the certificate version
669 """
670
671 @abc.abstractmethod
672 def public_key(self):
673 """
674 Returns the public key
675 """
676
677 @abc.abstractproperty
678 def not_valid_before(self):
679 """
680 Not before time (represented as UTC datetime)
681 """
682
683 @abc.abstractproperty
684 def not_valid_after(self):
685 """
686 Not after time (represented as UTC datetime)
687 """
Paul Kehrer719d5362015-01-01 20:03:52 -0600688
689 @abc.abstractproperty
690 def issuer(self):
691 """
692 Returns the issuer name object.
693 """
694
695 @abc.abstractproperty
696 def subject(self):
697 """
698 Returns the subject name object.
699 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600700
701 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600702 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600703 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600704 Returns a HashAlgorithm corresponding to the type of the digest signed
705 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600706 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600707
708
709@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500710class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600711 @abc.abstractmethod
712 def public_key(self):
713 """
714 Returns the public key
715 """
716
717 @abc.abstractproperty
718 def subject(self):
719 """
720 Returns the subject name object.
721 """
722
723 @abc.abstractproperty
724 def signature_hash_algorithm(self):
725 """
726 Returns a HashAlgorithm corresponding to the type of the digest signed
727 in the certificate.
728 """