hostapd: Update vendor branch to 0.6.10
[dragonfly.git] / contrib / hostapd / src / tls / asn1_test.c
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
21 extern int wpa_debug_level;
22
23
24 static 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
41 int 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
184 int 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 }