CryptoDataHub 0.12.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. CryptoDataHub-0.12.6.dist-info/LICENSE.txt +373 -0
  2. CryptoDataHub-0.12.6.dist-info/METADATA +119 -0
  3. CryptoDataHub-0.12.6.dist-info/RECORD +70 -0
  4. CryptoDataHub-0.12.6.dist-info/WHEEL +5 -0
  5. CryptoDataHub-0.12.6.dist-info/top_level.txt +1 -0
  6. cryptodatahub/__init__.py +0 -0
  7. cryptodatahub/__setup__.py +10 -0
  8. cryptodatahub/common/__init__.py +0 -0
  9. cryptodatahub/common/algorithm.py +164 -0
  10. cryptodatahub/common/attack-named.json +74 -0
  11. cryptodatahub/common/attack-type.json +58 -0
  12. cryptodatahub/common/authentication.json +113 -0
  13. cryptodatahub/common/block-cipher-mode.json +75 -0
  14. cryptodatahub/common/block-cipher.json +474 -0
  15. cryptodatahub/common/certificate-transparency-log.json +2394 -0
  16. cryptodatahub/common/client.json +20 -0
  17. cryptodatahub/common/dhparam-well-known.json +1975 -0
  18. cryptodatahub/common/ecparam-well-known.json +1868 -0
  19. cryptodatahub/common/entity.json +269 -0
  20. cryptodatahub/common/entity.py +110 -0
  21. cryptodatahub/common/exception.py +28 -0
  22. cryptodatahub/common/grade.py +200 -0
  23. cryptodatahub/common/hash.json +273 -0
  24. cryptodatahub/common/key-exchange.json +140 -0
  25. cryptodatahub/common/key.py +571 -0
  26. cryptodatahub/common/mac.json +404 -0
  27. cryptodatahub/common/named-group.json +902 -0
  28. cryptodatahub/common/parameter.py +149 -0
  29. cryptodatahub/common/root-certificate.json +19240 -0
  30. cryptodatahub/common/server.json +56 -0
  31. cryptodatahub/common/signature.json +233 -0
  32. cryptodatahub/common/standard.json +57 -0
  33. cryptodatahub/common/stores.py +323 -0
  34. cryptodatahub/common/types.py +524 -0
  35. cryptodatahub/common/utils.py +112 -0
  36. cryptodatahub/common/vulnerability.json +2 -0
  37. cryptodatahub/dnsrec/__init__.py +0 -0
  38. cryptodatahub/dnsrec/algorithm.json +114 -0
  39. cryptodatahub/dnsrec/algorithm.py +87 -0
  40. cryptodatahub/dnsrec/digest-type.json +26 -0
  41. cryptodatahub/dnsrec/rr-type.json +805 -0
  42. cryptodatahub/ssh/__init__.py +0 -0
  43. cryptodatahub/ssh/algorithm.py +194 -0
  44. cryptodatahub/ssh/compression-algorithm.json +24 -0
  45. cryptodatahub/ssh/elliptic-curve-identifier.json +50 -0
  46. cryptodatahub/ssh/encryption-algorithm.json +587 -0
  47. cryptodatahub/ssh/host-key-algorithm.json +482 -0
  48. cryptodatahub/ssh/kex-algorithm.json +709 -0
  49. cryptodatahub/ssh/mac-algorithm.json +566 -0
  50. cryptodatahub/tls/__init__.py +0 -0
  51. cryptodatahub/tls/algorithm.py +324 -0
  52. cryptodatahub/tls/certificate-compression-algorithm.json +14 -0
  53. cryptodatahub/tls/cipher-kind.json +171 -0
  54. cryptodatahub/tls/cipher-suite-extension.json +10 -0
  55. cryptodatahub/tls/cipher-suite.json +5098 -0
  56. cryptodatahub/tls/client.json +4757 -0
  57. cryptodatahub/tls/client.py +220 -0
  58. cryptodatahub/tls/compression-method.json +20 -0
  59. cryptodatahub/tls/ec-point-format.json +20 -0
  60. cryptodatahub/tls/extension-type.json +282 -0
  61. cryptodatahub/tls/grease-one-byte.json +34 -0
  62. cryptodatahub/tls/grease-two-byte.json +66 -0
  63. cryptodatahub/tls/hash-and-signature-algorithm.json +266 -0
  64. cryptodatahub/tls/named-curve.json +292 -0
  65. cryptodatahub/tls/next-protocol-name.json +20 -0
  66. cryptodatahub/tls/protocol-name.json +71 -0
  67. cryptodatahub/tls/psk-key-exchange-mode.json +10 -0
  68. cryptodatahub/tls/token-binding-paramater.json +14 -0
  69. cryptodatahub/tls/version.json +154 -0
  70. cryptodatahub/tls/version.py +17 -0
@@ -0,0 +1,571 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import abc
4
+ import base64
5
+ import collections
6
+ import datetime
7
+ import os
8
+
9
+ from collections import OrderedDict
10
+
11
+ import six
12
+ import asn1crypto.keys
13
+ import asn1crypto.pem
14
+ import asn1crypto.x509
15
+ import attr
16
+
17
+ from cryptodatahub.common.algorithm import Authentication, KeyExchange, Hash, NamedGroup, Signature
18
+ from cryptodatahub.common.exception import InvalidValue
19
+ from cryptodatahub.common.grade import (
20
+ AttackNamed,
21
+ AttackType,
22
+ Grade,
23
+ GradeableComplex,
24
+ GradeableVulnerabilities,
25
+ Vulnerability,
26
+ )
27
+ from cryptodatahub.common.types import _ConverterBase
28
+ from cryptodatahub.common.utils import bytes_to_hex_string, hash_bytes
29
+
30
+ from cryptodatahub.tls.algorithm import TlsExtensionType
31
+
32
+
33
+ @attr.s(frozen=True)
34
+ class _PublicKeySizeGradeable(GradeableVulnerabilities):
35
+ @classmethod
36
+ def get_gradeable_name(cls):
37
+ return 'public key size'
38
+
39
+
40
+ @attr.s(frozen=True)
41
+ class PublicKeySize(GradeableComplex):
42
+ _FINITE_FIELD_TYPES = [Authentication.RSA, Authentication.DSS, KeyExchange.ADH, KeyExchange.DH, KeyExchange.DHE]
43
+ _ELLIPTIC_CURVE_TYPES = [Authentication.ECDSA, Authentication.EDDSA, KeyExchange.ECDH, KeyExchange.ECDHE]
44
+
45
+ key_type = attr.ib(validator=attr.validators.instance_of((Authentication, KeyExchange)))
46
+ value = attr.ib(validator=attr.validators.instance_of(six.integer_types))
47
+
48
+ @value.validator
49
+ def _value_validator(self, attribute, value): # pylint: disable=unused-argument
50
+ if value <= 0:
51
+ raise InvalidValue(value, type(self), 'value')
52
+
53
+ def __attrs_post_init__(self):
54
+ if self.key_type in self._ELLIPTIC_CURVE_TYPES:
55
+ gradeables = []
56
+ attack_type = AttackType.DISCRETE_LOGARITHM
57
+ if self.value <= 112:
58
+ gradeables.append(Vulnerability(attack_type=attack_type, grade=Grade.INSECURE, named=None))
59
+ elif self.value <= 160:
60
+ gradeables.append(Vulnerability(attack_type=attack_type, grade=Grade.WEAK, named=None))
61
+ gradeables = [_PublicKeySizeGradeable(gradeables)]
62
+ elif self.key_type in self._FINITE_FIELD_TYPES:
63
+ gradeables = []
64
+ attack_type = AttackType.INTEGER_FACTORIZATION
65
+ if self.value <= 768:
66
+ if self.key_type == Authentication.RSA:
67
+ attack_named = AttackNamed.FREAK
68
+ elif isinstance(self.key_type, KeyExchange):
69
+ attack_named = AttackNamed.WEAK_DH
70
+ else:
71
+ attack_named = None
72
+
73
+ gradeables.append(Vulnerability(attack_type=attack_type, grade=Grade.INSECURE, named=attack_named))
74
+ elif self.value <= 1024:
75
+ gradeables.append(Vulnerability(attack_type=attack_type, grade=Grade.WEAK, named=None))
76
+ elif self.key_type in [KeyExchange.ADH, KeyExchange.DH, KeyExchange.DHE] and self.value > 4096:
77
+ gradeables.append(
78
+ Vulnerability(attack_type=AttackType.DOS_ATTACK, grade=Grade.WEAK, named=AttackNamed.DHEAT_ATTACK)
79
+ )
80
+ gradeables = [_PublicKeySizeGradeable(gradeables)]
81
+ elif self.key_type == KeyExchange.HYBRID_PQS:
82
+ gradeables = []
83
+ else:
84
+ gradeables = None
85
+
86
+ object.__setattr__(self, 'gradeables', gradeables)
87
+
88
+ def __str__(self):
89
+ return str(self.value)
90
+
91
+
92
+ @attr.s(repr=False, slots=True, hash=True)
93
+ class _PublicKeySizeConverter(_ConverterBase):
94
+ key_exchange = attr.ib(validator=attr.validators.instance_of(KeyExchange))
95
+
96
+ def __call__(self, value):
97
+ if value is None:
98
+ return None
99
+
100
+ try:
101
+ return PublicKeySize(self.key_exchange, value)
102
+ except (TypeError, InvalidValue):
103
+ return value
104
+
105
+ def __repr__(self):
106
+ return '<public key size converter>'
107
+
108
+
109
+ def convert_public_key_size(key_exchange):
110
+ return _PublicKeySizeConverter(key_exchange)
111
+
112
+
113
+ @attr.s(frozen=True)
114
+ class PublicKeyParamBase(object):
115
+ pass
116
+
117
+
118
+ @attr.s(frozen=True)
119
+ class PublicKeyParamsDsa(PublicKeyParamBase):
120
+ prime = attr.ib(validator=attr.validators.instance_of(six.integer_types))
121
+ generator = attr.ib(validator=attr.validators.instance_of(six.integer_types))
122
+ order = attr.ib(validator=attr.validators.instance_of(six.integer_types))
123
+ public_key_value = attr.ib(validator=attr.validators.instance_of(six.integer_types))
124
+
125
+
126
+ @attr.s(frozen=True)
127
+ class PublicKeyParamsEcdsa(PublicKeyParamBase):
128
+ named_group = attr.ib(validator=attr.validators.instance_of(NamedGroup))
129
+ point_x = attr.ib(validator=attr.validators.instance_of(six.integer_types))
130
+ point_y = attr.ib(validator=attr.validators.instance_of(six.integer_types))
131
+
132
+ @classmethod
133
+ def from_octet_bit_string(cls, named_group, octet_bit_string):
134
+ point_x, point_y = asn1crypto.keys.ECPointBitString(bytes(octet_bit_string)).to_coords()
135
+ return cls(
136
+ named_group,
137
+ point_x,
138
+ point_y,
139
+ )
140
+
141
+ @property
142
+ def octet_bit_string(self):
143
+ return bytes(asn1crypto.keys.ECPointBitString.from_coords(self.point_x, self.point_y))
144
+
145
+
146
+ @attr.s(frozen=True)
147
+ class PublicKeyParamsEddsa(PublicKeyParamBase):
148
+ curve_type = attr.ib(validator=attr.validators.instance_of(NamedGroup))
149
+ key_data = attr.ib(validator=attr.validators.instance_of((bytes, bytearray)))
150
+
151
+
152
+ @attr.s(frozen=True)
153
+ class PublicKeyParamsRsa(PublicKeyParamBase):
154
+ modulus = attr.ib(validator=attr.validators.instance_of(six.integer_types))
155
+ public_exponent = attr.ib(validator=attr.validators.instance_of(six.integer_types))
156
+
157
+
158
+ @attr.s(eq=False, frozen=True)
159
+ class PublicKey(object):
160
+ _public_key = attr.ib(validator=attr.validators.instance_of(asn1crypto.keys.PublicKeyInfo))
161
+
162
+ @classmethod
163
+ def from_der(cls, der):
164
+ return cls(asn1crypto.keys.PublicKeyInfo.load(bytes(der)))
165
+
166
+ @classmethod
167
+ def from_pem(cls, pem):
168
+ return cls.from_der(asn1crypto.pem.unarmor(pem.encode('ascii'))[2])
169
+
170
+ @classmethod
171
+ def from_pem_lines(cls, pem_lines):
172
+ return cls.from_pem(os.linesep.join(pem_lines))
173
+
174
+ @classmethod
175
+ def from_params(cls, params):
176
+ if isinstance(params, PublicKeyParamsDsa):
177
+ algorithm_id = asn1crypto.keys.PublicKeyAlgorithmId(six.u('dsa'))
178
+ parameters = asn1crypto.keys.DSAParams({
179
+ 'p': params.prime, 'g': params.generator, 'q': params.order,
180
+ })
181
+ public_key = asn1crypto.keys.PublicKeyInfo({
182
+ 'algorithm': asn1crypto.keys.PublicKeyAlgorithm({
183
+ 'algorithm': algorithm_id,
184
+ 'parameters': parameters,
185
+ }),
186
+ 'public_key': params.public_key_value,
187
+ })
188
+ elif isinstance(params, PublicKeyParamsEddsa):
189
+ if params.curve_type == NamedGroup.CURVE25519:
190
+ algorithm_name = six.u('ed25519')
191
+ elif params.curve_type == NamedGroup.CURVE448:
192
+ algorithm_name = six.u('ed448')
193
+ else:
194
+ raise NotImplementedError()
195
+
196
+ algorithm_id = asn1crypto.keys.PublicKeyAlgorithmId(algorithm_name)
197
+ public_key = asn1crypto.keys.PublicKeyInfo({
198
+ 'algorithm': asn1crypto.keys.PublicKeyAlgorithm({
199
+ 'algorithm': algorithm_id,
200
+ }),
201
+ 'public_key': asn1crypto.core.OctetBitString(bytes(params.key_data)),
202
+ })
203
+ elif isinstance(params, PublicKeyParamsRsa):
204
+ algorithm_id = asn1crypto.keys.PublicKeyAlgorithmId(six.u('rsa'))
205
+ public_key = asn1crypto.keys.PublicKeyInfo({
206
+ 'algorithm': asn1crypto.keys.PublicKeyAlgorithm({'algorithm': algorithm_id}),
207
+ 'public_key': asn1crypto.keys.RSAPublicKey(
208
+ attr.asdict(params, recurse=False, value_serializer=None)
209
+ )
210
+ })
211
+ elif isinstance(params, PublicKeyParamsEcdsa):
212
+ algorithm_id = asn1crypto.keys.PublicKeyAlgorithmId(six.u('ec'))
213
+ parameters = asn1crypto.keys.ECDomainParameters({
214
+ 'named': params.named_group.value.oid
215
+ })
216
+
217
+ public_key = asn1crypto.keys.PublicKeyInfo({
218
+ 'algorithm': asn1crypto.keys.PublicKeyAlgorithm({
219
+ 'algorithm': algorithm_id,
220
+ 'parameters': parameters,
221
+ }),
222
+ 'public_key': asn1crypto.keys.ECPointBitString.from_coords(params.point_x, params.point_y)
223
+ })
224
+ else:
225
+ raise NotImplementedError(type(params))
226
+
227
+ return cls(public_key)
228
+
229
+ @property
230
+ def params(self):
231
+ if self.key_type == Authentication.DSS:
232
+ public_key = self._public_key['public_key'].parsed
233
+ parameters = self._public_key['algorithm']['parameters']
234
+ return PublicKeyParamsDsa(
235
+ prime=parameters['p'].native,
236
+ generator=parameters['g'].native,
237
+ order=parameters['q'].native,
238
+ public_key_value=public_key.native,
239
+ )
240
+ if self.key_type == Authentication.ECDSA:
241
+ public_key = self._public_key['public_key']
242
+ parameters = self._public_key['algorithm']['parameters']
243
+
244
+ return PublicKeyParamsEcdsa(
245
+ NamedGroup.from_oid(parameters.chosen.dotted),
246
+ *public_key.to_coords()
247
+ )
248
+ if self.key_type == Authentication.EDDSA:
249
+ algorithm = self._public_key['algorithm']['algorithm']
250
+ signature = Signature.from_oid(algorithm.dotted)
251
+ if signature == Signature.ED25519:
252
+ curve_type = NamedGroup.CURVE25519
253
+ elif signature == Signature.ED448:
254
+ curve_type = NamedGroup.CURVE448
255
+ else:
256
+ raise NotImplementedError()
257
+
258
+ return PublicKeyParamsEddsa(
259
+ curve_type=curve_type,
260
+ key_data=self._public_key['public_key'].native
261
+ )
262
+ if self.key_type == Authentication.RSA:
263
+ public_key = self._public_key['public_key'].parsed
264
+ return PublicKeyParamsRsa(
265
+ modulus=public_key['modulus'].native,
266
+ public_exponent=public_key['public_exponent'].native,
267
+ )
268
+
269
+ raise NotImplementedError(self.key_type)
270
+
271
+ @classmethod
272
+ def _get_type_name(cls):
273
+ return 'public key'
274
+
275
+ def __eq__(self, other):
276
+ return self.der == other.der
277
+
278
+ @property
279
+ def der(self):
280
+ return self._public_key.dump()
281
+
282
+ @property
283
+ def pem(self):
284
+ return six.ensure_str(asn1crypto.pem.armor(six.u(self._get_type_name().upper()), self.der))
285
+
286
+ @property
287
+ def key_type(self):
288
+ try:
289
+ key_type_oid = self._public_key['algorithm']['algorithm'].dotted
290
+ except KeyError as e:
291
+ key_type_oid = e.args[0]
292
+
293
+ try:
294
+ return Signature.from_oid(key_type_oid).value.key_type
295
+ except InvalidValue:
296
+ return Authentication.from_oid(key_type_oid)
297
+
298
+ @property
299
+ def key_size(self):
300
+ if self.key_type == Authentication.GOST_R3410_12_256:
301
+ return 256
302
+ if self.key_type == Authentication.GOST_R3410_12_512:
303
+ return 512
304
+ if self.key_type == Authentication.GOST_R3410_01:
305
+ return 256
306
+ if self.key_type == Authentication.EDDSA:
307
+ return self.params.curve_type.value.size
308
+
309
+ return int(self._public_key.bit_size)
310
+
311
+ @property
312
+ def key_bytes(self):
313
+ return PublicKey.der.fget(self)
314
+
315
+ def get_digest(self, hash_type):
316
+ return hash_bytes(hash_type, self.der)
317
+
318
+ def fingerprint(self, hash_type):
319
+ return bytes_to_hex_string(self.get_digest(hash_type), ':')
320
+
321
+ @property
322
+ def fingerprints(self):
323
+ return OrderedDict([
324
+ (hash_type, self.fingerprint(hash_type))
325
+ for hash_type in [Hash.MD5, Hash.SHA1, Hash.SHA2_256]
326
+ ])
327
+
328
+ def _asdict(self):
329
+ return collections.OrderedDict([
330
+ ('algorithm', self.key_type),
331
+ ('size', PublicKeySize(self.key_type, self.key_size)),
332
+ ('fingerprints', self.fingerprints),
333
+ ])
334
+
335
+
336
+ class PublicKeySigned(PublicKey):
337
+ @property
338
+ @abc.abstractmethod
339
+ def valid_not_before(self):
340
+ raise NotImplementedError()
341
+
342
+ @property
343
+ @abc.abstractmethod
344
+ def valid_not_after(self):
345
+ raise NotImplementedError()
346
+
347
+ @property
348
+ def validity_period(self):
349
+ return self.valid_not_after - self.valid_not_before
350
+
351
+ @property
352
+ def validity_remaining_time(self):
353
+ now = datetime.datetime.now(asn1crypto.util.timezone.utc)
354
+ return self.valid_not_after - now if now < self.valid_not_after else None
355
+
356
+ @property
357
+ def expired(self):
358
+ return datetime.datetime.now(asn1crypto.util.timezone.utc) > self.valid_not_after
359
+
360
+ @property
361
+ @abc.abstractmethod
362
+ def signature_hash_algorithm(self):
363
+ raise NotImplementedError()
364
+
365
+
366
+ @attr.s(eq=False, init=False, frozen=True)
367
+ class PublicKeyX509Base(PublicKeySigned): # pylint: disable=too-many-public-methods
368
+ _EV_OIDS_BY_CA = {
369
+ 'A-Trust': ('1.2.40.0.17.1.22', ),
370
+ 'Actalis': ('1.3.159.1.17.1', ),
371
+ 'AffirmTrust': (
372
+ '1.3.6.1.4.1.34697.2.1',
373
+ '1.3.6.1.4.1.34697.2.2',
374
+ '1.3.6.1.4.1.34697.2.3',
375
+ '1.3.6.1.4.1.34697.2.4',
376
+ ),
377
+ 'Buypass': ('2.16.578.1.26.1.3.3', ),
378
+ 'Camerfirma': (
379
+ '1.3.6.1.4.1.17326.10.14.2.1.2',
380
+ '1.3.6.1.4.1.17326.10.8.12.1.2',
381
+ ),
382
+ 'Comodo Group': ('1.3.6.1.4.1.6449.1.2.1.5.1', ),
383
+ 'DigiCert': (
384
+ '2.16.840.1.114412.1.3.0.2',
385
+ '2.16.840.1.114412.2.1',
386
+ ),
387
+ 'DigiNotar': ('2.16.528.1.1001.1.1.1.12.6.1.1.1', ),
388
+ 'E-Tugra': ('2.16.792.3.0.4.1.1.4', ),
389
+ 'ETSI': (
390
+ '0.4.0.2042.1.4',
391
+ '0.4.0.2042.1.5',
392
+ ),
393
+ 'Entrust': ('2.16.840.1.114028.10.1.2', ),
394
+ 'Firmaprofesional': ('1.3.6.1.4.1.13177.10.1.3.10', ),
395
+ 'GeoTrust': ('1.3.6.1.4.1.14370.1.6', ),
396
+ 'GlobalSign': ('1.3.6.1.4.1.4146.1.1', ),
397
+ 'Go Daddy': ('2.16.840.1.114413.1.7.23.3', ),
398
+ 'Izenpe': ('1.3.6.1.4.1.14777.6.1.1', ),
399
+ 'Kamu Sertifikasyon Merkezi': ('2.16.792.1.2.1.1.5.7.1.9', ),
400
+ 'Logius PKIoverheid': ('2.16.528.1.1003.1.2.7', ),
401
+ 'Network Solutions': ('1.3.6.1.4.1.782.1.2.1.8.1', ),
402
+ 'OpenTrust/DocuSign France': ('1.3.6.1.4.1.22234.2.5.2.3.1', ),
403
+ 'QuoVadis': ('1.3.6.1.4.1.8024.0.2.100.1.2', ),
404
+ 'SECOM Trust Systems': ('1.2.392.200091.100.721.1', ),
405
+ 'SHECA': ('1.2.156.112570.1.1.3', ),
406
+ 'Starfield Technologies': ('2.16.840.1.114414.1.7.23.3', ),
407
+ 'StartCom Certification Authority': (
408
+ '1.3.6.1.4.1.23223.1.1.1',
409
+ '1.3.6.1.4.1.23223.2',
410
+ ),
411
+ 'SwissSign': ('2.16.756.1.89.1.2.1.1', ),
412
+ 'Swisscom': ('2.16.756.1.83.21.0', ),
413
+ 'Symantec (VeriSign)': ('2.16.840.1.113733.1.7.23.6', ),
414
+ 'T-Systems': ('1.3.6.1.4.1.7879.13.24.1', ),
415
+ 'Thawte': ('2.16.840.1.113733.1.7.48.1', ),
416
+ 'Trustwave': ('2.16.840.1.114404.1.1.2.4.1', ),
417
+ 'Verizon Business (formerly Cybertrust)': ('1.3.6.1.4.1.6334.1.100.1', ),
418
+ 'Wells Fargo': ('2.16.840.1.114171.500.9', ),
419
+ 'WoSign': ('1.3.6.1.4.1.36305.2', ),
420
+ }
421
+
422
+ _certificate = attr.ib(validator=attr.validators.instance_of(asn1crypto.x509.Certificate))
423
+
424
+ def __init__(self, certificate):
425
+ super(PublicKeySigned, self).__init__(certificate.public_key)
426
+
427
+ object.__setattr__(self, '_certificate', certificate)
428
+
429
+ @classmethod
430
+ def _get_type_name(cls):
431
+ return 'certificate'
432
+
433
+ @classmethod
434
+ def from_der(cls, der):
435
+ return cls(asn1crypto.x509.Certificate.load(bytes(der)))
436
+
437
+ @property
438
+ def der(self):
439
+ return self._certificate.dump()
440
+
441
+ @property
442
+ def valid_not_before(self):
443
+ return self._certificate.not_valid_before
444
+
445
+ @property
446
+ def valid_not_after(self):
447
+ return self._certificate.not_valid_after
448
+
449
+ @property
450
+ def signature_hash_algorithm(self):
451
+ try:
452
+ signature_oid = self._certificate['signature_algorithm']['algorithm'].dotted
453
+ except KeyError as e:
454
+ signature_oid = e.args[0]
455
+
456
+ return Signature.from_oid(signature_oid)
457
+
458
+ @property
459
+ def public_key(self):
460
+ return PublicKey(self._public_key)
461
+
462
+ @property
463
+ def public_key_pin(self):
464
+ return base64.b64encode(hash_bytes(Hash.SHA2_256, self.key_bytes)).decode('ascii')
465
+
466
+ def _has_any_policy_value(self, oid_values):
467
+ if self._certificate.certificate_policies_value is None:
468
+ return False
469
+
470
+ for policy_information in self._certificate.certificate_policies_value:
471
+ if policy_information['policy_identifier'].dotted in oid_values:
472
+ return True
473
+
474
+ return False
475
+
476
+ @property
477
+ def extended_validation(self):
478
+ return any(map(self._has_any_policy_value, self._EV_OIDS_BY_CA.values()))
479
+
480
+ @property
481
+ def tls_features(self):
482
+ tls_feature_value = self._certificate.tls_feature_value
483
+ if tls_feature_value is None:
484
+ return []
485
+
486
+ return list(map(lambda feature: TlsExtensionType.from_code(feature.native), tls_feature_value))
487
+
488
+ @property
489
+ def serial_number(self):
490
+ return self._certificate.serial_number
491
+
492
+ @property
493
+ def subject(self):
494
+ return OrderedDict([
495
+ (six.ensure_str(name), value)
496
+ for name, value in self._certificate.subject.native.items()
497
+ ])
498
+
499
+ @property
500
+ def issuer(self):
501
+ return self._certificate.issuer.native
502
+
503
+ @property
504
+ def valid_domains(self):
505
+ return self._certificate.valid_domains
506
+
507
+ def is_subject_matches(self, host_name):
508
+ return self._certificate.is_valid_domain_ip(six.u(host_name))
509
+
510
+ @property
511
+ def subject_alternative_names(self):
512
+ if self._certificate.subject_alt_name_value is None:
513
+ return []
514
+
515
+ return self._certificate.subject_alt_name_value.native
516
+
517
+ @property
518
+ def crl_distribution_points(self):
519
+ if self._certificate.crl_distribution_points_value is None:
520
+ return []
521
+
522
+ return [
523
+ crl_distribution_point.url
524
+ for crl_distribution_point in self._certificate.crl_distribution_points_value
525
+ ]
526
+
527
+ @property
528
+ def ocsp_responders(self):
529
+ return self._certificate.ocsp_urls
530
+
531
+ @property
532
+ def is_ca(self):
533
+ return self._certificate.ca
534
+
535
+ @property
536
+ def is_self_signed(self):
537
+ return self._certificate.self_issued
538
+
539
+ def _asdict(self):
540
+ items = [
541
+ ('algorithm', self.key_type),
542
+ ('size', PublicKeySize(self.key_type, self.key_size)),
543
+ ('version', self._certificate['tbs_certificate']['version'].native),
544
+ ('serial_number', str(self.serial_number)),
545
+ ('subject', self.subject),
546
+ ('subject_alternative_names', sorted(self.subject_alternative_names)),
547
+ ('issuer', self.issuer),
548
+ ('signature_hash_algorithm', self.signature_hash_algorithm),
549
+ ('validity', collections.OrderedDict([
550
+ ('not_before', str(self.valid_not_before)),
551
+ ('not_after', str(self.valid_not_after)),
552
+ ('period', str(self.validity_period)),
553
+ ('remaining', str(self.validity_remaining_time.days) if self.validity_remaining_time else None),
554
+ ])),
555
+ ('revocation', collections.OrderedDict([
556
+ ('crl_distribution_points', self.crl_distribution_points),
557
+ ('ocsp_responders', self.ocsp_responders),
558
+ ])),
559
+ ('fingerprints', self.fingerprints),
560
+ ('public_key_pin', self.public_key_pin),
561
+ ]
562
+
563
+ if not self.is_ca:
564
+ items += [
565
+ ('end_entity', collections.OrderedDict([
566
+ ('extended_validation', self.extended_validation),
567
+ ('tls_features', list(map(lambda feature: feature.name, self.tls_features))),
568
+ ]))
569
+ ]
570
+
571
+ return collections.OrderedDict(items)