X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=test%2Ftest_x509.c;h=c00706839bd3d9932de82d8e441621af06045555;hp=b81ff1d0de3169af00c474e7a8386081a3e9f0cd;hb=HEAD;hpb=9e71c0673a9f46f82e43125919619f296698292e diff --git a/test/test_x509.c b/test/test_x509.c index b81ff1d..c007068 100644 --- a/test/test_x509.c +++ b/test/test_x509.c @@ -27,10 +27,22 @@ #include #include +#ifdef _WIN32 +#include +#else +#include +#endif + #include "bearssl.h" +#define STR(x) STR_(x) +#define STR_(x) #x +#ifdef SRCDIRNAME +#define DIRNAME STR(SRCDIRNAME) "/test/x509" +#else #define DIRNAME "test/x509" -#define CONFFILE (DIRNAME "/alltests.txt") +#endif +#define CONFFILE DIRNAME "/alltests.txt" #define DEFAULT_TIME "2016-08-30T18:00:00Z" static void * @@ -1426,6 +1438,21 @@ eqpkey(const br_x509_pkey *pk1, const br_x509_pkey *pk2) static size_t max_dp_usage; static size_t max_rp_usage; +static int +check_time(void *ctx, uint32_t nbd, uint32_t nbs, uint32_t nad, uint32_t nas) +{ + test_case *tc; + + tc = ctx; + if (tc->days < nbd || (tc->days == nbd && tc->seconds < nbs)) { + return -1; + } + if (tc->days > nad || (tc->days == nad && tc->seconds > nas)) { + return 1; + } + return 0; +} + static void run_test_case(test_case *tc) { @@ -1440,6 +1467,7 @@ run_test_case(test_case *tc) const br_x509_pkey *ee_pkey; unsigned usages; unsigned status; + int j; printf("%s: ", tc->name); fflush(stdout); @@ -1508,110 +1536,130 @@ run_test_case(test_case *tc) } /* - * Initialise the engine. + * We do the test twice, to exercise distinct API functions. */ - br_x509_minimal_init(&ctx, dnhash, anchors, num_anchors); - for (u = 0; hash_impls[u].id; u ++) { - int id; + for (j = 0; j < 2; j ++) { + /* + * Initialise the engine. + */ + br_x509_minimal_init(&ctx, dnhash, anchors, num_anchors); + for (u = 0; hash_impls[u].id; u ++) { + int id; + + id = hash_impls[u].id; + if ((tc->hashes & ((unsigned)1 << id)) != 0) { + br_x509_minimal_set_hash(&ctx, + id, hash_impls[u].impl); + } + } + br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default()); + br_x509_minimal_set_ecdsa(&ctx, + br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default()); - id = hash_impls[u].id; - if ((tc->hashes & ((unsigned)1 << id)) != 0) { - br_x509_minimal_set_hash(&ctx, id, hash_impls[u].impl); + /* + * Set the validation date. + */ + if (j == 0) { + br_x509_minimal_set_time(&ctx, tc->days, tc->seconds); + } else { + br_x509_minimal_set_time_callback(&ctx, + tc, &check_time); } - } - br_x509_minimal_set_rsa(&ctx, br_rsa_i31_pkcs1_vrfy); - br_x509_minimal_set_ecdsa(&ctx, - &br_ec_prime_i31, br_ecdsa_i31_vrfy_asn1); - /* - * Set the validation date. - */ - br_x509_minimal_set_time(&ctx, tc->days, tc->seconds); + /* + * Put "canaries" to detect actual stack usage. + */ + for (u = 0; u < (sizeof ctx.dp_stack) / sizeof(uint32_t); + u ++) + { + ctx.dp_stack[u] = 0xA7C083FE; + } + for (u = 0; u < (sizeof ctx.rp_stack) / sizeof(uint32_t); + u ++) + { + ctx.rp_stack[u] = 0xA7C083FE; + } - /* - * Put "canaries" to detect actual stack usage. - */ - for (u = 0; u < (sizeof ctx.dp_stack) / sizeof(uint32_t); u ++) { - ctx.dp_stack[u] = 0xA7C083FE; - } - for (u = 0; u < (sizeof ctx.rp_stack) / sizeof(uint32_t); u ++) { - ctx.rp_stack[u] = 0xA7C083FE; - } + /* + * Run the engine. We inject certificates by chunks of 100 + * bytes in order to exercise the coroutine API. + */ + ctx.vtable->start_chain(&ctx.vtable, tc->servername); + for (u = 0; u < num_certs; u ++) { + size_t v; - /* - * Run the engine. We inject certificates by chunks of 100 bytes - * in order to exercise the coroutine API. - */ - ctx.vtable->start_chain(&ctx.vtable, tc->servername); - for (u = 0; u < num_certs; u ++) { - size_t v; + ctx.vtable->start_cert(&ctx.vtable, certs[u].len); + v = 0; + while (v < certs[u].len) { + size_t w; - ctx.vtable->start_cert(&ctx.vtable, certs[u].len); - v = 0; - while (v < certs[u].len) { - size_t w; + w = certs[u].len - v; + if (w > 100) { + w = 100; + } + ctx.vtable->append(&ctx.vtable, + certs[u].data + v, w); + v += w; + } + ctx.vtable->end_cert(&ctx.vtable); + } + status = ctx.vtable->end_chain(&ctx.vtable); + ee_pkey = ctx.vtable->get_pkey(&ctx.vtable, &usages); - w = certs[u].len - v; - if (w > 100) { - w = 100; + /* + * Check key type and usage. + */ + if (ee_pkey != NULL) { + unsigned ktu; + + ktu = ee_pkey->key_type | usages; + if (tc->key_type_usage != (ktu & tc->key_type_usage)) { + fprintf(stderr, "wrong key type + usage" + " (expected 0x%02X, got 0x%02X)\n", + tc->key_type_usage, ktu); + exit(EXIT_FAILURE); } - ctx.vtable->append(&ctx.vtable, certs[u].data + v, w); - v += w; } - ctx.vtable->end_cert(&ctx.vtable); - } - status = ctx.vtable->end_chain(&ctx.vtable); - ee_pkey = ctx.vtable->get_pkey(&ctx.vtable, &usages); - /* - * Check key type and usage. - */ - if (ee_pkey != NULL) { - unsigned ktu; - - ktu = ee_pkey->key_type | usages; - if (tc->key_type_usage != (ktu & tc->key_type_usage)) { - fprintf(stderr, "wrong key type + usage" - " (expected 0x%02X, got 0x%02X)\n", - tc->key_type_usage, ktu); + /* + * Check results. Note that we may still get a public key if + * the path is "not trusted" (but otherwise fine). + */ + if (status != tc->status) { + fprintf(stderr, "wrong status (got %d, expected %d)\n", + status, tc->status); + exit(EXIT_FAILURE); + } + if (status == BR_ERR_X509_NOT_TRUSTED) { + ee_pkey = NULL; + } + if (!eqpkey(ee_pkey, ee_pkey_ref)) { + fprintf(stderr, "wrong EE public key\n"); exit(EXIT_FAILURE); } - } - - /* - * Check results. Note that we may still get a public key if - * the path is "not trusted" (but otherwise fine). - */ - if (status != tc->status) { - fprintf(stderr, "wrong status (got %d, expected %d)\n", - status, tc->status); - exit(EXIT_FAILURE); - } - if (status == BR_ERR_X509_NOT_TRUSTED) { - ee_pkey = NULL; - } - if (!eqpkey(ee_pkey, ee_pkey_ref)) { - fprintf(stderr, "wrong EE public key\n"); - exit(EXIT_FAILURE); - } - /* - * Check stack usage. - */ - for (u = (sizeof ctx.dp_stack) / sizeof(uint32_t); u > 0; u --) { - if (ctx.dp_stack[u - 1] != 0xA7C083FE) { - if (max_dp_usage < u) { - max_dp_usage = u; + /* + * Check stack usage. + */ + for (u = (sizeof ctx.dp_stack) / sizeof(uint32_t); + u > 0; u --) + { + if (ctx.dp_stack[u - 1] != 0xA7C083FE) { + if (max_dp_usage < u) { + max_dp_usage = u; + } + break; } - break; } - } - for (u = (sizeof ctx.rp_stack) / sizeof(uint32_t); u > 0; u --) { - if (ctx.rp_stack[u - 1] != 0xA7C083FE) { - if (max_rp_usage < u) { - max_rp_usage = u; + for (u = (sizeof ctx.rp_stack) / sizeof(uint32_t); + u > 0; u --) + { + if (ctx.rp_stack[u - 1] != 0xA7C083FE) { + if (max_rp_usage < u) { + max_rp_usage = u; + } + break; } - break; } } @@ -1807,9 +1855,9 @@ test_name_extraction(void) id = hash_impls[u].id; br_x509_minimal_set_hash(&ctx, id, hash_impls[u].impl); } - br_x509_minimal_set_rsa(&ctx, br_rsa_i31_pkcs1_vrfy); + br_x509_minimal_set_rsa(&ctx, br_rsa_pkcs1_vrfy_get_default()); br_x509_minimal_set_ecdsa(&ctx, - &br_ec_prime_i31, br_ecdsa_i31_vrfy_asn1); + br_ec_get_default(), br_ecdsa_vrfy_asn1_get_default()); string_to_time(DEFAULT_TIME, &days, &seconds); br_x509_minimal_set_time(&ctx, days, seconds); @@ -1970,10 +2018,59 @@ test_name_extraction(void) } int -main(void) +main(int argc, const char *argv[]) { size_t u; +#ifdef SRCDIRNAME + /* + * We want to change the current directory to that of the + * executable, so that test files are reliably located. We + * do that only if SRCDIRNAME is defined (old Makefile would + * not do that). + */ + if (argc >= 1) { + const char *arg, *c; + + arg = argv[0]; + for (c = arg + strlen(arg);; c --) { + int sep, r; + +#ifdef _WIN32 + sep = (*c == '/') || (*c == '\\'); +#else + sep = (*c == '/'); +#endif + if (sep) { + size_t len; + char *dn; + + len = 1 + (c - arg); + dn = xmalloc(len + 1); + memcpy(dn, arg, len); + dn[len] = 0; +#ifdef _WIN32 + r = _chdir(dn); +#else + r = chdir(dn); +#endif + if (r != 0) { + fprintf(stderr, "warning: could not" + " set directory to '%s'\n", dn); + } + xfree(dn); + break; + } + if (c == arg) { + break; + } + } + } +#else + (void)argc; + (void)argv; +#endif + process_conf_file(CONFFILE); max_dp_usage = 0;