• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/wpa_supplicant/src/tls/
1/*
2 * Testing tool for ASN.1/X.509v3 routines
3 * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
4 *
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.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "asn1.h"
19#include "x509v3.h"
20
21extern int wpa_debug_level;
22
23
24static const char * asn1_class_str(int class)
25{
26	switch (class) {
27	case ASN1_CLASS_UNIVERSAL:
28		return "Universal";
29	case ASN1_CLASS_APPLICATION:
30		return "Application";
31	case ASN1_CLASS_CONTEXT_SPECIFIC:
32		return "Context-specific";
33	case ASN1_CLASS_PRIVATE:
34		return "Private";
35	default:
36		return "?";
37	}
38}
39
40
41int asn1_parse(const u8 *buf, size_t len, int level)
42{
43	const u8 *pos, *prev, *end;
44	char prefix[10], str[100];
45	int _level;
46	struct asn1_hdr hdr;
47	struct asn1_oid oid;
48	u8 tmp;
49
50	_level = level;
51	if ((size_t) _level > sizeof(prefix) - 1)
52		_level = sizeof(prefix) - 1;
53	memset(prefix, ' ', _level);
54	prefix[_level] = '\0';
55
56	pos = buf;
57	end = buf + len;
58
59	while (pos < end) {
60		if (asn1_get_next(pos, end - pos, &hdr) < 0)
61			return -1;
62
63		prev = pos;
64		pos = hdr.payload;
65
66		wpa_printf(MSG_MSGDUMP, "ASN.1:%s Class %d(%s) P/C %d(%s) "
67			   "Tag %u Length %u",
68			   prefix, hdr.class, asn1_class_str(hdr.class),
69			   hdr.constructed,
70			   hdr.constructed ? "Constructed" : "Primitive",
71			   hdr.tag, hdr.length);
72
73		if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC &&
74		    hdr.constructed) {
75			if (asn1_parse(pos, hdr.length, level + 1) < 0)
76				return -1;
77			pos += hdr.length;
78		}
79
80		if (hdr.class != ASN1_CLASS_UNIVERSAL)
81			continue;
82
83		switch (hdr.tag) {
84		case ASN1_TAG_EOC:
85			if (hdr.length) {
86				wpa_printf(MSG_DEBUG, "ASN.1: Non-zero "
87					   "end-of-contents length (%u)",
88					   hdr.length);
89				return -1;
90			}
91			wpa_printf(MSG_MSGDUMP, "ASN.1:%s EOC", prefix);
92			break;
93		case ASN1_TAG_BOOLEAN:
94			if (hdr.length != 1) {
95				wpa_printf(MSG_DEBUG, "ASN.1: Unexpected "
96					   "Boolean length (%u)", hdr.length);
97				return -1;
98			}
99			tmp = *pos++;
100			wpa_printf(MSG_MSGDUMP, "ASN.1:%s Boolean %s",
101				   prefix, tmp ? "TRUE" : "FALSE");
102			break;
103		case ASN1_TAG_INTEGER:
104			wpa_hexdump(MSG_MSGDUMP, "ASN.1: INTEGER",
105				    pos, hdr.length);
106			pos += hdr.length;
107			break;
108		case ASN1_TAG_BITSTRING:
109			wpa_hexdump(MSG_MSGDUMP, "ASN.1: BitString",
110				    pos, hdr.length);
111			pos += hdr.length;
112			break;
113		case ASN1_TAG_OCTETSTRING:
114			wpa_hexdump(MSG_MSGDUMP, "ASN.1: OctetString",
115				    pos, hdr.length);
116			pos += hdr.length;
117			break;
118		case ASN1_TAG_NULL:
119			if (hdr.length) {
120				wpa_printf(MSG_DEBUG, "ASN.1: Non-zero Null "
121					   "length (%u)", hdr.length);
122				return -1;
123			}
124			wpa_printf(MSG_MSGDUMP, "ASN.1:%s Null", prefix);
125			break;
126		case ASN1_TAG_OID:
127			if (asn1_get_oid(prev, end - prev, &oid, &prev) < 0) {
128				wpa_printf(MSG_DEBUG, "ASN.1: Invalid OID");
129				return -1;
130			}
131			asn1_oid_to_str(&oid, str, sizeof(str));
132			wpa_printf(MSG_DEBUG, "ASN.1:%s OID %s", prefix, str);
133			pos += hdr.length;
134			break;
135		case ANS1_TAG_RELATIVE_OID:
136			wpa_hexdump(MSG_MSGDUMP, "ASN.1: Relative OID",
137				    pos, hdr.length);
138			pos += hdr.length;
139			break;
140		case ASN1_TAG_SEQUENCE:
141			wpa_printf(MSG_MSGDUMP, "ASN.1:%s SEQUENCE", prefix);
142			if (asn1_parse(pos, hdr.length, level + 1) < 0)
143				return -1;
144			pos += hdr.length;
145			break;
146		case ASN1_TAG_SET:
147			wpa_printf(MSG_MSGDUMP, "ASN.1:%s SET", prefix);
148			if (asn1_parse(pos, hdr.length, level + 1) < 0)
149				return -1;
150			pos += hdr.length;
151			break;
152		case ASN1_TAG_PRINTABLESTRING:
153			wpa_hexdump_ascii(MSG_MSGDUMP,
154					  "ASN.1: PrintableString",
155					  pos, hdr.length);
156			pos += hdr.length;
157			break;
158		case ASN1_TAG_IA5STRING:
159			wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: IA5String",
160					  pos, hdr.length);
161			pos += hdr.length;
162			break;
163		case ASN1_TAG_UTCTIME:
164			wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: UTCTIME",
165					  pos, hdr.length);
166			pos += hdr.length;
167			break;
168		case ASN1_TAG_VISIBLESTRING:
169			wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: VisibleString",
170					  pos, hdr.length);
171			pos += hdr.length;
172			break;
173		default:
174			wpa_printf(MSG_DEBUG, "ASN.1: Unknown tag %d",
175				   hdr.tag);
176			return -1;
177		}
178	}
179
180	return 0;
181}
182
183
184int main(int argc, char *argv[])
185{
186	FILE *f;
187	u8 buf[3000];
188	size_t len;
189	struct x509_certificate *cert;
190
191	wpa_debug_level = 0;
192
193	f = fopen(argv[1], "rb");
194	if (f == NULL)
195		return -1;
196	len = fread(buf, 1, sizeof(buf), f);
197	fclose(f);
198
199	if (asn1_parse(buf, len, 0) < 0)
200		printf("Failed to parse DER ASN.1\n");
201
202	printf("\n\n");
203
204	cert = x509_certificate_parse(buf, len);
205	if (cert == NULL)
206		printf("Failed to parse X.509 certificate\n");
207	x509_certificate_free(cert);
208
209	return 0;
210}
211