Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

211 lines (186 sloc) 4.877 kb
/*
* Testing tool for ASN.1/X.509v3 routines
* Copyright (c) 2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "asn1.h"
#include "x509v3.h"
extern int wpa_debug_level;
static const char * asn1_class_str(int class)
{
switch (class) {
case ASN1_CLASS_UNIVERSAL:
return "Universal";
case ASN1_CLASS_APPLICATION:
return "Application";
case ASN1_CLASS_CONTEXT_SPECIFIC:
return "Context-specific";
case ASN1_CLASS_PRIVATE:
return "Private";
default:
return "?";
}
}
int asn1_parse(const u8 *buf, size_t len, int level)
{
const u8 *pos, *prev, *end;
char prefix[10], str[100];
int _level;
struct asn1_hdr hdr;
struct asn1_oid oid;
u8 tmp;
_level = level;
if ((size_t) _level > sizeof(prefix) - 1)
_level = sizeof(prefix) - 1;
memset(prefix, ' ', _level);
prefix[_level] = '\0';
pos = buf;
end = buf + len;
while (pos < end) {
if (asn1_get_next(pos, end - pos, &hdr) < 0)
return -1;
prev = pos;
pos = hdr.payload;
wpa_printf(MSG_MSGDUMP, "ASN.1:%s Class %d(%s) P/C %d(%s) "
"Tag %u Length %u",
prefix, hdr.class, asn1_class_str(hdr.class),
hdr.constructed,
hdr.constructed ? "Constructed" : "Primitive",
hdr.tag, hdr.length);
if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC &&
hdr.constructed) {
if (asn1_parse(pos, hdr.length, level + 1) < 0)
return -1;
pos += hdr.length;
}
if (hdr.class != ASN1_CLASS_UNIVERSAL)
continue;
switch (hdr.tag) {
case ASN1_TAG_EOC:
if (hdr.length) {
wpa_printf(MSG_DEBUG, "ASN.1: Non-zero "
"end-of-contents length (%u)",
hdr.length);
return -1;
}
wpa_printf(MSG_MSGDUMP, "ASN.1:%s EOC", prefix);
break;
case ASN1_TAG_BOOLEAN:
if (hdr.length != 1) {
wpa_printf(MSG_DEBUG, "ASN.1: Unexpected "
"Boolean length (%u)", hdr.length);
return -1;
}
tmp = *pos++;
wpa_printf(MSG_MSGDUMP, "ASN.1:%s Boolean %s",
prefix, tmp ? "TRUE" : "FALSE");
break;
case ASN1_TAG_INTEGER:
wpa_hexdump(MSG_MSGDUMP, "ASN.1: INTEGER",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_BITSTRING:
wpa_hexdump(MSG_MSGDUMP, "ASN.1: BitString",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_OCTETSTRING:
wpa_hexdump(MSG_MSGDUMP, "ASN.1: OctetString",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_NULL:
if (hdr.length) {
wpa_printf(MSG_DEBUG, "ASN.1: Non-zero Null "
"length (%u)", hdr.length);
return -1;
}
wpa_printf(MSG_MSGDUMP, "ASN.1:%s Null", prefix);
break;
case ASN1_TAG_OID:
if (asn1_get_oid(prev, end - prev, &oid, &prev) < 0) {
wpa_printf(MSG_DEBUG, "ASN.1: Invalid OID");
return -1;
}
asn1_oid_to_str(&oid, str, sizeof(str));
wpa_printf(MSG_DEBUG, "ASN.1:%s OID %s", prefix, str);
pos += hdr.length;
break;
case ANS1_TAG_RELATIVE_OID:
wpa_hexdump(MSG_MSGDUMP, "ASN.1: Relative OID",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_SEQUENCE:
wpa_printf(MSG_MSGDUMP, "ASN.1:%s SEQUENCE", prefix);
if (asn1_parse(pos, hdr.length, level + 1) < 0)
return -1;
pos += hdr.length;
break;
case ASN1_TAG_SET:
wpa_printf(MSG_MSGDUMP, "ASN.1:%s SET", prefix);
if (asn1_parse(pos, hdr.length, level + 1) < 0)
return -1;
pos += hdr.length;
break;
case ASN1_TAG_PRINTABLESTRING:
wpa_hexdump_ascii(MSG_MSGDUMP,
"ASN.1: PrintableString",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_IA5STRING:
wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: IA5String",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_UTCTIME:
wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: UTCTIME",
pos, hdr.length);
pos += hdr.length;
break;
case ASN1_TAG_VISIBLESTRING:
wpa_hexdump_ascii(MSG_MSGDUMP, "ASN.1: VisibleString",
pos, hdr.length);
pos += hdr.length;
break;
default:
wpa_printf(MSG_DEBUG, "ASN.1: Unknown tag %d",
hdr.tag);
return -1;
}
}
return 0;
}
int main(int argc, char *argv[])
{
FILE *f;
u8 buf[3000];
size_t len;
struct x509_certificate *cert;
wpa_debug_level = 0;
f = fopen(argv[1], "rb");
if (f == NULL)
return -1;
len = fread(buf, 1, sizeof(buf), f);
fclose(f);
if (asn1_parse(buf, len, 0) < 0)
printf("Failed to parse DER ASN.1\n");
printf("\n\n");
cert = x509_certificate_parse(buf, len);
if (cert == NULL)
printf("Failed to parse X.509 certificate\n");
x509_certificate_free(cert);
return 0;
}
Jump to Line
Something went wrong with that request. Please try again.