blob: 9dc49a60d85ccd3a5412e983988d36c912899b35 [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
Andre Caron9bbfcea2015-05-18 20:55:29 -04008import datetime
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
Ian Cordascob3ed4842015-07-01 22:46:03 -050014from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehreraa7a3222015-08-11 00:00:54 -050015from cryptography.x509.extensions import Extension, ExtensionType
Paul Kehrered036d22015-08-09 20:40:48 -050016from cryptography.x509.name import Name
Paul Kehrer912d3fb2015-01-29 11:19:22 -060017
Paul Kehrer016e08a2014-11-26 09:41:18 -100018
Ian Cordascoc5e1c252015-07-31 23:33:35 -050019_UNIX_EPOCH = datetime.datetime(1970, 1, 1)
20
Paul Kehrer9089c912015-04-20 22:15:20 -050021
Paul Kehrere76cd272014-12-14 19:00:51 -060022class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100023 v1 = 0
24 v3 = 2
25
26
Paul Kehrer016e08a2014-11-26 09:41:18 -100027def load_pem_x509_certificate(data, backend):
28 return backend.load_pem_x509_certificate(data)
29
30
Paul Kehrer016e08a2014-11-26 09:41:18 -100031def load_der_x509_certificate(data, backend):
32 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100033
34
Paul Kehrer31e39882015-03-11 11:37:04 -050035def load_pem_x509_csr(data, backend):
36 return backend.load_pem_x509_csr(data)
Paul Kehrerdc480ad2015-02-23 12:14:54 -060037
38
Paul Kehrer1effb6e2015-03-30 15:05:59 -050039def load_der_x509_csr(data, backend):
40 return backend.load_der_x509_csr(data)
41
42
Erik Trauschkedc570402015-09-24 20:24:28 -070043def load_pem_x509_crl(data, backend):
44 return backend.load_pem_x509_crl(data)
45
46
47def load_der_x509_crl(data, backend):
48 return backend.load_der_x509_crl(data)
49
50
Paul Kehrere76cd272014-12-14 19:00:51 -060051class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -060052 def __init__(self, msg, parsed_version):
53 super(InvalidVersion, self).__init__(msg)
54 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -060055
56
57@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -060058class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -060059 @abc.abstractmethod
60 def fingerprint(self, algorithm):
61 """
62 Returns bytes using digest passed.
63 """
64
65 @abc.abstractproperty
66 def serial(self):
67 """
68 Returns certificate serial number
69 """
70
71 @abc.abstractproperty
72 def version(self):
73 """
74 Returns the certificate version
75 """
76
77 @abc.abstractmethod
78 def public_key(self):
79 """
80 Returns the public key
81 """
82
83 @abc.abstractproperty
84 def not_valid_before(self):
85 """
86 Not before time (represented as UTC datetime)
87 """
88
89 @abc.abstractproperty
90 def not_valid_after(self):
91 """
92 Not after time (represented as UTC datetime)
93 """
Paul Kehrer719d5362015-01-01 20:03:52 -060094
95 @abc.abstractproperty
96 def issuer(self):
97 """
98 Returns the issuer name object.
99 """
100
101 @abc.abstractproperty
102 def subject(self):
103 """
104 Returns the subject name object.
105 """
Paul Kehrer56da2a52015-02-11 23:35:07 -0600106
107 @abc.abstractproperty
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600108 def signature_hash_algorithm(self):
Paul Kehrer56da2a52015-02-11 23:35:07 -0600109 """
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600110 Returns a HashAlgorithm corresponding to the type of the digest signed
111 in the certificate.
Paul Kehrer56da2a52015-02-11 23:35:07 -0600112 """
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600113
Paul Kehrer8c234d12015-05-15 09:27:22 -0700114 @abc.abstractproperty
115 def extensions(self):
116 """
117 Returns an Extensions object.
118 """
119
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500120 @abc.abstractmethod
121 def __eq__(self, other):
122 """
123 Checks equality.
124 """
125
126 @abc.abstractmethod
127 def __ne__(self, other):
128 """
129 Checks not equal.
130 """
131
Andre Carona8aded62015-05-19 20:11:57 -0400132 @abc.abstractmethod
Alex Gaynor969f3a52015-07-06 18:52:41 -0400133 def __hash__(self):
134 """
135 Computes a hash.
136 """
137
138 @abc.abstractmethod
Andre Carona8aded62015-05-19 20:11:57 -0400139 def public_bytes(self, encoding):
Andre Caron18ef34b2015-05-19 21:24:31 -0400140 """
141 Serializes the certificate to PEM or DER format.
142 """
Andre Carona8aded62015-05-19 20:11:57 -0400143
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600144
145@six.add_metaclass(abc.ABCMeta)
Erik Trauschke2dcce902015-05-14 16:12:24 -0700146class CertificateRevocationList(object):
147
148 @abc.abstractmethod
149 def fingerprint(self, algorithm):
150 """
151 Returns bytes using digest passed.
152 """
153
154 @abc.abstractproperty
155 def signature_hash_algorithm(self):
156 """
157 Returns a HashAlgorithm corresponding to the type of the digest signed
158 in the certificate.
159 """
160
161 @abc.abstractproperty
162 def issuer(self):
163 """
164 Returns the X509Name with the issuer of this CRL.
165 """
166
167 @abc.abstractproperty
168 def next_update(self):
169 """
170 Returns the date of next update for this CRL.
171 """
172
173 @abc.abstractproperty
174 def last_update(self):
175 """
176 Returns the date of last update for this CRL.
177 """
178
179 @abc.abstractproperty
Erik Trauschkeabb7b6e2015-05-27 15:07:35 -0700180 def revoked_certificates(self):
Erik Trauschke2dcce902015-05-14 16:12:24 -0700181 """
182 Returns a list of RevokedCertificate objects for this CRL.
183 """
184
185 @abc.abstractproperty
186 def extensions(self):
187 """
188 Returns an Extensions object containing a list of CRL extensions.
189 """
190
191 @abc.abstractmethod
Erik Trauschke2dcce902015-05-14 16:12:24 -0700192 def __eq__(self, other):
193 """
194 Checks equality.
195 """
196
197 @abc.abstractmethod
198 def __ne__(self, other):
199 """
200 Checks not equal.
201 """
202
203
204@six.add_metaclass(abc.ABCMeta)
Paul Kehrera1a1f232015-03-15 15:34:35 -0500205class CertificateSigningRequest(object):
Alex Gaynor935f6ca2015-07-06 21:03:46 -0400206 @abc.abstractmethod
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400207 def __eq__(self, other):
208 """
209 Checks equality.
210 """
211
212 @abc.abstractmethod
213 def __ne__(self, other):
214 """
215 Checks not equal.
216 """
217
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600218 @abc.abstractmethod
Alex Gaynor978137d2015-07-08 20:59:16 -0400219 def __hash__(self):
220 """
221 Computes a hash.
222 """
223
224 @abc.abstractmethod
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600225 def public_key(self):
226 """
227 Returns the public key
228 """
229
230 @abc.abstractproperty
231 def subject(self):
232 """
233 Returns the subject name object.
234 """
235
236 @abc.abstractproperty
237 def signature_hash_algorithm(self):
238 """
239 Returns a HashAlgorithm corresponding to the type of the digest signed
240 in the certificate.
241 """
Andre Caron6e721a92015-05-17 15:08:48 -0400242
243 @abc.abstractproperty
244 def extensions(self):
245 """
246 Returns the extensions in the signing request.
247 """
Andre Caron476c5df2015-05-18 10:23:28 -0400248
249 @abc.abstractmethod
250 def public_bytes(self, encoding):
251 """
252 Encodes the request to PEM or DER format.
253 """
Erik Trauschke2dcce902015-05-14 16:12:24 -0700254
255
256@six.add_metaclass(abc.ABCMeta)
257class RevokedCertificate(object):
258 @abc.abstractproperty
259 def serial_number(self):
260 """
261 Returns the serial number of the revoked certificate.
262 """
263
264 @abc.abstractproperty
265 def revocation_date(self):
266 """
267 Returns the date of when this certificate was revoked.
268 """
269
270 @abc.abstractproperty
271 def extensions(self):
272 """
273 Returns an Extensions object containing a list of Revoked extensions.
274 """
Andre Caron0ef595f2015-05-18 13:53:43 -0400275
276
277class CertificateSigningRequestBuilder(object):
Andre Caron99d0f902015-06-01 08:36:59 -0400278 def __init__(self, subject_name=None, extensions=[]):
Andre Caron0ef595f2015-05-18 13:53:43 -0400279 """
280 Creates an empty X.509 certificate request (v1).
281 """
Andre Caronfc164c52015-05-31 17:36:18 -0400282 self._subject_name = subject_name
Ian Cordasco41f51ce2015-06-17 11:49:11 -0500283 self._extensions = extensions
Andre Caron0ef595f2015-05-18 13:53:43 -0400284
Andre Carona9a51172015-06-06 20:18:44 -0400285 def subject_name(self, name):
Andre Caron0ef595f2015-05-18 13:53:43 -0400286 """
287 Sets the certificate requestor's distinguished name.
288 """
289 if not isinstance(name, Name):
290 raise TypeError('Expecting x509.Name object.')
Ian Cordascod09ec372015-06-17 21:37:51 -0500291 if self._subject_name is not None:
292 raise ValueError('The subject name may only be set once.')
Andre Caron99d0f902015-06-01 08:36:59 -0400293 return CertificateSigningRequestBuilder(name, self._extensions)
Andre Caron0ef595f2015-05-18 13:53:43 -0400294
Ian Cordascof06b6be2015-06-21 10:09:18 -0500295 def add_extension(self, extension, critical):
Andre Caron0ef595f2015-05-18 13:53:43 -0400296 """
297 Adds an X.509 extension to the certificate request.
298 """
Paul Kehrere59fd222015-08-08 22:50:19 -0500299 if not isinstance(extension, ExtensionType):
300 raise TypeError("extension must be an ExtensionType")
301
302 extension = Extension(extension.oid, critical, extension)
303
Ian Cordascof06b6be2015-06-21 10:09:18 -0500304 # TODO: This is quadratic in the number of extensions
Andre Caron0ef595f2015-05-18 13:53:43 -0400305 for e in self._extensions:
306 if e.oid == extension.oid:
307 raise ValueError('This extension has already been set.')
Andre Caronfc164c52015-05-31 17:36:18 -0400308 return CertificateSigningRequestBuilder(
Andre Caron99d0f902015-06-01 08:36:59 -0400309 self._subject_name, self._extensions + [extension]
Andre Caronfc164c52015-05-31 17:36:18 -0400310 )
Andre Caron0ef595f2015-05-18 13:53:43 -0400311
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -0400312 def sign(self, private_key, algorithm, backend):
Andre Caron0ef595f2015-05-18 13:53:43 -0400313 """
314 Signs the request using the requestor's private key.
315 """
Alex Gaynorba19c2e2015-06-27 00:07:09 -0400316 if self._subject_name is None:
317 raise ValueError("A CertificateSigningRequest must have a subject")
Andre Carona33ea282015-05-31 16:32:26 -0400318 return backend.create_x509_csr(self, private_key, algorithm)
Andre Caron9bbfcea2015-05-18 20:55:29 -0400319
320
321class CertificateBuilder(object):
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500322 def __init__(self, issuer_name=None, subject_name=None,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500323 public_key=None, serial_number=None, not_valid_before=None,
324 not_valid_after=None, extensions=[]):
Ian Cordasco893246f2015-07-24 14:52:18 -0500325 self._version = Version.v3
Ian Cordascob3ed4842015-07-01 22:46:03 -0500326 self._issuer_name = issuer_name
327 self._subject_name = subject_name
328 self._public_key = public_key
329 self._serial_number = serial_number
330 self._not_valid_before = not_valid_before
331 self._not_valid_after = not_valid_after
332 self._extensions = extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -0400333
Ian Cordascob3ed4842015-07-01 22:46:03 -0500334 def issuer_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400335 """
336 Sets the CA's distinguished name.
337 """
338 if not isinstance(name, Name):
339 raise TypeError('Expecting x509.Name object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500340 if self._issuer_name is not None:
341 raise ValueError('The issuer name may only be set once.')
342 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500343 name, self._subject_name, self._public_key,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500344 self._serial_number, self._not_valid_before,
345 self._not_valid_after, self._extensions
346 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400347
Ian Cordascob3ed4842015-07-01 22:46:03 -0500348 def subject_name(self, name):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400349 """
350 Sets the requestor's distinguished name.
351 """
352 if not isinstance(name, Name):
353 raise TypeError('Expecting x509.Name object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -0500354 if self._subject_name is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -0500355 raise ValueError('The subject name may only be set once.')
356 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500357 self._issuer_name, name, self._public_key,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500358 self._serial_number, self._not_valid_before,
359 self._not_valid_after, self._extensions
360 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400361
Ian Cordascob3ed4842015-07-01 22:46:03 -0500362 def public_key(self, key):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400363 """
364 Sets the requestor's public key (as found in the signing request).
365 """
Ian Cordascob3ed4842015-07-01 22:46:03 -0500366 if not isinstance(key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
367 ec.EllipticCurvePublicKey)):
368 raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
369 ' or EllipticCurvePublicKey.')
370 if self._public_key is not None:
371 raise ValueError('The public key may only be set once.')
372 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500373 self._issuer_name, self._subject_name, key,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500374 self._serial_number, self._not_valid_before,
375 self._not_valid_after, self._extensions
376 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400377
Ian Cordascob3ed4842015-07-01 22:46:03 -0500378 def serial_number(self, number):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400379 """
380 Sets the certificate serial number.
381 """
Ian Cordascob3ed4842015-07-01 22:46:03 -0500382 if not isinstance(number, six.integer_types):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400383 raise TypeError('Serial number must be of integral type.')
Ian Cordasco43ae7382015-07-18 23:27:31 -0500384 if self._serial_number is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -0500385 raise ValueError('The serial number may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500386 if number < 0:
387 raise ValueError('The serial number should be non-negative.')
388 if utils.bit_length(number) > 160: # As defined in RFC 5280
389 raise ValueError('The serial number should not be more than 160 '
390 'bits.')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500391 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500392 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500393 self._public_key, number, self._not_valid_before,
394 self._not_valid_after, self._extensions
395 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400396
Ian Cordascob3ed4842015-07-01 22:46:03 -0500397 def not_valid_before(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400398 """
399 Sets the certificate activation time.
400 """
Andre Caron9bbfcea2015-05-18 20:55:29 -0400401 if not isinstance(time, datetime.datetime):
402 raise TypeError('Expecting datetime object.')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500403 if self._not_valid_before is not None:
404 raise ValueError('The not valid before may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500405 if time <= _UNIX_EPOCH:
406 raise ValueError('The not valid before date must be after the unix'
407 ' epoch (1970 January 1).')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500408 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500409 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500410 self._public_key, self._serial_number, time,
411 self._not_valid_after, self._extensions
412 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400413
Ian Cordascob3ed4842015-07-01 22:46:03 -0500414 def not_valid_after(self, time):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400415 """
416 Sets the certificate expiration time.
417 """
Andre Caron9bbfcea2015-05-18 20:55:29 -0400418 if not isinstance(time, datetime.datetime):
419 raise TypeError('Expecting datetime object.')
Ian Cordasco43ae7382015-07-18 23:27:31 -0500420 if self._not_valid_after is not None:
Ian Cordascob3ed4842015-07-01 22:46:03 -0500421 raise ValueError('The not valid after may only be set once.')
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500422 if time <= _UNIX_EPOCH:
423 raise ValueError('The not valid after date must be after the unix'
424 ' epoch (1970 January 1).')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500425 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500426 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500427 self._public_key, self._serial_number, self._not_valid_before,
428 time, self._extensions
429 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400430
Ian Cordascob3ed4842015-07-01 22:46:03 -0500431 def add_extension(self, extension, critical):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400432 """
433 Adds an X.509 extension to the certificate.
434 """
Paul Kehrer08f950e2015-08-08 22:14:42 -0500435 if not isinstance(extension, ExtensionType):
436 raise TypeError("extension must be an ExtensionType")
437
438 extension = Extension(extension.oid, critical, extension)
Ian Cordascob3ed4842015-07-01 22:46:03 -0500439
440 # TODO: This is quadratic in the number of extensions
Andre Caron9bbfcea2015-05-18 20:55:29 -0400441 for e in self._extensions:
442 if e.oid == extension.oid:
443 raise ValueError('This extension has already been set.')
Ian Cordascob3ed4842015-07-01 22:46:03 -0500444
445 return CertificateBuilder(
Ian Cordascoc5e1c252015-07-31 23:33:35 -0500446 self._issuer_name, self._subject_name,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500447 self._public_key, self._serial_number, self._not_valid_before,
448 self._not_valid_after, self._extensions + [extension]
449 )
Andre Caron9bbfcea2015-05-18 20:55:29 -0400450
Paul Kehrer9add80e2015-08-03 17:53:14 +0100451 def sign(self, private_key, algorithm, backend):
Andre Caron9bbfcea2015-05-18 20:55:29 -0400452 """
453 Signs the certificate using the CA's private key.
454 """
Paul Kehrer25f19222015-08-04 23:05:09 +0100455 if self._subject_name is None:
456 raise ValueError("A certificate must have a subject name")
457
458 if self._issuer_name is None:
459 raise ValueError("A certificate must have an issuer name")
460
461 if self._serial_number is None:
462 raise ValueError("A certificate must have a serial number")
463
464 if self._not_valid_before is None:
465 raise ValueError("A certificate must have a not valid before time")
466
467 if self._not_valid_after is None:
468 raise ValueError("A certificate must have a not valid after time")
469
470 if self._public_key is None:
471 raise ValueError("A certificate must have a public key")
472
Paul Kehrer1ae76532015-08-06 12:37:10 +0100473 return backend.create_x509_certificate(self, private_key, algorithm)