X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Fasn1_encode_test.c;h=b8ec168943726d5570fbed9dbaa5a09915ace383;hp=36cf7f903141c447dbce14874fa43c03d9e5bec5;hb=ad887416f1e59c3294a7d8f83a0ca77120523b4a;hpb=afd7cae2713e407bce5cd7bbc47fcf9c1d7c3862 diff --git a/test/asn1_encode_test.c b/test/asn1_encode_test.c index 36cf7f9031..b8ec168943 100644 --- a/test/asn1_encode_test.c +++ b/test/asn1_encode_test.c @@ -10,9 +10,9 @@ #include #include +#include #include #include "internal/numbers.h" -#include "test_main.h" #include "testutil.h" #ifdef __GNUC__ @@ -38,6 +38,12 @@ static unsigned char t_zero[] = { static unsigned char t_one[] = { 0x01 }; +static unsigned char t_one_neg[] = { + 0xff +}; +static unsigned char t_minus_256[] = { + 0xff, 0x00 +}; static unsigned char t_longundef[] = { 0x7f, 0xff, 0xff, 0xff }; @@ -95,6 +101,8 @@ static TEST_CUSTOM_DATA test_custom_data[] = { CUSTOM_DATA(t_zero), CUSTOM_DATA(t_longundef), CUSTOM_DATA(t_one), + CUSTOM_DATA(t_one_neg), + CUSTOM_DATA(t_minus_256), CUSTOM_DATA(t_9bytes_1), CUSTOM_DATA(t_8bytes_1), CUSTOM_DATA(t_8bytes_2), @@ -132,11 +140,12 @@ static TEST_CUSTOM_DATA test_custom_data[] = { * A structure to collect all test information in. There MUST be one instance * of this for each test */ -typedef int i2d_fn(void **a, unsigned char **pp); +typedef int i2d_fn(void *a, unsigned char **pp); typedef void *d2i_fn(void **a, unsigned char **pp, long length); typedef void ifree_fn(void *a); typedef struct { - char *name; + ASN1_ITEM_EXP *asn1_type; + const char *name; int skip; /* 1 if this package should be skipped */ /* An array of structures to compare decoded custom data with */ @@ -194,6 +203,8 @@ static ASN1_LONG_DATA long_expected_32bit[] = { { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */ { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */ + CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ @@ -214,7 +225,7 @@ static ASN1_LONG_DATA long_encdec_data_32bit[] = { }; static TEST_PACKAGE long_test_package_32bit = { - "LONG", sizeof(long) != 4, + ASN1_ITEM_ref(ASN1_LONG_DATA), "LONG", sizeof(long) != 4, long_expected_32bit, sizeof(long_expected_32bit), sizeof(long_expected_32bit[0]), long_encdec_data_32bit, @@ -228,6 +239,8 @@ static ASN1_LONG_DATA long_expected_64bit[] = { { 0xff, 0, 1 }, { 0, 0, 0 }, /* t_zero */ { 0, 0, 0 }, { 0xff, 1, 0x7fffffff }, /* t_longundef */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */ + CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ CUSTOM_EXPECTED_SUCCESS(LONG_MAX, LONG_MAX), /* t_8bytes_2 */ @@ -248,7 +261,7 @@ static ASN1_LONG_DATA long_encdec_data_64bit[] = { }; static TEST_PACKAGE long_test_package_64bit = { - "LONG", sizeof(long) != 8, + ASN1_ITEM_ref(ASN1_LONG_DATA), "LONG", sizeof(long) != 8, long_expected_64bit, sizeof(long_expected_64bit), sizeof(long_expected_64bit[0]), long_encdec_data_64bit, @@ -268,8 +281,8 @@ typedef struct { ASN1_SEQUENCE(ASN1_INT32_DATA) = { ASN1_SIMPLE(ASN1_INT32_DATA, success, ASN1_FBOOLEAN), - ASN1_SIMPLE(ASN1_INT32_DATA, test_int32, INT32), - ASN1_EXP_OPT(ASN1_INT32_DATA, test_zint32, ZINT32, 0) + ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32), + ASN1_EXP_OPT_EMBED(ASN1_INT32_DATA, test_zint32, ZINT32, 0) } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) @@ -279,6 +292,8 @@ static ASN1_INT32_DATA int32_expected[] = { CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */ + CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ @@ -297,7 +312,7 @@ static ASN1_INT32_DATA int32_encdec_data[] = { }; static TEST_PACKAGE int32_test_package = { - "INT32", 0, + ASN1_ITEM_ref(ASN1_INT32_DATA), "INT32", 0, int32_expected, sizeof(int32_expected), sizeof(int32_expected[0]), int32_encdec_data, sizeof(int32_encdec_data), sizeof(int32_encdec_data[0]), (i2d_fn *)i2d_ASN1_INT32_DATA, (d2i_fn *)d2i_ASN1_INT32_DATA, @@ -314,8 +329,8 @@ typedef struct { ASN1_SEQUENCE(ASN1_UINT32_DATA) = { ASN1_SIMPLE(ASN1_UINT32_DATA, success, ASN1_FBOOLEAN), - ASN1_SIMPLE(ASN1_UINT32_DATA, test_uint32, UINT32), - ASN1_EXP_OPT(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0) + ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32), + ASN1_EXP_OPT_EMBED(ASN1_UINT32_DATA, test_zuint32, ZUINT32, 0) } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) @@ -325,6 +340,8 @@ static ASN1_UINT32_DATA uint32_expected[] = { CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_FAILURE, /* t_one_neg (illegal negative value) */ + CUSTOM_EXPECTED_FAILURE, /* t_minus_256 (illegal negative value) */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_2 */ @@ -343,7 +360,7 @@ static ASN1_UINT32_DATA uint32_encdec_data[] = { }; static TEST_PACKAGE uint32_test_package = { - "UINT32", 0, + ASN1_ITEM_ref(ASN1_UINT32_DATA), "UINT32", 0, uint32_expected, sizeof(uint32_expected), sizeof(uint32_expected[0]), uint32_encdec_data, sizeof(uint32_encdec_data), sizeof(uint32_encdec_data[0]), (i2d_fn *)i2d_ASN1_UINT32_DATA, (d2i_fn *)d2i_ASN1_UINT32_DATA, @@ -360,8 +377,8 @@ typedef struct { ASN1_SEQUENCE(ASN1_INT64_DATA) = { ASN1_SIMPLE(ASN1_INT64_DATA, success, ASN1_FBOOLEAN), - ASN1_SIMPLE(ASN1_INT64_DATA, test_int64, INT64), - ASN1_EXP_OPT(ASN1_INT64_DATA, test_zint64, ZINT64, 0) + ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64), + ASN1_EXP_OPT_EMBED(ASN1_INT64_DATA, test_zint64, ZINT64, 0) } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) @@ -371,6 +388,8 @@ static ASN1_INT64_DATA int64_expected[] = { CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_SUCCESS(-1, -1), /* t_one_neg */ + CUSTOM_EXPECTED_SUCCESS(-256, -256), /* t_minus_256 */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_FAILURE, /* t_8bytes_1 (too large positive) */ CUSTOM_EXPECTED_SUCCESS(INT64_MAX, INT64_MAX), /* t_8bytes_2 */ @@ -390,7 +409,7 @@ static ASN1_INT64_DATA int64_encdec_data[] = { }; static TEST_PACKAGE int64_test_package = { - "INT64", 0, + ASN1_ITEM_ref(ASN1_INT64_DATA), "INT64", 0, int64_expected, sizeof(int64_expected), sizeof(int64_expected[0]), int64_encdec_data, sizeof(int64_encdec_data), sizeof(int64_encdec_data[0]), (i2d_fn *)i2d_ASN1_INT64_DATA, (d2i_fn *)d2i_ASN1_INT64_DATA, @@ -407,8 +426,8 @@ typedef struct { ASN1_SEQUENCE(ASN1_UINT64_DATA) = { ASN1_SIMPLE(ASN1_UINT64_DATA, success, ASN1_FBOOLEAN), - ASN1_SIMPLE(ASN1_UINT64_DATA, test_uint64, UINT64), - ASN1_EXP_OPT(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0) + ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64), + ASN1_EXP_OPT_EMBED(ASN1_UINT64_DATA, test_zuint64, ZUINT64, 0) } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) @@ -418,6 +437,8 @@ static ASN1_UINT64_DATA uint64_expected[] = { CUSTOM_EXPECTED_SUCCESS(0, 0), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(ASN1_LONG_UNDEF, ASN1_LONG_UNDEF), /* t_zero */ CUSTOM_EXPECTED_SUCCESS(1, 1), /* t_one */ + CUSTOM_EXPECTED_FAILURE, /* t_one_neg (illegal negative value) */ + CUSTOM_EXPECTED_FAILURE, /* t_minus_256 (illegal negative value) */ CUSTOM_EXPECTED_FAILURE, /* t_9bytes_1 */ CUSTOM_EXPECTED_SUCCESS((uint64_t)INT64_MAX+1, (uint64_t)INT64_MAX+1), /* t_8bytes_1 */ @@ -437,7 +458,7 @@ static ASN1_UINT64_DATA uint64_encdec_data[] = { }; static TEST_PACKAGE uint64_test_package = { - "UINT64", 0, + ASN1_ITEM_ref(ASN1_UINT64_DATA), "UINT64", 0, uint64_expected, sizeof(uint64_expected), sizeof(uint64_expected[0]), uint64_encdec_data, sizeof(uint64_encdec_data), sizeof(uint64_encdec_data[0]), (i2d_fn *)i2d_ASN1_UINT64_DATA, (d2i_fn *)d2i_ASN1_UINT64_DATA, @@ -489,6 +510,41 @@ static int do_decode(unsigned char *bytes, long nbytes, return ret; } +/* + * do_encode returns a tristate: + * + * -1 Couldn't encode + * 0 encoded DER wasn't what was expected (failure) + * 1 encoded DER was what was expected (success) + */ +static int do_encode(EXPECTED *input, + const unsigned char *expected, size_t expected_len, + const TEST_PACKAGE *package) +{ + unsigned char *data = NULL; + int len; + int ret = 0; + + len = package->i2d(input, &data); + if (len < 0) + return -1; + + if ((size_t)len != expected_len + || memcmp(data, expected, expected_len) != 0) { + if (input->success == 0) { + ret = 1; + ERR_clear_error(); + } else { + ret = 0; + } + } else { + ret = 1; + } + + OPENSSL_free(data); + return ret; +} + /* Do an encode/decode round trip */ static int do_enc_dec(EXPECTED *bytes, long nbytes, const TEST_PACKAGE *package) @@ -535,15 +591,13 @@ static size_t der_encode_length(size_t len, unsigned char **pp) return lenbytes; } -/* Attempt to decode a custom encoding of the test structure */ -static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, - const EXPECTED *expected, size_t expected_size, - const TEST_PACKAGE *package) +static size_t make_custom_der(const TEST_CUSTOM_DATA *custom_data, + unsigned char **encoding, int explicit_default) { - size_t firstbytes, secondbytes, secondbytesinner, seqbytes; + size_t firstbytes, secondbytes = 0, secondbytesinner = 0, seqbytes; const unsigned char t_true[] = { V_ASN1_BOOLEAN, 0x01, 0xff }; - unsigned char *encoding, *p = NULL; - int ret; + unsigned char *p = NULL; + size_t i; /* * The first item is just an INTEGER tag, INTEGER length and INTEGER content @@ -552,15 +606,21 @@ static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, 1 + der_encode_length(custom_data->nbytes1, NULL) + custom_data->nbytes1; - /* - * The second item is an explicit tag, content length, INTEGER tag, - * INTEGER length, INTEGER bytes - */ - secondbytesinner = - 1 + der_encode_length(custom_data->nbytes2, NULL) - + custom_data->nbytes2; - secondbytes = - 1 + der_encode_length(secondbytesinner, NULL) + secondbytesinner; + for (i = custom_data->nbytes2; i > 0; i--) { + if (custom_data->bytes2[i - 1] != '\0') + break; + } + if (explicit_default || i > 0) { + /* + * The second item is an explicit tag, content length, INTEGER tag, + * INTEGER length, INTEGER bytes + */ + secondbytesinner = + 1 + der_encode_length(custom_data->nbytes2, NULL) + + custom_data->nbytes2; + secondbytes = + 1 + der_encode_length(secondbytesinner, NULL) + secondbytesinner; + } /* * The whole sequence is the sequence tag, content length, BOOLEAN true @@ -571,9 +631,9 @@ static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, 1 + der_encode_length(sizeof(t_true) + firstbytes + secondbytes, NULL) + sizeof(t_true) + firstbytes + secondbytes; - encoding = p = OPENSSL_malloc(seqbytes); - if (encoding == NULL) - return -1; + *encoding = p = OPENSSL_malloc(seqbytes); + if (*encoding == NULL) + return 0; /* Sequence tag */ *p++ = 0x30; @@ -589,23 +649,79 @@ static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, memcpy(p, custom_data->bytes1, custom_data->nbytes1); p += custom_data->nbytes1; - /* Second INTEGER item (optional) */ - /* Start with the explicit optional tag */ - *p++ = 0xa0; - der_encode_length(secondbytesinner, &p); - *p++ = V_ASN1_INTEGER; - der_encode_length(custom_data->nbytes2, &p); - memcpy(p, custom_data->bytes2, custom_data->nbytes2); - p += custom_data->nbytes2; + if (secondbytes > 0) { + /* Second INTEGER item (optional) */ + /* Start with the explicit optional tag */ + *p++ = 0xa0; + der_encode_length(secondbytesinner, &p); + *p++ = V_ASN1_INTEGER; + der_encode_length(custom_data->nbytes2, &p); + memcpy(p, custom_data->bytes2, custom_data->nbytes2); + p += custom_data->nbytes2; + } - OPENSSL_assert(seqbytes == (size_t)(p - encoding)); + OPENSSL_assert(seqbytes == (size_t)(p - *encoding)); - ret = do_decode(encoding, seqbytes, expected, expected_size, package); + return seqbytes; +} + +/* Attempt to decode a custom encoding of the test structure */ +static int do_decode_custom(const TEST_CUSTOM_DATA *custom_data, + const EXPECTED *expected, size_t expected_size, + const TEST_PACKAGE *package) +{ + unsigned char *encoding = NULL; + /* + * We force the defaults to be explicitely encoded to make sure we test + * for defaults that shouldn't be present (i.e. we check for failure) + */ + size_t encoding_length = make_custom_der(custom_data, &encoding, 1); + int ret; + + if (encoding_length == 0) + return -1; + + ret = do_decode(encoding, encoding_length, expected, expected_size, + package); OPENSSL_free(encoding); return ret; } +/* Attempt to encode the test structure and compare it to custom DER */ +static int do_encode_custom(EXPECTED *input, + const TEST_CUSTOM_DATA *custom_data, + const TEST_PACKAGE *package) +{ + unsigned char *expected = NULL; + size_t expected_length = make_custom_der(custom_data, &expected, 0); + int ret; + + if (expected_length == 0) + return -1; + + ret = do_encode(input, expected, expected_length, package); + OPENSSL_free(expected); + + return ret; +} + +static int do_print_item(const TEST_PACKAGE *package) +{ +#define DATA_BUF_SIZE 256 + unsigned char buf[DATA_BUF_SIZE]; + const ASN1_ITEM *i = ASN1_ITEM_ptr(package->asn1_type); + ASN1_VALUE *o = (ASN1_VALUE *)&buf; + int ret; + + OPENSSL_assert(package->encode_expectations_elem_size <= DATA_BUF_SIZE); + + (void)RAND_bytes(buf, (int)package->encode_expectations_elem_size); + ret = ASN1_item_print(bio_err, o, 0, i, NULL); + + return ret; +} + static int test_intern(const TEST_PACKAGE *package) { @@ -623,27 +739,48 @@ static int test_intern(const TEST_PACKAGE *package) sizeof(test_custom_data) / sizeof(test_custom_data[0])); for (i = 0; i < nelems; i++) { size_t pos = i * package->encode_expectations_elem_size; + switch (do_encode_custom((EXPECTED *)&((unsigned char *)package + ->encode_expectations)[pos], + &test_custom_data[i], package)) { + case -1: + TEST_error("Failed custom encode round trip %u of %s", + i, package->name); + TEST_openssl_errors(); + fail++; + break; + case 0: + TEST_error("Custom encode round trip %u of %s mismatch", + i, package->name); + TEST_openssl_errors(); + fail++; + break; + case 1: + break; + default: + OPENSSL_die("do_encode_custom() return unknown value", + __FILE__, __LINE__); + } switch (do_decode_custom(&test_custom_data[i], (EXPECTED *)&((unsigned char *)package ->encode_expectations)[pos], package->encode_expectations_elem_size, package)) { case -1: - fprintf(stderr, "Failed custom decode round trip %u of %s\n", - i, package->name); - ERR_print_errors_fp(stderr); + TEST_error("Failed custom decode round trip %u of %s", + i, package->name); + TEST_openssl_errors(); fail++; - ERR_clear_error(); break; case 0: - fprintf(stderr, "Custom decode round trip %u of %s mismatch\n", - i, package->name); + TEST_error("Custom decode round trip %u of %s mismatch", + i, package->name); + TEST_openssl_errors(); fail++; break; case 1: break; default: - OPENSSL_die("do_enc_dec() return unknown value", + OPENSSL_die("do_decode_custom() return unknown value", __FILE__, __LINE__); } } @@ -657,15 +794,14 @@ static int test_intern(const TEST_PACKAGE *package) package->encdec_data_elem_size, package)) { case -1: - fprintf(stderr, "Failed encode/decode round trip %u of %s\n", - i, package->name); - ERR_print_errors_fp(stderr); - ERR_clear_error(); + TEST_error("Failed encode/decode round trip %u of %s", + i, package->name); + TEST_openssl_errors(); fail++; break; case 0: - fprintf(stderr, "Encode/decode round trip %u of %s mismatch\n", - i, package->name); + TEST_error("Encode/decode round trip %u of %s mismatch", + i, package->name); fail++; break; case 1: @@ -676,6 +812,12 @@ static int test_intern(const TEST_PACKAGE *package) } } + if (!do_print_item(package)) { + TEST_error("Printing of %s failed", package->name); + TEST_openssl_errors(); + fail++; + } + return fail == 0; } @@ -711,7 +853,7 @@ static int test_uint64(void) return test_intern(&uint64_test_package); } -void register_tests(void) +int setup_tests(void) { #if OPENSSL_API_COMPAT < 0x10200000L ADD_TEST(test_long_32bit); @@ -721,4 +863,5 @@ void register_tests(void) ADD_TEST(test_uint32); ADD_TEST(test_int64); ADD_TEST(test_uint64); + return 1; }