blob: e280980b5daa33b997b15775f16fc05bc70d5c3e [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
13
Paul Kehrer016e08a2014-11-26 09:41:18 -100014
Paul Kehrer806bfb22015-02-02 17:05:24 -060015_OID_NAMES = {
16 "2.5.4.3": "commonName",
17 "2.5.4.6": "countryName",
18 "2.5.4.7": "localityName",
19 "2.5.4.8": "stateOrProvinceName",
20 "2.5.4.10": "organizationName",
21 "2.5.4.11": "organizationalUnitName",
22 "2.5.4.5": "serialNumber",
23 "2.5.4.4": "surname",
24 "2.5.4.42": "givenName",
25 "2.5.4.12": "title",
26 "2.5.4.44": "generationQualifier",
27 "2.5.4.46": "dnQualifier",
28 "2.5.4.65": "pseudonym",
29 "0.9.2342.19200300.100.1.25": "domainComponent",
30 "1.2.840.113549.1.9.1": "emailAddress",
31}
32
33
Paul Kehrere76cd272014-12-14 19:00:51 -060034class Version(Enum):
Paul Kehrer016e08a2014-11-26 09:41:18 -100035 v1 = 0
36 v3 = 2
37
38
Paul Kehrer016e08a2014-11-26 09:41:18 -100039def load_pem_x509_certificate(data, backend):
40 return backend.load_pem_x509_certificate(data)
41
42
Paul Kehrer016e08a2014-11-26 09:41:18 -100043def load_der_x509_certificate(data, backend):
44 return backend.load_der_x509_certificate(data)
Paul Kehrera68fd332014-11-27 07:08:40 -100045
46
Paul Kehrere76cd272014-12-14 19:00:51 -060047class InvalidVersion(Exception):
Paul Kehrerd5cccf72014-12-15 17:20:33 -060048 def __init__(self, msg, parsed_version):
49 super(InvalidVersion, self).__init__(msg)
50 self.parsed_version = parsed_version
Paul Kehrerb2de9482014-12-11 14:54:48 -060051
52
Paul Kehrer806bfb22015-02-02 17:05:24 -060053class NameAttribute(object):
Paul Kehrer912d3fb2015-01-29 11:19:22 -060054 def __init__(self, oid, value):
55 if not isinstance(oid, ObjectIdentifier):
Paul Kehrer858b9b72015-02-05 09:50:31 -060056 raise TypeError(
57 "oid argument must be an ObjectIdentifier instance."
58 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -060059
60 self._oid = oid
61 self._value = value
62
63 oid = utils.read_only_property("_oid")
64 value = utils.read_only_property("_value")
65
66 def __eq__(self, other):
Paul Kehrer806bfb22015-02-02 17:05:24 -060067 if not isinstance(other, NameAttribute):
Paul Kehrer912d3fb2015-01-29 11:19:22 -060068 return NotImplemented
69
70 return (
71 self.oid == other.oid and
72 self.value == other.value
73 )
74
75 def __ne__(self, other):
76 return not self == other
77
78
79class ObjectIdentifier(object):
Paul Kehrerd44f9a62015-02-04 14:47:34 -060080 def __init__(self, dotted_string):
81 self._dotted_string = dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -060082
83 def __eq__(self, other):
84 if not isinstance(other, ObjectIdentifier):
85 return NotImplemented
86
Paul Kehrerd44f9a62015-02-04 14:47:34 -060087 return self._dotted_string == other._dotted_string
Paul Kehrer912d3fb2015-01-29 11:19:22 -060088
89 def __ne__(self, other):
90 return not self == other
91
92 def __repr__(self):
93 return "<ObjectIdentifier(oid={0}, name={1})>".format(
Paul Kehrerd44f9a62015-02-04 14:47:34 -060094 self._dotted_string,
95 _OID_NAMES.get(self._dotted_string, "Unknown OID")
Paul Kehrer912d3fb2015-01-29 11:19:22 -060096 )
97
Paul Kehrerd44f9a62015-02-04 14:47:34 -060098 dotted_string = utils.read_only_property("_dotted_string")
Paul Kehrer912d3fb2015-01-29 11:19:22 -060099
100
Paul Kehrer806bfb22015-02-02 17:05:24 -0600101OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
102OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
103OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
104OID_STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8")
105OID_ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10")
106OID_ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11")
107OID_SERIAL_NUMBER = ObjectIdentifier("2.5.4.5")
108OID_SURNAME = ObjectIdentifier("2.5.4.4")
109OID_GIVEN_NAME = ObjectIdentifier("2.5.4.42")
110OID_TITLE = ObjectIdentifier("2.5.4.12")
111OID_GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44")
112OID_DN_QUALIFIER = ObjectIdentifier("2.5.4.46")
113OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
114OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
115OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -0600116
117
Paul Kehrerb2de9482014-12-11 14:54:48 -0600118@six.add_metaclass(abc.ABCMeta)
Paul Kehrere76cd272014-12-14 19:00:51 -0600119class Certificate(object):
Paul Kehrerb2de9482014-12-11 14:54:48 -0600120 @abc.abstractmethod
121 def fingerprint(self, algorithm):
122 """
123 Returns bytes using digest passed.
124 """
125
126 @abc.abstractproperty
127 def serial(self):
128 """
129 Returns certificate serial number
130 """
131
132 @abc.abstractproperty
133 def version(self):
134 """
135 Returns the certificate version
136 """
137
138 @abc.abstractmethod
139 def public_key(self):
140 """
141 Returns the public key
142 """
143
144 @abc.abstractproperty
145 def not_valid_before(self):
146 """
147 Not before time (represented as UTC datetime)
148 """
149
150 @abc.abstractproperty
151 def not_valid_after(self):
152 """
153 Not after time (represented as UTC datetime)
154 """