| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829 | /* *  Copyright 2014-2023 The GmSSL Project. All Rights Reserved. * *  Licensed under the Apache License, Version 2.0 (the License); you may *  not use this file except in compliance with the License. * *  http://www.apache.org/licenses/LICENSE-2.0 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <assert.h>#include <gmssl/asn1.h>#include <gmssl/error.h>static void print_buf(const uint8_t *a, size_t len){	size_t i;	for (i = 0; i < len; i++) {		printf("%02x ", a[i]);	}	printf("\n");}static void print_integer(const uint8_t *a, size_t alen){	size_t i;	printf("integer = ");	for (i = 0; i < alen; i++) {		printf("%02x", a[i]);	}	printf("\n");}static void print_bits(const uint8_t *bits, size_t nbits){	size_t i;	printf("bits (%zu) = ", nbits);	for (i = 0; i < (nbits + 7)/8; i++) {		printf("%02x", bits[i]);	}	printf("\n");}static void print_octets(const uint8_t *o, size_t olen){	size_t i;	printf("octets (%zu) = ", olen);	for (i = 0; i < olen; i++) {		printf("%02x", o[i]);	}	printf("\n");}static int test_asn1_tag(void){	int i;	format_print(stderr, 0, 0, "Tags:\n");	for (i = 1; i <= 13; i++) {		format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i);	}	for (i = 18; i <= 30; i++) {		format_print(stderr, 0, 4, "%s (0x%02x)\n", asn1_tag_name(i), i);	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_length(void){	size_t tests[] = {		0,		5,		127,		128,		256,		344,		65537,		1<<23,		INT_MAX, // INT_MAX = 2^31 - 1		//(size_t)1<<31, // default int value of (1<<31) is -2^31, 2^31 is larger than the INT_MAX limit	};	size_t length;	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "Length:\n");	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_length_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		int ret;		ret = asn1_length_from_der(&length, &cp, &len);		if (ret != 1 && ret != -2) {			error_print();			return -1;		}		if (length != tests[i]) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%zd\n", length);	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_boolean(void){	int tests[] = {0, 1};	int val;	uint8_t buf[128] = {0};	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BOOLEAN));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_boolean_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_boolean_from_der(&val, &cp, &len) != 1			|| asn1_check(val == tests[i]) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%s\n", val ? "true" : "false");	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_int(void){	int tests[] = {		0,		1,		127,		128,		65535,		65537,		1<<23,		1<<30,	};	int val;	uint8_t buf[256] = {0};	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_INTEGER));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_int_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	// 测试 -1 表示默认不编码	if (asn1_int_to_der(-1, &p, &len) != 0) {		error_print();		return -1;	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_int_from_der(&val, &cp, &len) != 1			|| asn1_check(val == tests[i]) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%d\n", val);	}	if (len != 0) {		error_print();		return -1;	}	// 测试返回0时是否对val值做初始化	if (asn1_int_from_der(&val, &cp, &len) != 0) {		error_print();		return -1;	}	if (val != -1) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_bits(void){	int tests[] = {		0x01,		0x02,		0x03,		0x7f,		0xfe,		0xff,		0xffff,		0xfffff,	};	uint8_t der[] = {		0x03,0x02,0x07,0x80,		0x03,0x02,0x06,0x40,		0x03,0x02,0x06,0xC0,		0x03,0x02,0x01,0xFE,		0x03,0x02,0x00,0x7F,		0x03,0x02,0x00,0xFF,		0x03,0x03,0x00,0xFF,0xFF,		0x03,0x04,0x04,0xFF,0xFF,0xF0,	};	int bits;	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_BIT_STRING));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_bits_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	if (sizeof(der) != len		|| memcmp(der, buf, len) != 0) {		error_print();		return -1;	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_bits_from_der(&bits, &cp, &len) != 1			|| asn1_check(bits == tests[i]) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%x\n", bits);	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_null(void){	uint8_t buf[256] = {0};	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "NULL\n");	for (i = 0; i < 3; i++) {		if (asn1_null_to_der(&p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < 3; i++) {		if (asn1_null_from_der(&cp, &len) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%s\n", asn1_tag_name(ASN1_TAG_NULL));	}	if (asn1_length_is_zero(len) != 1) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_object_identifier(void){	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_OBJECT_IDENTIFIER));	// test 1	{		char *name = "sm2";		uint32_t oid[] = { 1,2,156,10197,1,301 };		uint8_t der[] = { 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D };		uint32_t nodes[32];		size_t nodes_cnt;		uint8_t buf[128];		uint8_t *p = buf;		const uint8_t *cp = buf;		size_t len = 0;		format_print(stderr, 0 ,4, "%s ", name);		if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1			|| asn1_check(len == sizeof(der)) != 1			|| asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1			|| asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1			|| asn1_length_is_zero(len) != 1			|| asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) {			fprintf(stderr, "failed\n");			error_print();			return -1;		} else {			printf("ok\n");		}	}	// test 2	{		char *name = "x9.62-ecPublicKey";		uint32_t oid[] = { 1,2,840,10045,2,1 };		uint8_t der[] = { 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };		uint8_t buf[128];		uint32_t nodes[32];		size_t nodes_cnt;		uint8_t *p = buf;		const uint8_t *cp = buf;		size_t len = 0;		format_print(stderr, 0 ,4, "%s ", name);		if (asn1_object_identifier_to_der(oid, sizeof(oid)/sizeof(int), &p, &len) != 1			|| asn1_check(len == sizeof(der)) != 1			|| asn1_check(memcmp(buf, der, sizeof(der)) == 0) != 1			|| asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 1			|| asn1_length_is_zero(len) != 1			|| asn1_object_identifier_equ(nodes, nodes_cnt, oid, sizeof(oid)/sizeof(int)) != 1) {			fprintf(stderr, "failed\n");			error_print();			return -1;		} else {			printf("ok\n");		}	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_printable_string(void){	char *tests[] = {		"hello",		"world",		"Just do it", // string "Just do it!" include invalid '!'	};	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_PrintableString));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_printable_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		const char *d;		size_t dlen;		if (asn1_printable_string_from_der(&d, &dlen, &cp, &len) != 1			|| strlen(tests[i]) != dlen			|| memcmp(tests[i], d, dlen) != 0) {			error_print();			return -1;		}		format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_printable_string_check(void){	char *printable_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";	if (asn1_string_is_printable_string(printable_str, strlen(printable_str)) != 1) {		error_print();		return -1;	}	if (asn1_string_is_printable_string("a*b", 3) == 1) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_printable_string_case_ignore_match(void){	if (asn1_printable_string_case_ignore_match("HELLO", 5, "WORLD", 5) == 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match("HELLO", 5, "HELLO", 5) != 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match("HELLO", 5, "hello", 5) != 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match("  HELLO", 7, "hello", 5) != 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match("  HELLO", 7, "hello   ", 8) != 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match(" A2b ", 5, "  a2B  ", 7) != 1) {		error_print();		return -1;	}	if (asn1_printable_string_case_ignore_match("     ", 5, "       ", 7) != 1) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_utf8_string(void){	char *tests[] = {		"hello",		"world",		"Just do it!",	};	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTF8String));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_utf8_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		const char *d;		size_t dlen;		if (asn1_utf8_string_from_der(&d, &dlen, &cp, &len) != 1			|| strlen(tests[i]) != dlen			|| memcmp(tests[i], d, dlen) != 0) {			error_print();			return -1;		}		format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_ia5_string(void){	char *tests[] = {		"hello",		"world",		"Just do it!",	};	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_IA5String));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_ia5_string_to_der(tests[i], strlen(tests[i]), &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		const char *d;		size_t dlen;		if (asn1_ia5_string_from_der(&d, &dlen, &cp, &len) != 1			|| strlen(tests[i]) != dlen			|| memcmp(tests[i], d, dlen) != 0) {			error_print();			return -1;		}		format_string(stderr, 0, 4, "", (uint8_t *)d, dlen);	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_time(void){	time_t tval = 0;	printf("%s", ctime(&tval));	time(&tval);	printf("%s", ctime(&tval));	printf("%08x%08x\n", (uint32_t)(tval >> 32), (uint32_t)tval);	return 1;}static int test_asn1_time(void){	time_t tests[] = {		0,		31*86400,		(31+28)*86400,	 };	char *utc_time[] = {		"700101000000Z",		"700201000000Z",		"700301000000Z",	};	char *gen_time[] = {		"19700101000000Z",		"19700201000000Z",		"19700301000000Z",	};	time_t cur = time(NULL);	time_t ts;	char str[16] = {0};	int i;	if (asn1_time_to_str(0, cur, str) != 1		|| asn1_time_from_str(0, &ts, str) != 1		|| ts != cur) {		error_print();		return -1;	}	if (asn1_time_to_str(1, cur, str) != 1		|| asn1_time_from_str(1, &ts, str) != 1		|| ts != cur) {		error_print();		return -1;	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		memset(str, 0, sizeof(str));		if (asn1_time_to_str(1, tests[i], str) != 1			|| strcmp(str, utc_time[i]) != 0) {			error_print();			return -1;		}		memset(str, 0, sizeof(str));		if (asn1_time_to_str(0, tests[i], str) != 1			|| strcmp(str, gen_time[i]) != 0) {			error_print();			return -1;		}	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_time_limits(void){	char *tests[] = {		"20491231235959Z",		"20500101000000Z",		"99991231235959Z",	};	size_t i;	time_t tv[sizeof(tests)/sizeof(tests[0])];	char str[16] = {0};	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_time_from_str(0, &tv[i], tests[i]) != 1) {			error_print();			return -1;		}		fprintf(stderr, "    %s: %lld\n", tests[i], (long long)tv[i]);	}	if (tv[0] + 1 != tv[1]) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_utc_time(void){	time_t tests[] = {		0,		0,		1<<30,	};	time_t tv;	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	time(&tests[1]);	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_UTCTime));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_utc_time_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_utc_time_from_der(&tv, &cp, &len) != 1			|| asn1_check(tv == tests[i]) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%s", ctime(&tv));	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_generalized_time(void){	time_t tests[] = {		0,		1<<30,	};	uint8_t buf[256];	uint8_t *p = buf;	const uint8_t *cp = buf;	size_t len = 0;	size_t i;	time(&tests[0]);	format_print(stderr, 0, 0, "%s\n", asn1_tag_name(ASN1_TAG_GeneralizedTime));	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		if (asn1_generalized_time_to_der(tests[i], &p, &len) != 1) {			error_print();			return -1;		}		format_bytes(stderr, 0, 4, "", buf, len);	}	for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {		time_t tv;		if (asn1_generalized_time_from_der(&tv, &cp, &len) != 1			|| asn1_check(tv == tests[i]) != 1) {			error_print();			return -1;		}		format_print(stderr, 0, 4, "%s", ctime(&tv));	}	if (len != 0) {		error_print();		return -1;	}	printf("%s() ok\n", __FUNCTION__);	return 1;}static int test_asn1_from_der_null_args(void){	uint8_t buf[100];	const uint8_t *cp = NULL;	size_t len = 100;	int val;	const char *str;	size_t dlen;	time_t t;	uint32_t nodes[32];	size_t nodes_cnt;	fprintf(stderr, "%s: *inlen = 0\n", __FUNCTION__);	cp = buf;	len = 0;	if (asn1_boolean_from_der(&val, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_int_from_der(&val, &cp, &len)  != 0) { error_print(); return -1; }	if (asn1_bits_from_der(&val, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_null_from_der(&cp, &len) != 0) { error_print(); return -1; }	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_utf8_string_from_der(&str, &dlen, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_printable_string_from_der(&str, &dlen, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_ia5_string_from_der(&str, &dlen, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_utc_time_from_der(&t, &cp, &len) != 0) { error_print(); return -1; }	if (asn1_generalized_time_from_der(&t, &cp, &len) != 0) { error_print(); return -1; }	fprintf(stderr, "%s: result = NULL\n", __FUNCTION__);	cp = NULL;	len = 100;	if (asn1_boolean_from_der(NULL, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_int_from_der(NULL, &cp, &len)  != -1) { error_print(); return -1; }	if (asn1_bits_from_der(NULL, &cp, &len) != -1) { error_print(); return -1; }	//if (asn1_null_from_der(&cp, &len) != -1) { error_print(); return -1; }	if (asn1_object_identifier_from_der(NULL, &nodes_cnt, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_utf8_string_from_der(NULL, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_printable_string_from_der(NULL, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_ia5_string_from_der(NULL, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_utc_time_from_der(NULL, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_generalized_time_from_der(NULL, &cp, &len) != -1) { error_print(); return -1; }	fprintf(stderr, "%s: *inlen = 0\n", __FUNCTION__);	cp = buf;	len = 0;	if (asn1_boolean_from_der(&val, &cp, &len) != 0) { error_print(); return -1; }	fprintf(stderr, "%s: in = NULL\n", __FUNCTION__);	len = 100;	if (asn1_boolean_from_der(&val, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_int_from_der(&val, NULL, &len)  != -1) { error_print(); return -1; }	if (asn1_bits_from_der(&val, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_null_from_der(NULL, &len) != -1) { error_print(); return -1; }	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_utf8_string_from_der(&str, &dlen, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_printable_string_from_der(&str, &dlen, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_ia5_string_from_der(&str, &dlen, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_utc_time_from_der(&t, NULL, &len) != -1) { error_print(); return -1; }	if (asn1_generalized_time_from_der(&t, NULL, &len) != -1) { error_print(); return -1; }	fprintf(stderr, "%s: inlen = NULL\n", __FUNCTION__);	cp = buf;	if (asn1_boolean_from_der(&val, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_int_from_der(&val, &cp, NULL)  != -1) { error_print(); return -1; }	if (asn1_bits_from_der(&val, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_null_from_der(&cp, NULL) != -1) { error_print(); return -1; }	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_utf8_string_from_der(&str, &dlen, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_printable_string_from_der(&str, &dlen, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_ia5_string_from_der(&str, &dlen, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_utc_time_from_der(&t, &cp, NULL) != -1) { error_print(); return -1; }	if (asn1_generalized_time_from_der(&t, &cp, NULL) != -1) { error_print(); return -1; }	fprintf(stderr, "%s: *in = NULL\n", __FUNCTION__);	cp = NULL;	len = 100;	if (asn1_boolean_from_der(&val, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_int_from_der(&val, &cp, &len)  != -1) { error_print(); return -1; }	if (asn1_bits_from_der(&val, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_null_from_der(&cp, &len) != -1) { error_print(); return -1; }	if (asn1_object_identifier_from_der(nodes, &nodes_cnt, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_utf8_string_from_der(&str, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_printable_string_from_der(&str, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_ia5_string_from_der(&str, &dlen, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_utc_time_from_der(&t, &cp, &len) != -1) { error_print(); return -1; }	if (asn1_generalized_time_from_der(&t, &cp, &len) != -1) { error_print(); return -1; }	printf("%s() ok\n", __FUNCTION__);	return 1;}int main(void){	if (test_asn1_tag() != 1) goto err;	if (test_asn1_length() != 1) goto err;	if (test_asn1_boolean() != 1) goto err;	if (test_asn1_int() != 1) goto err;	if (test_asn1_bits() != 1) goto err;	if (test_asn1_null() != 1) goto err;	if (test_asn1_object_identifier() != 1) goto err;	if (test_asn1_printable_string() != 1) goto err;	if (test_asn1_printable_string_case_ignore_match() != 1) goto err;	if (test_asn1_utf8_string() != 1) goto err;	if (test_asn1_ia5_string() != 1) goto err;	if (test_asn1_time() != 1) goto err;	if (test_asn1_time_limits() != 1) goto err;	if (test_asn1_utc_time() != 1) goto err;	if (test_asn1_generalized_time() != 1) goto err;	if (test_asn1_from_der_null_args() != 1) goto err;	printf("%s all tests passed\n", __FILE__);	return 0;err:	error_print();	return -1;}
 |