1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
5# Acknowledgment: Maxence Tury <maxence.tury@ssi.gouv.fr>
6
7# Cool history about this file: http://natisbad.org/scapy/index.html
8
9"""
10X.509 certificates.
11"""
12
13from scapy.asn1.mib import conf # loads conf.mib
14from scapy.asn1.asn1 import ASN1_Codecs, ASN1_OID, \
15 ASN1_IA5_STRING, ASN1_NULL, ASN1_PRINTABLE_STRING, \
16 ASN1_UTC_TIME, ASN1_UTF8_STRING
17from scapy.asn1.ber import BER_tagging_dec, BER_Decoding_Error
18from scapy.asn1packet import ASN1_Packet
19from scapy.asn1fields import ASN1F_BIT_STRING, ASN1F_BIT_STRING_ENCAPS, \
20 ASN1F_BMP_STRING, ASN1F_BOOLEAN, ASN1F_CHOICE, ASN1F_ENUMERATED, \
21 ASN1F_FLAGS, ASN1F_GENERALIZED_TIME, ASN1F_IA5_STRING, ASN1F_INTEGER, \
22 ASN1F_ISO646_STRING, ASN1F_NULL, ASN1F_OID, ASN1F_PACKET, \
23 ASN1F_PRINTABLE_STRING, ASN1F_SEQUENCE, ASN1F_SEQUENCE_OF, ASN1F_SET_OF, \
24 ASN1F_STRING, ASN1F_T61_STRING, ASN1F_UNIVERSAL_STRING, ASN1F_UTC_TIME, \
25 ASN1F_UTF8_STRING, ASN1F_badsequence, ASN1F_enum_INTEGER, ASN1F_field, \
26 ASN1F_optional
27from scapy.packet import Packet
28from scapy.fields import PacketField, MultipleTypeField
29from scapy.volatile import ZuluTime, GeneralizedTime
30from scapy.compat import plain_str
31
32
33class ASN1P_OID(ASN1_Packet):
34 ASN1_codec = ASN1_Codecs.BER
35 ASN1_root = ASN1F_OID("oid", "0")
36
37
38class ASN1P_INTEGER(ASN1_Packet):
39 ASN1_codec = ASN1_Codecs.BER
40 ASN1_root = ASN1F_INTEGER("number", 0)
41
42
43class ASN1P_PRIVSEQ(ASN1_Packet):
44 # This class gets used in x509.uts
45 # It showcases the private high-tag decoding capacities of scapy.
46 ASN1_codec = ASN1_Codecs.BER
47 ASN1_root = ASN1F_SEQUENCE(
48 ASN1F_IA5_STRING("str", ""),
49 ASN1F_STRING("int", 0),
50 explicit_tag=0,
51 flexible_tag=True)
52
53
54#######################
55# RSA packets #
56#######################
57# based on RFC 3447
58
59# It could be interesting to use os.urandom and try to generate
60# a new modulus each time RSAPublicKey is called with default values.
61# (We might have to dig into scapy field initialization mechanisms...)
62# NEVER rely on the key below, which is provided only for debugging purposes.
63class RSAPublicKey(ASN1_Packet):
64 ASN1_codec = ASN1_Codecs.BER
65 ASN1_root = ASN1F_SEQUENCE(
66 ASN1F_INTEGER("modulus", 10),
67 ASN1F_INTEGER("publicExponent", 3))
68
69
70class RSAOtherPrimeInfo(ASN1_Packet):
71 ASN1_codec = ASN1_Codecs.BER
72 ASN1_root = ASN1F_SEQUENCE(
73 ASN1F_INTEGER("prime", 0),
74 ASN1F_INTEGER("exponent", 0),
75 ASN1F_INTEGER("coefficient", 0))
76
77
78class RSAPrivateKey(ASN1_Packet):
79 ASN1_codec = ASN1_Codecs.BER
80 ASN1_root = ASN1F_SEQUENCE(
81 ASN1F_enum_INTEGER("version", 0, ["two-prime", "multi"]),
82 ASN1F_INTEGER("modulus", 10),
83 ASN1F_INTEGER("publicExponent", 3),
84 ASN1F_INTEGER("privateExponent", 3),
85 ASN1F_INTEGER("prime1", 2),
86 ASN1F_INTEGER("prime2", 5),
87 ASN1F_INTEGER("exponent1", 0),
88 ASN1F_INTEGER("exponent2", 3),
89 ASN1F_INTEGER("coefficient", 1),
90 ASN1F_optional(
91 ASN1F_SEQUENCE_OF("otherPrimeInfos", None,
92 RSAOtherPrimeInfo)))
93
94####################################
95# ECDSA packets #
96####################################
97# based on RFC 3279 & 5480 & 5915
98
99
100class ECFieldID(ASN1_Packet):
101 # No characteristic-two-field support for now.
102 ASN1_codec = ASN1_Codecs.BER
103 ASN1_root = ASN1F_SEQUENCE(
104 ASN1F_OID("fieldType", "prime-field"),
105 ASN1F_INTEGER("prime", 0))
106
107
108class ECCurve(ASN1_Packet):
109 ASN1_codec = ASN1_Codecs.BER
110 ASN1_root = ASN1F_SEQUENCE(
111 ASN1F_STRING("a", ""),
112 ASN1F_STRING("b", ""),
113 ASN1F_optional(
114 ASN1F_BIT_STRING("seed", None)))
115
116
117class ECSpecifiedDomain(ASN1_Packet):
118 ASN1_codec = ASN1_Codecs.BER
119 ASN1_root = ASN1F_SEQUENCE(
120 ASN1F_enum_INTEGER("version", 1, {1: "ecpVer1"}),
121 ASN1F_PACKET("fieldID", ECFieldID(), ECFieldID),
122 ASN1F_PACKET("curve", ECCurve(), ECCurve),
123 ASN1F_STRING("base", ""),
124 ASN1F_INTEGER("order", 0),
125 ASN1F_optional(
126 ASN1F_INTEGER("cofactor", None)))
127
128
129class ECParameters(ASN1_Packet):
130 ASN1_codec = ASN1_Codecs.BER
131 ASN1_root = ASN1F_CHOICE("curve", ASN1_OID("ansip384r1"),
132 ASN1F_OID, # for named curves
133 ASN1F_NULL, # for implicit curves
134 ECSpecifiedDomain)
135
136
137class ECDSAPublicKey(ASN1_Packet):
138 ASN1_codec = ASN1_Codecs.BER
139 ASN1_root = ASN1F_BIT_STRING("ecPoint", "")
140
141
142class ECDSAPrivateKey(ASN1_Packet):
143 ASN1_codec = ASN1_Codecs.BER
144 ASN1_root = ASN1F_SEQUENCE(
145 ASN1F_enum_INTEGER("version", 1, {1: "ecPrivkeyVer1"}),
146 ASN1F_STRING("privateKey", ""),
147 ASN1F_optional(
148 ASN1F_PACKET("parameters", None, ECParameters,
149 explicit_tag=0xa0)),
150 ASN1F_optional(
151 ASN1F_PACKET("publicKey", None,
152 ECDSAPublicKey,
153 explicit_tag=0xa1)))
154
155
156class ECDSASignature(ASN1_Packet):
157 ASN1_codec = ASN1_Codecs.BER
158 ASN1_root = ASN1F_SEQUENCE(
159 ASN1F_INTEGER("r", 0),
160 ASN1F_INTEGER("s", 0))
161
162
163######################
164# X509 packets #
165######################
166# based on RFC 5280
167
168
169# Names #
170
171class ASN1F_X509_DirectoryString(ASN1F_CHOICE):
172 # we include ASN1 bit strings for rare instances of x500 addresses
173 def __init__(self, name, default, **kwargs):
174 ASN1F_CHOICE.__init__(self, name, default,
175 ASN1F_PRINTABLE_STRING, ASN1F_UTF8_STRING,
176 ASN1F_IA5_STRING, ASN1F_T61_STRING,
177 ASN1F_UNIVERSAL_STRING, ASN1F_BIT_STRING,
178 **kwargs)
179
180
181class X509_AttributeValue(ASN1_Packet):
182 ASN1_codec = ASN1_Codecs.BER
183 ASN1_root = ASN1F_CHOICE("value", ASN1_PRINTABLE_STRING("FR"),
184 ASN1F_PRINTABLE_STRING, ASN1F_UTF8_STRING,
185 ASN1F_IA5_STRING, ASN1F_T61_STRING,
186 ASN1F_UNIVERSAL_STRING)
187
188
189class X509_Attribute(ASN1_Packet):
190 ASN1_codec = ASN1_Codecs.BER
191 ASN1_root = ASN1F_SEQUENCE(
192 ASN1F_OID("type", "2.5.4.6"),
193 ASN1F_SET_OF("values",
194 [X509_AttributeValue()],
195 X509_AttributeValue))
196
197
198class X509_AttributeTypeAndValue(ASN1_Packet):
199 ASN1_codec = ASN1_Codecs.BER
200 ASN1_root = ASN1F_SEQUENCE(
201 ASN1F_OID("type", "2.5.4.6"),
202 ASN1F_X509_DirectoryString("value",
203 ASN1_PRINTABLE_STRING("FR")))
204
205
206class X509_RDN(ASN1_Packet):
207 ASN1_codec = ASN1_Codecs.BER
208 ASN1_root = ASN1F_SET_OF("rdn", [X509_AttributeTypeAndValue()],
209 X509_AttributeTypeAndValue)
210
211
212class X509_OtherName(ASN1_Packet):
213 ASN1_codec = ASN1_Codecs.BER
214 ASN1_root = ASN1F_SEQUENCE(
215 ASN1F_OID("type_id", "0"),
216 ASN1F_CHOICE("value", None,
217 ASN1F_IA5_STRING, ASN1F_ISO646_STRING,
218 ASN1F_BMP_STRING, ASN1F_UTF8_STRING,
219 explicit_tag=0xa0))
220
221
222class X509_RFC822Name(ASN1_Packet):
223 ASN1_codec = ASN1_Codecs.BER
224 ASN1_root = ASN1F_IA5_STRING("rfc822Name", "")
225
226
227class X509_DNSName(ASN1_Packet):
228 ASN1_codec = ASN1_Codecs.BER
229 ASN1_root = ASN1F_IA5_STRING("dNSName", "")
230
231# XXX write me
232
233
234class X509_X400Address(ASN1_Packet):
235 ASN1_codec = ASN1_Codecs.BER
236 ASN1_root = ASN1F_field("x400Address", "")
237
238
239_default_directoryName = [
240 X509_RDN(),
241 X509_RDN(
242 rdn=[X509_AttributeTypeAndValue(
243 type=ASN1_OID("2.5.4.10"),
244 value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]),
245 X509_RDN(
246 rdn=[X509_AttributeTypeAndValue(
247 type=ASN1_OID("2.5.4.3"),
248 value=ASN1_PRINTABLE_STRING("Scapy Default Name"))])
249]
250
251
252class X509_DirectoryName(ASN1_Packet):
253 ASN1_codec = ASN1_Codecs.BER
254 ASN1_root = ASN1F_SEQUENCE_OF("directoryName", _default_directoryName,
255 X509_RDN)
256
257
258class X509_EDIPartyName(ASN1_Packet):
259 ASN1_codec = ASN1_Codecs.BER
260 ASN1_root = ASN1F_SEQUENCE(
261 ASN1F_optional(
262 ASN1F_X509_DirectoryString("nameAssigner", None,
263 explicit_tag=0xa0)),
264 ASN1F_X509_DirectoryString("partyName", None,
265 explicit_tag=0xa1))
266
267
268class X509_URI(ASN1_Packet):
269 ASN1_codec = ASN1_Codecs.BER
270 ASN1_root = ASN1F_IA5_STRING("uniformResourceIdentifier", "")
271
272
273class X509_IPAddress(ASN1_Packet):
274 ASN1_codec = ASN1_Codecs.BER
275 ASN1_root = ASN1F_STRING("iPAddress", "")
276
277
278class X509_RegisteredID(ASN1_Packet):
279 ASN1_codec = ASN1_Codecs.BER
280 ASN1_root = ASN1F_OID("registeredID", "")
281
282
283class X509_GeneralName(ASN1_Packet):
284 ASN1_codec = ASN1_Codecs.BER
285 ASN1_root = ASN1F_CHOICE("generalName", X509_DirectoryName(),
286 ASN1F_PACKET("otherName", None, X509_OtherName,
287 implicit_tag=0xa0),
288 ASN1F_PACKET("rfc822Name", None, X509_RFC822Name,
289 implicit_tag=0x81),
290 ASN1F_PACKET("dNSName", None, X509_DNSName,
291 implicit_tag=0x82),
292 ASN1F_PACKET("x400Address", None, X509_X400Address, # noqa: E501
293 explicit_tag=0xa3),
294 ASN1F_PACKET("directoryName", None, X509_DirectoryName, # noqa: E501
295 explicit_tag=0xa4),
296 ASN1F_PACKET("ediPartyName", None, X509_EDIPartyName, # noqa: E501
297 explicit_tag=0xa5),
298 ASN1F_PACKET("uniformResourceIdentifier", None, X509_URI, # noqa: E501
299 implicit_tag=0x86),
300 ASN1F_PACKET("ipAddress", None, X509_IPAddress,
301 implicit_tag=0x87),
302 ASN1F_PACKET("registeredID", None, X509_RegisteredID, # noqa: E501
303 implicit_tag=0x88))
304
305
306# Extensions #
307
308class X509_ExtAuthorityKeyIdentifier(ASN1_Packet):
309 ASN1_codec = ASN1_Codecs.BER
310 ASN1_root = ASN1F_SEQUENCE(
311 ASN1F_optional(
312 ASN1F_STRING("keyIdentifier", b"\xff" * 20,
313 implicit_tag=0x80)),
314 ASN1F_optional(
315 ASN1F_SEQUENCE_OF("authorityCertIssuer", None,
316 X509_GeneralName,
317 implicit_tag=0xa1)),
318 ASN1F_optional(
319 ASN1F_INTEGER("authorityCertSerialNumber", None,
320 implicit_tag=0x82)))
321
322
323class X509_ExtSubjectDirectoryAttributes(ASN1_Packet):
324 ASN1_codec = ASN1_Codecs.BER
325 ASN1_root = ASN1F_SEQUENCE_OF("subjectDirectoryAttributes",
326 [X509_Attribute()],
327 X509_Attribute)
328
329
330class X509_ExtSubjectKeyIdentifier(ASN1_Packet):
331 ASN1_codec = ASN1_Codecs.BER
332 ASN1_root = ASN1F_STRING("keyIdentifier", "xff" * 20)
333
334
335class X509_ExtFullName(ASN1_Packet):
336 ASN1_codec = ASN1_Codecs.BER
337 ASN1_root = ASN1F_SEQUENCE_OF("fullName", [X509_GeneralName()],
338 X509_GeneralName, implicit_tag=0xa0)
339
340
341class X509_ExtNameRelativeToCRLIssuer(ASN1_Packet):
342 ASN1_codec = ASN1_Codecs.BER
343 ASN1_root = ASN1F_PACKET("nameRelativeToCRLIssuer", X509_RDN(), X509_RDN,
344 implicit_tag=0xa1)
345
346
347class X509_ExtDistributionPointName(ASN1_Packet):
348 ASN1_codec = ASN1_Codecs.BER
349 ASN1_root = ASN1F_CHOICE("distributionPointName", None,
350 X509_ExtFullName, X509_ExtNameRelativeToCRLIssuer)
351
352
353_reasons_mapping = ["unused",
354 "keyCompromise",
355 "cACompromise",
356 "affiliationChanged",
357 "superseded",
358 "cessationOfOperation",
359 "certificateHold",
360 "privilegeWithdrawn",
361 "aACompromise"]
362
363
364class X509_ExtDistributionPoint(ASN1_Packet):
365 ASN1_codec = ASN1_Codecs.BER
366 ASN1_root = ASN1F_SEQUENCE(
367 ASN1F_optional(
368 ASN1F_PACKET("distributionPoint",
369 X509_ExtDistributionPointName(),
370 X509_ExtDistributionPointName,
371 explicit_tag=0xa0)),
372 ASN1F_optional(
373 ASN1F_FLAGS("reasons", None, _reasons_mapping,
374 implicit_tag=0x81)),
375 ASN1F_optional(
376 ASN1F_SEQUENCE_OF("cRLIssuer", None,
377 X509_GeneralName,
378 implicit_tag=0xa2)))
379
380
381_ku_mapping = ["digitalSignature",
382 "nonRepudiation",
383 "keyEncipherment",
384 "dataEncipherment",
385 "keyAgreement",
386 "keyCertSign",
387 "cRLSign",
388 "encipherOnly",
389 "decipherOnly"]
390
391
392class X509_ExtKeyUsage(ASN1_Packet):
393 ASN1_codec = ASN1_Codecs.BER
394 ASN1_root = ASN1F_FLAGS("keyUsage", "101", _ku_mapping)
395
396 def get_keyUsage(self):
397 return self.ASN1_root.get_flags(self)
398
399
400class X509_ExtPrivateKeyUsagePeriod(ASN1_Packet):
401 ASN1_codec = ASN1_Codecs.BER
402 ASN1_root = ASN1F_SEQUENCE(
403 ASN1F_optional(
404 ASN1F_GENERALIZED_TIME("notBefore",
405 str(GeneralizedTime(-600)),
406 implicit_tag=0x80)),
407 ASN1F_optional(
408 ASN1F_GENERALIZED_TIME("notAfter",
409 str(GeneralizedTime(+86400)),
410 implicit_tag=0x81)))
411
412
413class X509_PolicyMapping(ASN1_Packet):
414 ASN1_codec = ASN1_Codecs.BER
415 ASN1_root = ASN1F_SEQUENCE(
416 ASN1F_OID("issuerDomainPolicy", None),
417 ASN1F_OID("subjectDomainPolicy", None))
418
419
420class X509_ExtPolicyMappings(ASN1_Packet):
421 ASN1_codec = ASN1_Codecs.BER
422 ASN1_root = ASN1F_SEQUENCE_OF("policyMappings", [], X509_PolicyMapping)
423
424
425class X509_ExtBasicConstraints(ASN1_Packet):
426 # The cA field should not be optional, but some certs omit it for False.
427 ASN1_codec = ASN1_Codecs.BER
428 ASN1_root = ASN1F_SEQUENCE(
429 ASN1F_optional(
430 ASN1F_BOOLEAN("cA", False)),
431 ASN1F_optional(
432 ASN1F_INTEGER("pathLenConstraint", None)))
433
434
435class X509_ExtCRLNumber(ASN1_Packet):
436 ASN1_codec = ASN1_Codecs.BER
437 ASN1_root = ASN1F_INTEGER("cRLNumber", 0)
438
439
440_cRL_reasons = ["unspecified",
441 "keyCompromise",
442 "cACompromise",
443 "affiliationChanged",
444 "superseded",
445 "cessationOfOperation",
446 "certificateHold",
447 "unused_reasonCode",
448 "removeFromCRL",
449 "privilegeWithdrawn",
450 "aACompromise"]
451
452
453class X509_ExtReasonCode(ASN1_Packet):
454 ASN1_codec = ASN1_Codecs.BER
455 ASN1_root = ASN1F_ENUMERATED("cRLReason", 0, _cRL_reasons)
456
457
458class X509_ExtDeltaCRLIndicator(ASN1_Packet):
459 ASN1_codec = ASN1_Codecs.BER
460 ASN1_root = ASN1F_INTEGER("deltaCRLIndicator", 0)
461
462
463class X509_ExtIssuingDistributionPoint(ASN1_Packet):
464 ASN1_codec = ASN1_Codecs.BER
465 ASN1_root = ASN1F_SEQUENCE(
466 ASN1F_optional(
467 ASN1F_PACKET("distributionPoint",
468 X509_ExtDistributionPointName(),
469 X509_ExtDistributionPointName,
470 explicit_tag=0xa0)),
471 ASN1F_BOOLEAN("onlyContainsUserCerts", False,
472 implicit_tag=0x81),
473 ASN1F_BOOLEAN("onlyContainsCACerts", False,
474 implicit_tag=0x82),
475 ASN1F_optional(
476 ASN1F_FLAGS("onlySomeReasons", None,
477 _reasons_mapping,
478 implicit_tag=0x83)),
479 ASN1F_BOOLEAN("indirectCRL", False,
480 implicit_tag=0x84),
481 ASN1F_BOOLEAN("onlyContainsAttributeCerts", False,
482 implicit_tag=0x85))
483
484
485class X509_ExtCertificateIssuer(ASN1_Packet):
486 ASN1_codec = ASN1_Codecs.BER
487 ASN1_root = ASN1F_SEQUENCE_OF("certificateIssuer", [], X509_GeneralName)
488
489
490class X509_ExtInvalidityDate(ASN1_Packet):
491 ASN1_codec = ASN1_Codecs.BER
492 ASN1_root = ASN1F_GENERALIZED_TIME("invalidityDate", str(ZuluTime(+86400)))
493
494
495class X509_ExtSubjectAltName(ASN1_Packet):
496 ASN1_codec = ASN1_Codecs.BER
497 ASN1_root = ASN1F_SEQUENCE_OF("subjectAltName", [], X509_GeneralName)
498
499
500class X509_ExtIssuerAltName(ASN1_Packet):
501 ASN1_codec = ASN1_Codecs.BER
502 ASN1_root = ASN1F_SEQUENCE_OF("issuerAltName", [], X509_GeneralName)
503
504
505class X509_ExtGeneralSubtree(ASN1_Packet):
506 # 'minimum' is not optional in RFC 5280, yet it is in some implementations.
507 ASN1_codec = ASN1_Codecs.BER
508 ASN1_root = ASN1F_SEQUENCE(
509 ASN1F_PACKET("base", X509_GeneralName(), X509_GeneralName),
510 ASN1F_optional(
511 ASN1F_INTEGER("minimum", None, implicit_tag=0x80)),
512 ASN1F_optional(
513 ASN1F_INTEGER("maximum", None, implicit_tag=0x81)))
514
515
516class X509_ExtNameConstraints(ASN1_Packet):
517 ASN1_codec = ASN1_Codecs.BER
518 ASN1_root = ASN1F_SEQUENCE(
519 ASN1F_optional(
520 ASN1F_SEQUENCE_OF("permittedSubtrees", None,
521 X509_ExtGeneralSubtree,
522 implicit_tag=0xa0)),
523 ASN1F_optional(
524 ASN1F_SEQUENCE_OF("excludedSubtrees", None,
525 X509_ExtGeneralSubtree,
526 implicit_tag=0xa1)))
527
528
529class X509_ExtPolicyConstraints(ASN1_Packet):
530 ASN1_codec = ASN1_Codecs.BER
531 ASN1_root = ASN1F_SEQUENCE(
532 ASN1F_optional(
533 ASN1F_INTEGER("requireExplicitPolicy", None,
534 implicit_tag=0x80)),
535 ASN1F_optional(
536 ASN1F_INTEGER("inhibitPolicyMapping", None,
537 implicit_tag=0x81)))
538
539
540class X509_ExtExtendedKeyUsage(ASN1_Packet):
541 ASN1_codec = ASN1_Codecs.BER
542 ASN1_root = ASN1F_SEQUENCE_OF("extendedKeyUsage", [], ASN1P_OID)
543
544 def get_extendedKeyUsage(self):
545 eku_array = self.extendedKeyUsage
546 return [eku.oid.oidname for eku in eku_array]
547
548
549class X509_ExtNoticeReference(ASN1_Packet):
550 ASN1_codec = ASN1_Codecs.BER
551 ASN1_root = ASN1F_SEQUENCE(
552 ASN1F_CHOICE("organization",
553 ASN1_UTF8_STRING("Dummy Organization"),
554 ASN1F_IA5_STRING, ASN1F_ISO646_STRING,
555 ASN1F_BMP_STRING, ASN1F_UTF8_STRING),
556 ASN1F_SEQUENCE_OF("noticeNumbers", [], ASN1P_INTEGER))
557
558
559class X509_ExtUserNotice(ASN1_Packet):
560 ASN1_codec = ASN1_Codecs.BER
561 ASN1_root = ASN1F_SEQUENCE(
562 ASN1F_optional(
563 ASN1F_PACKET("noticeRef", None,
564 X509_ExtNoticeReference)),
565 ASN1F_optional(
566 ASN1F_CHOICE("explicitText",
567 ASN1_UTF8_STRING("Dummy ExplicitText"),
568 ASN1F_IA5_STRING, ASN1F_ISO646_STRING,
569 ASN1F_BMP_STRING, ASN1F_UTF8_STRING)))
570
571
572class X509_ExtPolicyQualifierInfo(ASN1_Packet):
573 ASN1_codec = ASN1_Codecs.BER
574 ASN1_root = ASN1F_SEQUENCE(
575 ASN1F_OID("policyQualifierId", "1.3.6.1.5.5.7.2.1"),
576 ASN1F_CHOICE("qualifier", ASN1_IA5_STRING("cps_str"),
577 ASN1F_IA5_STRING, X509_ExtUserNotice))
578
579
580class X509_ExtPolicyInformation(ASN1_Packet):
581 ASN1_codec = ASN1_Codecs.BER
582 ASN1_root = ASN1F_SEQUENCE(
583 ASN1F_OID("policyIdentifier", "2.5.29.32.0"),
584 ASN1F_optional(
585 ASN1F_SEQUENCE_OF("policyQualifiers", None,
586 X509_ExtPolicyQualifierInfo)))
587
588
589class X509_ExtCertificatePolicies(ASN1_Packet):
590 ASN1_codec = ASN1_Codecs.BER
591 ASN1_root = ASN1F_SEQUENCE_OF("certificatePolicies",
592 [X509_ExtPolicyInformation()],
593 X509_ExtPolicyInformation)
594
595
596class X509_ExtCRLDistributionPoints(ASN1_Packet):
597 ASN1_codec = ASN1_Codecs.BER
598 ASN1_root = ASN1F_SEQUENCE_OF("cRLDistributionPoints",
599 [X509_ExtDistributionPoint()],
600 X509_ExtDistributionPoint)
601
602
603class X509_ExtInhibitAnyPolicy(ASN1_Packet):
604 ASN1_codec = ASN1_Codecs.BER
605 ASN1_root = ASN1F_INTEGER("skipCerts", 0)
606
607
608class X509_ExtFreshestCRL(ASN1_Packet):
609 ASN1_codec = ASN1_Codecs.BER
610 ASN1_root = ASN1F_SEQUENCE_OF("cRLDistributionPoints",
611 [X509_ExtDistributionPoint()],
612 X509_ExtDistributionPoint)
613
614
615class X509_AccessDescription(ASN1_Packet):
616 ASN1_codec = ASN1_Codecs.BER
617 ASN1_root = ASN1F_SEQUENCE(
618 ASN1F_OID("accessMethod", "0"),
619 ASN1F_PACKET("accessLocation", X509_GeneralName(),
620 X509_GeneralName))
621
622
623class X509_ExtAuthInfoAccess(ASN1_Packet):
624 ASN1_codec = ASN1_Codecs.BER
625 ASN1_root = ASN1F_SEQUENCE_OF("authorityInfoAccess",
626 [X509_AccessDescription()],
627 X509_AccessDescription)
628
629
630class X509_ExtQcStatement(ASN1_Packet):
631 ASN1_codec = ASN1_Codecs.BER
632 ASN1_root = ASN1F_SEQUENCE(
633 ASN1F_OID("statementId", "0.4.0.1862.1.1"),
634 ASN1F_optional(
635 ASN1F_field("statementInfo", None)))
636
637
638class X509_ExtQcStatements(ASN1_Packet):
639 ASN1_codec = ASN1_Codecs.BER
640 ASN1_root = ASN1F_SEQUENCE_OF("qcStatements",
641 [X509_ExtQcStatement()],
642 X509_ExtQcStatement)
643
644
645class X509_ExtSubjInfoAccess(ASN1_Packet):
646 ASN1_codec = ASN1_Codecs.BER
647 ASN1_root = ASN1F_SEQUENCE_OF("subjectInfoAccess",
648 [X509_AccessDescription()],
649 X509_AccessDescription)
650
651
652class X509_ExtNetscapeCertType(ASN1_Packet):
653 ASN1_codec = ASN1_Codecs.BER
654 ASN1_root = ASN1F_BIT_STRING("netscapeCertType", "")
655
656
657class X509_ExtComment(ASN1_Packet):
658 ASN1_codec = ASN1_Codecs.BER
659 ASN1_root = ASN1F_CHOICE("comment",
660 ASN1_UTF8_STRING("Dummy comment."),
661 ASN1F_IA5_STRING, ASN1F_ISO646_STRING,
662 ASN1F_BMP_STRING, ASN1F_UTF8_STRING)
663
664
665class X509_ExtDefault(ASN1_Packet):
666 ASN1_codec = ASN1_Codecs.BER
667 ASN1_root = ASN1F_field("value", None)
668
669
670# oid-info.com shows that some extensions share multiple OIDs.
671# Here we only reproduce those written in RFC5280.
672_ext_mapping = {
673 "2.5.29.9": X509_ExtSubjectDirectoryAttributes,
674 "2.5.29.14": X509_ExtSubjectKeyIdentifier,
675 "2.5.29.15": X509_ExtKeyUsage,
676 "2.5.29.16": X509_ExtPrivateKeyUsagePeriod,
677 "2.5.29.17": X509_ExtSubjectAltName,
678 "2.5.29.18": X509_ExtIssuerAltName,
679 "2.5.29.19": X509_ExtBasicConstraints,
680 "2.5.29.20": X509_ExtCRLNumber,
681 "2.5.29.21": X509_ExtReasonCode,
682 "2.5.29.24": X509_ExtInvalidityDate,
683 "2.5.29.27": X509_ExtDeltaCRLIndicator,
684 "2.5.29.28": X509_ExtIssuingDistributionPoint,
685 "2.5.29.29": X509_ExtCertificateIssuer,
686 "2.5.29.30": X509_ExtNameConstraints,
687 "2.5.29.31": X509_ExtCRLDistributionPoints,
688 "2.5.29.32": X509_ExtCertificatePolicies,
689 "2.5.29.33": X509_ExtPolicyMappings,
690 "2.5.29.35": X509_ExtAuthorityKeyIdentifier,
691 "2.5.29.36": X509_ExtPolicyConstraints,
692 "2.5.29.37": X509_ExtExtendedKeyUsage,
693 "2.5.29.46": X509_ExtFreshestCRL,
694 "2.5.29.54": X509_ExtInhibitAnyPolicy,
695 "2.16.840.1.113730.1.1": X509_ExtNetscapeCertType,
696 "2.16.840.1.113730.1.13": X509_ExtComment,
697 "1.3.6.1.5.5.7.1.1": X509_ExtAuthInfoAccess,
698 "1.3.6.1.5.5.7.1.3": X509_ExtQcStatements,
699 "1.3.6.1.5.5.7.1.11": X509_ExtSubjInfoAccess
700}
701
702
703class ASN1F_EXT_SEQUENCE(ASN1F_SEQUENCE):
704 # We use explicit_tag=0x04 with extnValue as STRING encapsulation.
705 def __init__(self, **kargs):
706 seq = [ASN1F_OID("extnID", "2.5.29.19"),
707 ASN1F_optional(
708 ASN1F_BOOLEAN("critical", False)),
709 ASN1F_PACKET("extnValue",
710 X509_ExtBasicConstraints(),
711 X509_ExtBasicConstraints,
712 explicit_tag=0x04)]
713 ASN1F_SEQUENCE.__init__(self, *seq, **kargs)
714
715 def dissect(self, pkt, s):
716 _, s = BER_tagging_dec(s, implicit_tag=self.implicit_tag,
717 explicit_tag=self.explicit_tag,
718 safe=self.flexible_tag)
719 codec = self.ASN1_tag.get_codec(pkt.ASN1_codec)
720 i, s, remain = codec.check_type_check_len(s)
721 extnID = self.seq[0]
722 critical = self.seq[1]
723 try:
724 oid, s = extnID.m2i(pkt, s)
725 extnID.set_val(pkt, oid)
726 s = critical.dissect(pkt, s)
727 encapsed = X509_ExtDefault
728 if oid.val in _ext_mapping:
729 encapsed = _ext_mapping[oid.val]
730 self.seq[2].cls = encapsed
731 self.seq[2].cls.ASN1_root.flexible_tag = True
732 # there are too many private extensions not to be flexible here
733 self.seq[2].default = encapsed()
734 s = self.seq[2].dissect(pkt, s)
735 if not self.flexible_tag and len(s) > 0:
736 err_msg = "extension sequence length issue"
737 raise BER_Decoding_Error(err_msg, remaining=s)
738 except ASN1F_badsequence:
739 raise Exception("could not parse extensions")
740 return remain
741
742
743class X509_Extension(ASN1_Packet):
744 ASN1_codec = ASN1_Codecs.BER
745 ASN1_root = ASN1F_EXT_SEQUENCE()
746
747
748class X509_Extensions(ASN1_Packet):
749 # we use this in OCSP status requests, in tls/handshake.py
750 ASN1_codec = ASN1_Codecs.BER
751 ASN1_root = ASN1F_optional(
752 ASN1F_SEQUENCE_OF("extensions",
753 None, X509_Extension))
754
755
756# Public key wrapper #
757
758class X509_AlgorithmIdentifier(ASN1_Packet):
759 ASN1_codec = ASN1_Codecs.BER
760 ASN1_root = ASN1F_SEQUENCE(
761 ASN1F_OID("algorithm", "1.2.840.113549.1.1.11"),
762 ASN1F_optional(
763 ASN1F_CHOICE("parameters", ASN1_NULL(0),
764 ASN1F_NULL, ECParameters)))
765
766
767class ASN1F_X509_SubjectPublicKeyInfo(ASN1F_SEQUENCE):
768 def __init__(self, **kargs):
769 seq = [ASN1F_PACKET("signatureAlgorithm",
770 X509_AlgorithmIdentifier(),
771 X509_AlgorithmIdentifier),
772 MultipleTypeField(
773 [
774 (ASN1F_BIT_STRING_ENCAPS("subjectPublicKey",
775 RSAPublicKey(),
776 RSAPublicKey),
777 lambda pkt: "rsa" in pkt.signatureAlgorithm.algorithm.oidname.lower()), # noqa: E501
778 (ASN1F_PACKET("subjectPublicKey",
779 ECDSAPublicKey(),
780 ECDSAPublicKey),
781 lambda pkt: "ecPublicKey" == pkt.signatureAlgorithm.algorithm.oidname), # noqa: E501
782 ],
783 ASN1F_BIT_STRING("subjectPublicKey", ""))]
784 ASN1F_SEQUENCE.__init__(self, *seq, **kargs)
785
786
787class X509_SubjectPublicKeyInfo(ASN1_Packet):
788 ASN1_codec = ASN1_Codecs.BER
789 ASN1_root = ASN1F_X509_SubjectPublicKeyInfo()
790
791
792# OpenSSL compatibility wrappers #
793
794# XXX As ECDSAPrivateKey already uses the structure from RFC 5958,
795# and as we would prefer encapsulated RSA private keys to be parsed,
796# this lazy implementation actually supports RSA encoding only.
797# We'd rather call it RSAPrivateKey_OpenSSL than X509_PrivateKeyInfo.
798class RSAPrivateKey_OpenSSL(ASN1_Packet):
799 ASN1_codec = ASN1_Codecs.BER
800 ASN1_root = ASN1F_SEQUENCE(
801 ASN1F_enum_INTEGER("version", 0, ["v1", "v2"]),
802 ASN1F_PACKET("privateKeyAlgorithm",
803 X509_AlgorithmIdentifier(),
804 X509_AlgorithmIdentifier),
805 ASN1F_PACKET("privateKey",
806 RSAPrivateKey(),
807 RSAPrivateKey,
808 explicit_tag=0x04),
809 ASN1F_optional(
810 ASN1F_PACKET("parameters", None, ECParameters,
811 explicit_tag=0xa0)),
812 ASN1F_optional(
813 ASN1F_PACKET("publicKey", None,
814 ECDSAPublicKey,
815 explicit_tag=0xa1)))
816
817# We need this hack because ECParameters parsing below must return
818# a Padding payload, and making the ASN1_Packet class have Padding
819# instead of Raw payload would break things...
820
821
822class _PacketFieldRaw(PacketField):
823 def getfield(self, pkt, s):
824 i = self.m2i(pkt, s)
825 remain = ""
826 if conf.raw_layer in i:
827 r = i[conf.raw_layer]
828 del r.underlayer.payload
829 remain = r.load
830 return remain, i
831
832
833class ECDSAPrivateKey_OpenSSL(Packet):
834 name = "ECDSA Params + Private Key"
835 fields_desc = [_PacketFieldRaw("ecparam",
836 ECParameters(),
837 ECParameters),
838 PacketField("privateKey",
839 ECDSAPrivateKey(),
840 ECDSAPrivateKey)]
841
842
843# TBSCertificate & Certificate #
844
845_default_issuer = [
846 X509_RDN(),
847 X509_RDN(
848 rdn=[X509_AttributeTypeAndValue(
849 type=ASN1_OID("2.5.4.10"),
850 value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]),
851 X509_RDN(
852 rdn=[X509_AttributeTypeAndValue(
853 type=ASN1_OID("2.5.4.3"),
854 value=ASN1_PRINTABLE_STRING("Scapy Default Issuer"))])
855]
856
857_default_subject = [
858 X509_RDN(),
859 X509_RDN(
860 rdn=[X509_AttributeTypeAndValue(
861 type=ASN1_OID("2.5.4.10"),
862 value=ASN1_PRINTABLE_STRING("Scapy, Inc."))]),
863 X509_RDN(
864 rdn=[X509_AttributeTypeAndValue(
865 type=ASN1_OID("2.5.4.3"),
866 value=ASN1_PRINTABLE_STRING("Scapy Default Subject"))])
867]
868
869
870class X509_Validity(ASN1_Packet):
871 ASN1_codec = ASN1_Codecs.BER
872 ASN1_root = ASN1F_SEQUENCE(
873 ASN1F_CHOICE("not_before",
874 ASN1_UTC_TIME(str(ZuluTime(-600))),
875 ASN1F_UTC_TIME, ASN1F_GENERALIZED_TIME),
876 ASN1F_CHOICE("not_after",
877 ASN1_UTC_TIME(str(ZuluTime(+86400))),
878 ASN1F_UTC_TIME, ASN1F_GENERALIZED_TIME))
879
880
881_attrName_mapping = [
882 ("countryName", "C"),
883 ("stateOrProvinceName", "ST"),
884 ("localityName", "L"),
885 ("organizationName", "O"),
886 ("organizationUnitName", "OU"),
887 ("commonName", "CN")
888]
889_attrName_specials = [name for name, symbol in _attrName_mapping]
890
891
892class X509_TBSCertificate(ASN1_Packet):
893 ASN1_codec = ASN1_Codecs.BER
894 ASN1_root = ASN1F_SEQUENCE(
895 ASN1F_optional(
896 ASN1F_enum_INTEGER("version", 0x2, ["v1", "v2", "v3"],
897 explicit_tag=0xa0)),
898 ASN1F_INTEGER("serialNumber", 1),
899 ASN1F_PACKET("signature",
900 X509_AlgorithmIdentifier(),
901 X509_AlgorithmIdentifier),
902 ASN1F_SEQUENCE_OF("issuer", _default_issuer, X509_RDN),
903 ASN1F_PACKET("validity",
904 X509_Validity(),
905 X509_Validity),
906 ASN1F_SEQUENCE_OF("subject", _default_subject, X509_RDN),
907 ASN1F_PACKET("subjectPublicKeyInfo",
908 X509_SubjectPublicKeyInfo(),
909 X509_SubjectPublicKeyInfo),
910 ASN1F_optional(
911 ASN1F_BIT_STRING("issuerUniqueID", None,
912 implicit_tag=0x81)),
913 ASN1F_optional(
914 ASN1F_BIT_STRING("subjectUniqueID", None,
915 implicit_tag=0x82)),
916 ASN1F_optional(
917 ASN1F_SEQUENCE_OF("extensions",
918 [X509_Extension()],
919 X509_Extension,
920 explicit_tag=0xa3)))
921
922 def get_issuer(self):
923 attrs = self.issuer
924 attrsDict = {}
925 for attr in attrs:
926 # we assume there is only one name in each rdn ASN1_SET
927 attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501
928 return attrsDict
929
930 def get_issuer_str(self):
931 """
932 Returns a one-line string containing every type/value
933 in a rather specific order. sorted() built-in ensures unicity.
934 """
935 name_str = ""
936 attrsDict = self.get_issuer()
937 for attrType, attrSymbol in _attrName_mapping:
938 if attrType in attrsDict:
939 name_str += "/" + attrSymbol + "="
940 name_str += attrsDict[attrType]
941 for attrType in sorted(attrsDict):
942 if attrType not in _attrName_specials:
943 name_str += "/" + attrType + "="
944 name_str += attrsDict[attrType]
945 return name_str
946
947 def get_subject(self):
948 attrs = self.subject
949 attrsDict = {}
950 for attr in attrs:
951 # we assume there is only one name in each rdn ASN1_SET
952 attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501
953 return attrsDict
954
955 def get_subject_str(self):
956 name_str = ""
957 attrsDict = self.get_subject()
958 for attrType, attrSymbol in _attrName_mapping:
959 if attrType in attrsDict:
960 name_str += "/" + attrSymbol + "="
961 name_str += attrsDict[attrType]
962 for attrType in sorted(attrsDict):
963 if attrType not in _attrName_specials:
964 name_str += "/" + attrType + "="
965 name_str += attrsDict[attrType]
966 return name_str
967
968
969class ASN1F_X509_Cert(ASN1F_SEQUENCE):
970 def __init__(self, **kargs):
971 seq = [ASN1F_PACKET("tbsCertificate",
972 X509_TBSCertificate(),
973 X509_TBSCertificate),
974 ASN1F_PACKET("signatureAlgorithm",
975 X509_AlgorithmIdentifier(),
976 X509_AlgorithmIdentifier),
977 MultipleTypeField(
978 [
979 (ASN1F_BIT_STRING_ENCAPS("signatureValue",
980 ECDSASignature(),
981 ECDSASignature),
982 lambda pkt: "ecdsa" in pkt.signatureAlgorithm.algorithm.oidname.lower()), # noqa: E501
983 ],
984 ASN1F_BIT_STRING("signatureValue",
985 "defaultsignature" * 2))]
986 ASN1F_SEQUENCE.__init__(self, *seq, **kargs)
987
988
989class X509_Cert(ASN1_Packet):
990 ASN1_codec = ASN1_Codecs.BER
991 ASN1_root = ASN1F_X509_Cert()
992
993
994# TBSCertList & CRL #
995
996class X509_RevokedCertificate(ASN1_Packet):
997 ASN1_codec = ASN1_Codecs.BER
998 ASN1_root = ASN1F_SEQUENCE(ASN1F_INTEGER("serialNumber", 1),
999 ASN1F_UTC_TIME("revocationDate",
1000 str(ZuluTime(+86400))),
1001 ASN1F_optional(
1002 ASN1F_SEQUENCE_OF("crlEntryExtensions",
1003 None, X509_Extension)))
1004
1005
1006class X509_TBSCertList(ASN1_Packet):
1007 ASN1_codec = ASN1_Codecs.BER
1008 ASN1_root = ASN1F_SEQUENCE(
1009 ASN1F_optional(
1010 ASN1F_enum_INTEGER("version", 1, ["v1", "v2"])),
1011 ASN1F_PACKET("signature",
1012 X509_AlgorithmIdentifier(),
1013 X509_AlgorithmIdentifier),
1014 ASN1F_SEQUENCE_OF("issuer", _default_issuer, X509_RDN),
1015 ASN1F_UTC_TIME("this_update", str(ZuluTime(-1))),
1016 ASN1F_optional(
1017 ASN1F_UTC_TIME("next_update", None)),
1018 ASN1F_optional(
1019 ASN1F_SEQUENCE_OF("revokedCertificates", None,
1020 X509_RevokedCertificate)),
1021 ASN1F_optional(
1022 ASN1F_SEQUENCE_OF("crlExtensions", None,
1023 X509_Extension,
1024 explicit_tag=0xa0)))
1025
1026 def get_issuer(self):
1027 attrs = self.issuer
1028 attrsDict = {}
1029 for attr in attrs:
1030 # we assume there is only one name in each rdn ASN1_SET
1031 attrsDict[attr.rdn[0].type.oidname] = plain_str(attr.rdn[0].value.val) # noqa: E501
1032 return attrsDict
1033
1034 def get_issuer_str(self):
1035 """
1036 Returns a one-line string containing every type/value
1037 in a rather specific order. sorted() built-in ensures unicity.
1038 """
1039 name_str = ""
1040 attrsDict = self.get_issuer()
1041 for attrType, attrSymbol in _attrName_mapping:
1042 if attrType in attrsDict:
1043 name_str += "/" + attrSymbol + "="
1044 name_str += attrsDict[attrType]
1045 for attrType in sorted(attrsDict):
1046 if attrType not in _attrName_specials:
1047 name_str += "/" + attrType + "="
1048 name_str += attrsDict[attrType]
1049 return name_str
1050
1051
1052class ASN1F_X509_CRL(ASN1F_SEQUENCE):
1053 def __init__(self, **kargs):
1054 seq = [ASN1F_PACKET("tbsCertList",
1055 X509_TBSCertList(),
1056 X509_TBSCertList),
1057 ASN1F_PACKET("signatureAlgorithm",
1058 X509_AlgorithmIdentifier(),
1059 X509_AlgorithmIdentifier),
1060 MultipleTypeField(
1061 [
1062 (ASN1F_BIT_STRING_ENCAPS("signatureValue",
1063 ECDSASignature(),
1064 ECDSASignature),
1065 lambda pkt: "ecdsa" in pkt.signatureAlgorithm.algorithm.oidname.lower()), # noqa: E501
1066 ],
1067 ASN1F_BIT_STRING("signatureValue",
1068 "defaultsignature" * 2))]
1069 ASN1F_SEQUENCE.__init__(self, *seq, **kargs)
1070
1071
1072class X509_CRL(ASN1_Packet):
1073 ASN1_codec = ASN1_Codecs.BER
1074 ASN1_root = ASN1F_X509_CRL()
1075
1076
1077#############################
1078# OCSP Status packets #
1079#############################
1080# based on RFC 6960
1081
1082class OCSP_CertID(ASN1_Packet):
1083 ASN1_codec = ASN1_Codecs.BER
1084 ASN1_root = ASN1F_SEQUENCE(
1085 ASN1F_PACKET("hashAlgorithm",
1086 X509_AlgorithmIdentifier(),
1087 X509_AlgorithmIdentifier),
1088 ASN1F_STRING("issuerNameHash", ""),
1089 ASN1F_STRING("issuerKeyHash", ""),
1090 ASN1F_INTEGER("serialNumber", 0))
1091
1092
1093class OCSP_GoodInfo(ASN1_Packet):
1094 ASN1_codec = ASN1_Codecs.BER
1095 ASN1_root = ASN1F_NULL("info", 0)
1096
1097
1098class OCSP_RevokedInfo(ASN1_Packet):
1099 ASN1_codec = ASN1_Codecs.BER
1100 ASN1_root = ASN1F_SEQUENCE(
1101 ASN1F_GENERALIZED_TIME("revocationTime", ""),
1102 ASN1F_optional(
1103 ASN1F_PACKET("revocationReason", None,
1104 X509_ExtReasonCode,
1105 explicit_tag=0xa0)))
1106
1107
1108class OCSP_UnknownInfo(ASN1_Packet):
1109 ASN1_codec = ASN1_Codecs.BER
1110 ASN1_root = ASN1F_NULL("info", 0)
1111
1112
1113class OCSP_CertStatus(ASN1_Packet):
1114 ASN1_codec = ASN1_Codecs.BER
1115 ASN1_root = ASN1F_CHOICE("certStatus", None,
1116 ASN1F_PACKET("good", OCSP_GoodInfo(),
1117 OCSP_GoodInfo, implicit_tag=0x80),
1118 ASN1F_PACKET("revoked", OCSP_RevokedInfo(),
1119 OCSP_RevokedInfo, implicit_tag=0xa1),
1120 ASN1F_PACKET("unknown", OCSP_UnknownInfo(),
1121 OCSP_UnknownInfo, implicit_tag=0x82))
1122
1123
1124class OCSP_SingleResponse(ASN1_Packet):
1125 ASN1_codec = ASN1_Codecs.BER
1126 ASN1_root = ASN1F_SEQUENCE(
1127 ASN1F_PACKET("certID", OCSP_CertID(), OCSP_CertID),
1128 ASN1F_PACKET("certStatus", OCSP_CertStatus(certStatus=OCSP_GoodInfo()),
1129 OCSP_CertStatus),
1130 ASN1F_GENERALIZED_TIME("thisUpdate", ""),
1131 ASN1F_optional(
1132 ASN1F_GENERALIZED_TIME("nextUpdate", "",
1133 explicit_tag=0xa0)),
1134 ASN1F_optional(
1135 ASN1F_SEQUENCE_OF("singleExtensions", None,
1136 X509_Extension,
1137 explicit_tag=0xa1)))
1138
1139
1140class OCSP_ByName(ASN1_Packet):
1141 ASN1_codec = ASN1_Codecs.BER
1142 ASN1_root = ASN1F_SEQUENCE_OF("byName", [], X509_RDN)
1143
1144
1145class OCSP_ByKey(ASN1_Packet):
1146 ASN1_codec = ASN1_Codecs.BER
1147 ASN1_root = ASN1F_STRING("byKey", "")
1148
1149
1150class OCSP_ResponderID(ASN1_Packet):
1151 ASN1_codec = ASN1_Codecs.BER
1152 ASN1_root = ASN1F_CHOICE("responderID", None,
1153 ASN1F_PACKET("byName", OCSP_ByName(), OCSP_ByName,
1154 explicit_tag=0xa1),
1155 ASN1F_PACKET("byKey", OCSP_ByKey(), OCSP_ByKey,
1156 explicit_tag=0xa2))
1157
1158
1159class OCSP_ResponseData(ASN1_Packet):
1160 ASN1_codec = ASN1_Codecs.BER
1161 ASN1_root = ASN1F_SEQUENCE(
1162 ASN1F_optional(
1163 ASN1F_enum_INTEGER("version", 0, {0: "v1"},
1164 explicit_tag=0x80)),
1165 ASN1F_PACKET("responderID", OCSP_ResponderID(responderID=OCSP_ByName()),
1166 OCSP_ResponderID),
1167 ASN1F_GENERALIZED_TIME("producedAt",
1168 str(GeneralizedTime())),
1169 ASN1F_SEQUENCE_OF("responses", [], OCSP_SingleResponse),
1170 ASN1F_optional(
1171 ASN1F_SEQUENCE_OF("responseExtensions", None,
1172 X509_Extension,
1173 explicit_tag=0xa1)))
1174
1175
1176class ASN1F_OCSP_BasicResponse(ASN1F_SEQUENCE):
1177 def __init__(self, **kargs):
1178 seq = [ASN1F_PACKET("tbsResponseData",
1179 OCSP_ResponseData(),
1180 OCSP_ResponseData),
1181 ASN1F_PACKET("signatureAlgorithm",
1182 X509_AlgorithmIdentifier(),
1183 X509_AlgorithmIdentifier),
1184 MultipleTypeField(
1185 [
1186 (ASN1F_BIT_STRING_ENCAPS("signature",
1187 ECDSASignature(),
1188 ECDSASignature),
1189 lambda pkt: "ecdsa" in pkt.signatureAlgorithm.algorithm.oidname.lower()), # noqa: E501
1190 ],
1191 ASN1F_BIT_STRING("signature",
1192 "defaultsignature" * 2)),
1193 ASN1F_optional(
1194 ASN1F_SEQUENCE_OF("certs", None, X509_Cert,
1195 explicit_tag=0xa0))]
1196 ASN1F_SEQUENCE.__init__(self, *seq, **kargs)
1197
1198
1199class OCSP_ResponseBytes(ASN1_Packet):
1200 ASN1_codec = ASN1_Codecs.BER
1201 ASN1_root = ASN1F_SEQUENCE(
1202 ASN1F_OID("responseType", "1.3.6.1.5.5.7.48.1.1"),
1203 ASN1F_OCSP_BasicResponse(explicit_tag=0x04))
1204
1205
1206_responseStatus_mapping = ["successful",
1207 "malformedRequest",
1208 "internalError",
1209 "tryLater",
1210 "notUsed",
1211 "sigRequired",
1212 "unauthorized"]
1213
1214
1215class OCSP_Response(ASN1_Packet):
1216 ASN1_codec = ASN1_Codecs.BER
1217 ASN1_root = ASN1F_SEQUENCE(
1218 ASN1F_ENUMERATED("responseStatus", 0,
1219 _responseStatus_mapping),
1220 ASN1F_optional(
1221 ASN1F_PACKET("responseBytes", None,
1222 OCSP_ResponseBytes,
1223 explicit_tag=0xa0)))