blob: 2bbd14d77c05b666a75dab0c0782dc01f7ab1b08 [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 Kehrer3e6d5582015-05-02 21:57:56 -050070 "1.3.6.1.5.5.7.48.2": "caIssuers",
71 "1.3.6.1.5.5.7.48.1": "OCSP",
Paul Kehrer806bfb22015-02-02 17:05:24 -060072}
73
74
Paul Kehrer9089c912015-04-20 22:15:20 -050075_GENERAL_NAMES = {
76 0: "otherName",
77 1: "rfc822Name",
78 2: "dNSName",
79 3: "x400Address",
80 4: "directoryName",
81 5: "ediPartyName",
82 6: "uniformResourceIdentifier",
83 7: "iPAddress",
84 8: "registeredID",
85}
86
87
Paul Kehrere76cd272014-12-14 19:00:51 -060088class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100089 v1 = 0
90 v3 = 2
91
92
Paul Kehrer016e08a2014-11-26 09:41:18 -100093def load_pem_x509_certificate(data, backend):
94 return backend.load_pem_x509_certificate(data)
95
96
Paul Kehrer016e08a2014-11-26 09:41:18 -100097def load_der_x509_certificate(data, backend):
98 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100099
100
Paul Kehrer31e39882015-03-11 11:37:04 -0500101def load_pem_x509_csr(data, backend):
102 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600103
104
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500105def load_der_x509_csr(data, backend):
106 return backend.load_der_x509_csr(data)
107
108
Paul Kehrere76cd272014-12-14 19:00:51 -0600109class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600110 def __init__(self, msg, parsed_version):
111 super(InvalidVersion, self).__init__(msg)
112 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -0600113
114
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500115class DuplicateExtension(Exception):
116 def __init__(self, msg, oid):
117 super(DuplicateExtension, self).__init__(msg)
118 self.oid = oid
119
120
121class UnsupportedExtension(Exception):
122 def __init__(self, msg, oid):
123 super(UnsupportedExtension, self).__init__(msg)
124 self.oid = oid
125
126
Paul Kehrerfa56a232015-03-17 13:14:03 -0500127class ExtensionNotFound(Exception):
128 def __init__(self, msg, oid):
129 super(ExtensionNotFound, self).__init__(msg)
130 self.oid = oid
131
132
Paul Kehrer9089c912015-04-20 22:15:20 -0500133class UnsupportedGeneralNameType(Exception):
Paul Kehrerbed07352015-04-21 08:31:10 -0500134 def __init__(self, msg, type):
135 super(UnsupportedGeneralNameType, self).__init__(msg)
136 self.type = type
Paul Kehrer9089c912015-04-20 22:15:20 -0500137
138
Paul Kehrer806bfb22015-02-02 17:05:24 -0600139class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600140 def __init__(self, oid, value):
141 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600142 raise TypeError(
143 "oid argument must be an ObjectIdentifier instance."
144 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600145
146 self._oid = oid
147 self._value = value
148
149 oid = utils.read_only_property("_oid")
150 value = utils.read_only_property("_value")
151
152 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600153 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600154 return NotImplemented
155
156 return (
157 self.oid == other.oid and
158 self.value == other.value
159 )
160
161 def __ne__(self, other):
162 return not self == other
163
Paul Kehrera498be82015-02-12 15:00:56 -0600164 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400165 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600166
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600167
168class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600169 def __init__(self, dotted_string):
170 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600171
172 def __eq__(self, other):
173 if not isinstance(other, ObjectIdentifier):
174 return NotImplemented
175
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600176 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600177
178 def __ne__(self, other):
179 return not self == other
180
181 def __repr__(self):
182 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600183 self._dotted_string,
184 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600185 )
186
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500187 def __hash__(self):
188 return hash(self.dotted_string)
189
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600190 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600191
192
Paul Kehrer719d5362015-01-01 20:03:52 -0600193class Name(object):
194 def __init__(self, attributes):
195 self._attributes = attributes
196
Paul Kehrere901d642015-02-11 18:50:58 -0600197 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800198 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600199
Paul Kehrer719d5362015-01-01 20:03:52 -0600200 def __eq__(self, other):
201 if not isinstance(other, Name):
202 return NotImplemented
203
Paul Kehrer53d8d492015-02-13 18:47:30 -0600204 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600205
206 def __ne__(self, other):
207 return not self == other
208
Paul Kehrer53d8d492015-02-13 18:47:30 -0600209 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600210 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600211
212 def __len__(self):
213 return len(self._attributes)
214
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400215 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400216 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400217
Paul Kehrer719d5362015-01-01 20:03:52 -0600218
Paul Kehrerd08b5492015-04-04 15:19:16 -0500219OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
220OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500221OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500222OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
223OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500224OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500225OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
226OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
227OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
228OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
229OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
230OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
231OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
232OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
233OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
234OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
235OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
236OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500237
238
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500239class Extensions(object):
240 def __init__(self, extensions):
241 self._extensions = extensions
242
Paul Kehrerfa56a232015-03-17 13:14:03 -0500243 def get_extension_for_oid(self, oid):
244 for ext in self:
245 if ext.oid == oid:
246 return ext
247
248 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
249
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500250 def __iter__(self):
251 return iter(self._extensions)
252
253 def __len__(self):
254 return len(self._extensions)
255
256
Paul Kehrer8cf26422015-03-21 09:50:24 -0500257class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500258 def __init__(self, oid, critical, value):
259 if not isinstance(oid, ObjectIdentifier):
260 raise TypeError(
261 "oid argument must be an ObjectIdentifier instance."
262 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500263
264 if not isinstance(critical, bool):
265 raise TypeError("critical must be a boolean value")
266
Paul Kehrer85894662015-03-22 13:19:31 -0500267 self._oid = oid
268 self._critical = critical
269 self._value = value
270
271 oid = utils.read_only_property("_oid")
272 critical = utils.read_only_property("_critical")
273 value = utils.read_only_property("_value")
274
275 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500276 return ("<Extension(oid={0.oid}, critical={0.critical}, "
277 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500278
279
Paul Kehrerffa2a152015-03-31 08:18:25 -0500280class ExtendedKeyUsage(object):
281 def __init__(self, usages):
Paul Kehrerb0476172015-05-02 19:34:51 -0500282 if not all(isinstance(x, ObjectIdentifier) for x in usages):
283 raise TypeError(
284 "Every item in the usages list must be an ObjectIdentifier"
285 )
Paul Kehrerffa2a152015-03-31 08:18:25 -0500286
287 self._usages = usages
288
289 def __iter__(self):
290 return iter(self._usages)
291
292 def __len__(self):
293 return len(self._usages)
294
Paul Kehrer23d10c32015-04-02 23:12:32 -0500295 def __repr__(self):
296 return "<ExtendedKeyUsage({0})>".format(self._usages)
297
Paul Kehrerb0476172015-05-02 19:34:51 -0500298 def __eq__(self, other):
299 if not isinstance(other, ExtendedKeyUsage):
300 return NotImplemented
301
Paul Kehrerf24bad72015-05-02 19:36:20 -0500302 return self._usages == other._usages
Paul Kehrerb0476172015-05-02 19:34:51 -0500303
304 def __ne__(self, other):
305 return not self == other
306
Paul Kehrerffa2a152015-03-31 08:18:25 -0500307
Paul Kehrer85894662015-03-22 13:19:31 -0500308class BasicConstraints(object):
309 def __init__(self, ca, path_length):
310 if not isinstance(ca, bool):
311 raise TypeError("ca must be a boolean value")
312
Paul Kehrer611d3d32015-03-22 13:31:18 -0500313 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500314 raise ValueError("path_length must be None when ca is False")
315
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500316 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500317 path_length is not None and
318 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500319 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500320 raise TypeError(
321 "path_length must be a non-negative integer or None"
322 )
323
324 self._ca = ca
325 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500326
327 ca = utils.read_only_property("_ca")
328 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500329
330 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500331 return ("<BasicConstraints(ca={0.ca}, "
332 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500333
334
Paul Kehrercecbbba2015-03-30 14:58:38 -0500335class KeyUsage(object):
336 def __init__(self, digital_signature, content_commitment, key_encipherment,
337 data_encipherment, key_agreement, key_cert_sign, crl_sign,
338 encipher_only, decipher_only):
339 if not key_agreement and (encipher_only or decipher_only):
340 raise ValueError(
341 "encipher_only and decipher_only can only be true when "
342 "key_agreement is true"
343 )
344
345 self._digital_signature = digital_signature
346 self._content_commitment = content_commitment
347 self._key_encipherment = key_encipherment
348 self._data_encipherment = data_encipherment
349 self._key_agreement = key_agreement
350 self._key_cert_sign = key_cert_sign
351 self._crl_sign = crl_sign
352 self._encipher_only = encipher_only
353 self._decipher_only = decipher_only
354
355 digital_signature = utils.read_only_property("_digital_signature")
356 content_commitment = utils.read_only_property("_content_commitment")
357 key_encipherment = utils.read_only_property("_key_encipherment")
358 data_encipherment = utils.read_only_property("_data_encipherment")
359 key_agreement = utils.read_only_property("_key_agreement")
360 key_cert_sign = utils.read_only_property("_key_cert_sign")
361 crl_sign = utils.read_only_property("_crl_sign")
362
363 @property
364 def encipher_only(self):
365 if not self.key_agreement:
366 raise ValueError(
367 "encipher_only is undefined unless key_agreement is true"
368 )
369 else:
370 return self._encipher_only
371
372 @property
373 def decipher_only(self):
374 if not self.key_agreement:
375 raise ValueError(
376 "decipher_only is undefined unless key_agreement is true"
377 )
378 else:
379 return self._decipher_only
380
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500381 def __repr__(self):
382 try:
383 encipher_only = self.encipher_only
384 decipher_only = self.decipher_only
385 except ValueError:
Paul Kehrerb372e672015-04-15 11:05:24 -0400386 encipher_only = None
387 decipher_only = None
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500388
389 return ("<KeyUsage(digital_signature={0.digital_signature}, "
390 "content_commitment={0.content_commitment}, "
391 "key_encipherment={0.key_encipherment}, "
392 "data_encipherment={0.data_encipherment}, "
393 "key_agreement={0.key_agreement}, "
394 "key_cert_sign={0.key_cert_sign}, crl_sign={0.crl_sign}, "
395 "encipher_only={1}, decipher_only={2})>").format(
396 self, encipher_only, decipher_only)
397
Paul Kehrercecbbba2015-03-30 14:58:38 -0500398
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500399class AuthorityInformationAccess(object):
400 def __init__(self, descriptions):
401 if not all(isinstance(x, AccessDescription) for x in descriptions):
402 raise TypeError(
403 "Every item in the descriptions list must be an "
404 "AccessDescription"
405 )
406
407 self._descriptions = descriptions
408
409 def __iter__(self):
410 return iter(self._descriptions)
411
412 def __len__(self):
413 return len(self._descriptions)
414
415 def __repr__(self):
416 return "<AuthorityInformationAccess({0})>".format(self._descriptions)
417
418 def __eq__(self, other):
419 if not isinstance(other, AuthorityInformationAccess):
420 return NotImplemented
421
422 return self._descriptions == other._descriptions
423
424 def __ne__(self, other):
425 return not self == other
426
427
428class AccessDescription(object):
429 def __init__(self, access_method, access_location):
430 if not (access_method == OID_OCSP or access_method == OID_CA_ISSUERS):
431 raise TypeError("access_method must be OID_OCSP or OID_CA_ISSUERS")
432
433 if not isinstance(access_location, GeneralName):
434 raise TypeError("access_location must be a GeneralName")
435
436 self._access_method = access_method
437 self._access_location = access_location
438
439 def __repr__(self):
440 return (
441 "<AccessDescription(access_method={0.access_method}, access_locati"
442 "on={0.access_location})>".format(self)
443 )
444
445 def __eq__(self, other):
446 if not isinstance(other, AccessDescription):
447 return NotImplemented
448
449 return (
450 self.access_method == other.access_method and
451 self.access_location == other.access_location
452 )
453
454 def __ne__(self, other):
455 return not self == other
456
457 access_method = utils.read_only_property("_access_method")
458 access_location = utils.read_only_property("_access_location")
459
460
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500461class SubjectKeyIdentifier(object):
462 def __init__(self, digest):
463 self._digest = digest
464
465 digest = utils.read_only_property("_digest")
466
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500467 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400468 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500469
470 def __eq__(self, other):
471 if not isinstance(other, SubjectKeyIdentifier):
472 return NotImplemented
473
474 return (
475 self.digest == other.digest
476 )
477
478 def __ne__(self, other):
479 return not self == other
480
481
Paul Kehrer31bdf792015-03-25 14:11:00 -0500482@six.add_metaclass(abc.ABCMeta)
483class GeneralName(object):
484 @abc.abstractproperty
485 def value(self):
486 """
487 Return the value of the object
488 """
489
490
491@utils.register_interface(GeneralName)
492class RFC822Name(object):
493 def __init__(self, value):
494 if not isinstance(value, six.text_type):
495 raise TypeError("value must be a unicode string")
496
497 self._value = value
498
499 value = utils.read_only_property("_value")
500
501 def __repr__(self):
502 return "<RFC822Name(value={0})>".format(self.value)
503
504 def __eq__(self, other):
505 if not isinstance(other, RFC822Name):
506 return NotImplemented
507
508 return self.value == other.value
509
510 def __ne__(self, other):
511 return not self == other
512
513
514@utils.register_interface(GeneralName)
515class DNSName(object):
516 def __init__(self, value):
517 if not isinstance(value, six.text_type):
518 raise TypeError("value must be a unicode string")
519
520 self._value = value
521
522 value = utils.read_only_property("_value")
523
524 def __repr__(self):
525 return "<DNSName(value={0})>".format(self.value)
526
527 def __eq__(self, other):
528 if not isinstance(other, DNSName):
529 return NotImplemented
530
531 return self.value == other.value
532
533 def __ne__(self, other):
534 return not self == other
535
536
537@utils.register_interface(GeneralName)
538class UniformResourceIdentifier(object):
539 def __init__(self, value):
540 if not isinstance(value, six.text_type):
541 raise TypeError("value must be a unicode string")
542
543 self._value = value
544
545 value = utils.read_only_property("_value")
546
547 def __repr__(self):
548 return "<UniformResourceIdentifier(value={0})>".format(self.value)
549
550 def __eq__(self, other):
551 if not isinstance(other, UniformResourceIdentifier):
552 return NotImplemented
553
554 return self.value == other.value
555
556 def __ne__(self, other):
557 return not self == other
558
559
560@utils.register_interface(GeneralName)
561class DirectoryName(object):
562 def __init__(self, value):
563 if not isinstance(value, Name):
564 raise TypeError("value must be a Name")
565
566 self._value = value
567
568 value = utils.read_only_property("_value")
569
570 def __repr__(self):
571 return "<DirectoryName(value={0})>".format(self.value)
572
573 def __eq__(self, other):
574 if not isinstance(other, DirectoryName):
575 return NotImplemented
576
577 return self.value == other.value
578
579 def __ne__(self, other):
580 return not self == other
581
582
583@utils.register_interface(GeneralName)
584class RegisteredID(object):
585 def __init__(self, value):
586 if not isinstance(value, ObjectIdentifier):
587 raise TypeError("value must be an ObjectIdentifier")
588
589 self._value = value
590
591 value = utils.read_only_property("_value")
592
593 def __repr__(self):
594 return "<RegisteredID(value={0})>".format(self.value)
595
596 def __eq__(self, other):
597 if not isinstance(other, RegisteredID):
598 return NotImplemented
599
600 return self.value == other.value
601
602 def __ne__(self, other):
603 return not self == other
604
605
606@utils.register_interface(GeneralName)
607class IPAddress(object):
608 def __init__(self, value):
609 if not isinstance(
610 value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
611 ):
612 raise TypeError(
613 "value must be an instance of ipaddress.IPv4Address or "
614 "ipaddress.IPv6Address"
615 )
616
617 self._value = value
618
619 value = utils.read_only_property("_value")
620
621 def __repr__(self):
622 return "<IPAddress(value={0})>".format(self.value)
623
624 def __eq__(self, other):
625 if not isinstance(other, IPAddress):
626 return NotImplemented
627
628 return self.value == other.value
629
630 def __ne__(self, other):
631 return not self == other
632
633
634class SubjectAlternativeName(object):
635 def __init__(self, general_names):
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500636 if not all(isinstance(x, GeneralName) for x in general_names):
637 raise TypeError(
638 "Every item in the general_names list must be an "
639 "object conforming to the GeneralName interface"
640 )
641
Paul Kehrer31bdf792015-03-25 14:11:00 -0500642 self._general_names = general_names
643
644 def __iter__(self):
645 return iter(self._general_names)
646
647 def __len__(self):
648 return len(self._general_names)
649
650 def get_values_for_type(self, type):
651 return [i.value for i in self if isinstance(i, type)]
652
653 def __repr__(self):
654 return "<SubjectAlternativeName({0})>".format(self._general_names)
655
656
Paul Kehrer2eb4ed92015-04-11 15:33:45 -0400657class AuthorityKeyIdentifier(object):
658 def __init__(self, key_identifier, authority_cert_issuer,
659 authority_cert_serial_number):
660 if authority_cert_issuer or authority_cert_serial_number:
661 if not authority_cert_issuer or not authority_cert_serial_number:
662 raise ValueError(
663 "authority_cert_issuer and authority_cert_serial_number "
664 "must both be present or both None"
665 )
666
667 if not isinstance(authority_cert_issuer, Name):
668 raise TypeError("authority_cert_issuer must be a Name")
669
670 if not isinstance(authority_cert_serial_number, six.integer_types):
671 raise TypeError(
672 "authority_cert_serial_number must be an integer"
673 )
674
675 self._key_identifier = key_identifier
676 self._authority_cert_issuer = authority_cert_issuer
677 self._authority_cert_serial_number = authority_cert_serial_number
678
679 def __repr__(self):
680 return (
681 "<AuthorityKeyIdentifier(key_identifier={0.key_identifier!r}, "
682 "authority_cert_issuer={0.authority_cert_issuer}, "
683 "authority_cert_serial_number={0.authority_cert_serial_number}"
684 ")>".format(self)
685 )
686
687 key_identifier = utils.read_only_property("_key_identifier")
688 authority_cert_issuer = utils.read_only_property("_authority_cert_issuer")
689 authority_cert_serial_number = utils.read_only_property(
690 "_authority_cert_serial_number"
691 )
692
693
Paul Kehrer806bfb22015-02-02 17:05:24 -0600694OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
695OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
696OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
697OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
698OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
699OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
700OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
701OID_SURNAME = ObjectIdentifier("2.5.4.4")
702OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
703OID_TITLE = ObjectIdentifier("2.5.4.12")
704OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
705OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
706OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
707OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
708OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600709
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600710OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
711OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
712OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
713OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
714OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
715OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -0600716OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
717OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
718OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
719OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
720OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
721OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
722OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
723
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600724_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600725 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
726 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
727 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
728 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
729 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
730 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -0600731 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
732 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
733 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
734 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
735 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
736 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
737 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600738}
739
Paul Kehrere1513fa2015-03-30 23:08:17 -0500740OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
741OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
742OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
743OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
744OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
745OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
746
Paul Kehrer3e6d5582015-05-02 21:57:56 -0500747OID_CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2")
748OID_OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1")
749
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600750
Paul Kehrerb2de9482014-12-11 14:54:48 -0600751@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600752class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600753 @abc.abstractmethod
754 def fingerprint(self, algorithm):
755 """
756 Returns bytes using digest passed.
757 """
758
759 @abc.abstractproperty
760 def serial(self):
761 """
762 Returns certificate serial number
763 """
764
765 @abc.abstractproperty
766 def version(self):
767 """
768 Returns the certificate version
769 """
770
771 @abc.abstractmethod
772 def public_key(self):
773 """
774 Returns the public key
775 """
776
777 @abc.abstractproperty
778 def not_valid_before(self):
779 """
780 Not before time (represented as UTC datetime)
781 """
782
783 @abc.abstractproperty
784 def not_valid_after(self):
785 """
786 Not after time (represented as UTC datetime)
787 """
Paul Kehrer719d5362015-01-01 20:03:52 -0600788
789 @abc.abstractproperty
790 def issuer(self):
791 """
792 Returns the issuer name object.
793 """
794
795 @abc.abstractproperty
796 def subject(self):
797 """
798 Returns the subject name object.
799 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600800
801 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600802 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600803 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600804 Returns a HashAlgorithm corresponding to the type of the digest signed
805 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600806 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600807
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500808 @abc.abstractmethod
809 def __eq__(self, other):
810 """
811 Checks equality.
812 """
813
814 @abc.abstractmethod
815 def __ne__(self, other):
816 """
817 Checks not equal.
818 """
819
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600820
821@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500822class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600823 @abc.abstractmethod
824 def public_key(self):
825 """
826 Returns the public key
827 """
828
829 @abc.abstractproperty
830 def subject(self):
831 """
832 Returns the subject name object.
833 """
834
835 @abc.abstractproperty
836 def signature_hash_algorithm(self):
837 """
838 Returns a HashAlgorithm corresponding to the type of the digest signed
839 in the certificate.
840 """