blob: 8554aeab56c9d682b0a580e9912619047bd789cd [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 Kehrer016e08a2014-11-26 09:41:18 -10008from enum import Enum
9
Paul Kehrerb2de9482014-12-11 14:54:48 -060010import six
11
Paul Kehrer912d3fb2015-01-29 11:19:22 -060012from cryptography import utils
Paul Kehrer8802a5b2015-02-13 12:06:57 -060013from cryptography.hazmat.primitives import hashes
Paul Kehrer912d3fb2015-01-29 11:19:22 -060014
Paul Kehrer016e08a2014-11-26 09:41:18 -100015
Paul Kehrer806bfb22015-02-02 17:05:24 -060016_OID_NAMES = {
17 "2.5.4.3": "commonName",
18 "2.5.4.6": "countryName",
19 "2.5.4.7": "localityName",
20 "2.5.4.8": "stateOrProvinceName",
21 "2.5.4.10": "organizationName",
22 "2.5.4.11": "organizationalUnitName",
23 "2.5.4.5": "serialNumber",
24 "2.5.4.4": "surname",
25 "2.5.4.42": "givenName",
26 "2.5.4.12": "title",
27 "2.5.4.44": "generationQualifier",
28 "2.5.4.46": "dnQualifier",
29 "2.5.4.65": "pseudonym",
30 "0.9.2342.19200300.100.1.25": "domainComponent",
31 "1.2.840.113549.1.9.1": "emailAddress",
Paul Kehrer71d40c62015-02-19 08:21:04 -060032 "1.2.840.113549.1.1.4": "md5WithRSAEncryption",
33 "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
Paul Kehrer56da2a52015-02-11 23:35:07 -060034 "1.2.840.113549.1.1.14": "sha224WithRSAEncryption",
35 "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
36 "1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
37 "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
Paul Kehrer71d40c62015-02-19 08:21:04 -060038 "1.2.840.10045.4.3.1": "ecdsa-with-SHA224",
39 "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
40 "1.2.840.10045.4.3.3": "ecdsa-with-SHA384",
41 "1.2.840.10045.4.3.4": "ecdsa-with-SHA512",
42 "1.2.840.10040.4.3": "dsa-with-sha1",
43 "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
44 "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
Paul Kehrere1513fa2015-03-30 23:08:17 -050045 "1.3.6.1.5.5.7.3.1": "serverAuth",
46 "1.3.6.1.5.5.7.3.2": "clientAuth",
47 "1.3.6.1.5.5.7.3.3": "codeSigning",
48 "1.3.6.1.5.5.7.3.4": "emailProtection",
49 "1.3.6.1.5.5.7.3.8": "timeStamping",
50 "1.3.6.1.5.5.7.3.9": "OCSPSigning",
Paul Kehrerd08b5492015-04-04 15:19:16 -050051 "2.5.29.9": "subjectDirectoryAttributes",
52 "2.5.29.14": "subjectKeyIdentifier",
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050053 "2.5.29.15": "keyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050054 "2.5.29.17": "subjectAltName",
55 "2.5.29.18": "issuerAltName",
56 "2.5.29.19": "basicConstraints",
57 "2.5.29.30": "nameConstraints",
58 "2.5.29.31": "cRLDistributionPoints",
59 "2.5.29.32": "certificatePolicies",
60 "2.5.29.33": "policyMappings",
61 "2.5.29.35": "authorityKeyIdentifier",
62 "2.5.29.36": "policyConstraints",
Paul Kehrere1513fa2015-03-30 23:08:17 -050063 "2.5.29.37": "extendedKeyUsage",
Paul Kehrerd08b5492015-04-04 15:19:16 -050064 "2.5.29.46": "freshestCRL",
65 "2.5.29.54": "inhibitAnyPolicy",
66 "1.3.6.1.5.5.7.1.1": "authorityInfoAccess",
67 "1.3.6.1.5.5.7.1.11": "subjectInfoAccess",
68 "1.3.6.1.5.5.7.48.1.5": "OCSPNoCheck",
Paul Kehrer806bfb22015-02-02 17:05:24 -060069}
70
71
Paul Kehrere76cd272014-12-14 19:00:51 -060072class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100073 v1 = 0
74 v3 = 2
75
76
Paul Kehrer016e08a2014-11-26 09:41:18 -100077def load_pem_x509_certificate(data, backend):
78 return backend.load_pem_x509_certificate(data)
79
80
Paul Kehrer016e08a2014-11-26 09:41:18 -100081def load_der_x509_certificate(data, backend):
82 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100083
84
Paul Kehrer31e39882015-03-11 11:37:04 -050085def load_pem_x509_csr(data, backend):
86 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -060087
88
Paul Kehrer1effb6e2015-03-30 15:05:59 -050089def load_der_x509_csr(data, backend):
90 return backend.load_der_x509_csr(data)
91
92
Paul Kehrere76cd272014-12-14 19:00:51 -060093class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -060094 def __init__(self, msg, parsed_version):
95 super(InvalidVersion, self).__init__(msg)
96 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -060097
98
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050099class DuplicateExtension(Exception):
100 def __init__(self, msg, oid):
101 super(DuplicateExtension, self).__init__(msg)
102 self.oid = oid
103
104
105class UnsupportedExtension(Exception):
106 def __init__(self, msg, oid):
107 super(UnsupportedExtension, self).__init__(msg)
108 self.oid = oid
109
110
Paul Kehrerfa56a232015-03-17 13:14:03 -0500111class ExtensionNotFound(Exception):
112 def __init__(self, msg, oid):
113 super(ExtensionNotFound, self).__init__(msg)
114 self.oid = oid
115
116
Paul Kehrer806bfb22015-02-02 17:05:24 -0600117class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600118 def __init__(self, oid, value):
119 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -0600120 raise TypeError(
121 "oid argument must be an ObjectIdentifier instance."
122 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600123
124 self._oid = oid
125 self._value = value
126
127 oid = utils.read_only_property("_oid")
128 value = utils.read_only_property("_value")
129
130 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -0600131 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600132 return NotImplemented
133
134 return (
135 self.oid == other.oid and
136 self.value == other.value
137 )
138
139 def __ne__(self, other):
140 return not self == other
141
Paul Kehrera498be82015-02-12 15:00:56 -0600142 def __repr__(self):
Alex Gaynord6b63da2015-03-23 00:25:44 -0400143 return "<NameAttribute(oid={0.oid}, value={0.value!r})>".format(self)
Paul Kehrera498be82015-02-12 15:00:56 -0600144
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600145
146class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600147 def __init__(self, dotted_string):
148 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600149
150 def __eq__(self, other):
151 if not isinstance(other, ObjectIdentifier):
152 return NotImplemented
153
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600154 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600155
156 def __ne__(self, other):
157 return not self == other
158
159 def __repr__(self):
160 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600161 self._dotted_string,
162 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600163 )
164
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500165 def __hash__(self):
166 return hash(self.dotted_string)
167
Paul Kehrerd44f9a62015-02-04 14:47:34 -0600168 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600169
170
Paul Kehrer719d5362015-01-01 20:03:52 -0600171class Name(object):
172 def __init__(self, attributes):
173 self._attributes = attributes
174
Paul Kehrere901d642015-02-11 18:50:58 -0600175 def get_attributes_for_oid(self, oid):
Alex Gaynorf9574232015-02-19 13:56:50 -0800176 return [i for i in self if i.oid == oid]
Paul Kehrer719d5362015-01-01 20:03:52 -0600177
Paul Kehrer719d5362015-01-01 20:03:52 -0600178 def __eq__(self, other):
179 if not isinstance(other, Name):
180 return NotImplemented
181
Paul Kehrer53d8d492015-02-13 18:47:30 -0600182 return self._attributes == other._attributes
Paul Kehrer719d5362015-01-01 20:03:52 -0600183
184 def __ne__(self, other):
185 return not self == other
186
Paul Kehrer53d8d492015-02-13 18:47:30 -0600187 def __iter__(self):
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600188 return iter(self._attributes)
Paul Kehrer53d8d492015-02-13 18:47:30 -0600189
190 def __len__(self):
191 return len(self._attributes)
192
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400193 def __repr__(self):
Paul Kehrerf4ed10a2015-04-11 15:53:12 -0400194 return "<Name({0!r})>".format(self._attributes)
Paul Kehrer1fb35c92015-04-11 15:42:54 -0400195
Paul Kehrer719d5362015-01-01 20:03:52 -0600196
Paul Kehrerd08b5492015-04-04 15:19:16 -0500197OID_SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9")
198OID_SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14")
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500199OID_KEY_USAGE = ObjectIdentifier("2.5.29.15")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500200OID_SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17")
201OID_ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500202OID_BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19")
Paul Kehrerd08b5492015-04-04 15:19:16 -0500203OID_NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30")
204OID_CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31")
205OID_CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32")
206OID_POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33")
207OID_AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35")
208OID_POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36")
209OID_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37")
210OID_FRESHEST_CRL = ObjectIdentifier("2.5.29.46")
211OID_INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54")
212OID_AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1")
213OID_SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11")
214OID_OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500215
216
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500217class Extensions(object):
218 def __init__(self, extensions):
219 self._extensions = extensions
220
Paul Kehrerfa56a232015-03-17 13:14:03 -0500221 def get_extension_for_oid(self, oid):
222 for ext in self:
223 if ext.oid == oid:
224 return ext
225
226 raise ExtensionNotFound("No {0} extension was found".format(oid), oid)
227
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500228 def __iter__(self):
229 return iter(self._extensions)
230
231 def __len__(self):
232 return len(self._extensions)
233
234
Paul Kehrer8cf26422015-03-21 09:50:24 -0500235class Extension(object):
Paul Kehrer85894662015-03-22 13:19:31 -0500236 def __init__(self, oid, critical, value):
237 if not isinstance(oid, ObjectIdentifier):
238 raise TypeError(
239 "oid argument must be an ObjectIdentifier instance."
240 )
Paul Kehrer8cf26422015-03-21 09:50:24 -0500241
242 if not isinstance(critical, bool):
243 raise TypeError("critical must be a boolean value")
244
Paul Kehrer85894662015-03-22 13:19:31 -0500245 self._oid = oid
246 self._critical = critical
247 self._value = value
248
249 oid = utils.read_only_property("_oid")
250 critical = utils.read_only_property("_critical")
251 value = utils.read_only_property("_value")
252
253 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500254 return ("<Extension(oid={0.oid}, critical={0.critical}, "
255 "value={0.value})>").format(self)
Paul Kehrer85894662015-03-22 13:19:31 -0500256
257
Paul Kehrerffa2a152015-03-31 08:18:25 -0500258class ExtendedKeyUsage(object):
259 def __init__(self, usages):
260 for oid in usages:
261 if not isinstance(oid, ObjectIdentifier):
262 raise TypeError(
263 "Every item in the usages list must be an ObjectIdentifier"
264 )
265
266 self._usages = usages
267
268 def __iter__(self):
269 return iter(self._usages)
270
271 def __len__(self):
272 return len(self._usages)
273
Paul Kehrer23d10c32015-04-02 23:12:32 -0500274 def __repr__(self):
275 return "<ExtendedKeyUsage({0})>".format(self._usages)
276
Paul Kehrerffa2a152015-03-31 08:18:25 -0500277
Paul Kehrer85894662015-03-22 13:19:31 -0500278class BasicConstraints(object):
279 def __init__(self, ca, path_length):
280 if not isinstance(ca, bool):
281 raise TypeError("ca must be a boolean value")
282
Paul Kehrer611d3d32015-03-22 13:31:18 -0500283 if path_length is not None and not ca:
Paul Kehrer8cf26422015-03-21 09:50:24 -0500284 raise ValueError("path_length must be None when ca is False")
285
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500286 if (
Paul Kehrer5553d572015-03-23 21:08:01 -0500287 path_length is not None and
288 (not isinstance(path_length, six.integer_types) or path_length < 0)
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500289 ):
Paul Kehrer8cf26422015-03-21 09:50:24 -0500290 raise TypeError(
291 "path_length must be a non-negative integer or None"
292 )
293
294 self._ca = ca
295 self._path_length = path_length
Paul Kehrer8cf26422015-03-21 09:50:24 -0500296
297 ca = utils.read_only_property("_ca")
298 path_length = utils.read_only_property("_path_length")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500299
300 def __repr__(self):
Paul Kehrer58b75692015-03-22 23:24:58 -0500301 return ("<BasicConstraints(ca={0.ca}, "
302 "path_length={0.path_length})>").format(self)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500303
304
Paul Kehrercecbbba2015-03-30 14:58:38 -0500305class KeyUsage(object):
306 def __init__(self, digital_signature, content_commitment, key_encipherment,
307 data_encipherment, key_agreement, key_cert_sign, crl_sign,
308 encipher_only, decipher_only):
309 if not key_agreement and (encipher_only or decipher_only):
310 raise ValueError(
311 "encipher_only and decipher_only can only be true when "
312 "key_agreement is true"
313 )
314
315 self._digital_signature = digital_signature
316 self._content_commitment = content_commitment
317 self._key_encipherment = key_encipherment
318 self._data_encipherment = data_encipherment
319 self._key_agreement = key_agreement
320 self._key_cert_sign = key_cert_sign
321 self._crl_sign = crl_sign
322 self._encipher_only = encipher_only
323 self._decipher_only = decipher_only
324
325 digital_signature = utils.read_only_property("_digital_signature")
326 content_commitment = utils.read_only_property("_content_commitment")
327 key_encipherment = utils.read_only_property("_key_encipherment")
328 data_encipherment = utils.read_only_property("_data_encipherment")
329 key_agreement = utils.read_only_property("_key_agreement")
330 key_cert_sign = utils.read_only_property("_key_cert_sign")
331 crl_sign = utils.read_only_property("_crl_sign")
332
333 @property
334 def encipher_only(self):
335 if not self.key_agreement:
336 raise ValueError(
337 "encipher_only is undefined unless key_agreement is true"
338 )
339 else:
340 return self._encipher_only
341
342 @property
343 def decipher_only(self):
344 if not self.key_agreement:
345 raise ValueError(
346 "decipher_only is undefined unless key_agreement is true"
347 )
348 else:
349 return self._decipher_only
350
351
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500352class SubjectKeyIdentifier(object):
353 def __init__(self, digest):
354 self._digest = digest
355
356 digest = utils.read_only_property("_digest")
357
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500358 def __repr__(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400359 return "<SubjectKeyIdentifier(digest={0!r})>".format(self.digest)
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500360
361 def __eq__(self, other):
362 if not isinstance(other, SubjectKeyIdentifier):
363 return NotImplemented
364
365 return (
366 self.digest == other.digest
367 )
368
369 def __ne__(self, other):
370 return not self == other
371
372
Paul Kehrer806bfb22015-02-02 17:05:24 -0600373OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
374OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
375OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
376OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
377OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
378OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
379OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
380OID_SURNAME = ObjectIdentifier("2.5.4.4")
381OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
382OID_TITLE = ObjectIdentifier("2.5.4.12")
383OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
384OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
385OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
386OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
387OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600388
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600389OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
390OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
391OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
392OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
393OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
394OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
Paul Kehrer56da2a52015-02-11 23:35:07 -0600395OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
396OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
397OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
398OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
399OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
400OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
401OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
402
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600403_SIG_OIDS_TO_HASH = {
Paul Kehrer1a7ba872015-02-19 18:09:05 -0600404 OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
405 OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
406 OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
407 OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
408 OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
409 OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
Paul Kehrer42a87cb2015-02-13 18:53:24 -0600410 OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
411 OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
412 OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
413 OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
414 OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
415 OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
416 OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600417}
418
Paul Kehrere1513fa2015-03-30 23:08:17 -0500419OID_SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1")
420OID_CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2")
421OID_CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3")
422OID_EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4")
423OID_TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8")
424OID_OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9")
425
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600426
Paul Kehrerb2de9482014-12-11 14:54:48 -0600427@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600428class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600429 @abc.abstractmethod
430 def fingerprint(self, algorithm):
431 """
432 Returns bytes using digest passed.
433 """
434
435 @abc.abstractproperty
436 def serial(self):
437 """
438 Returns certificate serial number
439 """
440
441 @abc.abstractproperty
442 def version(self):
443 """
444 Returns the certificate version
445 """
446
447 @abc.abstractmethod
448 def public_key(self):
449 """
450 Returns the public key
451 """
452
453 @abc.abstractproperty
454 def not_valid_before(self):
455 """
456 Not before time (represented as UTC datetime)
457 """
458
459 @abc.abstractproperty
460 def not_valid_after(self):
461 """
462 Not after time (represented as UTC datetime)
463 """
Paul Kehrer719d5362015-01-01 20:03:52 -0600464
465 @abc.abstractproperty
466 def issuer(self):
467 """
468 Returns the issuer name object.
469 """
470
471 @abc.abstractproperty
472 def subject(self):
473 """
474 Returns the subject name object.
475 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600476
477 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600478 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600479 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600480 Returns a HashAlgorithm corresponding to the type of the digest signed
481 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600482 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600483
484
485@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500486class CertificateSigningRequest(object):
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600487 @abc.abstractmethod
488 def public_key(self):
489 """
490 Returns the public key
491 """
492
493 @abc.abstractproperty
494 def subject(self):
495 """
496 Returns the subject name object.
497 """
498
499 @abc.abstractproperty
500 def signature_hash_algorithm(self):
501 """
502 Returns a HashAlgorithm corresponding to the type of the digest signed
503 in the certificate.
504 """