00001 00016 #include "includes.h" 00017 00018 #include "common.h" 00019 #include "asn1.h" 00020 #include "x509v3.h" 00021 00022 extern int wpa_debug_level; 00023 00024 00025 static const char * asn1_class_str(int class) 00026 { 00027 switch (class) { 00028 case ASN1_CLASS_UNIVERSAL: 00029 return "Universal"; 00030 case ASN1_CLASS_APPLICATION: 00031 return "Application"; 00032 case ASN1_CLASS_CONTEXT_SPECIFIC: 00033 return "Context-specific"; 00034 case ASN1_CLASS_PRIVATE: 00035 return "Private"; 00036 default: 00037 return "?"; 00038 } 00039 } 00040 00041 00042 int asn1_parse(const u8 *buf, size_t len, int level) 00043 { 00044 const u8 *pos, *prev, *end; 00045 char prefix[10], str[100]; 00046 int _level; 00047 struct asn1_hdr hdr; 00048 struct asn1_oid oid; 00049 u8 tmp; 00050 00051 _level = level; 00052 if ((size_t) _level > sizeof(prefix) - 1) 00053 _level = sizeof(prefix) - 1; 00054 memset(prefix, ' ', _level); 00055 prefix[_level] = '\0'; 00056 00057 pos = buf; 00058 end = buf + len; 00059 00060 while (pos < end) { 00061 if (asn1_get_next(pos, end - pos, &hdr) < 0) 00062 return -1; 00063 00064 prev = pos; 00065 pos = hdr.payload; 00066 00067 wpa_printf(MSG_MSGDUMP, "ASN.1:%s Class %d(%s) P/C %d(%s) " 00068 "Tag %u Length %u", 00069 prefix, hdr.class, asn1_class_str(hdr.class), 00070 hdr.constructed, 00071 hdr.constructed ? "Constructed" : "Primitive", 00072 hdr.tag, hdr.length); 00073 00074 if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC && 00075 hdr.constructed) { 00076 if (asn1_parse(pos, hdr.length, level + 1) < 0) 00077 return -1; 00078 pos += hdr.length; 00079 } 00080 00081 if (hdr.class != ASN1_CLASS_UNIVERSAL) 00082 continue; 00083 00084 switch (hdr.tag) { 00085 case ASN1_TAG_EOC: 00086 if (hdr.length) { 00087 wpa_printf(MSG_DEBUG, "ASN.1: Non-zero " 00088 "end-of-contents length (%u)", 00089 hdr.length); 00090 return -1; 00091 } 00092 wpa_printf(MSG_MSGDUMP, "ASN.1:%s EOC", prefix); 00093 break; 00094 case ASN1_TAG_BOOLEAN: 00095 if (hdr.length != 1) { 00096 wpa_printf(MSG_DEBUG, "ASN.1: Unexpected " 00097 "Boolean length (%u)", hdr.length); 00098 return -1; 00099 } 00100 tmp = *pos++; 00101 wpa_printf(MSG_MSGDUMP, "ASN.1:%s Boolean %s", 00102 prefix, tmp ? "TRUE" : "FALSE"); 00103 break; 00104 case ASN1_TAG_INTEGER: 00105 wpa_hexdump(MSG_MSGDUMP, "ASN.1: INTEGER", 00106 pos, hdr.length); 00107 pos += hdr.length; 00108 break; 00109 case ASN1_TAG_BITSTRING: 00110 wpa_hexdump(MSG_MSGDUMP, "ASN.1: BitString", 00111 pos, hdr.length); 00112 pos += hdr.length; 00113 break; 00114 case ASN1_TAG_OCTETSTRING: 00115 wpa_hexdump(MSG_MSGDUMP, "ASN.1: OctetString", 00116 pos, hdr.length); 00117 pos += hdr.length; 00118 break; 00119 case ASN1_TAG_NULL: 00120 if (hdr.length) { 00121 wpa_printf(MSG_DEBUG, "ASN.1: Non-zero Null " 00122 "length (%u)", hdr.length); 00123 return -1; 00124 } 00125 wpa_printf(MSG_MSGDUMP, "ASN.1:%s Null", prefix); 00126 break; 00127 case ASN1_TAG_OID: 00128 if (asn1_get_oid(prev, end - prev, &oid, &prev) < 0) { 00129 wpa_printf(MSG_DEBUG, "ASN.1: Invalid OID"); 00130 return -1; 00131 } 00132 asn1_oid_to_str(&oid, str, sizeof(str)); 00133 wpa_printf(MSG_DEBUG, "ASN.1:%s OID %s", prefix, str); 00134 pos += hdr.length; 00135 break; 00136 case ANS1_TAG_RELATIVE_OID: 00137 wpa_hexdump(MSG_MSGDUMP, "ASN.1: Relative OID", 00138 pos, hdr.length); 00139 pos += hdr.length; 00140 break; 00141 case ASN1_TAG_SEQUENCE: 00142 wpa_printf(MSG_MSGDUMP, "ASN.1:%s SEQUENCE", prefix); 00143 if (asn1_parse(pos, hdr.length, level + 1) < 0) 00144 return -1; 00145 pos += hdr.length; 00146 break; 00147 case ASN1_TAG_SET: 00148 wpa_printf(MSG_MSGDUMP, "ASN.1:%s SET", prefix); 00149 if (asn1_parse(pos, hdr.length, level + 1) < 0) 00150 return -1; 00151 pos += hdr.length; 00152 break; 00153 case ASN1_TAG_PRINTABLESTRING: 00154 wpa_hexdump_ascii(MSG_MSGDUMP, 00155 "ASN.1: PrintableString", 00156 pos, hdr.length); 00157 pos += hdr.length; 00158 break; 00159 case ASN1_TAG_IA5STRING: 00160 wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: IA5String", 00161 pos, hdr.length); 00162 pos += hdr.length; 00163 break; 00164 case ASN1_TAG_UTCTIME: 00165 wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: UTCTIME", 00166 pos, hdr.length); 00167 pos += hdr.length; 00168 break; 00169 case ASN1_TAG_VISIBLESTRING: 00170 wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: VisibleString", 00171 pos, hdr.length); 00172 pos += hdr.length; 00173 break; 00174 default: 00175 wpa_printf(MSG_DEBUG, "ASN.1: Unknown tag %d", 00176 hdr.tag); 00177 return -1; 00178 } 00179 } 00180 00181 return 0; 00182 } 00183 00184 00185 int main(int argc, char *argv[]) 00186 { 00187 FILE *f; 00188 u8 buf[3000]; 00189 size_t len; 00190 struct x509_certificate *cert; 00191 00192 wpa_debug_level = 0; 00193 00194 f = fopen(argv[1], "rb"); 00195 if (f == NULL) 00196 return -1; 00197 len = fread(buf, 1, sizeof(buf), f); 00198 fclose(f); 00199 00200 if (asn1_parse(buf, len, 0) < 0) 00201 printf("Failed to parse DER ASN.1\n"); 00202 00203 printf("\n\n"); 00204 00205 cert = x509_certificate_parse(buf, len); 00206 if (cert == NULL) 00207 printf("Failed to parse X.509 certificate\n"); 00208 x509_certificate_free(cert); 00209 00210 return 0; 00211 } 00212