/*
 * Testing tool for ASN.1 routines
 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "tls/asn1.h"


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;

	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");

	return 0;
}
