blob: dd6ea926507cdb527ca126605dfb331cef68faf0 [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):
Paul Kehrerbed07352015-04-21 08:31:10 -0500132 def __init__(self, msg, type):
133 super(UnsupportedGeneralNameType, self).__init__(msg)
134 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500135
136
Paul Kehrer806bfb22015-02-02 17:05:24 -0600137class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600138 def __init__(self, oid, value):
139 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600140 raise TypeError(
141 "oid argument must be an ObjectIdentifier instance."
142 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600143
144 self._oid = oid
145 self._value = value
146
147 oid = utils.read_only_property("_oid")
148 value = utils.read_only_property("_value")
149
150 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600151 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600152 return NotImplemented
153
154 return (
155 self.oid == other.oid and
156 self.value == other.value
157 )
158
159 def __ne__(self, other):
160 return not self == other
161
Paul Kehrera498be82015-02-12 15:00:56 -0600162 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400163 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600164
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600165
166class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600167 def __init__(self, dotted_string):
168 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600169
170 def __eq__(self, other):
171 if not isinstance(other, ObjectIdentifier):
172 return NotImplemented
173
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600174 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600175
176 def __ne__(self, other):
177 return not self == other
178
179 def __repr__(self):
180 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600181 self._dotted_string,
182 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600183 )
184
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500185 def __hash__(self):
186 return hash(self.dotted_string)
187
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600188 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600189
190
Paul Kehrer719d5362015-01-01 20:03:52 -0600191class Name(object):
192 def __init__(self, attributes):
193 self._attributes = attributes
194
Paul Kehrere901d642015-02-11 18:50:58 -0600195 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800196 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600197
Paul Kehrer719d5362015-01-01 20:03:52 -0600198 def __eq__(self, other):
199 if not isinstance(other, Name):
200 return NotImplemented
201
Paul Kehrer53d8d492015-02-13 18:47:30 -0600202 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600203
204 def __ne__(self, other):
205 return not self == other
206
Paul Kehrer53d8d492015-02-13 18:47:30 -0600207 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600208 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600209
210 def __len__(self):
211 return len(self._attributes)
212
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400213 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400214 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400215
Paul Kehrer719d5362015-01-01 20:03:52 -0600216
Paul Kehrerd08b5492015-04-04 15:19:16 -0500217OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
218OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500219OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500220OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
221OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500222OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500223OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
224OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
225OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
226OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
227OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
228OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
229OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
230OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
231OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
232OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
233OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
234OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500235
236
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500237class Extensions(object):
238 def __init__(self, extensions):
239 self._extensions = extensions
240
Paul Kehrerfa56a232015-03-17 13:14:03 -0500241 def get_extension_for_oid(self, oid):
242 for ext in self:
243 if ext.oid == oid:
244 return ext
245
246 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
247
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500248 def __iter__(self):
249 return iter(self._extensions)
250
251 def __len__(self):
252 return len(self._extensions)
253
254
Paul Kehrer8cf26422015-03-21 09:50:24 -0500255class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500256 def __init__(self, oid, critical, value):
257 if not isinstance(oid, ObjectIdentifier):
258 raise TypeError(
259 "oid argument must be an ObjectIdentifier instance."
260 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500261
262 if not isinstance(critical, bool):
263 raise TypeError("critical must be a boolean value")
264
Paul Kehrer85894662015-03-22 13:19:31 -0500265 self._oid = oid
266 self._critical = critical
267 self._value = value
268
269 oid = utils.read_only_property("_oid")
270 critical = utils.read_only_property("_critical")
271 value = utils.read_only_property("_value")
272
273 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500274 return ("<Extension(oid={0.oid}, critical={0.critical}, "
275 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500276
277
Paul Kehrerffa2a152015-03-31 08:18:25 -0500278class ExtendedKeyUsage(object):
279 def __init__(self, usages):
280 for oid in usages:
281 if not isinstance(oid, ObjectIdentifier):
282 raise TypeError(
283 "Every item in the usages list must be an ObjectIdentifier"
284 )
285
286 self._usages = usages
287
288 def __iter__(self):
289 return iter(self._usages)
290
291 def __len__(self):
292 return len(self._usages)
293
Paul Kehrer23d10c32015-04-02 23:12:32 -0500294 def __repr__(self):
295 return "<ExtendedKeyUsage({0})>".format(self._usages)
296
Paul Kehrerffa2a152015-03-31 08:18:25 -0500297
Paul Kehrer85894662015-03-22 13:19:31 -0500298class BasicConstraints(object):
299 def __init__(self, ca, path_length):
300 if not isinstance(ca, bool):
301 raise TypeError("ca must be a boolean value")
302
Paul Kehrer611d3d32015-03-22 13:31:18 -0500303 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500304 raise ValueError("path_length must be None when ca is False")
305
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500306 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500307 path_length is not None and
308 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500309 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500310 raise TypeError(
311 "path_length must be a non-negative integer or None"
312 )
313
314 self._ca = ca
315 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500316
317 ca = utils.read_only_property("_ca")
318 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500319
320 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500321 return ("<BasicConstraints(ca={0.ca}, "
322 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500323
324
Paul Kehrercecbbba2015-03-30 14:58:38 -0500325class KeyUsage(object):
326 def __init__(self, digital_signature, content_commitment, key_encipherment,
327 data_encipherment, key_agreement, key_cert_sign, crl_sign,
328 encipher_only, decipher_only):
329 if not key_agreement and (encipher_only or decipher_only):
330 raise ValueError(
331 "encipher_only and decipher_only can only be true when "
332 "key_agreement is true"
333 )
334
335 self._digital_signature = digital_signature
336 self._content_commitment = content_commitment
337 self._key_encipherment = key_encipherment
338 self._data_encipherment = data_encipherment
339 self._key_agreement = key_agreement
340 self._key_cert_sign = key_cert_sign
341 self._crl_sign = crl_sign
342 self._encipher_only = encipher_only
343 self._decipher_only = decipher_only
344
345 digital_signature = utils.read_only_property("_digital_signature")
346 content_commitment = utils.read_only_property("_content_commitment")
347 key_encipherment = utils.read_only_property("_key_encipherment")
348 data_encipherment = utils.read_only_property("_data_encipherment")
349 key_agreement = utils.read_only_property("_key_agreement")
350 key_cert_sign = utils.read_only_property("_key_cert_sign")
351 crl_sign = utils.read_only_property("_crl_sign")
352
353 @property
354 def encipher_only(self):
355 if not self.key_agreement:
356 raise ValueError(
357 "encipher_only is undefined unless key_agreement is true"
358 )
359 else:
360 return self._encipher_only
361
362 @property
363 def decipher_only(self):
364 if not self.key_agreement:
365 raise ValueError(
366 "decipher_only is undefined unless key_agreement is true"
367 )
368 else:
369 return self._decipher_only
370
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500371 def __repr__(self):
372 try:
373 encipher_only = self.encipher_only
374 decipher_only = self.decipher_only
375 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400376 encipher_only = None
377 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500378
379 return ("<KeyUsage(digital_signature={0.digital_signature}, "
380 "content_commitment={0.content_commitment}, "
381 "key_encipherment={0.key_encipherment}, "
382 "data_encipherment={0.data_encipherment}, "
383 "key_agreement={0.key_agreement}, "
384 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
385 "encipher_only={1}, decipher_only={2})>").format(
386 self, encipher_only, decipher_only)
387
Paul Kehrercecbbba2015-03-30 14:58:38 -0500388
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500389class SubjectKeyIdentifier(object):
390 def __init__(self, digest):
391 self._digest = digest
392
393 digest = utils.read_only_property("_digest")
394
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500395 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400396 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500397
398 def __eq__(self, other):
399 if not isinstance(other, SubjectKeyIdentifier):
400 return NotImplemented
401
402 return (
403 self.digest == other.digest
404 )
405
406 def __ne__(self, other):
407 return not self == other
408
409
Paul Kehrer31bdf792015-03-25 14:11:00 -0500410@six.add_metaclass(abc.ABCMeta)
411class GeneralName(object):
412 @abc.abstractproperty
413 def value(self):
414 """
415 Return the value of the object
416 """
417
418
419@utils.register_interface(GeneralName)
420class RFC822Name(object):
421 def __init__(self, value):
422 if not isinstance(value, six.text_type):
423 raise TypeError("value must be a unicode string")
424
425 self._value = value
426
427 value = utils.read_only_property("_value")
428
429 def __repr__(self):
430 return "<RFC822Name(value={0})>".format(self.value)
431
432 def __eq__(self, other):
433 if not isinstance(other, RFC822Name):
434 return NotImplemented
435
436 return self.value == other.value
437
438 def __ne__(self, other):
439 return not self == other
440
441
442@utils.register_interface(GeneralName)
443class DNSName(object):
444 def __init__(self, value):
445 if not isinstance(value, six.text_type):
446 raise TypeError("value must be a unicode string")
447
448 self._value = value
449
450 value = utils.read_only_property("_value")
451
452 def __repr__(self):
453 return "<DNSName(value={0})>".format(self.value)
454
455 def __eq__(self, other):
456 if not isinstance(other, DNSName):
457 return NotImplemented
458
459 return self.value == other.value
460
461 def __ne__(self, other):
462 return not self == other
463
464
465@utils.register_interface(GeneralName)
466class UniformResourceIdentifier(object):
467 def __init__(self, value):
468 if not isinstance(value, six.text_type):
469 raise TypeError("value must be a unicode string")
470
471 self._value = value
472
473 value = utils.read_only_property("_value")
474
475 def __repr__(self):
476 return "<UniformResourceIdentifier(value={0})>".format(self.value)
477
478 def __eq__(self, other):
479 if not isinstance(other, UniformResourceIdentifier):
480 return NotImplemented
481
482 return self.value == other.value
483
484 def __ne__(self, other):
485 return not self == other
486
487
488@utils.register_interface(GeneralName)
489class DirectoryName(object):
490 def __init__(self, value):
491 if not isinstance(value, Name):
492 raise TypeError("value must be a Name")
493
494 self._value = value
495
496 value = utils.read_only_property("_value")
497
498 def __repr__(self):
499 return "<DirectoryName(value={0})>".format(self.value)
500
501 def __eq__(self, other):
502 if not isinstance(other, DirectoryName):
503 return NotImplemented
504
505 return self.value == other.value
506
507 def __ne__(self, other):
508 return not self == other
509
510
511@utils.register_interface(GeneralName)
512class RegisteredID(object):
513 def __init__(self, value):
514 if not isinstance(value, ObjectIdentifier):
515 raise TypeError("value must be an ObjectIdentifier")
516
517 self._value = value
518
519 value = utils.read_only_property("_value")
520
521 def __repr__(self):
522 return "<RegisteredID(value={0})>".format(self.value)
523
524 def __eq__(self, other):
525 if not isinstance(other, RegisteredID):
526 return NotImplemented
527
528 return self.value == other.value
529
530 def __ne__(self, other):
531 return not self == other
532
533
534@utils.register_interface(GeneralName)
535class IPAddress(object):
536 def __init__(self, value):
537 if not isinstance(
538 value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
539 ):
540 raise TypeError(
541 "value must be an instance of ipaddress.IPv4Address or "
542 "ipaddress.IPv6Address"
543 )
544
545 self._value = value
546
547 value = utils.read_only_property("_value")
548
549 def __repr__(self):
550 return "<IPAddress(value={0})>".format(self.value)
551
552 def __eq__(self, other):
553 if not isinstance(other, IPAddress):
554 return NotImplemented
555
556 return self.value == other.value
557
558 def __ne__(self, other):
559 return not self == other
560
561
562class SubjectAlternativeName(object):
563 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500564 if not all(isinstance(x, GeneralName) for x in general_names):
565 raise TypeError(
566 "Every item in the general_names list must be an "
567 "object conforming to the GeneralName interface"
568 )
569
Paul Kehrer31bdf792015-03-25 14:11:00 -0500570 self._general_names = general_names
571
572 def __iter__(self):
573 return iter(self._general_names)
574
575 def __len__(self):
576 return len(self._general_names)
577
578 def get_values_for_type(self, type):
579 return [i.value for i in self if isinstance(i, type)]
580
581 def __repr__(self):
582 return "<SubjectAlternativeName({0})>".format(self._general_names)
583
584
Paul Kehrer2eb4ed92015-04-11 15:33:45 -0400585class AuthorityKeyIdentifier(object):
586 def __init__(self, key_identifier, authority_cert_issuer,
587 authority_cert_serial_number):
588 if authority_cert_issuer or authority_cert_serial_number:
589 if not authority_cert_issuer or not authority_cert_serial_number:
590 raise ValueError(
591 "authority_cert_issuer and authority_cert_serial_number "
592 "must both be present or both None"
593 )
594
595 if not isinstance(authority_cert_issuer, Name):
596 raise TypeError("authority_cert_issuer must be a Name")
597
598 if not isinstance(authority_cert_serial_number, six.integer_types):
599 raise TypeError(
600 "authority_cert_serial_number must be an integer"
601 )
602
603 self._key_identifier = key_identifier
604 self._authority_cert_issuer = authority_cert_issuer
605 self._authority_cert_serial_number = authority_cert_serial_number
606
607 def __repr__(self):
608 return (
609 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
610 "authority_cert_issuer={0.authority_cert_issuer}, "
611 "authority_cert_serial_number={0.authority_cert_serial_number}"
612 ")>".format(self)
613 )
614
615 key_identifier = utils.read_only_property("_key_identifier")
616 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
617 authority_cert_serial_number = utils.read_only_property(
618 "_authority_cert_serial_number"
619 )
620
621
Paul Kehrer806bfb22015-02-02 17:05:24 -0600622OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
623OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
624OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
625OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
626OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
627OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
628OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
629OID_SURNAME = ObjectIdentifier("2.5.4.4")
630OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
631OID_TITLE = ObjectIdentifier("2.5.4.12")
632OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
633OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
634OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
635OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
636OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600637
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600638OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
639OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
640OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
641OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
642OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
643OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -0600644OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
645OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
646OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
647OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
648OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
649OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
650OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
651
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600652_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600653 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
654 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
655 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
656 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
657 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
658 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -0600659 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
660 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
661 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
662 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
663 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
664 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
665 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600666}
667
Paul Kehrere1513fa2015-03-30 23:08:17 -0500668OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
669OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
670OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
671OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
672OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
673OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
674
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600675
Paul Kehrerb2de9482014-12-11 14:54:48 -0600676@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600677class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600678 @abc.abstractmethod
679 def fingerprint(self, algorithm):
680 """
681 Returns bytes using digest passed.
682 """
683
684 @abc.abstractproperty
685 def serial(self):
686 """
687 Returns certificate serial number
688 """
689
690 @abc.abstractproperty
691 def version(self):
692 """
693 Returns the certificate version
694 """
695
696 @abc.abstractmethod
697 def public_key(self):
698 """
699 Returns the public key
700 """
701
702 @abc.abstractproperty
703 def not_valid_before(self):
704 """
705 Not before time (represented as UTC datetime)
706 """
707
708 @abc.abstractproperty
709 def not_valid_after(self):
710 """
711 Not after time (represented as UTC datetime)
712 """
Paul Kehrer719d5362015-01-01 20:03:52 -0600713
714 @abc.abstractproperty
715 def issuer(self):
716 """
717 Returns the issuer name object.
718 """
719
720 @abc.abstractproperty
721 def subject(self):
722 """
723 Returns the subject name object.
724 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600725
726 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600727 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600728 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600729 Returns a HashAlgorithm corresponding to the type of the digest signed
730 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600731 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600732
733
734@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500735class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600736 @abc.abstractmethod
737 def public_key(self):
738 """
739 Returns the public key
740 """
741
742 @abc.abstractproperty
743 def subject(self):
744 """
745 Returns the subject name object.
746 """
747
748 @abc.abstractproperty
749 def signature_hash_algorithm(self):
750 """
751 Returns a HashAlgorithm corresponding to the type of the digest signed
752 in the certificate.
753 """