2 * Testing tool for ASN.1 routines
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
15 static const char * asn1_class_str(int class)
18 case ASN1_CLASS_UNIVERSAL
:
20 case ASN1_CLASS_APPLICATION
:
22 case ASN1_CLASS_CONTEXT_SPECIFIC
:
23 return "Context-specific";
24 case ASN1_CLASS_PRIVATE
:
32 int asn1_parse(const u8
*buf
, size_t len
, int level
)
34 const u8
*pos
, *prev
, *end
;
35 char prefix
[10], str
[100];
42 if ((size_t) _level
> sizeof(prefix
) - 1)
43 _level
= sizeof(prefix
) - 1;
44 memset(prefix
, ' ', _level
);
45 prefix
[_level
] = '\0';
51 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0)
57 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Class %d(%s) P/C %d(%s) "
59 prefix
, hdr
.class, asn1_class_str(hdr
.class),
61 hdr
.constructed
? "Constructed" : "Primitive",
64 if (hdr
.class == ASN1_CLASS_CONTEXT_SPECIFIC
&&
66 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
71 if (hdr
.class != ASN1_CLASS_UNIVERSAL
)
77 wpa_printf(MSG_DEBUG
, "ASN.1: Non-zero "
78 "end-of-contents length (%u)",
82 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s EOC", prefix
);
84 case ASN1_TAG_BOOLEAN
:
85 if (hdr
.length
!= 1) {
86 wpa_printf(MSG_DEBUG
, "ASN.1: Unexpected "
87 "Boolean length (%u)", hdr
.length
);
91 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Boolean %s",
92 prefix
, tmp
? "TRUE" : "FALSE");
94 case ASN1_TAG_INTEGER
:
95 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: INTEGER",
99 case ASN1_TAG_BITSTRING
:
100 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: BitString",
104 case ASN1_TAG_OCTETSTRING
:
105 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: OctetString",
111 wpa_printf(MSG_DEBUG
, "ASN.1: Non-zero Null "
112 "length (%u)", hdr
.length
);
115 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Null", prefix
);
118 if (asn1_get_oid(prev
, end
- prev
, &oid
, &prev
) < 0) {
119 wpa_printf(MSG_DEBUG
, "ASN.1: Invalid OID");
122 asn1_oid_to_str(&oid
, str
, sizeof(str
));
123 wpa_printf(MSG_DEBUG
, "ASN.1:%s OID %s", prefix
, str
);
126 case ANS1_TAG_RELATIVE_OID
:
127 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: Relative OID",
131 case ASN1_TAG_SEQUENCE
:
132 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s SEQUENCE", prefix
);
133 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
138 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s SET", prefix
);
139 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
143 case ASN1_TAG_PRINTABLESTRING
:
144 wpa_hexdump_ascii(MSG_MSGDUMP
,
145 "ASN.1: PrintableString",
149 case ASN1_TAG_IA5STRING
:
150 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: IA5String",
154 case ASN1_TAG_UTCTIME
:
155 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: UTCTIME",
159 case ASN1_TAG_VISIBLESTRING
:
160 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: VisibleString",
165 wpa_printf(MSG_DEBUG
, "ASN.1: Unknown tag %d",
175 int main(int argc
, char *argv
[])
183 f
= fopen(argv
[1], "rb");
186 len
= fread(buf
, 1, sizeof(buf
), f
);
189 if (asn1_parse(buf
, len
, 0) < 0)
190 printf("Failed to parse DER ASN.1\n");