blob: 3dc066fa7c2c0c33ef1c2bfe8e0505632e0f691d [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 Kehrer9089c912015-04-20 22:15:20 -050073_GENERAL_NAMES = {
74 0: "otherName",
75 1: "rfc822Name",
76 2: "dNSName",
77 3: "x400Address",
78 4: "directoryName",
79 5: "ediPartyName",
80 6: "uniformResourceIdentifier",
81 7: "iPAddress",
82 8: "registeredID",
83}
84
85
Paul Kehrere76cd272014-12-14 19:00:51 -060086class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100087 v1 = 0
88 v3 = 2
89
90
Paul Kehrer016e08a2014-11-26 09:41:18 -100091def load_pem_x509_certificate(data, backend):
92 return backend.load_pem_x509_certificate(data)
93
94
Paul Kehrer016e08a2014-11-26 09:41:18 -100095def load_der_x509_certificate(data, backend):
96 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100097
98
Paul Kehrer31e39882015-03-11 11:37:04 -050099def load_pem_x509_csr(data, backend):
100 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600101
102
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500103def load_der_x509_csr(data, backend):
104 return backend.load_der_x509_csr(data)
105
106
Paul Kehrere76cd272014-12-14 19:00:51 -0600107class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600108 def __init__(self, msg, parsed_version):
109 super(InvalidVersion, self).__init__(msg)
110 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600111
112
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500113class DuplicateExtension(Exception):
114 def __init__(self, msg, oid):
115 super(DuplicateExtension, self).__init__(msg)
116 self.oid = oid
117
118
119class UnsupportedExtension(Exception):
120 def __init__(self, msg, oid):
121 super(UnsupportedExtension, self).__init__(msg)
122 self.oid = oid
123
124
Paul Kehrerfa56a232015-03-17 13:14:03 -0500125class ExtensionNotFound(Exception):
126 def __init__(self, msg, oid):
127 super(ExtensionNotFound, self).__init__(msg)
128 self.oid = oid
129
130
Paul Kehrer9089c912015-04-20 22:15:20 -0500131class UnsupportedGeneralNameType(Exception):
132 pass
133
134
Paul Kehrer806bfb22015-02-02 17:05:24 -0600135class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600136 def __init__(self, oid, value):
137 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600138 raise TypeError(
139 "oid argument must be an ObjectIdentifier instance."
140 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600141
142 self._oid = oid
143 self._value = value
144
145 oid = utils.read_only_property("_oid")
146 value = utils.read_only_property("_value")
147
148 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600149 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600150 return NotImplemented
151
152 return (
153 self.oid == other.oid and
154 self.value == other.value
155 )
156
157 def __ne__(self, other):
158 return not self == other
159
Paul Kehrera498be82015-02-12 15:00:56 -0600160 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400161 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600162
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600163
164class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600165 def __init__(self, dotted_string):
166 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600167
168 def __eq__(self, other):
169 if not isinstance(other, ObjectIdentifier):
170 return NotImplemented
171
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600172 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600173
174 def __ne__(self, other):
175 return not self == other
176
177 def __repr__(self):
178 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600179 self._dotted_string,
180 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600181 )
182
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500183 def __hash__(self):
184 return hash(self.dotted_string)
185
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600186 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600187
188
Paul Kehrer719d5362015-01-01 20:03:52 -0600189class Name(object):
190 def __init__(self, attributes):
191 self._attributes = attributes
192
Paul Kehrere901d642015-02-11 18:50:58 -0600193 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800194 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600195
Paul Kehrer719d5362015-01-01 20:03:52 -0600196 def __eq__(self, other):
197 if not isinstance(other, Name):
198 return NotImplemented
199
Paul Kehrer53d8d492015-02-13 18:47:30 -0600200 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600201
202 def __ne__(self, other):
203 return not self == other
204
Paul Kehrer53d8d492015-02-13 18:47:30 -0600205 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600206 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600207
208 def __len__(self):
209 return len(self._attributes)
210
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400211 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400212 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400213
Paul Kehrer719d5362015-01-01 20:03:52 -0600214
Paul Kehrerd08b5492015-04-04 15:19:16 -0500215OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
216OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500217OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500218OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
219OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500220OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500221OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
222OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
223OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
224OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
225OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
226OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
227OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
228OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
229OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
230OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
231OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
232OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500233
234
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500235class Extensions(object):
236 def __init__(self, extensions):
237 self._extensions = extensions
238
Paul Kehrerfa56a232015-03-17 13:14:03 -0500239 def get_extension_for_oid(self, oid):
240 for ext in self:
241 if ext.oid == oid:
242 return ext
243
244 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
245
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500246 def __iter__(self):
247 return iter(self._extensions)
248
249 def __len__(self):
250 return len(self._extensions)
251
252
Paul Kehrer8cf26422015-03-21 09:50:24 -0500253class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500254 def __init__(self, oid, critical, value):
255 if not isinstance(oid, ObjectIdentifier):
256 raise TypeError(
257 "oid argument must be an ObjectIdentifier instance."
258 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500259
260 if not isinstance(critical, bool):
261 raise TypeError("critical must be a boolean value")
262
Paul Kehrer85894662015-03-22 13:19:31 -0500263 self._oid = oid
264 self._critical = critical
265 self._value = value
266
267 oid = utils.read_only_property("_oid")
268 critical = utils.read_only_property("_critical")
269 value = utils.read_only_property("_value")
270
271 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500272 return ("<Extension(oid={0.oid}, critical={0.critical}, "
273 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500274
275
Paul Kehrerffa2a152015-03-31 08:18:25 -0500276class ExtendedKeyUsage(object):
277 def __init__(self, usages):
278 for oid in usages:
279 if not isinstance(oid, ObjectIdentifier):
280 raise TypeError(
281 "Every item in the usages list must be an ObjectIdentifier"
282 )
283
284 self._usages = usages
285
286 def __iter__(self):
287 return iter(self._usages)
288
289 def __len__(self):
290 return len(self._usages)
291
Paul Kehrer23d10c32015-04-02 23:12:32 -0500292 def __repr__(self):
293 return "<ExtendedKeyUsage({0})>".format(self._usages)
294
Paul Kehrerffa2a152015-03-31 08:18:25 -0500295
Paul Kehrer85894662015-03-22 13:19:31 -0500296class BasicConstraints(object):
297 def __init__(self, ca, path_length):
298 if not isinstance(ca, bool):
299 raise TypeError("ca must be a boolean value")
300
Paul Kehrer611d3d32015-03-22 13:31:18 -0500301 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500302 raise ValueError("path_length must be None when ca is False")
303
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500304 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500305 path_length is not None and
306 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500307 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500308 raise TypeError(
309 "path_length must be a non-negative integer or None"
310 )
311
312 self._ca = ca
313 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500314
315 ca = utils.read_only_property("_ca")
316 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500317
318 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500319 return ("<BasicConstraints(ca={0.ca}, "
320 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500321
322
Paul Kehrercecbbba2015-03-30 14:58:38 -0500323class KeyUsage(object):
324 def __init__(self, digital_signature, content_commitment, key_encipherment,
325 data_encipherment, key_agreement, key_cert_sign, crl_sign,
326 encipher_only, decipher_only):
327 if not key_agreement and (encipher_only or decipher_only):
328 raise ValueError(
329 "encipher_only and decipher_only can only be true when "
330 "key_agreement is true"
331 )
332
333 self._digital_signature = digital_signature
334 self._content_commitment = content_commitment
335 self._key_encipherment = key_encipherment
336 self._data_encipherment = data_encipherment
337 self._key_agreement = key_agreement
338 self._key_cert_sign = key_cert_sign
339 self._crl_sign = crl_sign
340 self._encipher_only = encipher_only
341 self._decipher_only = decipher_only
342
343 digital_signature = utils.read_only_property("_digital_signature")
344 content_commitment = utils.read_only_property("_content_commitment")
345 key_encipherment = utils.read_only_property("_key_encipherment")
346 data_encipherment = utils.read_only_property("_data_encipherment")
347 key_agreement = utils.read_only_property("_key_agreement")
348 key_cert_sign = utils.read_only_property("_key_cert_sign")
349 crl_sign = utils.read_only_property("_crl_sign")
350
351 @property
352 def encipher_only(self):
353 if not self.key_agreement:
354 raise ValueError(
355 "encipher_only is undefined unless key_agreement is true"
356 )
357 else:
358 return self._encipher_only
359
360 @property
361 def decipher_only(self):
362 if not self.key_agreement:
363 raise ValueError(
364 "decipher_only is undefined unless key_agreement is true"
365 )
366 else:
367 return self._decipher_only
368
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500369 def __repr__(self):
370 try:
371 encipher_only = self.encipher_only
372 decipher_only = self.decipher_only
373 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400374 encipher_only = None
375 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500376
377 return ("<KeyUsage(digital_signature={0.digital_signature}, "
378 "content_commitment={0.content_commitment}, "
379 "key_encipherment={0.key_encipherment}, "
380 "data_encipherment={0.data_encipherment}, "
381 "key_agreement={0.key_agreement}, "
382 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
383 "encipher_only={1}, decipher_only={2})>").format(
384 self, encipher_only, decipher_only)
385
Paul Kehrercecbbba2015-03-30 14:58:38 -0500386
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500387class SubjectKeyIdentifier(object):
388 def __init__(self, digest):
389 self._digest = digest
390
391 digest = utils.read_only_property("_digest")
392
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500393 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400394 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500395
396 def __eq__(self, other):
397 if not isinstance(other, SubjectKeyIdentifier):
398 return NotImplemented
399
400 return (
401 self.digest == other.digest
402 )
403
404 def __ne__(self, other):
405 return not self == other
406
407
Paul Kehrer31bdf792015-03-25 14:11:00 -0500408@six.add_metaclass(abc.ABCMeta)
409class GeneralName(object):
410 @abc.abstractproperty
411 def value(self):
412 """
413 Return the value of the object
414 """
415
416
417@utils.register_interface(GeneralName)
418class RFC822Name(object):
419 def __init__(self, value):
420 if not isinstance(value, six.text_type):
421 raise TypeError("value must be a unicode string")
422
423 self._value = value
424
425 value = utils.read_only_property("_value")
426
427 def __repr__(self):
428 return "<RFC822Name(value={0})>".format(self.value)
429
430 def __eq__(self, other):
431 if not isinstance(other, RFC822Name):
432 return NotImplemented
433
434 return self.value == other.value
435
436 def __ne__(self, other):
437 return not self == other
438
439
440@utils.register_interface(GeneralName)
441class DNSName(object):
442 def __init__(self, value):
443 if not isinstance(value, six.text_type):
444 raise TypeError("value must be a unicode string")
445
446 self._value = value
447
448 value = utils.read_only_property("_value")
449
450 def __repr__(self):
451 return "<DNSName(value={0})>".format(self.value)
452
453 def __eq__(self, other):
454 if not isinstance(other, DNSName):
455 return NotImplemented
456
457 return self.value == other.value
458
459 def __ne__(self, other):
460 return not self == other
461
462
463@utils.register_interface(GeneralName)
464class UniformResourceIdentifier(object):
465 def __init__(self, value):
466 if not isinstance(value, six.text_type):
467 raise TypeError("value must be a unicode string")
468
469 self._value = value
470
471 value = utils.read_only_property("_value")
472
473 def __repr__(self):
474 return "<UniformResourceIdentifier(value={0})>".format(self.value)
475
476 def __eq__(self, other):
477 if not isinstance(other, UniformResourceIdentifier):
478 return NotImplemented
479
480 return self.value == other.value
481
482 def __ne__(self, other):
483 return not self == other
484
485
486@utils.register_interface(GeneralName)
487class DirectoryName(object):
488 def __init__(self, value):
489 if not isinstance(value, Name):
490 raise TypeError("value must be a Name")
491
492 self._value = value
493
494 value = utils.read_only_property("_value")
495
496 def __repr__(self):
497 return "<DirectoryName(value={0})>".format(self.value)
498
499 def __eq__(self, other):
500 if not isinstance(other, DirectoryName):
501 return NotImplemented
502
503 return self.value == other.value
504
505 def __ne__(self, other):
506 return not self == other
507
508
509@utils.register_interface(GeneralName)
510class RegisteredID(object):
511 def __init__(self, value):
512 if not isinstance(value, ObjectIdentifier):
513 raise TypeError("value must be an ObjectIdentifier")
514
515 self._value = value
516
517 value = utils.read_only_property("_value")
518
519 def __repr__(self):
520 return "<RegisteredID(value={0})>".format(self.value)
521
522 def __eq__(self, other):
523 if not isinstance(other, RegisteredID):
524 return NotImplemented
525
526 return self.value == other.value
527
528 def __ne__(self, other):
529 return not self == other
530
531
532@utils.register_interface(GeneralName)
533class IPAddress(object):
534 def __init__(self, value):
535 if not isinstance(
536 value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
537 ):
538 raise TypeError(
539 "value must be an instance of ipaddress.IPv4Address or "
540 "ipaddress.IPv6Address"
541 )
542
543 self._value = value
544
545 value = utils.read_only_property("_value")
546
547 def __repr__(self):
548 return "<IPAddress(value={0})>".format(self.value)
549
550 def __eq__(self, other):
551 if not isinstance(other, IPAddress):
552 return NotImplemented
553
554 return self.value == other.value
555
556 def __ne__(self, other):
557 return not self == other
558
559
560class SubjectAlternativeName(object):
561 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500562 if not all(isinstance(x, GeneralName) for x in general_names):
563 raise TypeError(
564 "Every item in the general_names list must be an "
565 "object conforming to the GeneralName interface"
566 )
567
Paul Kehrer31bdf792015-03-25 14:11:00 -0500568 self._general_names = general_names
569
570 def __iter__(self):
571 return iter(self._general_names)
572
573 def __len__(self):
574 return len(self._general_names)
575
576 def get_values_for_type(self, type):
577 return [i.value for i in self if isinstance(i, type)]
578
579 def __repr__(self):
580 return "<SubjectAlternativeName({0})>".format(self._general_names)
581
582
Paul Kehrer2eb4ed92015-04-11 15:33:45 -0400583class AuthorityKeyIdentifier(object):
584 def __init__(self, key_identifier, authority_cert_issuer,
585 authority_cert_serial_number):
586 if authority_cert_issuer or authority_cert_serial_number:
587 if not authority_cert_issuer or not authority_cert_serial_number:
588 raise ValueError(
589 "authority_cert_issuer and authority_cert_serial_number "
590 "must both be present or both None"
591 )
592
593 if not isinstance(authority_cert_issuer, Name):
594 raise TypeError("authority_cert_issuer must be a Name")
595
596 if not isinstance(authority_cert_serial_number, six.integer_types):
597 raise TypeError(
598 "authority_cert_serial_number must be an integer"
599 )
600
601 self._key_identifier = key_identifier
602 self._authority_cert_issuer = authority_cert_issuer
603 self._authority_cert_serial_number = authority_cert_serial_number
604
605 def __repr__(self):
606 return (
607 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
608 "authority_cert_issuer={0.authority_cert_issuer}, "
609 "authority_cert_serial_number={0.authority_cert_serial_number}"
610 ")>".format(self)
611 )
612
613 key_identifier = utils.read_only_property("_key_identifier")
614 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
615 authority_cert_serial_number = utils.read_only_property(
616 "_authority_cert_serial_number"
617 )
618
619
Paul Kehrer806bfb22015-02-02 17:05:24 -0600620OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
621OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
622OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
623OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
624OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
625OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
626OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
627OID_SURNAME = ObjectIdentifier("2.5.4.4")
628OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
629OID_TITLE = ObjectIdentifier("2.5.4.12")
630OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
631OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
632OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
633OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
634OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600635
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600636OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
637OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
638OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
639OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
640OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
641OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -0600642OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
643OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
644OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
645OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
646OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
647OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
648OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
649
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600650_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600651 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
652 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
653 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
654 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
655 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
656 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -0600657 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
658 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
659 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
660 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
661 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
662 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
663 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600664}
665
Paul Kehrere1513fa2015-03-30 23:08:17 -0500666OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
667OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
668OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
669OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
670OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
671OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
672
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600673
Paul Kehrerb2de9482014-12-11 14:54:48 -0600674@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600675class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600676 @abc.abstractmethod
677 def fingerprint(self, algorithm):
678 """
679 Returns bytes using digest passed.
680 """
681
682 @abc.abstractproperty
683 def serial(self):
684 """
685 Returns certificate serial number
686 """
687
688 @abc.abstractproperty
689 def version(self):
690 """
691 Returns the certificate version
692 """
693
694 @abc.abstractmethod
695 def public_key(self):
696 """
697 Returns the public key
698 """
699
700 @abc.abstractproperty
701 def not_valid_before(self):
702 """
703 Not before time (represented as UTC datetime)
704 """
705
706 @abc.abstractproperty
707 def not_valid_after(self):
708 """
709 Not after time (represented as UTC datetime)
710 """
Paul Kehrer719d5362015-01-01 20:03:52 -0600711
712 @abc.abstractproperty
713 def issuer(self):
714 """
715 Returns the issuer name object.
716 """
717
718 @abc.abstractproperty
719 def subject(self):
720 """
721 Returns the subject name object.
722 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600723
724 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600725 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600726 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600727 Returns a HashAlgorithm corresponding to the type of the digest signed
728 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600729 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600730
731
732@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500733class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600734 @abc.abstractmethod
735 def public_key(self):
736 """
737 Returns the public key
738 """
739
740 @abc.abstractproperty
741 def subject(self):
742 """
743 Returns the subject name object.
744 """
745
746 @abc.abstractproperty
747 def signature_hash_algorithm(self):
748 """
749 Returns a HashAlgorithm corresponding to the type of the digest signed
750 in the certificate.
751 """