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