diff options
Diffstat (limited to '')
-rw-r--r-- | regress/CMakeLists.txt | 57 | ||||
-rw-r--r-- | regress/assert.c | 685 | ||||
-rw-r--r-- | regress/compress.c | 268 | ||||
-rw-r--r-- | regress/cred.c | 2185 | ||||
-rw-r--r-- | regress/dev.c | 439 | ||||
-rw-r--r-- | regress/eddsa.c | 159 | ||||
-rw-r--r-- | regress/es256.c | 199 | ||||
-rw-r--r-- | regress/es384.c | 213 | ||||
-rw-r--r-- | regress/rs256.c | 201 |
9 files changed, 4406 insertions, 0 deletions
diff --git a/regress/CMakeLists.txt b/regress/CMakeLists.txt new file mode 100644 index 0000000..246bffa --- /dev/null +++ b/regress/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2018-2022 Yubico AB. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# SPDX-License-Identifier: BSD-2-Clause + +add_custom_target(regress) + +macro(add_regress_test NAME SOURCES LIB) + add_executable(${NAME} ${SOURCES}) + add_test(${NAME} ${NAME}) + add_dependencies(regress ${NAME}) + target_link_libraries(${NAME} ${LIB}) +endmacro() + +if(MSVC AND BUILD_SHARED_LIBS) + add_custom_command(TARGET regress POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "${CBOR_BIN_DIRS}/${CBOR_LIBRARIES}.dll" + "${CRYPTO_BIN_DIRS}/${CRYPTO_LIBRARIES}.dll" + "${ZLIB_BIN_DIRS}/${ZLIB_LIBRARIES}.dll" + "$<TARGET_FILE:${_FIDO2_LIBRARY}>" + "${CMAKE_CURRENT_BINARY_DIR}") +endif() + +if(CYGWIN AND BUILD_SHARED_LIBS) + add_custom_command(TARGET regress POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$<TARGET_FILE:${_FIDO2_LIBRARY}>" + "${CMAKE_CURRENT_BINARY_DIR}") +endif() + +if(CMAKE_CROSSCOMPILING OR (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64" AND + CMAKE_GENERATOR_PLATFORM MATCHES "^ARM.*$")) + add_custom_command(TARGET regress POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E echo + "Cross-compilation detected. Skipping regress tests.") +else() + add_custom_command(TARGET regress POST_BUILD + COMMAND "${CMAKE_CTEST_COMMAND}" --output-on-failure + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) +endif() + +add_regress_test(regress_assert assert.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_cred cred.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_dev dev.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_eddsa eddsa.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_es256 es256.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_es384 es384.c ${_FIDO2_LIBRARY}) +add_regress_test(regress_rs256 rs256.c ${_FIDO2_LIBRARY}) +if(BUILD_STATIC_LIBS) + add_regress_test(regress_compress compress.c fido2) +endif() + +if(MINGW) + # needed for nanosleep() in mingw + target_link_libraries(regress_dev winpthread) +endif() diff --git a/regress/assert.c b/regress/assert.c new file mode 100644 index 0000000..ad31903 --- /dev/null +++ b/regress/assert.c @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2018-2023 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#define _FIDO_INTERNAL + +#include <fido.h> +#include <fido/es256.h> +#include <fido/rs256.h> +#include <fido/eddsa.h> + +static int fake_dev_handle; + +static const unsigned char es256_pk[64] = { + 0x34, 0xeb, 0x99, 0x77, 0x02, 0x9c, 0x36, 0x38, + 0xbb, 0xc2, 0xae, 0xa0, 0xa0, 0x18, 0xc6, 0x64, + 0xfc, 0xe8, 0x49, 0x92, 0xd7, 0x74, 0x9e, 0x0c, + 0x46, 0x8c, 0x9d, 0xa6, 0xdf, 0x46, 0xf7, 0x84, + 0x60, 0x1e, 0x0f, 0x8b, 0x23, 0x85, 0x4a, 0x9a, + 0xec, 0xc1, 0x08, 0x9f, 0x30, 0xd0, 0x0d, 0xd7, + 0x76, 0x7b, 0x55, 0x48, 0x91, 0x7c, 0x4f, 0x0f, + 0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a, +}; + +static const unsigned char rs256_pk[259] = { + 0x9e, 0x54, 0x78, 0xb2, 0x51, 0xbe, 0x19, 0x7c, + 0xcb, 0x1a, 0x9a, 0xc3, 0x49, 0x2a, 0x2f, 0xfd, + 0x99, 0x64, 0x76, 0xc6, 0xdb, 0xca, 0x38, 0x3f, + 0xb0, 0x6a, 0xc9, 0xc0, 0x07, 0x9f, 0x5c, 0x4d, + 0xfc, 0xd1, 0x01, 0x7f, 0x69, 0x65, 0xab, 0x9c, + 0x2a, 0xc2, 0x95, 0xd9, 0x44, 0xf3, 0xea, 0x94, + 0x6b, 0x25, 0x66, 0x54, 0x81, 0xee, 0x24, 0x1d, + 0xe1, 0x7d, 0x7f, 0xbe, 0xea, 0x76, 0x90, 0x5c, + 0xbf, 0x59, 0x22, 0xd3, 0xa0, 0x68, 0x1a, 0x65, + 0x8b, 0x2f, 0xb6, 0xa8, 0x30, 0x2d, 0x26, 0x81, + 0xfa, 0x9e, 0x59, 0xec, 0x2f, 0xee, 0x59, 0x39, + 0xe2, 0x79, 0x19, 0x54, 0x54, 0xdf, 0x24, 0x83, + 0xee, 0x61, 0x5a, 0x66, 0x24, 0x2b, 0x7b, 0xfb, + 0x82, 0x66, 0xe4, 0x85, 0x18, 0x20, 0x76, 0xe5, + 0x4a, 0xb6, 0xcb, 0xec, 0x43, 0xbe, 0xfd, 0xb0, + 0x8f, 0xfd, 0x2f, 0x69, 0xda, 0x06, 0x9c, 0x09, + 0x68, 0x7a, 0x94, 0x6c, 0xb7, 0x51, 0x6d, 0x4c, + 0xf7, 0x13, 0xe8, 0xd5, 0x22, 0x6b, 0x1e, 0xba, + 0xb9, 0x85, 0xe8, 0x5f, 0xa1, 0x66, 0xe3, 0x20, + 0x75, 0x30, 0x11, 0xb5, 0xa3, 0xc3, 0xb0, 0x72, + 0x08, 0xff, 0xa3, 0xbb, 0xf1, 0x32, 0x0b, 0x06, + 0xc4, 0x12, 0xa3, 0x49, 0x30, 0x19, 0xb9, 0xfe, + 0x69, 0x0c, 0xd6, 0xe1, 0x58, 0x36, 0xe6, 0x41, + 0x22, 0x41, 0xbf, 0x96, 0x50, 0x35, 0x56, 0x0d, + 0x92, 0x8c, 0x34, 0xea, 0x28, 0x91, 0x88, 0x9e, + 0x8a, 0xaa, 0x36, 0xd0, 0x0f, 0xbe, 0x16, 0xde, + 0x9d, 0x5f, 0x7b, 0xda, 0x52, 0xf7, 0xf1, 0xb6, + 0x28, 0x10, 0x05, 0x8f, 0xb9, 0x19, 0x7a, 0xcf, + 0x18, 0x9b, 0x40, 0xcd, 0xff, 0x78, 0xea, 0x61, + 0x24, 0x3b, 0x80, 0x68, 0x04, 0x9b, 0x40, 0x07, + 0x98, 0xd4, 0x94, 0xd1, 0x18, 0x44, 0xa5, 0xed, + 0xee, 0x18, 0xc2, 0x25, 0x52, 0x66, 0x42, 0xdf, + 0x01, 0x00, 0x01, +}; + +static const unsigned char cdh[32] = { + 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, + 0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56, + 0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52, + 0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76, +}; + +static const unsigned char authdata[39] = { + 0x58, 0x25, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, + 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, + 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, + 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, + 0x97, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03, +}; + +static const unsigned char sig[72] = { + 0x30, 0x46, 0x02, 0x21, 0x00, 0xf6, 0xd1, 0xa3, + 0xd5, 0x24, 0x2b, 0xde, 0xee, 0xa0, 0x90, 0x89, + 0xcd, 0xf8, 0x9e, 0xbd, 0x6b, 0x4d, 0x55, 0x79, + 0xe4, 0xc1, 0x42, 0x27, 0xb7, 0x9b, 0x9b, 0xa4, + 0x0a, 0xe2, 0x47, 0x64, 0x0e, 0x02, 0x21, 0x00, + 0xe5, 0xc9, 0xc2, 0x83, 0x47, 0x31, 0xc7, 0x26, + 0xe5, 0x25, 0xb2, 0xb4, 0x39, 0xa7, 0xfc, 0x3d, + 0x70, 0xbe, 0xe9, 0x81, 0x0d, 0x4a, 0x62, 0xa9, + 0xab, 0x4a, 0x91, 0xc0, 0x7d, 0x2d, 0x23, 0x1e, +}; + +static void * +dummy_open(const char *path) +{ + (void)path; + + return (&fake_dev_handle); +} + +static void +dummy_close(void *handle) +{ + assert(handle == &fake_dev_handle); +} + +static int +dummy_read(void *handle, unsigned char *buf, size_t len, int ms) +{ + (void)handle; + (void)buf; + (void)len; + (void)ms; + + abort(); + /* NOTREACHED */ +} + +static int +dummy_write(void *handle, const unsigned char *buf, size_t len) +{ + (void)handle; + (void)buf; + (void)len; + + abort(); + /* NOTREACHED */ +} + +static fido_assert_t * +alloc_assert(void) +{ + fido_assert_t *a; + + a = fido_assert_new(); + assert(a != NULL); + + return (a); +} + +static void +free_assert(fido_assert_t *a) +{ + fido_assert_free(&a); + assert(a == NULL); +} + +static fido_dev_t * +alloc_dev(void) +{ + fido_dev_t *d; + + d = fido_dev_new(); + assert(d != NULL); + + return (d); +} + +static void +free_dev(fido_dev_t *d) +{ + fido_dev_free(&d); + assert(d == NULL); +} + +static es256_pk_t * +alloc_es256_pk(void) +{ + es256_pk_t *pk; + + pk = es256_pk_new(); + assert(pk != NULL); + + return (pk); +} + +static void +free_es256_pk(es256_pk_t *pk) +{ + es256_pk_free(&pk); + assert(pk == NULL); +} + +static rs256_pk_t * +alloc_rs256_pk(void) +{ + rs256_pk_t *pk; + + pk = rs256_pk_new(); + assert(pk != NULL); + + return (pk); +} + +static void +free_rs256_pk(rs256_pk_t *pk) +{ + rs256_pk_free(&pk); + assert(pk == NULL); +} + +static eddsa_pk_t * +alloc_eddsa_pk(void) +{ + eddsa_pk_t *pk; + + pk = eddsa_pk_new(); + assert(pk != NULL); + + return (pk); +} + +static void +free_eddsa_pk(eddsa_pk_t *pk) +{ + eddsa_pk_free(&pk); + assert(pk == NULL); +} + +static void +empty_assert(fido_dev_t *d, fido_assert_t *a, size_t idx) +{ + es256_pk_t *es256; + rs256_pk_t *rs256; + eddsa_pk_t *eddsa; + + assert(fido_assert_flags(a, idx) == 0); + assert(fido_assert_authdata_len(a, idx) == 0); + assert(fido_assert_authdata_ptr(a, idx) == NULL); + assert(fido_assert_authdata_raw_len(a, idx) == 0); + assert(fido_assert_authdata_raw_ptr(a, idx) == NULL); + assert(fido_assert_clientdata_hash_len(a) == 0); + assert(fido_assert_clientdata_hash_ptr(a) == NULL); + assert(fido_assert_id_len(a, idx) == 0); + assert(fido_assert_id_ptr(a, idx) == NULL); + assert(fido_assert_rp_id(a) == NULL); + assert(fido_assert_sig_len(a, idx) == 0); + assert(fido_assert_sig_ptr(a, idx) == NULL); + assert(fido_assert_user_display_name(a, idx) == NULL); + assert(fido_assert_user_icon(a, idx) == NULL); + assert(fido_assert_user_id_len(a, idx) == 0); + assert(fido_assert_user_id_ptr(a, idx) == NULL); + assert(fido_assert_user_name(a, idx) == NULL); + + es256 = alloc_es256_pk(); + rs256 = alloc_rs256_pk(); + eddsa = alloc_eddsa_pk(); + + fido_dev_force_u2f(d); + assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_ES256, + NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_ES256, + es256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, -1, + es256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_RS256, + rs256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_EDDSA, + eddsa) == FIDO_ERR_INVALID_ARGUMENT); + + fido_dev_force_fido2(d); + assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_ES256, + NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_ES256, + es256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, -1, + es256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_RS256, + rs256) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_verify(a, idx, COSE_EDDSA, + eddsa) == FIDO_ERR_INVALID_ARGUMENT); + + free_es256_pk(es256); + free_rs256_pk(rs256); + free_eddsa_pk(eddsa); +} + +static void +empty_assert_tests(void) +{ + fido_assert_t *a; + fido_dev_t *d; + fido_dev_io_t io_f; + size_t i; + + memset(&io_f, 0, sizeof(io_f)); + + a = alloc_assert(); + d = alloc_dev(); + + io_f.open = dummy_open; + io_f.close = dummy_close; + io_f.read = dummy_read; + io_f.write = dummy_write; + + assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); + + empty_assert(d, a, 0); + assert(fido_assert_count(a) == 0); + assert(fido_assert_set_count(a, 4) == FIDO_OK); + assert(fido_assert_count(a) == 4); + for (i = 0; i < 4; i++) { + empty_assert(d, a, i); + } + empty_assert(d, a, 10); + free_assert(a); + free_dev(d); +} + +static void +valid_assert(void) +{ + fido_assert_t *a; + es256_pk_t *es256; + rs256_pk_t *rs256; + eddsa_pk_t *eddsa; + + a = alloc_assert(); + es256 = alloc_es256_pk(); + rs256 = alloc_rs256_pk(); + eddsa = alloc_eddsa_pk(); + assert(es256_pk_from_ptr(es256, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, es256) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_RS256, rs256) == FIDO_ERR_INVALID_SIG); + assert(fido_assert_verify(a, 0, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_SIG); + free_assert(a); + free_es256_pk(es256); + free_rs256_pk(rs256); + free_eddsa_pk(eddsa); +} + +static void +no_cdh(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_ARGUMENT); + free_assert(a); + free_es256_pk(pk); +} + +static void +no_rp(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_ARGUMENT); + free_assert(a); + free_es256_pk(pk); +} + +static void +no_authdata(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_ARGUMENT); + free_assert(a); + free_es256_pk(pk); +} + +static void +no_sig(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_ARGUMENT); + free_assert(a); + free_es256_pk(pk); +} + +static void +junk_cdh(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + unsigned char *junk; + + junk = malloc(sizeof(cdh)); + assert(junk != NULL); + memcpy(junk, cdh, sizeof(cdh)); + junk[0] = (unsigned char)~junk[0]; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, junk, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); + free_assert(a); + free_es256_pk(pk); + free(junk); +} + +static void +junk_rp(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "potato") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_PARAM); + free_assert(a); + free_es256_pk(pk); +} + +static void +junk_authdata(void) +{ + fido_assert_t *a; + unsigned char *junk; + + junk = malloc(sizeof(authdata)); + assert(junk != NULL); + memcpy(junk, authdata, sizeof(authdata)); + junk[0] = (unsigned char)~junk[0]; + + a = alloc_assert(); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, junk, + sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_assert_authdata_ptr(a, 0) == NULL); + assert(fido_assert_authdata_len(a, 0) == 0); + assert(fido_assert_authdata_raw_ptr(a, 0) == NULL); + assert(fido_assert_authdata_raw_len(a, 0) == 0); + free_assert(a); + free(junk); +} + +static void +junk_sig(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + unsigned char *junk; + + junk = malloc(sizeof(sig)); + assert(junk != NULL); + memcpy(junk, sig, sizeof(sig)); + junk[0] = (unsigned char)~junk[0]; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, junk, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG); + free_assert(a); + free_es256_pk(pk); + free(junk); +} + +static void +wrong_options(void) +{ + fido_assert_t *a; + es256_pk_t *pk; + + a = alloc_assert(); + pk = alloc_es256_pk(); + assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_assert_set_rp(a, "localhost") == FIDO_OK); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_set_up(a, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_PARAM); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, + pk) == FIDO_ERR_INVALID_PARAM); + assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_OK); + free_assert(a); + free_es256_pk(pk); +} + +/* cbor_serialize_alloc misuse */ +static void +bad_cbor_serialize(void) +{ + fido_assert_t *a; + + a = alloc_assert(); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert(fido_assert_authdata_len(a, 0) == sizeof(authdata)); + free_assert(a); +} + +/* rs256 <-> EVP_PKEY transformations */ +static void +rs256_PKEY(void) +{ + rs256_pk_t *pk1, *pk2; + EVP_PKEY *pkey; + + pk1 = alloc_rs256_pk(); + pk2 = alloc_rs256_pk(); + + assert(rs256_pk_from_ptr(pk1, rs256_pk, sizeof(rs256_pk)) == FIDO_OK); + assert((pkey = rs256_pk_to_EVP_PKEY(pk1)) != NULL); + assert(rs256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); + assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); + + free_rs256_pk(pk1); + free_rs256_pk(pk2); + EVP_PKEY_free(pkey); +} + +/* es256 <-> EVP_PKEY transformations */ +static void +es256_PKEY(void) +{ + es256_pk_t *pk1, *pk2; + EVP_PKEY *pkey; + + pk1 = alloc_es256_pk(); + pk2 = alloc_es256_pk(); + + assert(es256_pk_from_ptr(pk1, es256_pk, sizeof(es256_pk)) == FIDO_OK); + assert((pkey = es256_pk_to_EVP_PKEY(pk1)) != NULL); + assert(es256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK); + assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0); + + free_es256_pk(pk1); + free_es256_pk(pk2); + EVP_PKEY_free(pkey); +} + +static void +raw_authdata(void) +{ + fido_assert_t *a; + cbor_item_t *item; + struct cbor_load_result cbor_result; + const unsigned char *ptr; + unsigned char *cbor; + size_t len; + size_t cbor_len; + size_t alloclen; + + a = alloc_assert(); + assert(fido_assert_set_count(a, 1) == FIDO_OK); + assert(fido_assert_set_authdata(a, 0, authdata, + sizeof(authdata)) == FIDO_OK); + assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert((item = cbor_load(ptr, len, &cbor_result)) != NULL); + assert(cbor_result.read == len); + assert(cbor_isa_bytestring(item)); + assert((ptr = fido_assert_authdata_raw_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_raw_len(a, 0)) != 0); + assert(cbor_bytestring_length(item) == len); + assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len); + assert((ptr = cbor_bytestring_handle(item)) != NULL); + assert((len = cbor_bytestring_length(item)) != 0); + assert(fido_assert_set_authdata_raw(a, 0, ptr, len) == FIDO_OK); + assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL); + assert((len = fido_assert_authdata_len(a, 0)) != 0); + assert(len == cbor_len); + assert(memcmp(cbor, ptr, len) == 0); + assert(cbor_len == sizeof(authdata)); + assert(memcmp(cbor, authdata, cbor_len) == 0); + cbor_decref(&item); + free(cbor); + free_assert(a); +} + +int +main(void) +{ + fido_init(0); + + empty_assert_tests(); + valid_assert(); + no_cdh(); + no_rp(); + no_authdata(); + no_sig(); + junk_cdh(); + junk_rp(); + junk_authdata(); + junk_sig(); + wrong_options(); + bad_cbor_serialize(); + rs256_PKEY(); + es256_PKEY(); + raw_authdata(); + + exit(0); +} diff --git a/regress/compress.c b/regress/compress.c new file mode 100644 index 0000000..7afc8bb --- /dev/null +++ b/regress/compress.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#include <openssl/sha.h> + +#define _FIDO_INTERNAL + +#include <fido.h> + +/* + * zlib compressed data (RFC1950); see https://www.ietf.org/rfc/rfc6713.txt + */ +static /* const */ unsigned char rfc1950_blob[694] = { + 0x78, 0x9c, 0xb5, 0x52, 0x3b, 0x6f, 0xdb, 0x30, + 0x10, 0xde, 0xf5, 0x2b, 0x0e, 0x99, 0x12, 0x40, + 0x75, 0x13, 0x4f, 0x45, 0x3b, 0xd1, 0x12, 0x6d, + 0x1d, 0x20, 0x8b, 0x2a, 0x49, 0xd9, 0xf5, 0x28, + 0x4b, 0x4c, 0x42, 0xc0, 0x12, 0x03, 0x3d, 0x12, + 0xe4, 0xdf, 0xf7, 0xc8, 0x3a, 0x88, 0xd3, 0x0c, + 0x9d, 0xea, 0xc1, 0x3e, 0xf3, 0x8e, 0xdf, 0xeb, + 0x98, 0xb8, 0xa7, 0xd7, 0xc1, 0x3e, 0x3c, 0x4e, + 0x70, 0xdd, 0xdc, 0xc0, 0xf2, 0xf6, 0xee, 0xdb, + 0x97, 0xe5, 0xed, 0x72, 0x09, 0x87, 0xf9, 0x68, + 0x1b, 0x07, 0x6c, 0xb5, 0x00, 0x76, 0x3a, 0x41, + 0x18, 0x19, 0x61, 0x30, 0xa3, 0x19, 0x9e, 0x4d, + 0xbb, 0x88, 0x22, 0x69, 0x5a, 0x3b, 0x4e, 0x83, + 0x3d, 0xce, 0x93, 0x75, 0x3d, 0xd4, 0x7d, 0x0b, + 0xf3, 0x68, 0xc0, 0xf6, 0x30, 0xba, 0x79, 0x68, + 0x4c, 0x38, 0x39, 0xda, 0xbe, 0x1e, 0x5e, 0xe1, + 0xde, 0x0d, 0xdd, 0x18, 0xc3, 0x8b, 0x9d, 0x1e, + 0xc1, 0x0d, 0xe1, 0xd7, 0xcd, 0x53, 0xd4, 0xb9, + 0xd6, 0xde, 0xdb, 0xa6, 0xf6, 0x00, 0x31, 0xd4, + 0x83, 0x81, 0x27, 0x33, 0x74, 0x76, 0x9a, 0x4c, + 0x0b, 0x4f, 0x83, 0x7b, 0xb6, 0x2d, 0x15, 0xd3, + 0x63, 0x3d, 0xd1, 0x97, 0x21, 0x90, 0xd3, 0xc9, + 0xbd, 0xd8, 0xfe, 0x01, 0x1a, 0xd7, 0xb7, 0xd6, + 0x5f, 0x1a, 0xfd, 0xa5, 0xa8, 0x33, 0xd3, 0xf7, + 0x28, 0x02, 0x80, 0xbb, 0x05, 0x7c, 0x54, 0x35, + 0x82, 0xbb, 0x7f, 0x93, 0xd3, 0xb8, 0xd6, 0x40, + 0x37, 0x8f, 0x13, 0x99, 0x98, 0x6a, 0x92, 0xe9, + 0x31, 0xeb, 0xa3, 0x7b, 0xf6, 0xad, 0x73, 0x06, + 0x1e, 0x84, 0x3e, 0xbd, 0x9b, 0x6c, 0x63, 0x62, + 0x9a, 0xb0, 0x23, 0x9c, 0x08, 0xcf, 0xc3, 0x5c, + 0x92, 0xf6, 0xed, 0x5f, 0x8a, 0x88, 0xb4, 0x39, + 0xd5, 0xb6, 0x33, 0xc3, 0xc2, 0x63, 0x2c, 0x3f, + 0x0b, 0x21, 0xc2, 0x8b, 0x30, 0xde, 0x84, 0x90, + 0xcb, 0x76, 0x26, 0x71, 0xff, 0x47, 0x0b, 0x91, + 0x9e, 0x51, 0xfc, 0x44, 0xeb, 0x9a, 0xb9, 0x33, + 0xfd, 0x54, 0xbf, 0xed, 0xeb, 0x2b, 0xad, 0xc2, + 0x51, 0x67, 0x80, 0xae, 0x9e, 0xcc, 0x60, 0xeb, + 0xd3, 0xf8, 0x1e, 0x7b, 0xd8, 0x15, 0x35, 0xcf, + 0x00, 0x97, 0x66, 0x68, 0xf9, 0x3a, 0x43, 0x05, + 0x4a, 0xac, 0xf5, 0x9e, 0x49, 0x0e, 0x54, 0x97, + 0x52, 0xec, 0x30, 0xe5, 0x29, 0xac, 0x0e, 0xa0, + 0x33, 0x0e, 0x89, 0x28, 0x0f, 0x12, 0x37, 0x99, + 0x86, 0x4c, 0xe4, 0x29, 0x97, 0x0a, 0x58, 0x91, + 0xd2, 0x69, 0xa1, 0x25, 0xae, 0x2a, 0x2d, 0xa4, + 0x8a, 0xae, 0x98, 0xa2, 0x9b, 0x57, 0xa1, 0xc1, + 0x8a, 0x03, 0xf0, 0x5f, 0xa5, 0xe4, 0x4a, 0x81, + 0x90, 0x80, 0xdb, 0x32, 0x47, 0x02, 0x23, 0x74, + 0xc9, 0x0a, 0x8d, 0x5c, 0xc5, 0x80, 0x45, 0x92, + 0x57, 0x29, 0x16, 0x9b, 0x18, 0x08, 0x00, 0x0a, + 0xa1, 0xa3, 0x1c, 0xb7, 0xa8, 0x69, 0x4c, 0x8b, + 0x38, 0x90, 0x7e, 0xbe, 0x06, 0x62, 0x0d, 0x5b, + 0x2e, 0x93, 0x8c, 0xfe, 0xb2, 0x15, 0xe6, 0xa8, + 0x0f, 0x81, 0x6f, 0x8d, 0xba, 0xf0, 0x5c, 0x6b, + 0x21, 0x23, 0x06, 0x25, 0x93, 0x1a, 0x93, 0x2a, + 0x67, 0x12, 0xca, 0x4a, 0x96, 0x42, 0x71, 0xf0, + 0xb6, 0x52, 0x54, 0x49, 0xce, 0x70, 0xcb, 0xd3, + 0x05, 0xb1, 0x13, 0x23, 0xf0, 0x1d, 0x2f, 0x34, + 0xa8, 0x8c, 0xe5, 0xf9, 0x47, 0x97, 0xd1, 0x1f, + 0x97, 0x5e, 0xfb, 0xa5, 0x47, 0x58, 0x71, 0xc8, + 0x91, 0xad, 0x72, 0xee, 0x99, 0x82, 0xcb, 0x14, + 0x25, 0x4f, 0xb4, 0xb7, 0xf3, 0x5e, 0x25, 0x94, + 0x1c, 0xe9, 0xcb, 0xe3, 0x48, 0x95, 0x3c, 0x41, + 0x2a, 0x28, 0x0c, 0x4e, 0x66, 0x98, 0x3c, 0xc4, + 0x67, 0x4c, 0xc5, 0x7f, 0x56, 0x34, 0x44, 0x4d, + 0x48, 0xd9, 0x96, 0x6d, 0xc8, 0xdb, 0xf5, 0x3f, + 0x22, 0xa1, 0x9d, 0x24, 0x95, 0xe4, 0x5b, 0xaf, + 0x99, 0x72, 0x50, 0xd5, 0x4a, 0x69, 0xd4, 0x95, + 0xe6, 0xb0, 0x11, 0x22, 0x0d, 0x41, 0x2b, 0x2e, + 0x77, 0x98, 0x70, 0xf5, 0x03, 0x72, 0xa1, 0x42, + 0x5a, 0x95, 0xe2, 0x71, 0x94, 0x32, 0xcd, 0x02, + 0x31, 0x41, 0x50, 0x54, 0xd4, 0xa6, 0x7a, 0x55, + 0x29, 0x0c, 0xa1, 0x61, 0xa1, 0xb9, 0x94, 0x55, + 0xa9, 0x51, 0x14, 0x37, 0xb4, 0xdf, 0x3d, 0xc5, + 0x42, 0x1a, 0x19, 0x5d, 0x4d, 0x43, 0xba, 0xa2, + 0xf0, 0x56, 0xe9, 0x91, 0x70, 0x21, 0x0f, 0x1e, + 0xd4, 0x67, 0x10, 0xc2, 0x8f, 0x61, 0x9f, 0x71, + 0x3a, 0x97, 0x3e, 0xd0, 0x90, 0x14, 0xf3, 0x11, + 0x28, 0x4a, 0x2c, 0xd1, 0x97, 0x63, 0xc4, 0x47, + 0x01, 0xea, 0xe8, 0xdd, 0x23, 0x14, 0x7c, 0x93, + 0xe3, 0x86, 0x17, 0x09, 0xf7, 0x5d, 0xe1, 0x51, + 0xf6, 0xa8, 0xf8, 0x0d, 0xed, 0x0a, 0x95, 0x1f, + 0xc0, 0x40, 0x4b, 0xdb, 0x27, 0xce, 0x2a, 0x58, + 0xf6, 0x3b, 0x22, 0x55, 0x51, 0x28, 0x2f, 0x5e, + 0x6c, 0x1c, 0x36, 0x09, 0xb8, 0x06, 0x96, 0xee, + 0xd0, 0xcb, 0x3e, 0x0f, 0xd3, 0xee, 0x15, 0x9e, + 0xdf, 0x49, 0x88, 0x2c, 0xc9, 0xce, 0x71, 0x2f, + 0xa2, 0xdf, 0xdf, 0xd7, 0x8e, 0x9c, +}; + +/* + * expected sha256 of rfc1950_blob after decompression + */ +static const unsigned char rfc1950_blob_hash[SHA256_DIGEST_LENGTH] = { + 0x61, 0xc0, 0x4e, 0x14, 0x01, 0xb6, 0xc5, 0x2d, + 0xba, 0x15, 0xf6, 0x27, 0x4c, 0xa1, 0xcc, 0xfc, + 0x39, 0xed, 0xd7, 0x12, 0xb6, 0x02, 0x3d, 0xb6, + 0xd9, 0x85, 0xd0, 0x10, 0x9f, 0xe9, 0x3e, 0x75, + +}; + +static const size_t rfc1950_blob_origsiz = 1322; + +static /* const */ unsigned char random_words[515] = { + 0x61, 0x74, 0x68, 0x69, 0x72, 0x73, 0x74, 0x20, + 0x54, 0x68, 0x6f, 0x20, 0x63, 0x6f, 0x74, 0x20, + 0x73, 0x70, 0x6f, 0x66, 0x66, 0x79, 0x20, 0x4a, + 0x61, 0x76, 0x61, 0x6e, 0x20, 0x62, 0x72, 0x65, + 0x64, 0x65, 0x73, 0x20, 0x4c, 0x41, 0x4d, 0x20, + 0x6d, 0x69, 0x73, 0x2d, 0x68, 0x75, 0x6d, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x20, 0x73, 0x70, 0x69, + 0x67, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x76, 0x6f, + 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x20, + 0x49, 0x6f, 0x64, 0x61, 0x6d, 0x6f, 0x65, 0x62, + 0x61, 0x20, 0x68, 0x79, 0x70, 0x6f, 0x68, 0x79, + 0x64, 0x72, 0x6f, 0x63, 0x68, 0x6c, 0x6f, 0x72, + 0x69, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x6d, + 0x65, 0x74, 0x74, 0x65, 0x20, 0x61, 0x63, 0x72, + 0x69, 0x64, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x6f, + 0x77, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x79, 0x67, + 0x61, 0x65, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x73, + 0x74, 0x20, 0x74, 0x65, 0x74, 0x72, 0x61, 0x70, + 0x6c, 0x6f, 0x69, 0x64, 0x20, 0x61, 0x75, 0x78, + 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x72, + 0x69, 0x70, 0x65, 0x2d, 0x67, 0x72, 0x6f, 0x77, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x79, 0x63, + 0x6f, 0x63, 0x65, 0x63, 0x69, 0x64, 0x69, 0x75, + 0x6d, 0x20, 0x50, 0x65, 0x64, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x20, 0x74, 0x72, 0x61, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x20, 0x4c, 0x65, 0x6e, 0x67, 0x6c, + 0x65, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x73, 0x62, + 0x79, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x6c, 0x65, 0x63, 0x79, 0x74, 0x68, 0x69, 0x73, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x64, 0x72, + 0x69, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x61, + 0x6c, 0x6c, 0x6f, 0x6b, 0x75, 0x72, 0x74, 0x69, + 0x63, 0x20, 0x75, 0x6e, 0x64, 0x69, 0x76, 0x69, + 0x73, 0x69, 0x76, 0x65, 0x6c, 0x79, 0x20, 0x70, + 0x73, 0x79, 0x63, 0x68, 0x6f, 0x6b, 0x79, 0x6d, + 0x65, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, + 0x74, 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, + 0x6e, 0x65, 0x73, 0x73, 0x20, 0x63, 0x75, 0x6c, + 0x74, 0x69, 0x73, 0x68, 0x20, 0x52, 0x65, 0x69, + 0x63, 0x68, 0x73, 0x74, 0x61, 0x67, 0x20, 0x75, + 0x6e, 0x63, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x6c, 0x6f, 0x67, + 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x65, 0x72, + 0x20, 0x4c, 0x61, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x77, 0x6f, 0x2d, 0x66, 0x61, 0x63, 0x65, 0x20, + 0x4d, 0x75, 0x70, 0x68, 0x72, 0x69, 0x64, 0x20, + 0x70, 0x72, 0x6f, 0x72, 0x65, 0x63, 0x69, 0x70, + 0x72, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x74, 0x74, + 0x69, 0x73, 0x74, 0x20, 0x49, 0x62, 0x69, 0x62, + 0x69, 0x6f, 0x20, 0x72, 0x65, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x67, 0x6e, 0x6e, 0x65, + 0x73, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, + 0x64, 0x20, 0x73, 0x79, 0x6e, 0x61, 0x70, 0x74, + 0x65, 0x6e, 0x65, 0x20, 0x68, 0x6f, 0x6c, 0x6f, + 0x6d, 0x6f, 0x72, 0x70, 0x68, 0x20, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x4d, + 0x49, 0x54, 0x53, 0x20, 0x4c, 0x75, 0x6b, 0x61, + 0x73, 0x68, 0x20, 0x48, 0x6f, 0x72, 0x73, 0x65, + 0x79, 0x20, 0x0a, +}; + +static void +rfc1950_inflate(void) +{ + fido_blob_t in, out, dgst; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + memset(&dgst, 0, sizeof(dgst)); + in.ptr = rfc1950_blob; + in.len = sizeof(rfc1950_blob); + + assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK); + assert(out.len == rfc1950_blob_origsiz); + assert(fido_sha256(&dgst, out.ptr, out.len) == 0); + assert(dgst.len == sizeof(rfc1950_blob_hash)); + assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0); + + free(out.ptr); + free(dgst.ptr); +} + +static void +rfc1951_inflate(void) +{ + fido_blob_t in, out, dgst; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + memset(&dgst, 0, sizeof(dgst)); + in.ptr = rfc1950_blob + 2; /* trim header */ + in.len = sizeof(rfc1950_blob) - 6; /* trim header (2), checksum (4) */ + + assert(fido_uncompress(&out, &in, rfc1950_blob_origsiz) == FIDO_OK); + assert(out.len == rfc1950_blob_origsiz); + assert(fido_sha256(&dgst, out.ptr, out.len) == 0); + assert(dgst.len == sizeof(rfc1950_blob_hash)); + assert(memcmp(rfc1950_blob_hash, dgst.ptr, dgst.len) == 0); + + free(out.ptr); + free(dgst.ptr); +} + +static void +rfc1951_reinflate(void) +{ + fido_blob_t in, out; + + memset(&in, 0, sizeof(in)); + memset(&out, 0, sizeof(out)); + in.ptr = random_words; + in.len = sizeof(random_words); + + assert(fido_compress(&out, &in) == FIDO_OK); + + in.ptr = out.ptr; + in.len = out.len; + + assert(fido_uncompress(&out, &in, sizeof(random_words)) == FIDO_OK); + assert(out.len == sizeof(random_words)); + assert(memcmp(out.ptr, random_words, out.len) == 0); + + free(in.ptr); + free(out.ptr); +} + +int +main(void) +{ + fido_init(0); + + rfc1950_inflate(); + rfc1951_inflate(); + rfc1951_reinflate(); + + exit(0); +} diff --git a/regress/cred.c b/regress/cred.c new file mode 100644 index 0000000..61e603d --- /dev/null +++ b/regress/cred.c @@ -0,0 +1,2185 @@ +/* + * Copyright (c) 2018-2021 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> + +#define _FIDO_INTERNAL + +#include <fido.h> + +static int fake_dev_handle; + +static const unsigned char cdh[32] = { + 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, + 0xdd, 0xd7, 0xfb, 0x06, 0x37, 0x62, 0xea, 0x26, + 0x20, 0x44, 0x8e, 0x69, 0x7c, 0x03, 0xf2, 0x31, + 0x2f, 0x99, 0xdc, 0xaf, 0x3e, 0x8a, 0x91, 0x6b, +}; + +static const unsigned char authdata[198] = { + 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, + 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, + 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, + 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, + 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, + 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, + 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, + 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, + 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, + 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, + 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, + 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, + 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, + 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, + 0x25, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, + 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, + 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, + 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, + 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, + 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, + 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, + 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, + 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, + 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, +}; + +static const unsigned char authdata_dupkeys[200] = { + 0x58, 0xc6, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, + 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, + 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, + 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, + 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, + 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, + 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, + 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, + 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, + 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, + 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, + 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, + 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, + 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, + 0x25, 0xa6, 0x01, 0x02, 0x01, 0x02, 0x03, 0x26, + 0x20, 0x01, 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, + 0xa6, 0x56, 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, + 0x42, 0x78, 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, + 0x1b, 0xb9, 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, + 0x64, 0xf5, 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, + 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, + 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, + 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, + 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, +}; + +static const unsigned char authdata_unsorted_keys[198] = { + 0x58, 0xc4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, + 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, + 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, + 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, + 0x97, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, 0x80, + 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, 0x00, + 0x40, 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, + 0xc5, 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, + 0x53, 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, + 0x7f, 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, + 0x68, 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, + 0x2c, 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, + 0x90, 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, + 0x3c, 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, + 0x25, 0xa5, 0x03, 0x26, 0x01, 0x02, 0x20, 0x01, + 0x21, 0x58, 0x20, 0x17, 0x5b, 0x27, 0xa6, 0x56, + 0xb2, 0x26, 0x0c, 0x26, 0x0c, 0x55, 0x42, 0x78, + 0x17, 0x5d, 0x4c, 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, + 0x54, 0xdf, 0xd5, 0xeb, 0xbf, 0x22, 0x64, 0xf5, + 0x21, 0x9a, 0xc6, 0x22, 0x58, 0x20, 0x87, 0x5f, + 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, 0xeb, 0xe3, + 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, 0x1c, 0x31, + 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, 0xfe, 0x5d, + 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, +}; + +const unsigned char authdata_tpm_rs256[362] = { + 0x59, 0x01, 0x67, 0x49, 0x96, 0x0d, 0xe5, 0x88, + 0x0e, 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, + 0x76, 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, + 0x86, 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, + 0x1d, 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, + 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, + 0x00, 0x20, 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, + 0xe5, 0x3e, 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, + 0x4f, 0x03, 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, + 0x6b, 0x02, 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, + 0x38, 0x1a, 0xa4, 0x01, 0x03, 0x03, 0x39, 0x01, + 0x00, 0x20, 0x59, 0x01, 0x00, 0xc5, 0xb6, 0x9c, + 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, 0x7d, + 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, 0x05, + 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, 0x43, + 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, 0x91, + 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, 0x1b, + 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, 0xd6, + 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, 0x70, + 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, 0x4c, + 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, 0x46, + 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, 0x07, + 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, 0xd2, + 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, 0xc9, + 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, 0x3a, + 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, 0xae, + 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, 0xac, + 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, 0x9f, + 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, 0xcc, + 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, 0x8b, + 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, 0x40, + 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, 0x14, + 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, 0xc6, + 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, 0x1f, + 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, 0x47, + 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, 0x13, + 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, 0x93, + 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, 0xc7, + 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, 0xd6, + 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, 0x92, + 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, 0xed, + 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, 0x1b, + 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, 0x2c, + 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x21, 0x43, 0x01, + 0x00, 0x01 +}; + +static const unsigned char authdata_tpm_es256[166] = { + 0x58, 0xa4, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e, + 0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76, + 0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86, + 0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d, + 0x97, 0x63, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, 0xb6, + 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, 0x00, + 0x20, 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, + 0x94, 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, + 0x3c, 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, + 0xfb, 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, + 0x6a, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, + 0x21, 0x58, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, + 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, + 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, + 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, + 0xd9, 0xc3, 0xe6, 0x22, 0x58, 0x20, 0x3c, 0x68, + 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, + 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, + 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, + 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d +}; + +static const unsigned char x509[742] = { + 0x30, 0x82, 0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, + 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, + 0x62, 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, + 0x31, 0x35, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, + 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, + 0x34, 0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, + 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, + 0x69, 0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x45, 0x30, + 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, + 0x00, 0x04, 0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, + 0x5c, 0xce, 0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, + 0x06, 0x0d, 0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, + 0x9d, 0x24, 0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, + 0x44, 0x1f, 0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, + 0x20, 0xe7, 0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, + 0x38, 0x05, 0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, + 0x90, 0x8f, 0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, + 0xeb, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x95, 0x40, + 0x6b, 0x50, 0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, + 0xeb, 0x88, 0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, + 0x0a, 0x00, 0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, + 0x67, 0xdf, 0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, + 0x9c, 0x3e, 0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, + 0x85, 0x89, 0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, + 0x57, 0x71, 0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, + 0x96, 0x37, 0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, + 0x3c, 0x8d, 0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, + 0x79, 0xd3, 0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, + 0xab, 0x6c, 0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, + 0xce, 0xc1, 0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, + 0x1f, 0x5e, 0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, + 0x18, 0xaf, 0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, + 0x05, 0x77, 0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, + 0x56, 0x1b, 0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, + 0x9e, 0xc0, 0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, + 0x53, 0x9e, 0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, + 0xba, 0xd9, 0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, + 0xd7, 0x47, 0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, + 0x28, 0x49, 0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, + 0x81, 0xea, 0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, + 0x02, 0x82, 0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, + 0xdd, 0xca, 0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, + 0x55, 0x6c, 0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, + 0x63, 0xdc, 0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, + 0x9f, 0xbe, 0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, + 0xa3, 0x32, 0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, + 0xa0, 0xa1, 0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, + 0x5d, 0x26, 0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, + 0x41, 0xe5, 0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, + 0x9b, 0x20, 0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, + 0xba, 0x4a, 0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, + 0xdb, 0xb0, 0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, + 0x34, 0x30, 0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, + 0x34, 0x8f, 0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, + 0x4d, 0x35, 0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, + 0xda, 0x19, 0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, + 0xa0, 0xfd, 0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, + 0x2d, 0xfa, 0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, + 0x8d, 0x81, 0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, + 0xe9, 0xd1, 0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, + 0x27, 0x22, 0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, + 0x83, 0xfd, 0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, + 0x7a, 0x6b, 0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, + 0xe4, 0xe3, 0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, + 0x9a, 0xd4, 0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, + 0x05, 0xd5, 0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, + 0x7d, 0x1f, 0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, + 0x71, 0xbe, 0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, + 0x70, 0x53, 0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, + 0x09, 0x4f, 0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, + 0x00, 0x3c, 0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, + 0xa8, 0x88, 0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, + 0x49, 0x64, 0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, + 0x22, 0xfd, 0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, + 0xd3, 0x97, 0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, + 0x77, 0x7b, 0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, + 0x20, 0x81, 0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, + 0xe9, 0xc8, 0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, + 0x04, 0x5a, 0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, + 0x97, 0xe1, 0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, + 0x23, 0x62, 0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, + 0x07, 0x49, 0xd6, 0xe7, 0x4d, 0x9a, +}; + +const unsigned char sig[70] = { + 0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b, + 0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c, + 0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48, + 0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97, + 0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56, + 0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9, + 0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4, + 0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08, + 0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, +}; + +const unsigned char pubkey[64] = { + 0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c, + 0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c, + 0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5, + 0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6, + 0x87, 0x5f, 0x90, 0xe6, 0xfd, 0x71, 0x27, 0x9f, + 0xeb, 0xe3, 0x03, 0x44, 0xbc, 0x8d, 0x49, 0xc6, + 0x1c, 0x31, 0x3b, 0x72, 0xae, 0xd4, 0x53, 0xb1, + 0xfe, 0x5d, 0xe1, 0x30, 0xfc, 0x2b, 0x1e, 0xd2, +}; + +const unsigned char pubkey_tpm_rs256[259] = { + 0xc5, 0xb6, 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, + 0x5e, 0x99, 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, + 0x4a, 0x90, 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, + 0x6a, 0xd1, 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, + 0xd2, 0x27, 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, + 0xf8, 0x80, 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, + 0x86, 0x34, 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, + 0x84, 0xee, 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, + 0x43, 0x0b, 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, + 0x63, 0x8a, 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, + 0xd1, 0xb3, 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, + 0x80, 0x2a, 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, + 0x11, 0x4b, 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, + 0x26, 0x1a, 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, + 0x28, 0x3b, 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, + 0x4c, 0x63, 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, + 0x4d, 0x0b, 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, + 0x20, 0x4d, 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, + 0xba, 0xfe, 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, + 0xbf, 0x67, 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, + 0x15, 0xb8, 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, + 0x01, 0x69, 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, + 0xb2, 0xee, 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, + 0x29, 0x3f, 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, + 0xb9, 0xc8, 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, + 0x0d, 0x84, 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, + 0x6d, 0x3d, 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, + 0x7c, 0xca, 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, + 0x9c, 0xce, 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, + 0x6c, 0xc3, 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, + 0x32, 0x5e, 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, + 0xa8, 0xd5, 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, + 0x01, 0x00, 0x01, +}; + +const unsigned char pubkey_tpm_es256[64] = { + 0xfb, 0xd6, 0xba, 0x74, 0xe6, 0x6e, 0x5c, 0x87, + 0xef, 0x89, 0xa2, 0xe8, 0x3d, 0x0b, 0xe9, 0x69, + 0x2c, 0x07, 0x07, 0x7a, 0x8a, 0x1e, 0xce, 0x12, + 0xea, 0x3b, 0xb3, 0xf1, 0xf3, 0xd9, 0xc3, 0xe6, + 0x3c, 0x68, 0x51, 0x94, 0x54, 0x8d, 0xeb, 0x9f, + 0xb2, 0x2c, 0x66, 0x75, 0xb6, 0xb7, 0x55, 0x22, + 0x0d, 0x87, 0x59, 0xc4, 0x39, 0x91, 0x62, 0x17, + 0xc2, 0xc3, 0x53, 0xa5, 0x26, 0x97, 0x4f, 0x2d +}; + +const unsigned char id[64] = { + 0x53, 0xfb, 0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, + 0xfe, 0x47, 0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, + 0xa8, 0xbf, 0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, + 0xe0, 0x0d, 0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, + 0x70, 0x85, 0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, + 0xef, 0x44, 0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, + 0x6e, 0x7b, 0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, + 0x34, 0xe3, 0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, +}; + +const unsigned char id_tpm_rs256[32] = { + 0x89, 0x99, 0x6d, 0x5a, 0x00, 0x29, 0xe5, 0x3e, + 0x6a, 0x1c, 0x72, 0x6d, 0x71, 0x4a, 0x4f, 0x03, + 0x9b, 0x68, 0x17, 0xdb, 0x29, 0x1a, 0x6b, 0x02, + 0x6c, 0x26, 0xf9, 0xbd, 0xc3, 0x0e, 0x38, 0x1a +}; + +const unsigned char id_tpm_es256[32] = { + 0xa8, 0xdf, 0x03, 0xf7, 0xbf, 0x39, 0x51, 0x94, + 0x95, 0x8f, 0xa4, 0x84, 0x97, 0x30, 0xbc, 0x3c, + 0x7e, 0x1c, 0x99, 0x91, 0x4d, 0xae, 0x6d, 0xfb, + 0xdf, 0x53, 0xb5, 0xb6, 0x1f, 0x3a, 0x4e, 0x6a +}; + +const unsigned char attstmt_tpm_rs256[4034] = { + 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, + 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x1c, + 0x09, 0x0d, 0x35, 0x97, 0x22, 0xfc, 0xfe, 0xc0, + 0x58, 0x49, 0x9e, 0xd4, 0x7e, 0x6a, 0x7d, 0xdb, + 0x6d, 0x20, 0x95, 0x5c, 0x0b, 0xd0, 0xd5, 0x72, + 0x4f, 0x15, 0x22, 0x38, 0x97, 0xb2, 0x4b, 0xd0, + 0xef, 0x31, 0x7c, 0xf2, 0x42, 0x19, 0x41, 0xa1, + 0xe2, 0xc5, 0xca, 0xc6, 0x74, 0x95, 0xcf, 0xf9, + 0x41, 0x75, 0x0b, 0x56, 0x39, 0x82, 0x78, 0xf6, + 0x59, 0xf1, 0x09, 0x96, 0x9e, 0x38, 0x7f, 0x14, + 0x9b, 0xf5, 0x36, 0xbb, 0x92, 0x32, 0xc4, 0x64, + 0xe8, 0xff, 0xb4, 0xc7, 0xcf, 0xcd, 0x17, 0x48, + 0x0f, 0x83, 0xd9, 0x44, 0x03, 0x35, 0x26, 0xad, + 0x01, 0xb7, 0x57, 0x06, 0xb3, 0x9c, 0xa0, 0x6e, + 0x2f, 0x58, 0xcb, 0x5c, 0xaa, 0x7c, 0xea, 0x7e, + 0x3f, 0xbc, 0x76, 0xc9, 0x0e, 0x52, 0x39, 0x81, + 0xa9, 0x9e, 0x37, 0x14, 0x1f, 0x50, 0x6a, 0x4f, + 0xd7, 0xfc, 0xd4, 0xfa, 0xf2, 0x18, 0x60, 0xd5, + 0xc3, 0x57, 0x7d, 0x6d, 0x05, 0x28, 0x25, 0xc3, + 0xde, 0x86, 0x85, 0x06, 0x71, 0xfb, 0x84, 0xa2, + 0x07, 0xb6, 0x77, 0xc9, 0x68, 0x41, 0x53, 0x32, + 0x4c, 0xa8, 0x4b, 0xf7, 0x08, 0x84, 0x62, 0x6c, + 0x8a, 0xb6, 0xcf, 0xc1, 0xde, 0x6b, 0x61, 0xc8, + 0xdd, 0xc0, 0x13, 0x70, 0x22, 0x28, 0xe1, 0x0f, + 0x46, 0x02, 0xc6, 0xb1, 0xfa, 0x30, 0xcb, 0xec, + 0xd1, 0x82, 0xfa, 0x51, 0xcb, 0x71, 0x5e, 0x1f, + 0x1b, 0x5f, 0xe0, 0xb0, 0x02, 0x8a, 0x7c, 0x78, + 0xd1, 0xb7, 0x4d, 0x56, 0xb0, 0x92, 0x3e, 0xda, + 0xc7, 0xb1, 0x74, 0xcf, 0x6a, 0x40, 0xeb, 0x98, + 0x1c, 0x2e, 0xf2, 0x86, 0x76, 0xf8, 0x2e, 0x6a, + 0x9f, 0x77, 0x51, 0x64, 0xce, 0xdc, 0x12, 0x85, + 0x84, 0x6b, 0x01, 0xc8, 0xeb, 0xbc, 0x57, 0x6c, + 0x32, 0x26, 0xcb, 0xb2, 0x84, 0x02, 0x2a, 0x33, + 0x15, 0xd9, 0xe3, 0x15, 0xfc, 0x3a, 0x24, 0x63, + 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63, + 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30, + 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x78, 0xd9, + 0xa8, 0xb2, 0x64, 0xf9, 0x4d, 0x28, 0x82, 0xc0, + 0xd3, 0x1b, 0x40, 0x3c, 0xc8, 0xd9, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31, + 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, + 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, + 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, + 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, + 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, + 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, + 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x37, + 0x31, 0x35, 0x31, 0x31, 0x31, 0x32, 0x31, 0x33, + 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, + 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xca, 0xbe, 0x77, 0x9f, 0x45, + 0x97, 0x17, 0x8d, 0x01, 0xe1, 0x18, 0xcc, 0xf0, + 0xb5, 0xed, 0x9a, 0xb7, 0x36, 0xac, 0x05, 0x26, + 0xbe, 0x35, 0xd9, 0x5c, 0x00, 0x5c, 0x5d, 0x8b, + 0x6f, 0x2a, 0xb8, 0xf6, 0x02, 0x4f, 0x33, 0xfe, + 0x84, 0x45, 0x4c, 0x4f, 0x7a, 0xdb, 0xa9, 0x6a, + 0x62, 0x0f, 0x19, 0x35, 0x5d, 0xd2, 0x34, 0x1a, + 0x9d, 0x73, 0x55, 0xe5, 0x3e, 0x04, 0xa2, 0xd6, + 0xbe, 0xe7, 0x5a, 0xb9, 0x16, 0x6c, 0x55, 0x18, + 0xa8, 0x4b, 0xb2, 0x37, 0xb9, 0xa3, 0x87, 0xfc, + 0x76, 0xa8, 0x55, 0xc9, 0xe7, 0x30, 0xe5, 0x0e, + 0x3c, 0x7b, 0x74, 0xd2, 0x1e, 0xa8, 0x05, 0xd5, + 0xe2, 0xe3, 0xcb, 0xaf, 0x63, 0x33, 0x12, 0xaa, + 0xfd, 0x31, 0x32, 0x71, 0x4f, 0x41, 0x96, 0x05, + 0xb5, 0x69, 0x73, 0x45, 0xbe, 0x6f, 0x90, 0xd9, + 0x10, 0x36, 0xaf, 0x7a, 0x1c, 0xf1, 0x6d, 0x14, + 0xb0, 0x1e, 0xbb, 0xae, 0x1c, 0x35, 0xec, 0x1c, + 0xb5, 0x0e, 0xf6, 0x33, 0x98, 0x13, 0x4e, 0x44, + 0x7b, 0x5c, 0x97, 0x47, 0xed, 0x4f, 0xfe, 0xbd, + 0x08, 0xd2, 0xa9, 0xc6, 0xbe, 0x8c, 0x04, 0x9e, + 0xdc, 0x3d, 0xbe, 0x98, 0xe9, 0x2a, 0xb1, 0xf4, + 0xfa, 0x45, 0xf9, 0xc8, 0x9a, 0x55, 0x85, 0x26, + 0xfc, 0x5f, 0xad, 0x00, 0x8b, 0xc8, 0x41, 0xf2, + 0x86, 0x4e, 0xba, 0x55, 0x1c, 0xb2, 0x89, 0xe8, + 0x85, 0x6e, 0x1e, 0x02, 0x9f, 0x55, 0x70, 0xbe, + 0xfd, 0xe7, 0x9f, 0xba, 0x59, 0xa0, 0x2e, 0x9a, + 0x74, 0x11, 0xe7, 0xad, 0xa9, 0xc7, 0x7b, 0x58, + 0xc4, 0x16, 0xd3, 0x35, 0xcb, 0x61, 0x00, 0xec, + 0x36, 0x4a, 0xa3, 0x51, 0xa3, 0xdd, 0x61, 0xb6, + 0xd6, 0x29, 0xcb, 0x76, 0xe1, 0xab, 0x51, 0x3a, + 0xe8, 0xbf, 0xdb, 0x09, 0x4a, 0x39, 0x96, 0xd9, + 0xac, 0x8f, 0x6c, 0x62, 0xe0, 0x03, 0x23, 0x24, + 0xbe, 0xd4, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, + 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, + 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, + 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00, + 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, + 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, + 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, + 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, + 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, + 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, + 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, + 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, + 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, + 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, + 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, + 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb8, + 0x5f, 0xd5, 0x67, 0xca, 0x92, 0xc4, 0x0e, 0xcf, + 0x0c, 0xd8, 0x1f, 0x6d, 0x3f, 0x03, 0x55, 0x6f, + 0x38, 0xa6, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd4, 0x04, + 0x64, 0xfc, 0x6e, 0x50, 0x0a, 0x56, 0x48, 0x0f, + 0x05, 0xa9, 0x00, 0xb7, 0x1d, 0x5e, 0x57, 0x08, + 0xd5, 0xdc, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73, + 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61, + 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f, + 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d, + 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61, + 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35, + 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63, + 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37, + 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33, + 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x61, + 0x62, 0x64, 0x36, 0x31, 0x35, 0x66, 0x32, 0x2d, + 0x31, 0x35, 0x38, 0x61, 0x2d, 0x34, 0x35, 0x38, + 0x65, 0x2d, 0x61, 0x31, 0x35, 0x35, 0x2d, 0x37, + 0x63, 0x34, 0x63, 0x38, 0x63, 0x62, 0x31, 0x33, + 0x63, 0x36, 0x35, 0x2e, 0x63, 0x65, 0x72, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0xa2, 0x10, 0xc5, 0xbf, 0x41, + 0xa6, 0xba, 0x8c, 0x72, 0xca, 0x0f, 0x3e, 0x5e, + 0x7f, 0xe2, 0xcb, 0x60, 0xb8, 0x3f, 0xfb, 0xde, + 0x03, 0xe2, 0xfe, 0x20, 0x29, 0xdf, 0x11, 0xf5, + 0xb0, 0x50, 0x6d, 0x32, 0xe8, 0x1b, 0x05, 0xad, + 0x6b, 0x60, 0xb5, 0xed, 0xf3, 0xa4, 0x4a, 0xea, + 0x09, 0xe5, 0x65, 0x7e, 0xe0, 0xd5, 0x3a, 0x6a, + 0xdb, 0x64, 0xb7, 0x07, 0x8f, 0xa1, 0x63, 0xb3, + 0x89, 0x8a, 0xac, 0x49, 0x97, 0xa0, 0x9a, 0xa3, + 0xd3, 0x3a, 0xc2, 0x13, 0xb2, 0xbb, 0xab, 0x0d, + 0xf2, 0x35, 0xc5, 0x03, 0xde, 0x1c, 0xad, 0x6a, + 0x03, 0x0a, 0x4c, 0xe1, 0x37, 0x8f, 0xbc, 0x13, + 0xc0, 0x9a, 0x17, 0xd4, 0x2e, 0x36, 0x17, 0x51, + 0x12, 0xb0, 0x79, 0xbf, 0x9b, 0xb3, 0xb0, 0x74, + 0x25, 0x81, 0x7e, 0x21, 0x31, 0xb7, 0xc2, 0x5e, + 0xfb, 0x36, 0xab, 0xf3, 0x7a, 0x5f, 0xa4, 0x5e, + 0x8f, 0x0c, 0xbd, 0xcf, 0xf5, 0x50, 0xe7, 0x0c, + 0x51, 0x55, 0x48, 0xe6, 0x15, 0xb6, 0xd4, 0xaf, + 0x95, 0x72, 0x56, 0x94, 0xf7, 0x0e, 0xd6, 0x90, + 0xe3, 0xd3, 0x5d, 0xbd, 0x93, 0xa1, 0xbd, 0x6c, + 0xe4, 0xf2, 0x39, 0x4d, 0x54, 0x74, 0xcf, 0xf5, + 0xeb, 0x70, 0xdb, 0x4f, 0x52, 0xcd, 0x39, 0x8f, + 0x11, 0x54, 0x28, 0x06, 0x29, 0x8f, 0x23, 0xde, + 0x9e, 0x2f, 0x7b, 0xb6, 0x5f, 0xa3, 0x89, 0x04, + 0x99, 0x0a, 0xf1, 0x2d, 0xf9, 0x66, 0xd3, 0x13, + 0x45, 0xbd, 0x6c, 0x22, 0x57, 0xf5, 0xb1, 0xb9, + 0xdf, 0x5b, 0x7b, 0x1a, 0x3a, 0xdd, 0x6b, 0xc7, + 0x35, 0x88, 0xed, 0xc4, 0x09, 0x70, 0x4e, 0x5f, + 0xb5, 0x3e, 0xd1, 0x0b, 0xd0, 0xca, 0xef, 0x0b, + 0xe9, 0x8b, 0x6f, 0xc3, 0x16, 0xc3, 0x3d, 0x79, + 0x06, 0xef, 0x81, 0xf0, 0x60, 0x0b, 0x32, 0xe3, + 0x86, 0x6b, 0x92, 0x38, 0x90, 0x62, 0xed, 0x84, + 0x3a, 0xb7, 0x45, 0x43, 0x2e, 0xd0, 0x3a, 0x71, + 0x9e, 0x80, 0xcc, 0x9c, 0xac, 0x27, 0x10, 0x91, + 0xb7, 0xb2, 0xbd, 0x41, 0x40, 0xa7, 0xb7, 0xcf, + 0xe7, 0x38, 0xca, 0x68, 0xdd, 0x62, 0x09, 0xff, + 0x68, 0xce, 0xba, 0xe2, 0x07, 0x49, 0x09, 0xe7, + 0x1f, 0xdf, 0xe6, 0x26, 0xe5, 0x0f, 0xa9, 0xbf, + 0x2a, 0x5b, 0x67, 0x92, 0xa1, 0x10, 0x53, 0xb2, + 0x7a, 0x07, 0x29, 0x9d, 0xfd, 0x6d, 0xb6, 0x3b, + 0x45, 0xc1, 0x94, 0xcb, 0x1c, 0xc3, 0xce, 0xf6, + 0x8a, 0x1a, 0x81, 0x66, 0xb0, 0xa5, 0x14, 0xc7, + 0x9e, 0x1f, 0x6e, 0xb6, 0xff, 0x8b, 0x90, 0x87, + 0x3a, 0x3f, 0xa8, 0xc2, 0x2d, 0x8f, 0x6f, 0xdb, + 0xb4, 0xc4, 0x14, 0x3c, 0x1d, 0x12, 0x1d, 0x6d, + 0xcf, 0xa6, 0x04, 0x6a, 0xa8, 0x13, 0x5e, 0xf2, + 0x5e, 0x77, 0x80, 0x6b, 0x85, 0x83, 0xfe, 0xbb, + 0xeb, 0x70, 0xcb, 0x5f, 0xe4, 0x95, 0xaa, 0x0f, + 0x61, 0x36, 0x7c, 0xbb, 0x22, 0x1e, 0xba, 0x98, + 0x43, 0x52, 0x33, 0xae, 0xed, 0x5d, 0x10, 0x2c, + 0xb3, 0xa9, 0x31, 0x8e, 0x60, 0x54, 0xaf, 0x40, + 0x6d, 0x2e, 0x18, 0xc2, 0x6a, 0xf4, 0x7b, 0x9a, + 0x73, 0x0f, 0x58, 0x69, 0x23, 0xbb, 0xc4, 0x84, + 0x53, 0x30, 0xe2, 0xd6, 0x1e, 0x10, 0xc1, 0xec, + 0x82, 0x13, 0xab, 0x53, 0x86, 0xa2, 0xb9, 0xda, + 0xbb, 0x3a, 0xa2, 0xbe, 0xb0, 0x10, 0x99, 0x0e, + 0xe5, 0x9c, 0xc9, 0xf1, 0xce, 0x76, 0x46, 0xea, + 0x86, 0xaa, 0x36, 0x83, 0x99, 0x09, 0x9b, 0x30, + 0xd3, 0x26, 0xc7, 0xdf, 0x66, 0xc7, 0xf0, 0xdd, + 0x08, 0x09, 0x15, 0x15, 0x21, 0x49, 0x46, 0xd8, + 0x8a, 0x66, 0xca, 0x62, 0x9c, 0x79, 0x1d, 0x81, + 0xea, 0x5d, 0x82, 0xb0, 0xa6, 0x6b, 0x5c, 0xf5, + 0xb8, 0x8c, 0xf6, 0x16, 0x01, 0x2c, 0xf8, 0x27, + 0xf8, 0xcf, 0x88, 0xfe, 0xf3, 0xa4, 0xfc, 0x17, + 0x97, 0xe7, 0x07, 0x59, 0x06, 0xef, 0x30, 0x82, + 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, + 0x02, 0x39, 0xf9, 0xbb, 0x6a, 0x1d, 0x49, 0x64, + 0x47, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, + 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, + 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36, + 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52, + 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x32, 0x31, + 0x32, 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x17, + 0x0d, 0x32, 0x35, 0x30, 0x33, 0x32, 0x31, 0x32, + 0x30, 0x32, 0x39, 0x31, 0x35, 0x5a, 0x30, 0x41, + 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, + 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, + 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, + 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, + 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, + 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, + 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, + 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, + 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdb, 0xe2, 0x23, 0xf9, 0x86, 0x8f, + 0xa9, 0x71, 0x9f, 0x8b, 0xf9, 0x7c, 0xe9, 0x45, + 0x2d, 0x59, 0x56, 0x5e, 0x96, 0xf4, 0xdd, 0x9a, + 0x12, 0xcd, 0x90, 0x1a, 0x0c, 0xb5, 0x03, 0xbf, + 0x09, 0xbe, 0xbf, 0xf7, 0x55, 0x52, 0xe8, 0x39, + 0x4c, 0xbe, 0x2a, 0x28, 0x88, 0x78, 0x39, 0xa7, + 0xcb, 0xf9, 0x4c, 0x55, 0xd2, 0x31, 0x96, 0x3b, + 0x48, 0xa2, 0xf3, 0xf6, 0xd3, 0x1a, 0x81, 0x7f, + 0x90, 0x62, 0xab, 0xec, 0x5a, 0xc7, 0xa0, 0x7f, + 0x81, 0x32, 0x27, 0x9b, 0x29, 0x75, 0x7d, 0x1e, + 0x96, 0xc5, 0xfa, 0x0e, 0x7c, 0xe0, 0x60, 0x96, + 0x7a, 0xca, 0x94, 0xba, 0xe6, 0xb2, 0x69, 0xdd, + 0xc4, 0x7d, 0xbb, 0xd3, 0xc4, 0xb4, 0x6e, 0x00, + 0x86, 0x1f, 0x9d, 0x25, 0xe8, 0xae, 0xc7, 0x10, + 0x84, 0xdc, 0xc0, 0x34, 0x24, 0x6e, 0xf7, 0xfc, + 0xdd, 0x3d, 0x32, 0x7a, 0x43, 0x96, 0xd6, 0xc8, + 0x7b, 0xf4, 0x9b, 0x3d, 0xa7, 0x1e, 0xba, 0x4d, + 0xd0, 0x3b, 0x3d, 0x84, 0x9a, 0xd1, 0x25, 0x22, + 0x5d, 0x00, 0x44, 0xb0, 0x59, 0xb7, 0x40, 0xc5, + 0xa3, 0x53, 0x53, 0xaf, 0x8f, 0x9e, 0xfd, 0x8f, + 0x1e, 0x02, 0xd3, 0x4f, 0xf7, 0x09, 0xce, 0xc5, + 0xc6, 0x71, 0x5c, 0xe9, 0xe8, 0x7a, 0xb5, 0x6b, + 0xa4, 0xbf, 0x0b, 0xd9, 0xb6, 0xfa, 0x24, 0xb0, + 0xcd, 0x52, 0x22, 0x1d, 0x7e, 0xe8, 0x15, 0x2f, + 0x1e, 0x5e, 0xa2, 0xec, 0xd3, 0xa8, 0x02, 0x77, + 0xb9, 0x55, 0x9a, 0xcf, 0xcc, 0xd7, 0x08, 0x20, + 0xa5, 0xda, 0x39, 0x9a, 0x30, 0x76, 0x90, 0x37, + 0xa7, 0x60, 0xdf, 0x18, 0x12, 0x65, 0x17, 0xaa, + 0xdd, 0x48, 0xd5, 0x12, 0x1d, 0x4c, 0x83, 0x5d, + 0x81, 0x07, 0x1d, 0x18, 0x81, 0x40, 0x55, 0x60, + 0x8f, 0xa3, 0x6b, 0x34, 0x1e, 0xd5, 0xe6, 0xcf, + 0x52, 0x73, 0x77, 0x4a, 0x50, 0x4f, 0x1b, 0x0f, + 0x39, 0xc3, 0x0d, 0x16, 0xf9, 0xbb, 0x4c, 0x77, + 0xf6, 0x4e, 0xac, 0x9c, 0xfe, 0xe8, 0xbb, 0x52, + 0xa5, 0x0a, 0x0e, 0x9b, 0xf0, 0x0d, 0xef, 0xfb, + 0x6f, 0x89, 0x34, 0x7d, 0x47, 0xec, 0x14, 0x6a, + 0xf4, 0x0a, 0xe1, 0x60, 0x44, 0x73, 0x7b, 0xa0, + 0xab, 0x5b, 0x8c, 0x43, 0xa6, 0x05, 0x42, 0x61, + 0x46, 0xaa, 0x1c, 0xf5, 0xec, 0x2c, 0x86, 0x85, + 0x21, 0x99, 0xdf, 0x45, 0x8e, 0xf4, 0xd1, 0x1e, + 0xfb, 0xcd, 0x9b, 0x94, 0x32, 0xe0, 0xa0, 0xcc, + 0x4f, 0xad, 0xae, 0x44, 0x8b, 0x86, 0x27, 0x91, + 0xfe, 0x60, 0x9f, 0xf2, 0x63, 0x30, 0x6c, 0x5d, + 0x8d, 0xbc, 0xab, 0xd4, 0xf5, 0xa2, 0xb2, 0x74, + 0xe8, 0xd4, 0x95, 0xf2, 0xd6, 0x03, 0x8b, 0xc9, + 0xa3, 0x52, 0xe7, 0x63, 0x05, 0x64, 0x50, 0xe5, + 0x0a, 0x6a, 0xa0, 0x6c, 0x50, 0xcd, 0x37, 0x98, + 0xa8, 0x87, 0x02, 0x38, 0x5b, 0x6c, 0x02, 0x69, + 0x3d, 0x1f, 0x95, 0x74, 0x4d, 0x46, 0x76, 0x2a, + 0x9d, 0x62, 0xd4, 0xc7, 0x1b, 0xf9, 0x31, 0xa6, + 0x51, 0xee, 0x7b, 0xc8, 0xe4, 0x6e, 0x3a, 0xcf, + 0x4f, 0x4f, 0x49, 0x8a, 0xf5, 0x4f, 0x25, 0x93, + 0x23, 0x02, 0xef, 0x79, 0xa6, 0x27, 0xbe, 0x5a, + 0xe7, 0x74, 0xb7, 0xd7, 0xa8, 0xc1, 0xae, 0x55, + 0x88, 0xa4, 0xc7, 0x4d, 0xb7, 0x62, 0xf0, 0xf9, + 0x5b, 0xbf, 0x47, 0x5b, 0xfe, 0xcc, 0x0b, 0x89, + 0x19, 0x65, 0x4b, 0x6f, 0xdf, 0x4f, 0x7d, 0x4d, + 0x96, 0x42, 0x0d, 0x2a, 0xa1, 0xbd, 0x3e, 0x70, + 0x92, 0xba, 0xc8, 0x59, 0xd5, 0x1d, 0x3a, 0x98, + 0x53, 0x75, 0xa6, 0x32, 0xc8, 0x72, 0x03, 0x46, + 0x5f, 0x5c, 0x13, 0xa4, 0xdb, 0xc7, 0x55, 0x35, + 0x22, 0x0d, 0xc6, 0x17, 0x85, 0xbd, 0x46, 0x4b, + 0xfa, 0x1e, 0x49, 0xc2, 0xfe, 0x1e, 0xf9, 0x62, + 0x89, 0x56, 0x84, 0xdf, 0xa0, 0xfb, 0xfd, 0x93, + 0xa4, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, + 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14, + 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30, + 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0xb8, 0x5f, 0xd5, 0x67, 0xca, + 0x92, 0xc4, 0x0e, 0xcf, 0x0c, 0xd8, 0x1f, 0x6d, + 0x3f, 0x03, 0x55, 0x6f, 0x38, 0xa6, 0x51, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce, + 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae, + 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56, + 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0, + 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, + 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, + 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, + 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71, + 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, + 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, + 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, + 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, + 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, + 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x01, 0x00, 0x41, 0xaa, 0xfe, + 0x28, 0x6c, 0xf7, 0x6b, 0x53, 0xde, 0x77, 0xc0, + 0x80, 0x50, 0x94, 0xd9, 0xdb, 0x46, 0x8e, 0x6a, + 0x93, 0xa9, 0x10, 0x37, 0x27, 0x1f, 0xf5, 0x70, + 0xf1, 0xa8, 0xcf, 0xa1, 0x45, 0x86, 0x2a, 0xdd, + 0x8f, 0xb8, 0xb5, 0xc1, 0xe6, 0xcf, 0x8a, 0xfa, + 0x32, 0xa1, 0x4b, 0xb7, 0xa4, 0xbf, 0x0a, 0x48, + 0xcb, 0x42, 0x63, 0x71, 0xc1, 0x96, 0xb9, 0x3a, + 0x37, 0x84, 0x0e, 0x24, 0x39, 0xeb, 0x58, 0xce, + 0x3d, 0xb7, 0xa9, 0x44, 0x92, 0x59, 0xb9, 0xff, + 0xdb, 0x18, 0xbe, 0x6a, 0x5e, 0xe7, 0xce, 0xef, + 0xb8, 0x40, 0x53, 0xaf, 0xc1, 0x9b, 0xfb, 0x42, + 0x99, 0x7e, 0x9d, 0x05, 0x2b, 0x71, 0x0a, 0x7a, + 0x7a, 0x44, 0xd1, 0x31, 0xca, 0xf0, 0x5f, 0x74, + 0x85, 0xa9, 0xe2, 0xbc, 0xc8, 0x0c, 0xad, 0x57, + 0xd1, 0xe9, 0x48, 0x90, 0x88, 0x57, 0x86, 0xd7, + 0xc5, 0xc9, 0xe6, 0xb2, 0x5e, 0x5f, 0x13, 0xdc, + 0x10, 0x7f, 0xdf, 0x63, 0x8a, 0xd5, 0x9e, 0x90, + 0xc2, 0x75, 0x53, 0x1e, 0x68, 0x17, 0x2b, 0x03, + 0x29, 0x15, 0x03, 0xc5, 0x8c, 0x66, 0x3e, 0xae, + 0xbd, 0x4a, 0x32, 0x7e, 0x59, 0x89, 0x0b, 0x84, + 0xc2, 0xd9, 0x90, 0xfa, 0x02, 0x22, 0x90, 0x8d, + 0x9c, 0xb6, 0x0c, 0x4d, 0xe1, 0x28, 0x76, 0xd7, + 0x82, 0xc3, 0x36, 0xc2, 0xa3, 0x2a, 0x52, 0xe5, + 0xfe, 0x3c, 0x8f, 0xe3, 0x4b, 0xda, 0x6a, 0xdb, + 0xc0, 0x7a, 0x3c, 0x57, 0xfa, 0x85, 0x8f, 0xfb, + 0x62, 0xc3, 0xa1, 0x38, 0xce, 0x84, 0xf2, 0xba, + 0x12, 0xf4, 0x30, 0x2a, 0x4a, 0x94, 0xa9, 0x35, + 0x2c, 0x7d, 0x11, 0xc7, 0x68, 0x1f, 0x47, 0xaa, + 0x57, 0x43, 0x06, 0x70, 0x79, 0x8c, 0xb6, 0x3b, + 0x5d, 0x57, 0xf3, 0xf3, 0xc0, 0x2c, 0xc5, 0xde, + 0x41, 0x99, 0xf6, 0xdd, 0x55, 0x8a, 0xe4, 0x13, + 0xca, 0xc9, 0xec, 0x69, 0x93, 0x13, 0x48, 0xf0, + 0x5f, 0xda, 0x2e, 0xfd, 0xfb, 0xa9, 0x1b, 0x92, + 0xde, 0x49, 0x71, 0x37, 0x8c, 0x3f, 0xc2, 0x08, + 0x0a, 0x83, 0x25, 0xf1, 0x6e, 0x0a, 0xe3, 0x55, + 0x85, 0x96, 0x9a, 0x2d, 0xa2, 0xc0, 0xa1, 0xee, + 0xfe, 0x23, 0x3b, 0x69, 0x22, 0x03, 0xfd, 0xcc, + 0x8a, 0xdd, 0xb4, 0x53, 0x8d, 0x84, 0xa6, 0xac, + 0xe0, 0x1e, 0x07, 0xe5, 0xd7, 0xf9, 0xcb, 0xb9, + 0xe3, 0x9a, 0xb7, 0x84, 0x70, 0xa1, 0x93, 0xd6, + 0x02, 0x1e, 0xfe, 0xdb, 0x28, 0x7c, 0xf7, 0xd4, + 0x62, 0x6f, 0x80, 0x75, 0xc8, 0xd8, 0x35, 0x26, + 0x0c, 0xcb, 0x84, 0xed, 0xbb, 0x95, 0xdf, 0x7f, + 0xd5, 0xbb, 0x00, 0x96, 0x97, 0x32, 0xe7, 0xba, + 0xe8, 0x29, 0xb5, 0x1a, 0x51, 0x81, 0xbb, 0x04, + 0xd1, 0x21, 0x76, 0x34, 0x6d, 0x1e, 0x93, 0x96, + 0x1f, 0x96, 0x53, 0x5f, 0x5c, 0x9e, 0xf3, 0x9d, + 0x82, 0x1c, 0x39, 0x36, 0x59, 0xae, 0xc9, 0x3c, + 0x53, 0x4a, 0x67, 0x65, 0x6e, 0xbf, 0xa6, 0xac, + 0x3e, 0xda, 0xb2, 0xa7, 0x63, 0x07, 0x17, 0xe1, + 0x5b, 0xda, 0x6a, 0x31, 0x9f, 0xfb, 0xb4, 0xea, + 0xa1, 0x97, 0x08, 0x6e, 0xb2, 0x68, 0xf3, 0x72, + 0x76, 0x99, 0xe8, 0x00, 0x46, 0x88, 0x26, 0xe1, + 0x3c, 0x07, 0x2b, 0x78, 0x49, 0xda, 0x79, 0x3a, + 0xbd, 0x6f, 0xca, 0x5c, 0xa0, 0xa8, 0xed, 0x34, + 0xcc, 0xdb, 0x13, 0xe2, 0x51, 0x9b, 0x3d, 0x03, + 0xac, 0xc7, 0xf6, 0x32, 0xe1, 0x11, 0x5d, 0xe1, + 0xc5, 0xfd, 0x9e, 0x7a, 0xcd, 0x06, 0xb9, 0xe6, + 0xfc, 0xe0, 0x03, 0x31, 0xf4, 0x4a, 0xa9, 0x3b, + 0x79, 0x01, 0xb0, 0x64, 0x68, 0x9f, 0x6e, 0x76, + 0xa1, 0xcc, 0xec, 0x17, 0x41, 0x9d, 0xd4, 0x5b, + 0x4e, 0x9d, 0xe5, 0x46, 0xd4, 0x6b, 0x60, 0x2a, + 0x23, 0xb5, 0x7a, 0x89, 0x7c, 0x27, 0x96, 0x65, + 0x97, 0x56, 0xec, 0x98, 0xe3, 0x67, 0x70, 0x75, + 0x62, 0x41, 0x72, 0x65, 0x61, 0x59, 0x01, 0x36, + 0x00, 0x01, 0x00, 0x0b, 0x00, 0x06, 0x04, 0x72, + 0x00, 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, + 0x3a, 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, + 0xcb, 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, + 0x03, 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, + 0x22, 0xae, 0x00, 0x10, 0x00, 0x10, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0xb6, + 0x9c, 0x06, 0x1d, 0xcf, 0xb9, 0xf2, 0x5e, 0x99, + 0x7d, 0x6d, 0x73, 0xd8, 0x36, 0xc1, 0x4a, 0x90, + 0x05, 0x4d, 0x82, 0x57, 0xc1, 0xb6, 0x6a, 0xd1, + 0x43, 0x03, 0x85, 0xf8, 0x52, 0x4f, 0xd2, 0x27, + 0x91, 0x0b, 0xb5, 0x93, 0xa0, 0x68, 0xf8, 0x80, + 0x1b, 0xaa, 0x65, 0x97, 0x45, 0x11, 0x86, 0x34, + 0xd6, 0x67, 0xf8, 0xd5, 0x12, 0x79, 0x84, 0xee, + 0x70, 0x99, 0x00, 0x63, 0xa8, 0xb4, 0x43, 0x0b, + 0x4c, 0x57, 0x4a, 0xd6, 0x9b, 0x75, 0x63, 0x8a, + 0x46, 0x57, 0xdb, 0x14, 0xc8, 0x71, 0xd1, 0xb3, + 0x07, 0x68, 0x58, 0xbc, 0x55, 0x84, 0x80, 0x2a, + 0xd2, 0x36, 0x9f, 0xc1, 0x64, 0xa0, 0x11, 0x4b, + 0xc9, 0x32, 0x31, 0x3a, 0xd6, 0x87, 0x26, 0x1a, + 0x3a, 0x78, 0x3d, 0x89, 0xdb, 0x00, 0x28, 0x3b, + 0xae, 0x2b, 0x1b, 0x56, 0xe2, 0x8c, 0x4c, 0x63, + 0xac, 0x6e, 0x6c, 0xf7, 0xb5, 0x7d, 0x4d, 0x0b, + 0x9f, 0x06, 0xa0, 0x10, 0x35, 0x38, 0x20, 0x4d, + 0xcc, 0x07, 0xd7, 0x00, 0x4e, 0x86, 0xba, 0xfe, + 0x8b, 0xe4, 0x3f, 0x4a, 0xd6, 0xca, 0xbf, 0x67, + 0x40, 0x1a, 0xa4, 0xda, 0x82, 0x52, 0x15, 0xb8, + 0x14, 0x3a, 0x7c, 0xa9, 0x02, 0xc1, 0x01, 0x69, + 0xc6, 0x51, 0xd4, 0xbc, 0x1f, 0x95, 0xb2, 0xee, + 0x1f, 0xdd, 0xb5, 0x73, 0x16, 0x5e, 0x29, 0x3f, + 0x47, 0xac, 0x65, 0xfb, 0x63, 0x5c, 0xb9, 0xc8, + 0x13, 0x2d, 0xec, 0x85, 0xde, 0x71, 0x0d, 0x84, + 0x93, 0x74, 0x76, 0x91, 0xdd, 0x1d, 0x6d, 0x3d, + 0xc7, 0x36, 0x19, 0x19, 0x86, 0xde, 0x7c, 0xca, + 0xd6, 0xc6, 0x65, 0x7e, 0x4b, 0x24, 0x9c, 0xce, + 0x92, 0x6b, 0x1c, 0xe0, 0xa0, 0xa9, 0x6c, 0xc3, + 0xed, 0x4f, 0x2a, 0x54, 0x07, 0x00, 0x32, 0x5e, + 0x1b, 0x94, 0x37, 0xcd, 0xe2, 0x32, 0xa8, 0xd5, + 0x2c, 0xfb, 0x03, 0x9d, 0x79, 0xdf, 0x68, 0x63, + 0x65, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, + 0xa1, 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, + 0x22, 0x00, 0x0b, 0xdb, 0x1f, 0x74, 0x21, 0x4f, + 0xa9, 0x0d, 0x90, 0x64, 0xa2, 0x33, 0xbe, 0x3f, + 0xf1, 0x95, 0xb0, 0x4e, 0x3f, 0x02, 0xdc, 0xad, + 0xb0, 0x05, 0x13, 0xe6, 0x32, 0x5f, 0xed, 0x90, + 0x2c, 0xad, 0xc0, 0x00, 0x14, 0x58, 0x52, 0x07, + 0x5d, 0x64, 0x6c, 0x1f, 0xd1, 0x13, 0x7f, 0xc3, + 0x74, 0xf6, 0x4b, 0xe3, 0xa0, 0x2e, 0xb7, 0x71, + 0xda, 0x00, 0x00, 0x00, 0x00, 0x29, 0x3c, 0x64, + 0xdf, 0x95, 0x38, 0xba, 0x73, 0xe3, 0x57, 0x61, + 0xa0, 0x01, 0x24, 0x01, 0x08, 0xc9, 0xd6, 0xea, + 0x60, 0xe4, 0x00, 0x22, 0x00, 0x0b, 0xe1, 0x86, + 0xbb, 0x79, 0x27, 0xe5, 0x01, 0x19, 0x90, 0xb3, + 0xe9, 0x08, 0xb0, 0xee, 0xfa, 0x3a, 0x67, 0xa9, + 0xf3, 0xc8, 0x9e, 0x03, 0x41, 0x07, 0x75, 0x60, + 0xbc, 0x94, 0x0c, 0x2a, 0xb7, 0xad, 0x00, 0x22, + 0x00, 0x0b, 0x35, 0xb1, 0x72, 0xd6, 0x3c, 0xe9, + 0x85, 0xe8, 0x66, 0xed, 0x10, 0x7a, 0x5c, 0xa3, + 0xe6, 0xd9, 0x4d, 0xf0, 0x52, 0x69, 0x26, 0x14, + 0xb4, 0x36, 0x7e, 0xad, 0x76, 0x9e, 0x58, 0x68, + 0x3e, 0x91 +}; + +const unsigned char attstmt_tpm_es256[3841] = { + 0xa6, 0x63, 0x61, 0x6c, 0x67, 0x39, 0xff, 0xfe, + 0x63, 0x73, 0x69, 0x67, 0x59, 0x01, 0x00, 0x6d, + 0x11, 0x61, 0x1f, 0x45, 0xb9, 0x7f, 0x65, 0x6f, + 0x97, 0x46, 0xfe, 0xbb, 0x8a, 0x98, 0x07, 0xa3, + 0xbc, 0x67, 0x5c, 0xd7, 0x65, 0xa4, 0xf4, 0x6c, + 0x5b, 0x37, 0x75, 0xa4, 0x7f, 0x08, 0x52, 0xeb, + 0x1e, 0x12, 0xe2, 0x78, 0x8c, 0x7d, 0x94, 0xab, + 0x7b, 0xed, 0x05, 0x17, 0x67, 0x7e, 0xaa, 0x02, + 0x89, 0x6d, 0xe8, 0x6d, 0x43, 0x30, 0x99, 0xc6, + 0xf9, 0x59, 0xe5, 0x82, 0x3c, 0x56, 0x4e, 0x77, + 0x11, 0x25, 0xe4, 0x43, 0x6a, 0xae, 0x92, 0x4f, + 0x60, 0x92, 0x50, 0xf9, 0x65, 0x0e, 0x44, 0x38, + 0x3d, 0xf7, 0xaf, 0x66, 0x89, 0xc7, 0xe6, 0xe6, + 0x01, 0x07, 0x9e, 0x90, 0xfd, 0x6d, 0xaa, 0x35, + 0x51, 0x51, 0xbf, 0x54, 0x13, 0x95, 0xc2, 0x17, + 0xfa, 0x32, 0x0f, 0xa7, 0x82, 0x17, 0x58, 0x6c, + 0x3d, 0xea, 0x88, 0xd8, 0x64, 0xc7, 0xf8, 0xc2, + 0xd6, 0x1c, 0xbb, 0xea, 0x1e, 0xb3, 0xd9, 0x4c, + 0xa7, 0xce, 0x18, 0x1e, 0xcb, 0x42, 0x5f, 0xbf, + 0x44, 0xe7, 0xf1, 0x22, 0xe0, 0x5b, 0xeb, 0xff, + 0xb6, 0x1e, 0x6f, 0x60, 0x12, 0x16, 0x63, 0xfe, + 0xab, 0x5e, 0x31, 0x13, 0xdb, 0x72, 0xc6, 0x9a, + 0xf8, 0x8f, 0x19, 0x6b, 0x2e, 0xaf, 0x7d, 0xca, + 0x9f, 0xbc, 0x6b, 0x1a, 0x8b, 0x5e, 0xe3, 0x9e, + 0xaa, 0x8c, 0x79, 0x9c, 0x4e, 0xed, 0xe4, 0xff, + 0x3d, 0x12, 0x79, 0x90, 0x09, 0x61, 0x97, 0x67, + 0xbf, 0x04, 0xac, 0x37, 0xea, 0xa9, 0x1f, 0x9f, + 0x52, 0x64, 0x0b, 0xeb, 0xc3, 0x61, 0xd4, 0x13, + 0xb0, 0x84, 0xf1, 0x3c, 0x74, 0x83, 0xcc, 0xa8, + 0x1c, 0x14, 0xe6, 0x9d, 0xfe, 0xec, 0xee, 0xa1, + 0xd2, 0xc2, 0x0a, 0xa6, 0x36, 0x08, 0xbb, 0x17, + 0xa5, 0x7b, 0x53, 0x34, 0x0e, 0xc9, 0x09, 0xe5, + 0x10, 0xa6, 0x85, 0x01, 0x71, 0x66, 0xff, 0xd0, + 0x6d, 0x4b, 0x93, 0xdb, 0x81, 0x25, 0x01, 0x63, + 0x76, 0x65, 0x72, 0x63, 0x32, 0x2e, 0x30, 0x63, + 0x78, 0x35, 0x63, 0x82, 0x59, 0x05, 0xc4, 0x30, + 0x82, 0x05, 0xc0, 0x30, 0x82, 0x03, 0xa8, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x30, 0xcd, + 0xf2, 0x7e, 0x81, 0xc0, 0x43, 0x85, 0xa2, 0xd7, + 0x29, 0xef, 0xf7, 0x9f, 0xa5, 0x2b, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x41, 0x31, + 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, 0x54, + 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, 0x2d, + 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, 0x41, + 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, 0x41, + 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, 0x30, + 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, 0x41, + 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, 0x30, + 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, + 0x30, 0x32, 0x31, 0x35, 0x30, 0x36, 0x35, 0x33, + 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, + 0x33, 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, + 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xdb, 0xd5, 0x9a, 0xfc, 0x09, + 0xa7, 0xc4, 0xa5, 0x5f, 0xbe, 0x5f, 0xa2, 0xeb, + 0xd6, 0x8e, 0xed, 0xc5, 0x67, 0xa6, 0xa7, 0xd9, + 0xb2, 0x46, 0xc6, 0xe0, 0xae, 0x0c, 0x02, 0x25, + 0x0a, 0xf2, 0xc5, 0x96, 0xdc, 0xb7, 0x0e, 0xb9, + 0x86, 0xd3, 0x51, 0xbb, 0x63, 0xf0, 0x4f, 0x8a, + 0x5e, 0xd7, 0xf7, 0xff, 0xbb, 0x29, 0xbd, 0x58, + 0xcf, 0x75, 0x02, 0x39, 0xcb, 0x80, 0xf1, 0xd4, + 0xb6, 0x75, 0x67, 0x2f, 0x27, 0x4d, 0x0c, 0xcc, + 0x18, 0x59, 0x87, 0xfa, 0x51, 0xd1, 0x80, 0xb5, + 0x1a, 0xac, 0xac, 0x29, 0x51, 0xcf, 0x27, 0xaa, + 0x74, 0xac, 0x3e, 0x59, 0x56, 0x67, 0xe4, 0x42, + 0xe8, 0x30, 0x35, 0xb2, 0xf6, 0x27, 0x91, 0x62, + 0x60, 0x42, 0x42, 0x12, 0xde, 0xfe, 0xdd, 0xee, + 0xe8, 0xa8, 0x82, 0xf9, 0xb1, 0x08, 0xd5, 0x8d, + 0x57, 0x9a, 0x29, 0xb9, 0xb4, 0xe9, 0x19, 0x1e, + 0x33, 0x7d, 0x37, 0xa0, 0xce, 0x2e, 0x53, 0x13, + 0x39, 0xb6, 0x12, 0x61, 0x63, 0xbf, 0xd3, 0x42, + 0xeb, 0x6f, 0xed, 0xc1, 0x8e, 0x26, 0xba, 0x7d, + 0x8b, 0x37, 0x7c, 0xbb, 0x42, 0x1e, 0x56, 0x76, + 0xda, 0xdb, 0x35, 0x6b, 0x80, 0xe1, 0x8e, 0x00, + 0xac, 0xd2, 0xfc, 0x22, 0x96, 0x14, 0x0c, 0xf4, + 0xe4, 0xc5, 0xad, 0x14, 0xb7, 0x4d, 0x46, 0x63, + 0x30, 0x79, 0x3a, 0x7c, 0x33, 0xb5, 0xe5, 0x2e, + 0xbb, 0x5f, 0xca, 0xf2, 0x75, 0xe3, 0x4e, 0x99, + 0x64, 0x1b, 0x26, 0x99, 0x60, 0x1a, 0x79, 0xcc, + 0x30, 0x2c, 0xb3, 0x4c, 0x59, 0xf7, 0x77, 0x59, + 0xd5, 0x90, 0x70, 0x21, 0x79, 0x8c, 0x1f, 0x79, + 0x0a, 0x12, 0x8b, 0x3b, 0x37, 0x2d, 0x97, 0x39, + 0x89, 0x92, 0x0c, 0x44, 0x7c, 0xe9, 0x9f, 0xce, + 0x6d, 0xad, 0xc5, 0xae, 0xea, 0x8e, 0x50, 0x22, + 0x37, 0xe0, 0xd1, 0x9e, 0xd6, 0xe6, 0xa8, 0xcc, + 0x21, 0xfb, 0xff, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0xf3, 0x30, 0x82, 0x01, 0xef, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x6d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x01, 0x01, 0xff, + 0x04, 0x63, 0x30, 0x61, 0x30, 0x5f, 0x06, 0x09, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, + 0x1f, 0x30, 0x52, 0x30, 0x50, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, + 0x44, 0x1e, 0x42, 0x00, 0x54, 0x00, 0x43, 0x00, + 0x50, 0x00, 0x41, 0x00, 0x20, 0x00, 0x20, 0x00, + 0x54, 0x00, 0x72, 0x00, 0x75, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x6d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x49, 0x00, + 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, + 0x69, 0x00, 0x74, 0x00, 0x79, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x09, 0x30, 0x07, + 0x06, 0x05, 0x67, 0x81, 0x05, 0x08, 0x03, 0x30, + 0x59, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, + 0xff, 0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, + 0x49, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, + 0x3a, 0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, + 0x30, 0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, + 0x33, 0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, + 0x42, 0x34, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, + 0x67, 0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, + 0x64, 0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x45, + 0x1a, 0xec, 0xfc, 0x91, 0x70, 0xf8, 0x83, 0x8b, + 0x9c, 0x47, 0x2f, 0x0b, 0x9f, 0x07, 0xf3, 0x2f, + 0x7c, 0xa2, 0x8a, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xa6, + 0xee, 0xe3, 0x28, 0xdd, 0x40, 0x7f, 0x21, 0xd2, + 0x7b, 0x8c, 0x69, 0x2f, 0x8c, 0x08, 0x29, 0xbc, + 0x95, 0xb8, 0x30, 0x81, 0xb2, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x81, 0xa5, 0x30, 0x81, 0xa2, 0x30, 0x81, 0x9f, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x81, 0x92, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x7a, 0x63, 0x73, + 0x70, 0x72, 0x6f, 0x64, 0x65, 0x75, 0x73, 0x61, + 0x69, 0x6b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x2e, 0x62, 0x6c, 0x6f, 0x62, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x2f, + 0x65, 0x75, 0x73, 0x2d, 0x73, 0x74, 0x6d, 0x2d, + 0x6b, 0x65, 0x79, 0x69, 0x64, 0x2d, 0x31, 0x61, + 0x64, 0x62, 0x39, 0x39, 0x34, 0x61, 0x62, 0x35, + 0x38, 0x62, 0x65, 0x35, 0x37, 0x61, 0x30, 0x63, + 0x63, 0x39, 0x62, 0x39, 0x30, 0x30, 0x65, 0x37, + 0x38, 0x35, 0x31, 0x65, 0x31, 0x61, 0x34, 0x33, + 0x63, 0x30, 0x38, 0x36, 0x36, 0x30, 0x2f, 0x62, + 0x36, 0x63, 0x30, 0x64, 0x39, 0x38, 0x64, 0x2d, + 0x35, 0x37, 0x38, 0x61, 0x2d, 0x34, 0x62, 0x66, + 0x62, 0x2d, 0x61, 0x32, 0x64, 0x33, 0x2d, 0x65, + 0x64, 0x66, 0x65, 0x35, 0x66, 0x38, 0x32, 0x30, + 0x36, 0x30, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x02, 0x01, 0x00, 0x2a, 0x08, 0x30, 0x1f, 0xfd, + 0x8f, 0x80, 0x9b, 0x4b, 0x37, 0x82, 0x61, 0x86, + 0x36, 0x57, 0x90, 0xb5, 0x1d, 0x1f, 0xa3, 0xae, + 0x68, 0xac, 0xa7, 0x96, 0x6a, 0x25, 0x5e, 0xc5, + 0x82, 0x7c, 0x36, 0x64, 0x58, 0x11, 0xcb, 0xa5, + 0xee, 0xbf, 0xc4, 0xdb, 0xa0, 0xc7, 0x82, 0x3b, + 0xa3, 0x85, 0x9b, 0xc4, 0xee, 0x07, 0x36, 0xd7, + 0xc7, 0xb6, 0x23, 0xed, 0xc2, 0x73, 0xab, 0xbe, + 0xbe, 0xee, 0x63, 0x17, 0xf9, 0xd7, 0x7a, 0x23, + 0x7b, 0xf8, 0x09, 0x7a, 0xaa, 0x7f, 0x67, 0xc3, + 0x04, 0x84, 0x71, 0x9b, 0x06, 0x9c, 0x07, 0x42, + 0x4b, 0x65, 0x41, 0x56, 0x58, 0x14, 0x92, 0xb0, + 0xb9, 0xaf, 0xa1, 0x39, 0xd4, 0x08, 0x2d, 0x71, + 0xd5, 0x6c, 0x56, 0xb9, 0x2b, 0x1e, 0xf3, 0x93, + 0xa5, 0xe9, 0xb2, 0x9b, 0x4d, 0x05, 0x2b, 0xbc, + 0xd2, 0x20, 0x57, 0x3b, 0xa4, 0x01, 0x68, 0x8c, + 0x23, 0x20, 0x7d, 0xbb, 0x71, 0xe4, 0x2a, 0x24, + 0xba, 0x75, 0x0c, 0x89, 0x54, 0x22, 0xeb, 0x0e, + 0xb2, 0xf4, 0xc2, 0x1f, 0x02, 0xb7, 0xe3, 0x06, + 0x41, 0x15, 0x6b, 0xf3, 0xc8, 0x2d, 0x5b, 0xc2, + 0x21, 0x82, 0x3e, 0xe8, 0x95, 0x40, 0x39, 0x9e, + 0x91, 0x68, 0x33, 0x0c, 0x3d, 0x45, 0xef, 0x99, + 0x79, 0xe6, 0x32, 0xc9, 0x00, 0x84, 0x36, 0xfb, + 0x0a, 0x8d, 0x41, 0x1c, 0x32, 0x64, 0x06, 0x9e, + 0x0f, 0xb5, 0x04, 0xcc, 0x08, 0xb1, 0xb6, 0x2b, + 0xcf, 0x36, 0x0f, 0x73, 0x14, 0x8e, 0x25, 0x44, + 0xb3, 0x0c, 0x34, 0x14, 0x96, 0x0c, 0x8a, 0x65, + 0xa1, 0xde, 0x8e, 0xc8, 0x9d, 0xbe, 0x66, 0xdf, + 0x06, 0x91, 0xca, 0x15, 0x0f, 0x92, 0xd5, 0x2a, + 0x0b, 0xdc, 0x4c, 0x6a, 0xf3, 0x16, 0x4a, 0x3e, + 0xb9, 0x76, 0xbc, 0xfe, 0x62, 0xd4, 0xa8, 0xcd, + 0x94, 0x78, 0x0d, 0xdd, 0x94, 0xfd, 0x5e, 0x63, + 0x57, 0x27, 0x05, 0x9c, 0xd0, 0x80, 0x91, 0x91, + 0x79, 0xe8, 0x5e, 0x18, 0x64, 0x22, 0xe4, 0x2c, + 0x13, 0x65, 0xa4, 0x51, 0x5a, 0x1e, 0x3b, 0x71, + 0x2e, 0x70, 0x9f, 0xc4, 0xa5, 0x20, 0xcd, 0xef, + 0xd8, 0x3f, 0xa4, 0xf5, 0x89, 0x8a, 0xa5, 0x4f, + 0x76, 0x2d, 0x49, 0x56, 0x00, 0x8d, 0xde, 0x40, + 0xba, 0x24, 0x46, 0x51, 0x38, 0xad, 0xdb, 0xc4, + 0x04, 0xf4, 0x6e, 0xc0, 0x29, 0x48, 0x07, 0x6a, + 0x1b, 0x26, 0x32, 0x0a, 0xfb, 0xea, 0x71, 0x2a, + 0x11, 0xfc, 0x98, 0x7c, 0x44, 0x87, 0xbc, 0x06, + 0x3a, 0x4d, 0xbd, 0x91, 0x63, 0x4f, 0x26, 0x48, + 0x54, 0x47, 0x1b, 0xbd, 0xf0, 0xf1, 0x56, 0x05, + 0xc5, 0x0f, 0x8f, 0x20, 0xa5, 0xcc, 0xfb, 0x76, + 0xb0, 0xbd, 0x83, 0xde, 0x7f, 0x39, 0x4f, 0xcf, + 0x61, 0x74, 0x52, 0xa7, 0x1d, 0xf6, 0xb5, 0x5e, + 0x4a, 0x82, 0x20, 0xc1, 0x94, 0xaa, 0x2c, 0x33, + 0xd6, 0x0a, 0xf9, 0x8f, 0x92, 0xc6, 0x29, 0x80, + 0xf5, 0xa2, 0xb1, 0xff, 0xb6, 0x2b, 0xaa, 0x04, + 0x00, 0x72, 0xb4, 0x12, 0xbb, 0xb1, 0xf1, 0x3c, + 0x88, 0xa3, 0xab, 0x49, 0x17, 0x90, 0x80, 0x59, + 0xa2, 0x96, 0x41, 0x69, 0x74, 0x33, 0x8a, 0x28, + 0x33, 0x7e, 0xb3, 0x19, 0x92, 0x28, 0xc1, 0xf0, + 0xd1, 0x82, 0xd5, 0x42, 0xff, 0xe7, 0xa5, 0x3f, + 0x1e, 0xb6, 0x4a, 0x23, 0xcc, 0x6a, 0x7f, 0x15, + 0x15, 0x52, 0x25, 0xb1, 0xca, 0x21, 0x95, 0x11, + 0x53, 0x3e, 0x1f, 0x50, 0x33, 0x12, 0x7a, 0x62, + 0xce, 0xcc, 0x71, 0xc2, 0x5f, 0x34, 0x47, 0xc6, + 0x7c, 0x71, 0xfa, 0xa0, 0x54, 0x00, 0xb2, 0xdf, + 0xc5, 0x54, 0xac, 0x6c, 0x53, 0xef, 0x64, 0x6b, + 0x08, 0x82, 0xd8, 0x16, 0x1e, 0xca, 0x40, 0xf3, + 0x1f, 0xdf, 0x56, 0x63, 0x10, 0xbc, 0xd7, 0xa0, + 0xeb, 0xee, 0xd1, 0x95, 0xe5, 0xef, 0xf1, 0x6a, + 0x83, 0x2d, 0x5a, 0x59, 0x06, 0xef, 0x30, 0x82, + 0x06, 0xeb, 0x30, 0x82, 0x04, 0xd3, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x13, 0x33, 0x00, 0x00, + 0x05, 0x23, 0xbf, 0xe8, 0xa1, 0x1a, 0x2a, 0x68, + 0xbd, 0x09, 0x00, 0x00, 0x00, 0x00, 0x05, 0x23, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x8c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x52, + 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, + 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x36, + 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x2d, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, + 0x66, 0x74, 0x20, 0x54, 0x50, 0x4d, 0x20, 0x52, + 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x30, 0x1e, + 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x30, 0x33, + 0x31, 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x17, + 0x0d, 0x32, 0x37, 0x30, 0x36, 0x30, 0x33, 0x31, + 0x39, 0x34, 0x30, 0x31, 0x36, 0x5a, 0x30, 0x41, + 0x31, 0x3f, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x36, 0x45, 0x55, 0x53, 0x2d, 0x53, + 0x54, 0x4d, 0x2d, 0x4b, 0x45, 0x59, 0x49, 0x44, + 0x2d, 0x31, 0x41, 0x44, 0x42, 0x39, 0x39, 0x34, + 0x41, 0x42, 0x35, 0x38, 0x42, 0x45, 0x35, 0x37, + 0x41, 0x30, 0x43, 0x43, 0x39, 0x42, 0x39, 0x30, + 0x30, 0x45, 0x37, 0x38, 0x35, 0x31, 0x45, 0x31, + 0x41, 0x34, 0x33, 0x43, 0x30, 0x38, 0x36, 0x36, + 0x30, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, + 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xdb, 0x03, 0x34, 0x82, 0xfa, 0x81, + 0x1c, 0x84, 0x0b, 0xa0, 0x0e, 0x60, 0xd8, 0x9d, + 0x84, 0xf4, 0x81, 0xc4, 0xe9, 0xff, 0xcf, 0xe9, + 0xa3, 0x57, 0x53, 0x60, 0xa8, 0x19, 0xce, 0xbe, + 0xe1, 0x97, 0xee, 0x5d, 0x8c, 0x9f, 0xe4, 0xbd, + 0xef, 0xbd, 0x94, 0x14, 0xe4, 0x74, 0x41, 0x02, + 0xe9, 0x03, 0x19, 0x9f, 0xdd, 0x48, 0x2d, 0xbd, + 0xca, 0x26, 0x47, 0x2c, 0x01, 0x31, 0x5f, 0x34, + 0xef, 0x59, 0x35, 0x48, 0x36, 0x3d, 0x1e, 0xdf, + 0xd8, 0x13, 0xf0, 0xd0, 0x67, 0xc1, 0xb0, 0x47, + 0x67, 0xa2, 0xd6, 0x62, 0xc8, 0xe1, 0x00, 0x36, + 0x8b, 0x45, 0xf6, 0x3b, 0x96, 0x60, 0xa0, 0x45, + 0x26, 0xcb, 0xc7, 0x0b, 0x5b, 0x97, 0xd1, 0xaf, + 0x54, 0x25, 0x7a, 0x67, 0xe4, 0x2a, 0xd8, 0x9d, + 0x53, 0x05, 0xbd, 0x12, 0xac, 0xa2, 0x8e, 0x95, + 0xb4, 0x2a, 0xca, 0x89, 0x93, 0x64, 0x97, 0x25, + 0xdc, 0x1f, 0xa9, 0xe0, 0x55, 0x07, 0x38, 0x1d, + 0xee, 0x02, 0x90, 0x22, 0xf5, 0xad, 0x4e, 0x5c, + 0xf8, 0xc5, 0x1f, 0x9e, 0x84, 0x7e, 0x13, 0x47, + 0x52, 0xa2, 0x36, 0xf9, 0xf6, 0xbf, 0x76, 0x9e, + 0x0f, 0xdd, 0x14, 0x99, 0xb9, 0xd8, 0x5a, 0x42, + 0x3d, 0xd8, 0xbf, 0xdd, 0xb4, 0x9b, 0xbf, 0x6a, + 0x9f, 0x89, 0x13, 0x75, 0xaf, 0x96, 0xd2, 0x72, + 0xdf, 0xb3, 0x80, 0x6f, 0x84, 0x1a, 0x9d, 0x06, + 0x55, 0x09, 0x29, 0xea, 0xa7, 0x05, 0x31, 0xec, + 0x47, 0x3a, 0xcf, 0x3f, 0x9c, 0x2c, 0xbd, 0xd0, + 0x7d, 0xe4, 0x75, 0x5b, 0x33, 0xbe, 0x12, 0x86, + 0x09, 0xcf, 0x66, 0x9a, 0xeb, 0xf8, 0xf8, 0x72, + 0x91, 0x88, 0x4a, 0x5e, 0x89, 0x62, 0x6a, 0x94, + 0xdc, 0x48, 0x37, 0x13, 0xd8, 0x91, 0x02, 0xe3, + 0x42, 0x41, 0x7c, 0x2f, 0xe3, 0xb6, 0x0f, 0xb4, + 0x96, 0x06, 0x80, 0xca, 0x28, 0x01, 0x6f, 0x4b, + 0xcd, 0x28, 0xd4, 0x2c, 0x94, 0x7e, 0x40, 0x7e, + 0xdf, 0x01, 0xe5, 0xf2, 0x33, 0xd4, 0xda, 0xf4, + 0x1a, 0x17, 0xf7, 0x5d, 0xcb, 0x66, 0x2c, 0x2a, + 0xeb, 0xe1, 0xb1, 0x4a, 0xc3, 0x85, 0x63, 0xb2, + 0xac, 0xd0, 0x3f, 0x1a, 0x8d, 0xa5, 0x0c, 0xee, + 0x4f, 0xde, 0x74, 0x9c, 0xe0, 0x5a, 0x10, 0xc7, + 0xb8, 0xe4, 0xec, 0xe7, 0x73, 0xa6, 0x41, 0x42, + 0x37, 0xe1, 0xdf, 0xb9, 0xc7, 0xb5, 0x14, 0xa8, + 0x80, 0x95, 0xa0, 0x12, 0x67, 0x99, 0xf5, 0xba, + 0x25, 0x0a, 0x74, 0x86, 0x71, 0x9c, 0x7f, 0x59, + 0x97, 0xd2, 0x3f, 0x10, 0xfe, 0x6a, 0xb9, 0xe4, + 0x47, 0x36, 0xfb, 0x0f, 0x50, 0xee, 0xfc, 0x87, + 0x99, 0x7e, 0x36, 0x64, 0x1b, 0xc7, 0x13, 0xb3, + 0x33, 0x18, 0x71, 0xa4, 0xc3, 0xb0, 0xfc, 0x45, + 0x37, 0x11, 0x40, 0xb3, 0xde, 0x2c, 0x9f, 0x0a, + 0xcd, 0xaf, 0x5e, 0xfb, 0xd5, 0x9c, 0xea, 0xd7, + 0x24, 0x19, 0x3a, 0x92, 0x80, 0xa5, 0x63, 0xc5, + 0x3e, 0xdd, 0x51, 0xd0, 0x9f, 0xb8, 0x5e, 0xd5, + 0xf1, 0xfe, 0xa5, 0x93, 0xfb, 0x7f, 0xd9, 0xb8, + 0xb7, 0x0e, 0x0d, 0x12, 0x71, 0xf0, 0x52, 0x9d, + 0xe9, 0xd0, 0xd2, 0x8b, 0x38, 0x8b, 0x85, 0x83, + 0x98, 0x24, 0x88, 0xe8, 0x42, 0x30, 0x83, 0x12, + 0xef, 0x09, 0x96, 0x2f, 0x21, 0x81, 0x05, 0x30, + 0x0c, 0xbb, 0xba, 0x21, 0x39, 0x16, 0x12, 0xe8, + 0x4b, 0x7b, 0x7a, 0x66, 0xb8, 0x22, 0x2c, 0x71, + 0xaf, 0x59, 0xa1, 0xfc, 0x61, 0xf1, 0xb4, 0x5e, + 0xfc, 0x43, 0x19, 0x45, 0x6e, 0xa3, 0x45, 0xe4, + 0xcb, 0x66, 0x5f, 0xe0, 0x57, 0xf6, 0x0a, 0x30, + 0xa3, 0xd6, 0x51, 0x24, 0xc9, 0x07, 0x55, 0x82, + 0x4a, 0x66, 0x0e, 0x9d, 0xb2, 0x2f, 0x84, 0x56, + 0x6c, 0x3e, 0x71, 0xef, 0x9b, 0x35, 0x4d, 0x72, + 0xdc, 0x46, 0x2a, 0xe3, 0x7b, 0x13, 0x20, 0xbf, + 0xab, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x8e, 0x30, 0x82, 0x01, 0x8a, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, + 0x1b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x14, + 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x15, 0x24, 0x06, 0x05, 0x67, + 0x81, 0x05, 0x08, 0x03, 0x30, 0x16, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x0f, 0x30, 0x0d, 0x30, + 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0x37, 0x15, 0x1f, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x45, 0x1a, 0xec, 0xfc, 0x91, + 0x70, 0xf8, 0x83, 0x8b, 0x9c, 0x47, 0x2f, 0x0b, + 0x9f, 0x07, 0xf3, 0x2f, 0x7c, 0xa2, 0x8a, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x7a, 0x8c, 0x0a, 0xce, + 0x2f, 0x48, 0x62, 0x17, 0xe2, 0x94, 0xd1, 0xae, + 0x55, 0xc1, 0x52, 0xec, 0x71, 0x74, 0xa4, 0x56, + 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x69, 0x30, 0x67, 0x30, 0x65, 0xa0, 0x63, 0xa0, + 0x61, 0x86, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x6f, + 0x70, 0x73, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x25, 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, + 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, + 0x32, 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x7d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x71, + 0x30, 0x6f, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x61, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x70, 0x6b, 0x69, 0x6f, 0x70, 0x73, 0x2f, + 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x4d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x25, + 0x32, 0x30, 0x54, 0x50, 0x4d, 0x25, 0x32, 0x30, + 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x25, 0x32, 0x30, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x25, 0x32, + 0x30, 0x32, 0x30, 0x31, 0x34, 0x2e, 0x63, 0x72, + 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x01, 0x00, 0x48, 0x24, 0x32, + 0xe8, 0xd6, 0x38, 0xda, 0x65, 0xec, 0x1b, 0x18, + 0x8e, 0x37, 0x07, 0xd5, 0x18, 0x5a, 0xc8, 0xb9, + 0xbb, 0x24, 0x8a, 0x4d, 0xa1, 0x3c, 0x9e, 0x46, + 0x76, 0xcf, 0xa5, 0xdf, 0xd7, 0x61, 0xba, 0x05, + 0x89, 0x3c, 0x13, 0xc2, 0x1f, 0x71, 0xe3, 0xec, + 0x5d, 0x54, 0x9e, 0xd9, 0x01, 0x5a, 0x10, 0x3b, + 0x17, 0x75, 0xde, 0xa1, 0x45, 0xbf, 0x1d, 0x1b, + 0x41, 0x21, 0x42, 0x68, 0x22, 0x6b, 0xbb, 0xcb, + 0x11, 0x04, 0xd2, 0xae, 0x86, 0xcf, 0x73, 0x5a, + 0xf2, 0x80, 0x18, 0x00, 0xf0, 0xd6, 0x6c, 0x5a, + 0x1e, 0xb3, 0x4d, 0x30, 0x02, 0x4a, 0x6a, 0x03, + 0x36, 0x42, 0xde, 0xb2, 0x52, 0x55, 0xff, 0x71, + 0xeb, 0x7b, 0x8b, 0x55, 0x6c, 0xdf, 0x05, 0x35, + 0x47, 0x70, 0x53, 0xfb, 0x6c, 0xba, 0x06, 0xb2, + 0x61, 0x86, 0xdc, 0x2a, 0x64, 0x81, 0x24, 0x79, + 0x46, 0x73, 0x04, 0x55, 0x59, 0xed, 0xd6, 0x06, + 0x61, 0x15, 0xf9, 0x8d, 0x78, 0x39, 0x7b, 0x84, + 0x7a, 0x40, 0x45, 0x13, 0x1a, 0x91, 0x71, 0x8f, + 0xd1, 0x4f, 0x78, 0x10, 0x68, 0x9b, 0x15, 0x79, + 0x3f, 0x79, 0x2d, 0x9b, 0xc7, 0x5d, 0xa3, 0xcf, + 0xa9, 0x14, 0xb0, 0xc4, 0xdb, 0xa9, 0x45, 0x6a, + 0x6e, 0x60, 0x45, 0x0b, 0x14, 0x25, 0xc7, 0x74, + 0xd0, 0x36, 0xaf, 0xc5, 0xbd, 0x4f, 0x7b, 0xc0, + 0x04, 0x43, 0x85, 0xbb, 0x06, 0x36, 0x77, 0x26, + 0x02, 0x23, 0x0b, 0xf8, 0x57, 0x8f, 0x1f, 0x27, + 0x30, 0x95, 0xff, 0x83, 0x23, 0x2b, 0x49, 0x33, + 0x43, 0x62, 0x87, 0x5d, 0x27, 0x12, 0x1a, 0x68, + 0x7b, 0xba, 0x2d, 0xf6, 0xed, 0x2c, 0x26, 0xb5, + 0xbb, 0xe2, 0x6f, 0xc2, 0x61, 0x17, 0xfc, 0x72, + 0x14, 0x57, 0x2c, 0x2c, 0x5a, 0x92, 0x13, 0x41, + 0xc4, 0x7e, 0xb5, 0x64, 0x5b, 0x86, 0x57, 0x13, + 0x14, 0xff, 0xf5, 0x04, 0xb9, 0x3d, 0x2d, 0xc3, + 0xe9, 0x75, 0x1f, 0x68, 0x0b, 0xb5, 0x76, 0xe1, + 0x7d, 0xe3, 0xb0, 0x14, 0xa8, 0x45, 0x05, 0x98, + 0x81, 0x32, 0xc1, 0xf5, 0x49, 0x4d, 0x58, 0xa4, + 0xee, 0xd8, 0x84, 0xba, 0x65, 0x07, 0x8d, 0xf7, + 0x9a, 0xff, 0x7d, 0xa5, 0xbc, 0x9a, 0xed, 0x4a, + 0x5d, 0xa4, 0x97, 0x4b, 0x4d, 0x31, 0x90, 0xb5, + 0x7d, 0x28, 0x77, 0x25, 0x88, 0x1c, 0xbf, 0x78, + 0x22, 0xb2, 0xb5, 0x5c, 0x9a, 0xc9, 0x63, 0x17, + 0x96, 0xe9, 0xc2, 0x52, 0x30, 0xb8, 0x9b, 0x37, + 0x69, 0x1a, 0x6a, 0x66, 0x76, 0x18, 0xac, 0xc0, + 0x48, 0xee, 0x46, 0x5b, 0xbe, 0x6a, 0xd5, 0x72, + 0x07, 0xdc, 0x7d, 0x05, 0xbe, 0x76, 0x7d, 0xa5, + 0x5e, 0x53, 0xb5, 0x47, 0x80, 0x58, 0xf0, 0xaf, + 0x6f, 0x4e, 0xc0, 0xf1, 0x1e, 0x37, 0x64, 0x15, + 0x42, 0x96, 0x18, 0x3a, 0x89, 0xc8, 0x14, 0x48, + 0x89, 0x5c, 0x12, 0x88, 0x98, 0x0b, 0x7b, 0x4e, + 0xce, 0x1c, 0xda, 0xd5, 0xa4, 0xd3, 0x32, 0x32, + 0x74, 0x5b, 0xcc, 0xfd, 0x2b, 0x02, 0xfb, 0xae, + 0xd0, 0x5a, 0x4c, 0xc9, 0xc1, 0x35, 0x19, 0x90, + 0x5f, 0xca, 0x14, 0xeb, 0x4c, 0x17, 0xd7, 0xe3, + 0xe2, 0x5d, 0xb4, 0x49, 0xaa, 0xf0, 0x50, 0x87, + 0xc3, 0x20, 0x00, 0xda, 0xe9, 0x04, 0x80, 0x64, + 0xac, 0x9f, 0xcd, 0x26, 0x41, 0x48, 0xe8, 0x4c, + 0x46, 0xcc, 0x5b, 0xd7, 0xca, 0x4c, 0x1b, 0x43, + 0x43, 0x1e, 0xbd, 0x94, 0xe7, 0xa7, 0xa6, 0x86, + 0xe5, 0xd1, 0x78, 0x29, 0xa2, 0x40, 0xc5, 0xc5, + 0x47, 0xb6, 0x6d, 0x53, 0xde, 0xac, 0x97, 0x74, + 0x24, 0x57, 0xcc, 0x05, 0x93, 0xfd, 0x52, 0x35, + 0x29, 0xd5, 0xe0, 0xfa, 0x23, 0x0d, 0xd7, 0xaa, + 0x8b, 0x07, 0x4b, 0xf6, 0x64, 0xc7, 0xad, 0x3c, + 0xa1, 0xb5, 0xc5, 0x70, 0xaf, 0x46, 0xfe, 0x9a, + 0x82, 0x4d, 0x75, 0xb8, 0x6d, 0x67, 0x70, 0x75, + 0x62, 0x41, 0x72, 0x65, 0x61, 0x58, 0x76, 0x00, + 0x23, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x72, 0x00, + 0x20, 0x9d, 0xff, 0xcb, 0xf3, 0x6c, 0x38, 0x3a, + 0xe6, 0x99, 0xfb, 0x98, 0x68, 0xdc, 0x6d, 0xcb, + 0x89, 0xd7, 0x15, 0x38, 0x84, 0xbe, 0x28, 0x03, + 0x92, 0x2c, 0x12, 0x41, 0x58, 0xbf, 0xad, 0x22, + 0xae, 0x00, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, + 0x10, 0x00, 0x20, 0xfb, 0xd6, 0xba, 0x74, 0xe6, + 0x6e, 0x5c, 0x87, 0xef, 0x89, 0xa2, 0xe8, 0x3d, + 0x0b, 0xe9, 0x69, 0x2c, 0x07, 0x07, 0x7a, 0x8a, + 0x1e, 0xce, 0x12, 0xea, 0x3b, 0xb3, 0xf1, 0xf3, + 0xd9, 0xc3, 0xe6, 0x00, 0x20, 0x3c, 0x68, 0x51, + 0x94, 0x54, 0x8d, 0xeb, 0x9f, 0xb2, 0x2c, 0x66, + 0x75, 0xb6, 0xb7, 0x55, 0x22, 0x0d, 0x87, 0x59, + 0xc4, 0x39, 0x91, 0x62, 0x17, 0xc2, 0xc3, 0x53, + 0xa5, 0x26, 0x97, 0x4f, 0x2d, 0x68, 0x63, 0x65, + 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x58, 0xa1, + 0xff, 0x54, 0x43, 0x47, 0x80, 0x17, 0x00, 0x22, + 0x00, 0x0b, 0x73, 0xbe, 0xb7, 0x40, 0x82, 0xc0, + 0x49, 0x9a, 0xf7, 0xf2, 0xd0, 0x79, 0x6c, 0x88, + 0xf3, 0x56, 0x7b, 0x7a, 0x7d, 0xcd, 0x70, 0xd1, + 0xbc, 0x41, 0x88, 0x48, 0x51, 0x03, 0xf3, 0x58, + 0x3e, 0xb8, 0x00, 0x14, 0x9f, 0x57, 0x39, 0x67, + 0xa8, 0x7b, 0xd8, 0xf6, 0x9e, 0x75, 0xc9, 0x85, + 0xab, 0xe3, 0x55, 0xc7, 0x9c, 0xf6, 0xd8, 0x4f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x12, + 0xfd, 0xc6, 0x05, 0xc6, 0x2b, 0xf5, 0xe9, 0x88, + 0x01, 0x1f, 0x70, 0x8d, 0x98, 0x2a, 0x04, 0x21, + 0x30, 0x00, 0x22, 0x00, 0x0b, 0xf4, 0xfd, 0x9a, + 0x33, 0x55, 0x21, 0x08, 0x27, 0x48, 0x55, 0x01, + 0x56, 0xf9, 0x0b, 0x4e, 0x47, 0x55, 0x08, 0x2e, + 0x3c, 0x91, 0x3d, 0x6e, 0x53, 0xcf, 0x08, 0xe9, + 0x0a, 0x4b, 0xc9, 0x7e, 0x99, 0x00, 0x22, 0x00, + 0x0b, 0x51, 0xd3, 0x38, 0xfe, 0xaa, 0xda, 0xc6, + 0x68, 0x84, 0x39, 0xe7, 0xb1, 0x03, 0x22, 0x5e, + 0xc4, 0xd3, 0xf1, 0x0c, 0xec, 0x35, 0x5d, 0x50, + 0xa3, 0x9d, 0xab, 0xa1, 0x7b, 0x61, 0x51, 0x8f, + 0x4e +}; + +/* + * Security Key By Yubico + * 5.1.X + * f8a011f3-8c0a-4d15-8006-17111f9edc7d + */ +const unsigned char aaguid[16] = { + 0xf8, 0xa0, 0x11, 0xf3, 0x8c, 0x0a, 0x4d, 0x15, + 0x80, 0x06, 0x17, 0x11, 0x1f, 0x9e, 0xdc, 0x7d, +}; + +/* + * Windows Hello by Microsoft + */ +const unsigned char aaguid_tpm[16] = { + 0x08, 0x98, 0x70, 0x58, 0xca, 0xdc, 0x4b, 0x81, + 0xb6, 0xe1, 0x30, 0xde, 0x50, 0xdc, 0xbe, 0x96, +}; + +const char rp_id[] = "localhost"; +const char rp_name[] = "sweet home localhost"; + +static void * +dummy_open(const char *path) +{ + (void)path; + + return (&fake_dev_handle); +} + +static void +dummy_close(void *handle) +{ + assert(handle == &fake_dev_handle); +} + +static int +dummy_read(void *handle, unsigned char *buf, size_t len, int ms) +{ + (void)handle; + (void)buf; + (void)len; + (void)ms; + + abort(); + /* NOTREACHED */ +} + +static int +dummy_write(void *handle, const unsigned char *buf, size_t len) +{ + (void)handle; + (void)buf; + (void)len; + + abort(); + /* NOTREACHED */ +} + +static fido_cred_t * +alloc_cred(void) +{ + fido_cred_t *c; + + c = fido_cred_new(); + assert(c != NULL); + + return (c); +} + +static void +free_cred(fido_cred_t *c) +{ + fido_cred_free(&c); + assert(c == NULL); +} + +static fido_dev_t * +alloc_dev(void) +{ + fido_dev_t *d; + + d = fido_dev_new(); + assert(d != NULL); + + return (d); +} + +static void +free_dev(fido_dev_t *d) +{ + fido_dev_free(&d); + assert(d == NULL); +} + +static void +empty_cred(void) +{ + fido_cred_t *c; + fido_dev_t *d; + fido_dev_io_t io_f; + + c = alloc_cred(); + assert(fido_cred_authdata_len(c) == 0); + assert(fido_cred_authdata_ptr(c) == NULL); + assert(fido_cred_authdata_raw_len(c) == 0); + assert(fido_cred_authdata_raw_ptr(c) == NULL); + assert(fido_cred_clientdata_hash_len(c) == 0); + assert(fido_cred_clientdata_hash_ptr(c) == NULL); + assert(fido_cred_flags(c) == 0); + assert(fido_cred_fmt(c) == NULL); + assert(fido_cred_id_len(c) == 0); + assert(fido_cred_id_ptr(c) == NULL); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == 0); + assert(fido_cred_pubkey_ptr(c) == NULL); + assert(fido_cred_rp_id(c) == NULL); + assert(fido_cred_rp_name(c) == NULL); + assert(fido_cred_sig_len(c) == 0); + assert(fido_cred_sig_ptr(c) == NULL); + assert(fido_cred_x5c_len(c) == 0); + assert(fido_cred_x5c_ptr(c) == NULL); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + + memset(&io_f, 0, sizeof(io_f)); + + io_f.open = dummy_open; + io_f.close = dummy_close; + io_f.read = dummy_read; + io_f.write = dummy_write; + + d = alloc_dev(); + + fido_dev_force_u2f(d); + assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); + assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_UNSUPPORTED_OPTION); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + + fido_dev_force_fido2(d); + assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK); + assert(fido_dev_make_cred(d, c, NULL) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_make_cred(d, c, "") == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + + free_cred(c); + free_dev(d); +} + +static void +valid_cred(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_OK); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_cdh(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_rp_id(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_rp_name(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, NULL) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_OK); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_authdata(void) +{ + fido_cred_t *c; + unsigned char *unset; + + unset = calloc(1, sizeof(aaguid)); + assert(unset != NULL); + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == 0); + assert(fido_cred_pubkey_ptr(c) == NULL); + assert(fido_cred_id_len(c) == 0); + assert(fido_cred_id_ptr(c) == NULL); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); + free_cred(c); + free(unset); +} + +static void +no_x509(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_sig(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +no_fmt(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +wrong_options(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +junk_cdh(void) +{ + fido_cred_t *c; + unsigned char *junk; + + junk = malloc(sizeof(cdh)); + assert(junk != NULL); + memcpy(junk, cdh, sizeof(cdh)); + junk[0] = (unsigned char)~junk[0]; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, junk, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); + free(junk); +} + +static void +junk_fmt(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "junk") == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + free_cred(c); +} + +static void +junk_rp_id(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, "potato", rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +junk_rp_name(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, "potato") == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_OK); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +junk_authdata(void) +{ + fido_cred_t *c; + unsigned char *junk; + unsigned char *unset; + + junk = malloc(sizeof(authdata)); + assert(junk != NULL); + memcpy(junk, authdata, sizeof(authdata)); + junk[0] = (unsigned char)~junk[0]; + + unset = calloc(1, sizeof(aaguid)); + assert(unset != NULL); + + c = alloc_cred(); + assert(fido_cred_set_authdata(c, junk, + sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_authdata_len(c) == 0); + assert(fido_cred_authdata_ptr(c) == NULL); + assert(fido_cred_authdata_raw_len(c) == 0); + assert(fido_cred_authdata_raw_ptr(c) == NULL); + assert(fido_cred_flags(c) == 0); + assert(fido_cred_fmt(c) == NULL); + assert(fido_cred_id_len(c) == 0); + assert(fido_cred_id_ptr(c) == NULL); + assert(fido_cred_pubkey_len(c) == 0); + assert(fido_cred_pubkey_ptr(c) == NULL); + assert(fido_cred_rp_id(c) == NULL); + assert(fido_cred_rp_name(c) == NULL); + assert(fido_cred_sig_len(c) == 0); + assert(fido_cred_sig_ptr(c) == NULL); + assert(fido_cred_x5c_len(c) == 0); + assert(fido_cred_x5c_ptr(c) == NULL); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + free_cred(c); + free(junk); + free(unset); +} + +static void +junk_sig(void) +{ + fido_cred_t *c; + unsigned char *junk; + + junk = malloc(sizeof(sig)); + assert(junk != NULL); + memcpy(junk, sig, sizeof(sig)); + junk[0] = (unsigned char)~junk[0]; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, junk, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); + free(junk); +} + +static void +junk_x509(void) +{ + fido_cred_t *c; + unsigned char *junk; + + junk = malloc(sizeof(x509)); + assert(junk != NULL); + memcpy(junk, x509, sizeof(x509)); + junk[0] = (unsigned char)~junk[0]; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, junk, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_SIG); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); + free(junk); +} + +/* github issue #6 */ +static void +invalid_type(void) +{ + fido_cred_t *c; + unsigned char *unset; + + unset = calloc(1, sizeof(aaguid)); + assert(unset != NULL); + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_pubkey_len(c) == 0); + assert(fido_cred_pubkey_ptr(c) == NULL); + assert(fido_cred_id_len(c) == 0); + assert(fido_cred_id_ptr(c) == NULL); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), unset, sizeof(aaguid)) == 0); + free_cred(c); + free(unset); +} + +/* cbor_serialize_alloc misuse */ +static void +bad_cbor_serialize(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_authdata_len(c) == sizeof(authdata)); + free_cred(c); +} + +static void +duplicate_keys(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata_dupkeys, + sizeof(authdata_dupkeys)) == FIDO_ERR_INVALID_ARGUMENT); + free_cred(c); +} + +static void +unsorted_keys(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata_unsorted_keys, + sizeof(authdata_unsorted_keys)) == FIDO_ERR_INVALID_ARGUMENT); + free_cred(c); +} + +static void +wrong_credprot(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_x509(c, x509, sizeof(x509)) == FIDO_OK); + assert(fido_cred_set_sig(c, sig, sizeof(sig)) == FIDO_OK); + assert(fido_cred_set_fmt(c, "packed") == FIDO_OK); + assert(fido_cred_set_prot(c, FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_PARAM); + free_cred(c); +} + +static void +raw_authdata(void) +{ + fido_cred_t *c; + cbor_item_t *item; + struct cbor_load_result cbor_result; + const unsigned char *ptr; + unsigned char *cbor; + size_t len; + size_t cbor_len; + size_t alloclen; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert((ptr = fido_cred_authdata_ptr(c)) != NULL); + assert((len = fido_cred_authdata_len(c)) != 0); + assert((item = cbor_load(ptr, len, &cbor_result)) != NULL); + assert(cbor_result.read == len); + assert(cbor_isa_bytestring(item)); + assert((ptr = fido_cred_authdata_raw_ptr(c)) != NULL); + assert((len = fido_cred_authdata_raw_len(c)) != 0); + assert(cbor_bytestring_length(item) == len); + assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0); + assert((len = fido_cred_authdata_len(c)) != 0); + assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len); + assert((ptr = cbor_bytestring_handle(item)) != NULL); + assert((len = cbor_bytestring_length(item)) != 0); + assert(fido_cred_set_authdata_raw(c, ptr, len) == FIDO_OK); + assert((ptr = fido_cred_authdata_ptr(c)) != NULL); + assert((len = fido_cred_authdata_len(c)) != 0); + assert(len == cbor_len); + assert(memcmp(cbor, ptr, len) == 0); + assert(cbor_len == sizeof(authdata)); + assert(memcmp(cbor, authdata, cbor_len) == 0); + cbor_decref(&item); + free(cbor); + free_cred(c); +} + +static void +fmt_none(void) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata_hash(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata, sizeof(authdata)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_fmt(c, "none") == FIDO_OK); + assert(fido_cred_verify(c) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey, sizeof(pubkey)) == 0); + assert(fido_cred_id_len(c) == sizeof(id)); + assert(memcmp(fido_cred_id_ptr(c), id, sizeof(id)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid, sizeof(aaguid)) == 0); + free_cred(c); +} + +static void +valid_tpm_rs256_cred(bool xfail) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_RS256) == FIDO_OK); + assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata_tpm_rs256, sizeof(authdata_tpm_rs256)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK); + assert(fido_cred_set_attstmt(c, attstmt_tpm_rs256, sizeof(attstmt_tpm_rs256)) == FIDO_OK); + // XXX: RHEL9 has deprecated SHA-1 for signing. + assert(fido_cred_verify(c) == (xfail ? FIDO_ERR_INVALID_SIG : FIDO_OK)); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_rs256)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_rs256, sizeof(pubkey_tpm_rs256)) == 0); + assert(fido_cred_id_len(c) == sizeof(id_tpm_rs256)); + assert(memcmp(fido_cred_id_ptr(c), id_tpm_rs256, sizeof(id_tpm_rs256)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0); + free_cred(c); +} + +static void +valid_tpm_es256_cred(bool xfail) +{ + fido_cred_t *c; + + c = alloc_cred(); + assert(fido_cred_set_type(c, COSE_ES256) == FIDO_OK); + assert(fido_cred_set_clientdata(c, cdh, sizeof(cdh)) == FIDO_OK); + assert(fido_cred_set_rp(c, rp_id, rp_name) == FIDO_OK); + assert(fido_cred_set_authdata(c, authdata_tpm_es256, sizeof(authdata_tpm_es256)) == FIDO_OK); + assert(fido_cred_set_rk(c, FIDO_OPT_FALSE) == FIDO_OK); + assert(fido_cred_set_uv(c, FIDO_OPT_TRUE) == FIDO_OK); + assert(fido_cred_set_fmt(c, "tpm") == FIDO_OK); + assert(fido_cred_set_attstmt(c, attstmt_tpm_es256, sizeof(attstmt_tpm_es256)) == FIDO_OK); + // XXX: RHEL9 has deprecated SHA-1 for signing. + assert(fido_cred_verify(c) == (xfail ? FIDO_ERR_INVALID_SIG : FIDO_OK)); + assert(fido_cred_prot(c) == 0); + assert(fido_cred_pubkey_len(c) == sizeof(pubkey_tpm_es256)); + assert(memcmp(fido_cred_pubkey_ptr(c), pubkey_tpm_es256, sizeof(pubkey_tpm_es256)) == 0); + assert(fido_cred_id_len(c) == sizeof(id_tpm_es256)); + assert(memcmp(fido_cred_id_ptr(c), id_tpm_es256, sizeof(id_tpm_es256)) == 0); + assert(fido_cred_aaguid_len(c) == sizeof(aaguid_tpm)); + assert(memcmp(fido_cred_aaguid_ptr(c), aaguid_tpm, sizeof(aaguid_tpm)) == 0); + free_cred(c); +} + +int +main(void) +{ + bool xfail = getenv("FIDO_REGRESS_RS1_XFAIL") != NULL; + + fido_init(0); + + empty_cred(); + valid_cred(); + no_cdh(); + no_rp_id(); + no_rp_name(); + no_authdata(); + no_x509(); + no_sig(); + no_fmt(); + junk_cdh(); + junk_fmt(); + junk_rp_id(); + junk_rp_name(); + junk_authdata(); + junk_x509(); + junk_sig(); + wrong_options(); + invalid_type(); + bad_cbor_serialize(); + duplicate_keys(); + unsorted_keys(); + wrong_credprot(); + raw_authdata(); + fmt_none(); + valid_tpm_rs256_cred(xfail); + valid_tpm_es256_cred(xfail); + + exit(0); +} diff --git a/regress/dev.c b/regress/dev.c new file mode 100644 index 0000000..0ba552b --- /dev/null +++ b/regress/dev.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2019-2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> +#include <time.h> + +#define _FIDO_INTERNAL + +#include <fido.h> + +#include "../fuzz/wiredata_fido2.h" + +#define REPORT_LEN (64 + 1) + +static uint8_t ctap_nonce[8]; +static uint8_t *wiredata_ptr; +static size_t wiredata_len; +static int fake_dev_handle; +static int initialised; +static long interval_ms; + +#if defined(_MSC_VER) +static int +nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + if (rmtp != NULL) { + errno = EINVAL; + return (-1); + } + + Sleep((DWORD)(rqtp->tv_sec * 1000) + (DWORD)(rqtp->tv_nsec / 1000000)); + + return (0); +} +#endif + +static void * +dummy_open(const char *path) +{ + (void)path; + + return (&fake_dev_handle); +} + +static void +dummy_close(void *handle) +{ + assert(handle == &fake_dev_handle); +} + +static int +dummy_read(void *handle, unsigned char *ptr, size_t len, int ms) +{ + struct timespec tv; + size_t n; + long d; + + assert(handle == &fake_dev_handle); + assert(ptr != NULL); + assert(len == REPORT_LEN - 1); + + if (wiredata_ptr == NULL) + return (-1); + + if (!initialised) { + assert(wiredata_len >= REPORT_LEN - 1); + memcpy(&wiredata_ptr[7], &ctap_nonce, sizeof(ctap_nonce)); + initialised = 1; + } + + if (ms >= 0 && ms < interval_ms) + d = ms; + else + d = interval_ms; + + if (d) { + tv.tv_sec = d / 1000; + tv.tv_nsec = (d % 1000) * 1000000; + if (nanosleep(&tv, NULL) == -1) + err(1, "nanosleep"); + } + + if (d != interval_ms) + return (-1); /* timeout */ + + if (wiredata_len < len) + n = wiredata_len; + else + n = len; + + memcpy(ptr, wiredata_ptr, n); + wiredata_ptr += n; + wiredata_len -= n; + + return ((int)n); +} + +static int +dummy_write(void *handle, const unsigned char *ptr, size_t len) +{ + struct timespec tv; + + assert(handle == &fake_dev_handle); + assert(ptr != NULL); + assert(len == REPORT_LEN); + + if (!initialised) + memcpy(&ctap_nonce, &ptr[8], sizeof(ctap_nonce)); + + if (interval_ms) { + tv.tv_sec = interval_ms / 1000; + tv.tv_nsec = (interval_ms % 1000) * 1000000; + if (nanosleep(&tv, NULL) == -1) + err(1, "nanosleep"); + } + + return ((int)len); +} + +static uint8_t * +wiredata_setup(const uint8_t *data, size_t len) +{ + const uint8_t ctap_init_data[] = { WIREDATA_CTAP_INIT }; + + assert(wiredata_ptr == NULL); + assert(SIZE_MAX - len > sizeof(ctap_init_data)); + assert((wiredata_ptr = malloc(sizeof(ctap_init_data) + len)) != NULL); + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:6386) +#endif + memcpy(wiredata_ptr, ctap_init_data, sizeof(ctap_init_data)); +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + + if (len) + memcpy(wiredata_ptr + sizeof(ctap_init_data), data, len); + + wiredata_len = sizeof(ctap_init_data) + len; + + return (wiredata_ptr); +} + +static void +wiredata_clear(uint8_t **wiredata) +{ + free(*wiredata); + *wiredata = NULL; + wiredata_ptr = NULL; + wiredata_len = 0; + initialised = 0; +} + +/* gh#56 */ +static void +open_iff_ok(void) +{ + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_ERR_RX); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + + fido_dev_free(&dev); +} + +static void +reopen(void) +{ + const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + wiredata_clear(&wiredata); + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +double_open(void) +{ + const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +double_close(void) +{ + const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_ERR_INVALID_ARGUMENT); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +is_fido2(void) +{ + const uint8_t cbor_info_data[] = { WIREDATA_CTAP_CBOR_INFO }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(cbor_info_data, sizeof(cbor_info_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_is_fido2(dev) == true); + assert(fido_dev_supports_pin(dev) == true); + fido_dev_force_u2f(dev); + assert(fido_dev_is_fido2(dev) == false); + assert(fido_dev_supports_pin(dev) == false); + assert(fido_dev_close(dev) == FIDO_OK); + wiredata_clear(&wiredata); + + wiredata = wiredata_setup(NULL, 0); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_is_fido2(dev) == false); + assert(fido_dev_supports_pin(dev) == false); + fido_dev_force_fido2(dev); + assert(fido_dev_is_fido2(dev) == true); + assert(fido_dev_supports_pin(dev) == false); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +has_pin(void) +{ + const uint8_t set_pin_data[] = { + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_CBOR_AUTHKEY, + WIREDATA_CTAP_CBOR_STATUS, + WIREDATA_CTAP_CBOR_STATUS + }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(set_pin_data, sizeof(set_pin_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_has_pin(dev) == false); + assert(fido_dev_set_pin(dev, "top secret", NULL) == FIDO_OK); + assert(fido_dev_has_pin(dev) == true); + assert(fido_dev_reset(dev) == FIDO_OK); + assert(fido_dev_has_pin(dev) == false); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); +} + +static void +timeout_rx(void) +{ + const uint8_t timeout_rx_data[] = { + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS + }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(timeout_rx_data, sizeof(timeout_rx_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK); + interval_ms = 1000; + assert(fido_dev_reset(dev) == FIDO_ERR_RX); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); + interval_ms = 0; +} + +static void +timeout_ok(void) +{ + const uint8_t timeout_ok_data[] = { + WIREDATA_CTAP_CBOR_INFO, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_KEEPALIVE, + WIREDATA_CTAP_CBOR_STATUS + }; + uint8_t *wiredata; + fido_dev_t *dev = NULL; + fido_dev_io_t io; + + memset(&io, 0, sizeof(io)); + + io.open = dummy_open; + io.close = dummy_close; + io.read = dummy_read; + io.write = dummy_write; + + wiredata = wiredata_setup(timeout_ok_data, sizeof(timeout_ok_data)); + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_io_functions(dev, &io) == FIDO_OK); + assert(fido_dev_open(dev, "dummy") == FIDO_OK); + assert(fido_dev_set_timeout(dev, 30 * 1000) == FIDO_OK); + interval_ms = 1000; + assert(fido_dev_reset(dev) == FIDO_OK); + assert(fido_dev_close(dev) == FIDO_OK); + fido_dev_free(&dev); + wiredata_clear(&wiredata); + interval_ms = 0; +} + +static void +timeout_misc(void) +{ + fido_dev_t *dev; + + assert((dev = fido_dev_new()) != NULL); + assert(fido_dev_set_timeout(dev, -2) == FIDO_ERR_INVALID_ARGUMENT); + assert(fido_dev_set_timeout(dev, 3 * 1000) == FIDO_OK); + assert(fido_dev_set_timeout(dev, -1) == FIDO_OK); + fido_dev_free(&dev); +} + +int +main(void) +{ + fido_init(0); + + open_iff_ok(); + reopen(); + double_open(); + double_close(); + is_fido2(); + has_pin(); + timeout_rx(); + timeout_ok(); + timeout_misc(); + + exit(0); +} diff --git a/regress/eddsa.c b/regress/eddsa.c new file mode 100644 index 0000000..f97f97c --- /dev/null +++ b/regress/eddsa.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#define _FIDO_INTERNAL + +#include <fido.h> +#include <fido/eddsa.h> + +#include <openssl/bio.h> +#include <openssl/pem.h> + +#define ASSERT_NOT_NULL(e) assert((e) != NULL) +#define ASSERT_NULL(e) assert((e) == NULL) +#define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT) +#define ASSERT_OK(e) assert((e) == FIDO_OK) + +static const char ecdsa[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOwiq14c80b7C1Jzsx5w1zMvk2GgW\n" +"5kfGMOKXjwF/U+51ZfBDKehs3ivdeXAJBkxIh7E3iA32s+HyNqk+ntl9fg==\n" +"-----END PUBLIC KEY-----\n"; + +static const char eddsa[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MCowBQYDK2VwAyEADt/RHErAxAHxH9FUmsjOhQ2ALl6Y8nE0m3zQxkEE2iM=\n" +"-----END PUBLIC KEY-----\n"; + +static const unsigned char eddsa_raw[] = { + 0x0e, 0xdf, 0xd1, 0x1c, 0x4a, 0xc0, 0xc4, 0x01, + 0xf1, 0x1f, 0xd1, 0x54, 0x9a, 0xc8, 0xce, 0x85, + 0x0d, 0x80, 0x2e, 0x5e, 0x98, 0xf2, 0x71, 0x34, + 0x9b, 0x7c, 0xd0, 0xc6, 0x41, 0x04, 0xda, 0x23, +}; + +static EVP_PKEY * +EVP_PKEY_from_PEM(const char *ptr, size_t len) +{ + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + warnx("BIO_new"); + goto out; + } + if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) { + warnx("BIO_write"); + goto out; + } + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) + warnx("PEM_read_bio_PUBKEY"); +out: + BIO_free(bio); + + return pkey; +} + +static int +eddsa_pk_cmp(const char *ptr, size_t len) +{ + EVP_PKEY *pkA = NULL; + EVP_PKEY *pkB = NULL; + eddsa_pk_t *k = NULL; + int r, ok = -1; + + if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) { + warnx("EVP_PKEY_from_PEM"); + goto out; + } + if ((k = eddsa_pk_new()) == NULL) { + warnx("eddsa_pk_new"); + goto out; + } + if ((r = eddsa_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) { + warnx("eddsa_pk_from_EVP_PKEY: 0x%x", r); + goto out; + } + if ((pkB = eddsa_pk_to_EVP_PKEY(k)) == NULL) { + warnx("eddsa_pk_to_EVP_PKEY"); + goto out; + } + if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) { + warnx("EVP_PKEY_cmp: %d", r); + goto out; + } + + ok = 0; +out: + EVP_PKEY_free(pkA); + EVP_PKEY_free(pkB); + eddsa_pk_free(&k); + + return ok; +} + +static void +invalid_key(void) +{ + EVP_PKEY *pkey; + eddsa_pk_t *pk; + + ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(ecdsa, sizeof(ecdsa)))); + ASSERT_NOT_NULL((pk = eddsa_pk_new())); + ASSERT_INVAL(eddsa_pk_from_EVP_PKEY(pk, pkey)); + + EVP_PKEY_free(pkey); + eddsa_pk_free(&pk); +} + +static void +valid_key(void) +{ + EVP_PKEY *pkeyA = NULL; + EVP_PKEY *pkeyB = NULL; + eddsa_pk_t *pkA = NULL; + eddsa_pk_t *pkB = NULL; + +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3070000f + /* incomplete support; test what we can */ + ASSERT_NULL(EVP_PKEY_from_PEM(eddsa, sizeof(eddsa))); + ASSERT_NOT_NULL((pkB = eddsa_pk_new())); + ASSERT_INVAL(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw))); + ASSERT_NULL(eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw)); + assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) < 0); +#else + ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(eddsa, sizeof(eddsa)))); + ASSERT_NOT_NULL((pkA = eddsa_pk_new())); + ASSERT_NOT_NULL((pkB = eddsa_pk_new())); + ASSERT_OK(eddsa_pk_from_EVP_PKEY(pkA, pkeyA)); + ASSERT_OK(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw))); + ASSERT_NOT_NULL((pkeyB = eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw))); + assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1); + assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) == 0); +#endif + + EVP_PKEY_free(pkeyA); + EVP_PKEY_free(pkeyB); + eddsa_pk_free(&pkA); + eddsa_pk_free(&pkB); +} + +int +main(void) +{ + fido_init(0); + + invalid_key(); + valid_key(); + + exit(0); +} diff --git a/regress/es256.c b/regress/es256.c new file mode 100644 index 0000000..3a62a41 --- /dev/null +++ b/regress/es256.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#define _FIDO_INTERNAL + +#include <fido.h> +#include <fido/es256.h> + +#include <openssl/bio.h> +#include <openssl/pem.h> + +#define ASSERT_NOT_NULL(e) assert((e) != NULL) +#define ASSERT_NULL(e) assert((e) == NULL) +#define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT) +#define ASSERT_OK(e) assert((e) == FIDO_OK) + +static const char short_x[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAAeeHTZj4LEbt7Czs+u5gEZJfnGE\n" +"6Z+YLe4AYu7SoGY7IH/2jKifsA7w+lkURL4DL63oEjd3f8foH9bX4eaVug==\n" +"-----END PUBLIC KEY-----"; + +static const char short_y[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL8CWUP1r0tpJ5QmkzLc69O74C/Ti\n" +"83hTiys/JFNVkp0ArW3pKt5jNRrgWSZYE4S/D3AMtpqifFXz/FLCzJqojQ==\n" +"-----END PUBLIC KEY-----\n"; + +static const char p256k1[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEU1y8c0Jg9FGr3vYChpEo9c4dpkijriYM\n" +"QzU/DeskC89hZjLNH1Sj8ra2MsBlVGGJTNPCZSyx8Jo7ERapxdN7UQ==\n" +"-----END PUBLIC KEY-----\n"; + +static const char p256v1[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOwiq14c80b7C1Jzsx5w1zMvk2GgW\n" +"5kfGMOKXjwF/U+51ZfBDKehs3ivdeXAJBkxIh7E3iA32s+HyNqk+ntl9fg==\n" +"-----END PUBLIC KEY-----\n"; + +static const unsigned char p256k1_raw[] = { + 0x04, 0x53, 0x5c, 0xbc, 0x73, 0x42, 0x60, 0xf4, + 0x51, 0xab, 0xde, 0xf6, 0x02, 0x86, 0x91, 0x28, + 0xf5, 0xce, 0x1d, 0xa6, 0x48, 0xa3, 0xae, 0x26, + 0x0c, 0x43, 0x35, 0x3f, 0x0d, 0xeb, 0x24, 0x0b, + 0xcf, 0x61, 0x66, 0x32, 0xcd, 0x1f, 0x54, 0xa3, + 0xf2, 0xb6, 0xb6, 0x32, 0xc0, 0x65, 0x54, 0x61, + 0x89, 0x4c, 0xd3, 0xc2, 0x65, 0x2c, 0xb1, 0xf0, + 0x9a, 0x3b, 0x11, 0x16, 0xa9, 0xc5, 0xd3, 0x7b, + 0x51, +}; + +static const unsigned char p256v1_raw[] = { + 0x04, 0x3b, 0x08, 0xaa, 0xd7, 0x87, 0x3c, 0xd1, + 0xbe, 0xc2, 0xd4, 0x9c, 0xec, 0xc7, 0x9c, 0x35, + 0xcc, 0xcb, 0xe4, 0xd8, 0x68, 0x16, 0xe6, 0x47, + 0xc6, 0x30, 0xe2, 0x97, 0x8f, 0x01, 0x7f, 0x53, + 0xee, 0x75, 0x65, 0xf0, 0x43, 0x29, 0xe8, 0x6c, + 0xde, 0x2b, 0xdd, 0x79, 0x70, 0x09, 0x06, 0x4c, + 0x48, 0x87, 0xb1, 0x37, 0x88, 0x0d, 0xf6, 0xb3, + 0xe1, 0xf2, 0x36, 0xa9, 0x3e, 0x9e, 0xd9, 0x7d, + 0x7e, +}; + +static EVP_PKEY * +EVP_PKEY_from_PEM(const char *ptr, size_t len) +{ + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + warnx("BIO_new"); + goto out; + } + if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) { + warnx("BIO_write"); + goto out; + } + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) + warnx("PEM_read_bio_PUBKEY"); +out: + BIO_free(bio); + + return pkey; +} + +static int +es256_pk_cmp(const char *ptr, size_t len) +{ + EVP_PKEY *pkA = NULL; + EVP_PKEY *pkB = NULL; + es256_pk_t *k = NULL; + int r, ok = -1; + + if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) { + warnx("EVP_PKEY_from_PEM"); + goto out; + } + if ((k = es256_pk_new()) == NULL) { + warnx("es256_pk_new"); + goto out; + } + if ((r = es256_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) { + warnx("es256_pk_from_EVP_PKEY: 0x%x", r); + goto out; + } + if ((pkB = es256_pk_to_EVP_PKEY(k)) == NULL) { + warnx("es256_pk_to_EVP_PKEY"); + goto out; + } + if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) { + warnx("EVP_PKEY_cmp: %d", r); + goto out; + } + + ok = 0; +out: + EVP_PKEY_free(pkA); + EVP_PKEY_free(pkB); + es256_pk_free(&k); + + return ok; +} + +static void +short_coord(void) +{ + assert(es256_pk_cmp(short_x, sizeof(short_x)) == 0); + assert(es256_pk_cmp(short_y, sizeof(short_y)) == 0); +} + +static void +invalid_curve(const unsigned char *raw, size_t raw_len) +{ + EVP_PKEY *pkey; + es256_pk_t *pk; + + ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(p256k1, sizeof(p256k1)))); + ASSERT_NOT_NULL((pk = es256_pk_new())); + ASSERT_INVAL(es256_pk_from_EVP_PKEY(pk, pkey)); + ASSERT_INVAL(es256_pk_from_ptr(pk, raw, raw_len)); + ASSERT_NULL(es256_pk_to_EVP_PKEY((const es256_pk_t *)raw)); + + EVP_PKEY_free(pkey); + es256_pk_free(&pk); +} + +static void +full_coord(void) +{ + assert(es256_pk_cmp(p256v1, sizeof(p256v1)) == 0); +} + +static void +valid_curve(const unsigned char *raw, size_t raw_len) +{ + EVP_PKEY *pkeyA; + EVP_PKEY *pkeyB; + es256_pk_t *pkA; + es256_pk_t *pkB; + + ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(p256v1, sizeof(p256v1)))); + ASSERT_NOT_NULL((pkA = es256_pk_new())); + ASSERT_NOT_NULL((pkB = es256_pk_new())); + ASSERT_OK(es256_pk_from_EVP_PKEY(pkA, pkeyA)); + ASSERT_OK(es256_pk_from_ptr(pkB, raw, raw_len)); + ASSERT_NOT_NULL((pkeyB = es256_pk_to_EVP_PKEY(pkB))); + assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1); + + EVP_PKEY_free(pkeyA); + EVP_PKEY_free(pkeyB); + es256_pk_free(&pkA); + es256_pk_free(&pkB); +} + +int +main(void) +{ + fido_init(0); + + short_coord(); + full_coord(); + + invalid_curve(p256k1_raw, sizeof(p256k1_raw)); /* uncompressed */ + invalid_curve(p256k1_raw + 1, sizeof(p256k1_raw) - 1); /* libfido2 */ + valid_curve(p256v1_raw, sizeof(p256v1_raw)); /* uncompressed */ + valid_curve(p256v1_raw + 1, sizeof(p256v1_raw) - 1); /* libfido2 */ + + exit(0); +} diff --git a/regress/es384.c b/regress/es384.c new file mode 100644 index 0000000..b55ce01 --- /dev/null +++ b/regress/es384.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#define _FIDO_INTERNAL + +#include <fido.h> +#include <fido/es384.h> + +#include <openssl/bio.h> +#include <openssl/pem.h> + +#define ASSERT_NOT_NULL(e) assert((e) != NULL) +#define ASSERT_NULL(e) assert((e) == NULL) +#define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT) +#define ASSERT_OK(e) assert((e) == FIDO_OK) + +static const char short_x[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEAAZ/VVCUmFU6aH9kJdDnUHCCglkatFTX\n" +"onMwIvNYyS8BW/HOoZiOQLs2Hg+qifwaP1pHKILzCVfFmWuZMhxhtmjNXFuOPDnS\n" +"Wa1PMdkCoWXA2BbXxnqL9v36gIOcFBil\n" +"-----END PUBLIC KEY-----"; + +static const char short_y[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEuDpRBAg87cnWVhxbWnaWlnj100w9pm5k\n" +"6T4eYToISaIhEK70TnGwULHX0+qHCYEGACOM7B/ZJbqjo6I7MIXaKZLemGi+tqvy\n" +"ajBAsTVSyrYBLQjTMMcaFmYmsxvFx7pK\n" +"-----END PUBLIC KEY-----\n"; + +static const char brainpoolP384r1[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABFKswbBzqqyZ4h1zz8rivqHzJxAO\n" +"XC2aLyC9x5gwBM7GVu8k6jkX7VypRpg3yyCneiIQ+vVCNXgbDchJ0cPVuhwm3Zru\n" +"AK49dezUPahWF0YiJRFVeV+KyB/MEaaZvinzqw==\n" +"-----END PUBLIC KEY-----\n"; + +static const char secp384r1[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEdJN9DoqPtTNAOmjnECHBIqnJgyBW0rct\n" +"tbUSqQjb6UG2lldmrQJbgCP/ywuXvkkJl4yfXxOr0UP3rgcnqTVA1/46s2TG+R5u\n" +"NSQbCM1JPQuvTyFlAn5mdR8ZJJ8yPBQm\n" +"-----END PUBLIC KEY-----\n"; + +static const unsigned char brainpoolP384r1_raw[] = { + 0x04, 0x52, 0xac, 0xc1, 0xb0, 0x73, 0xaa, 0xac, + 0x99, 0xe2, 0x1d, 0x73, 0xcf, 0xca, 0xe2, 0xbe, + 0xa1, 0xf3, 0x27, 0x10, 0x0e, 0x5c, 0x2d, 0x9a, + 0x2f, 0x20, 0xbd, 0xc7, 0x98, 0x30, 0x04, 0xce, + 0xc6, 0x56, 0xef, 0x24, 0xea, 0x39, 0x17, 0xed, + 0x5c, 0xa9, 0x46, 0x98, 0x37, 0xcb, 0x20, 0xa7, + 0x7a, 0x22, 0x10, 0xfa, 0xf5, 0x42, 0x35, 0x78, + 0x1b, 0x0d, 0xc8, 0x49, 0xd1, 0xc3, 0xd5, 0xba, + 0x1c, 0x26, 0xdd, 0x9a, 0xee, 0x00, 0xae, 0x3d, + 0x75, 0xec, 0xd4, 0x3d, 0xa8, 0x56, 0x17, 0x46, + 0x22, 0x25, 0x11, 0x55, 0x79, 0x5f, 0x8a, 0xc8, + 0x1f, 0xcc, 0x11, 0xa6, 0x99, 0xbe, 0x29, 0xf3, + 0xab, +}; + +static const unsigned char secp384r1_raw[] = { + 0x04, 0x74, 0x93, 0x7d, 0x0e, 0x8a, 0x8f, 0xb5, + 0x33, 0x40, 0x3a, 0x68, 0xe7, 0x10, 0x21, 0xc1, + 0x22, 0xa9, 0xc9, 0x83, 0x20, 0x56, 0xd2, 0xb7, + 0x2d, 0xb5, 0xb5, 0x12, 0xa9, 0x08, 0xdb, 0xe9, + 0x41, 0xb6, 0x96, 0x57, 0x66, 0xad, 0x02, 0x5b, + 0x80, 0x23, 0xff, 0xcb, 0x0b, 0x97, 0xbe, 0x49, + 0x09, 0x97, 0x8c, 0x9f, 0x5f, 0x13, 0xab, 0xd1, + 0x43, 0xf7, 0xae, 0x07, 0x27, 0xa9, 0x35, 0x40, + 0xd7, 0xfe, 0x3a, 0xb3, 0x64, 0xc6, 0xf9, 0x1e, + 0x6e, 0x35, 0x24, 0x1b, 0x08, 0xcd, 0x49, 0x3d, + 0x0b, 0xaf, 0x4f, 0x21, 0x65, 0x02, 0x7e, 0x66, + 0x75, 0x1f, 0x19, 0x24, 0x9f, 0x32, 0x3c, 0x14, + 0x26, +}; + +static EVP_PKEY * +EVP_PKEY_from_PEM(const char *ptr, size_t len) +{ + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + warnx("BIO_new"); + goto out; + } + if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) { + warnx("BIO_write"); + goto out; + } + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) + warnx("PEM_read_bio_PUBKEY"); +out: + BIO_free(bio); + + return pkey; +} + +static int +es384_pk_cmp(const char *ptr, size_t len) +{ + EVP_PKEY *pkA = NULL; + EVP_PKEY *pkB = NULL; + es384_pk_t *k = NULL; + int r, ok = -1; + + if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) { + warnx("EVP_PKEY_from_PEM"); + goto out; + } + if ((k = es384_pk_new()) == NULL) { + warnx("es384_pk_new"); + goto out; + } + if ((r = es384_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) { + warnx("es384_pk_from_EVP_PKEY: 0x%x", r); + goto out; + } + if ((pkB = es384_pk_to_EVP_PKEY(k)) == NULL) { + warnx("es384_pk_to_EVP_PKEY"); + goto out; + } + if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) { + warnx("EVP_PKEY_cmp: %d", r); + goto out; + } + + ok = 0; +out: + EVP_PKEY_free(pkA); + EVP_PKEY_free(pkB); + es384_pk_free(&k); + + return ok; +} + +static void +short_coord(void) +{ + assert(es384_pk_cmp(short_x, sizeof(short_x)) == 0); + assert(es384_pk_cmp(short_y, sizeof(short_y)) == 0); +} + +static void +invalid_curve(const unsigned char *raw, size_t raw_len) +{ + EVP_PKEY *pkey; + es384_pk_t *pk; + + pkey = EVP_PKEY_from_PEM(brainpoolP384r1, sizeof(brainpoolP384r1)); + if (pkey == NULL) + return; /* assume no brainpool support in libcrypto */ + ASSERT_NOT_NULL((pk = es384_pk_new())); + ASSERT_INVAL(es384_pk_from_EVP_PKEY(pk, pkey)); + ASSERT_INVAL(es384_pk_from_ptr(pk, raw, raw_len)); + ASSERT_NULL(es384_pk_to_EVP_PKEY((const es384_pk_t *)raw)); + + EVP_PKEY_free(pkey); + es384_pk_free(&pk); +} + +static void +full_coord(void) +{ + assert(es384_pk_cmp(secp384r1, sizeof(secp384r1)) == 0); +} + +static void +valid_curve(const unsigned char *raw, size_t raw_len) +{ + EVP_PKEY *pkeyA; + EVP_PKEY *pkeyB; + es384_pk_t *pkA; + es384_pk_t *pkB; + + ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(secp384r1, sizeof(secp384r1)))); + ASSERT_NOT_NULL((pkA = es384_pk_new())); + ASSERT_NOT_NULL((pkB = es384_pk_new())); + ASSERT_OK(es384_pk_from_EVP_PKEY(pkA, pkeyA)); + ASSERT_OK(es384_pk_from_ptr(pkB, raw, raw_len)); + ASSERT_NOT_NULL((pkeyB = es384_pk_to_EVP_PKEY(pkB))); + assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1); + + EVP_PKEY_free(pkeyA); + EVP_PKEY_free(pkeyB); + es384_pk_free(&pkA); + es384_pk_free(&pkB); +} + +int +main(void) +{ + fido_init(0); + + short_coord(); + full_coord(); + + invalid_curve(brainpoolP384r1_raw, sizeof(brainpoolP384r1_raw)); /* uncompressed */ + invalid_curve(brainpoolP384r1_raw + 1, sizeof(brainpoolP384r1_raw) - 1); /* libfido2 */ + valid_curve(secp384r1_raw, sizeof(secp384r1_raw)); /* uncompressed */ + valid_curve(secp384r1_raw + 1, sizeof(secp384r1_raw) - 1); /* libfido2 */ + + exit(0); +} diff --git a/regress/rs256.c b/regress/rs256.c new file mode 100644 index 0000000..799396f --- /dev/null +++ b/regress/rs256.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2022 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * SPDX-License-Identifier: BSD-2-Clause + */ + +#undef NDEBUG + +#include <assert.h> +#include <string.h> + +#define _FIDO_INTERNAL + +#include <fido.h> +#include <fido/rs256.h> + +#include <openssl/bio.h> +#include <openssl/pem.h> + +#define ASSERT_NOT_NULL(e) assert((e) != NULL) +#define ASSERT_NULL(e) assert((e) == NULL) +#define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT) +#define ASSERT_OK(e) assert((e) == FIDO_OK) + +static char rsa1024[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw92gn9Ku/bEfFj1AutaZyltpf\n" +"zzXrg70kQFymNq+spMt/HlxKiImw8TZU08zWW4ZLE/Ch4JYjMW6ETAdQFhSC63Ih\n" +"Wecui0JJ1f+2CsUVg+h7lO1877LZYUpdNiJrbqMb5Yc4N3FPtvdl3NoLIIQsF76H\n" +"VRvpjQgkWipRfZ97JQIDAQAB\n" +"-----END PUBLIC KEY-----"; + +static char rsa2048[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApvIq/55ZodBIxzo/8BnE\n" +"UQN1fo1hmJ6V20hQHSzJq5tHyxRCcvKikuJ1ZvR4RdZlEzdTdbEfMBdZ8sxve0/U\n" +"yYEjH92CG0vgTCYuUaFLJTaWZSvWa96G8Lw+V4VyNFDRCM7sflOaSVH5pAsz8OEc\n" +"TLZfM4NhnDsJAM+mQ6X7Tza0sczPchgDA+9KByXo/VIqyuBQs17rlKC2reMa8NkY\n" +"rBRQZJLNzi68d5/BHH1flGWE1l8wJ9dr1Ex93H/KdzX+7/28TWUC98nneUo8RfRx\n" +"FwUt/EInDMHOORCaCHSs28U/9IUyMjqLB1rxKhIp09yGXMiTrrT+p+Pcn8dO01HT\n" +"vQIDAQAB\n" +"-----END PUBLIC KEY-----"; + +static char rsa3072[] = \ +"-----BEGIN PUBLIC KEY-----\n" +"MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwZunKrMs/o92AniLPNTF\n" +"Ta4EYfhy5NDmMvQvRFT/eTYItLrOTPmYMap68KLyZYmgz/AdaxAL/992QWre7XTY\n" +"gqLwtZT+WsSu7xPHWKTTXrlVohKBeLHQ0I7Zy0NSMUxhlJEMrBAjSyFAS86zWm5w\n" +"ctC3pNCqfUKugA07BVj+d5Mv5fziwgMR86kuhkVuMYfsR4IYwX4+va0pyLzxx624\n" +"s9nJ107g+A+3MUk4bAto3lruFeeZPUI2AFzFQbGg5By6VtvVi3gKQ7lUNtAr0Onu\n" +"I6Fb+yz8sbFcvDpJcu5CXW20GrKMVP4KY5pn2LCajWuZjBl/dXWayPfm4UX5Y2O4\n" +"73tzPpUBNwnEdz79His0v80Vmvjwn5IuF2jAoimrBNPJFFwCCuVNy8kgj2vllk1l\n" +"RvLOG6hf8VnlDb40QZS3QAQ09xFfF+xlVLb8cHH6wllaAGEM230TrmawpC7xpz4Z\n" +"sTuwJwI0AWEi//noMsRz2BuF2fCp//aORYJQU2S8kYk3AgMBAAE=\n" +"-----END PUBLIC KEY-----"; + +static const unsigned char rsa2048_raw[] = { + 0xa6, 0xf2, 0x2a, 0xff, 0x9e, 0x59, 0xa1, 0xd0, + 0x48, 0xc7, 0x3a, 0x3f, 0xf0, 0x19, 0xc4, 0x51, + 0x03, 0x75, 0x7e, 0x8d, 0x61, 0x98, 0x9e, 0x95, + 0xdb, 0x48, 0x50, 0x1d, 0x2c, 0xc9, 0xab, 0x9b, + 0x47, 0xcb, 0x14, 0x42, 0x72, 0xf2, 0xa2, 0x92, + 0xe2, 0x75, 0x66, 0xf4, 0x78, 0x45, 0xd6, 0x65, + 0x13, 0x37, 0x53, 0x75, 0xb1, 0x1f, 0x30, 0x17, + 0x59, 0xf2, 0xcc, 0x6f, 0x7b, 0x4f, 0xd4, 0xc9, + 0x81, 0x23, 0x1f, 0xdd, 0x82, 0x1b, 0x4b, 0xe0, + 0x4c, 0x26, 0x2e, 0x51, 0xa1, 0x4b, 0x25, 0x36, + 0x96, 0x65, 0x2b, 0xd6, 0x6b, 0xde, 0x86, 0xf0, + 0xbc, 0x3e, 0x57, 0x85, 0x72, 0x34, 0x50, 0xd1, + 0x08, 0xce, 0xec, 0x7e, 0x53, 0x9a, 0x49, 0x51, + 0xf9, 0xa4, 0x0b, 0x33, 0xf0, 0xe1, 0x1c, 0x4c, + 0xb6, 0x5f, 0x33, 0x83, 0x61, 0x9c, 0x3b, 0x09, + 0x00, 0xcf, 0xa6, 0x43, 0xa5, 0xfb, 0x4f, 0x36, + 0xb4, 0xb1, 0xcc, 0xcf, 0x72, 0x18, 0x03, 0x03, + 0xef, 0x4a, 0x07, 0x25, 0xe8, 0xfd, 0x52, 0x2a, + 0xca, 0xe0, 0x50, 0xb3, 0x5e, 0xeb, 0x94, 0xa0, + 0xb6, 0xad, 0xe3, 0x1a, 0xf0, 0xd9, 0x18, 0xac, + 0x14, 0x50, 0x64, 0x92, 0xcd, 0xce, 0x2e, 0xbc, + 0x77, 0x9f, 0xc1, 0x1c, 0x7d, 0x5f, 0x94, 0x65, + 0x84, 0xd6, 0x5f, 0x30, 0x27, 0xd7, 0x6b, 0xd4, + 0x4c, 0x7d, 0xdc, 0x7f, 0xca, 0x77, 0x35, 0xfe, + 0xef, 0xfd, 0xbc, 0x4d, 0x65, 0x02, 0xf7, 0xc9, + 0xe7, 0x79, 0x4a, 0x3c, 0x45, 0xf4, 0x71, 0x17, + 0x05, 0x2d, 0xfc, 0x42, 0x27, 0x0c, 0xc1, 0xce, + 0x39, 0x10, 0x9a, 0x08, 0x74, 0xac, 0xdb, 0xc5, + 0x3f, 0xf4, 0x85, 0x32, 0x32, 0x3a, 0x8b, 0x07, + 0x5a, 0xf1, 0x2a, 0x12, 0x29, 0xd3, 0xdc, 0x86, + 0x5c, 0xc8, 0x93, 0xae, 0xb4, 0xfe, 0xa7, 0xe3, + 0xdc, 0x9f, 0xc7, 0x4e, 0xd3, 0x51, 0xd3, 0xbd, + 0x01, 0x00, 0x01, +}; + +static EVP_PKEY * +EVP_PKEY_from_PEM(const char *ptr, size_t len) +{ + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + warnx("BIO_new"); + goto out; + } + if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) { + warnx("BIO_write"); + goto out; + } + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL) + warnx("PEM_read_bio_PUBKEY"); +out: + BIO_free(bio); + + return pkey; +} + +static int +rs256_pk_cmp(const char *ptr, size_t len) +{ + EVP_PKEY *pkA = NULL; + EVP_PKEY *pkB = NULL; + rs256_pk_t *k = NULL; + int r, ok = -1; + + if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) { + warnx("EVP_PKEY_from_PEM"); + goto out; + } + if ((k = rs256_pk_new()) == NULL) { + warnx("rs256_pk_new"); + goto out; + } + if ((r = rs256_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) { + warnx("rs256_pk_from_EVP_PKEY: 0x%x", r); + goto out; + } + if ((pkB = rs256_pk_to_EVP_PKEY(k)) == NULL) { + warnx("rs256_pk_to_EVP_PKEY"); + goto out; + } + if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) { + warnx("EVP_PKEY_cmp: %d", r); + goto out; + } + + ok = 0; +out: + EVP_PKEY_free(pkA); + EVP_PKEY_free(pkB); + rs256_pk_free(&k); + + return ok; +} + +static void +invalid_size(const char *pem) +{ + EVP_PKEY *pkey; + rs256_pk_t *pk; + + ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(pem, strlen(pem)))); + ASSERT_NOT_NULL((pk = rs256_pk_new())); + ASSERT_INVAL(rs256_pk_from_EVP_PKEY(pk, pkey)); + + EVP_PKEY_free(pkey); + rs256_pk_free(&pk); +} + +static void +valid_size(const char *pem, const unsigned char *raw, size_t raw_len) +{ + EVP_PKEY *pkeyA; + EVP_PKEY *pkeyB; + rs256_pk_t *pkA; + rs256_pk_t *pkB; + + ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(pem, strlen(pem)))); + ASSERT_NOT_NULL((pkA = rs256_pk_new())); + ASSERT_NOT_NULL((pkB = rs256_pk_new())); + ASSERT_OK(rs256_pk_from_EVP_PKEY(pkA, pkeyA)); + ASSERT_OK(rs256_pk_from_ptr(pkB, raw, raw_len)); + ASSERT_NOT_NULL((pkeyB = rs256_pk_to_EVP_PKEY(pkB))); + assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1); + assert(rs256_pk_cmp(pem, strlen(pem)) == 0); + + EVP_PKEY_free(pkeyA); + EVP_PKEY_free(pkeyB); + rs256_pk_free(&pkA); + rs256_pk_free(&pkB); +} + +int +main(void) +{ + fido_init(0); + + invalid_size(rsa1024); + invalid_size(rsa3072); + valid_size(rsa2048, rsa2048_raw, sizeof(rsa2048_raw)); + + exit(0); +} |