2 * Testing tool for ASN.1 routines
3 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 extern int wpa_debug_level
;
23 static const char * asn1_class_str(int class)
26 case ASN1_CLASS_UNIVERSAL
:
28 case ASN1_CLASS_APPLICATION
:
30 case ASN1_CLASS_CONTEXT_SPECIFIC
:
31 return "Context-specific";
32 case ASN1_CLASS_PRIVATE
:
40 int asn1_parse(const u8
*buf
, size_t len
, int level
)
42 const u8
*pos
, *prev
, *end
;
43 char prefix
[10], str
[100];
50 if ((size_t) _level
> sizeof(prefix
) - 1)
51 _level
= sizeof(prefix
) - 1;
52 memset(prefix
, ' ', _level
);
53 prefix
[_level
] = '\0';
59 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0)
65 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Class %d(%s) P/C %d(%s) "
67 prefix
, hdr
.class, asn1_class_str(hdr
.class),
69 hdr
.constructed
? "Constructed" : "Primitive",
72 if (hdr
.class == ASN1_CLASS_CONTEXT_SPECIFIC
&&
74 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
79 if (hdr
.class != ASN1_CLASS_UNIVERSAL
)
85 wpa_printf(MSG_DEBUG
, "ASN.1: Non-zero "
86 "end-of-contents length (%u)",
90 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s EOC", prefix
);
92 case ASN1_TAG_BOOLEAN
:
93 if (hdr
.length
!= 1) {
94 wpa_printf(MSG_DEBUG
, "ASN.1: Unexpected "
95 "Boolean length (%u)", hdr
.length
);
99 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Boolean %s",
100 prefix
, tmp
? "TRUE" : "FALSE");
102 case ASN1_TAG_INTEGER
:
103 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: INTEGER",
107 case ASN1_TAG_BITSTRING
:
108 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: BitString",
112 case ASN1_TAG_OCTETSTRING
:
113 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: OctetString",
119 wpa_printf(MSG_DEBUG
, "ASN.1: Non-zero Null "
120 "length (%u)", hdr
.length
);
123 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s Null", prefix
);
126 if (asn1_get_oid(prev
, end
- prev
, &oid
, &prev
) < 0) {
127 wpa_printf(MSG_DEBUG
, "ASN.1: Invalid OID");
130 asn1_oid_to_str(&oid
, str
, sizeof(str
));
131 wpa_printf(MSG_DEBUG
, "ASN.1:%s OID %s", prefix
, str
);
134 case ANS1_TAG_RELATIVE_OID
:
135 wpa_hexdump(MSG_MSGDUMP
, "ASN.1: Relative OID",
139 case ASN1_TAG_SEQUENCE
:
140 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s SEQUENCE", prefix
);
141 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
146 wpa_printf(MSG_MSGDUMP
, "ASN.1:%s SET", prefix
);
147 if (asn1_parse(pos
, hdr
.length
, level
+ 1) < 0)
151 case ASN1_TAG_PRINTABLESTRING
:
152 wpa_hexdump_ascii(MSG_MSGDUMP
,
153 "ASN.1: PrintableString",
157 case ASN1_TAG_IA5STRING
:
158 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: IA5String",
162 case ASN1_TAG_UTCTIME
:
163 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: UTCTIME",
167 case ASN1_TAG_VISIBLESTRING
:
168 wpa_hexdump_ascii(MSG_MSGDUMP
, "ASN.1: VisibleString",
173 wpa_printf(MSG_DEBUG
, "ASN.1: Unknown tag %d",
183 int main(int argc
, char *argv
[])
191 f
= fopen(argv
[1], "rb");
194 len
= fread(buf
, 1, sizeof(buf
), f
);
197 if (asn1_parse(buf
, len
, 0) < 0)
198 printf("Failed to parse DER ASN.1\n");