summaryrefslogtreecommitdiffstats
path: root/regress
diff options
context:
space:
mode:
Diffstat (limited to 'regress')
-rw-r--r--regress/CMakeLists.txt57
-rw-r--r--regress/assert.c637
-rw-r--r--regress/compress.c268
-rw-r--r--regress/cred.c2179
-rw-r--r--regress/dev.c439
-rw-r--r--regress/eddsa.c159
-rw-r--r--regress/es256.c199
-rw-r--r--regress/es384.c213
-rw-r--r--regress/rs256.c201
9 files changed, 4352 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..9860925
--- /dev/null
+++ b/regress/assert.c
@@ -0,0 +1,637 @@
+/*
+ * 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>
+
+#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_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);
+ 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);
+}
+
+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();
+
+ 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..e4dc76a
--- /dev/null
+++ b/regress/cred.c
@@ -0,0 +1,2179 @@
+/*
+ * 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>
+
+#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(void)
+{
+ 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);
+ assert(fido_cred_verify(c) == 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(void)
+{
+ 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);
+ assert(fido_cred_verify(c) == 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)
+{
+ 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();
+ valid_tpm_es256_cred();
+
+ 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..0623698
--- /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)
+ /* 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);
+}