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