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