Add files via upload

This commit is contained in:
Token2
2024-05-24 11:44:25 +02:00
committed by GitHub
parent df1b66988f
commit ca68f70495
71 changed files with 13997 additions and 0 deletions

57
regress/CMakeLists.txt Normal file
View File

@@ -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()

685
regress/assert.c Normal file
View File

@@ -0,0 +1,685 @@
/*
* Copyright (c) 2018-2023 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
* SPDX-License-Identifier: BSD-2-Clause
*/
#undef NDEBUG
#include <assert.h>
#include <string.h>
#define _FIDO_INTERNAL
#include <fido.h>
#include <fido/es256.h>
#include <fido/rs256.h>
#include <fido/eddsa.h>
static int fake_dev_handle;
static const unsigned char es256_pk[64] = {
0x34, 0xeb, 0x99, 0x77, 0x02, 0x9c, 0x36, 0x38,
0xbb, 0xc2, 0xae, 0xa0, 0xa0, 0x18, 0xc6, 0x64,
0xfc, 0xe8, 0x49, 0x92, 0xd7, 0x74, 0x9e, 0x0c,
0x46, 0x8c, 0x9d, 0xa6, 0xdf, 0x46, 0xf7, 0x84,
0x60, 0x1e, 0x0f, 0x8b, 0x23, 0x85, 0x4a, 0x9a,
0xec, 0xc1, 0x08, 0x9f, 0x30, 0xd0, 0x0d, 0xd7,
0x76, 0x7b, 0x55, 0x48, 0x91, 0x7c, 0x4f, 0x0f,
0x64, 0x1a, 0x1d, 0xf8, 0xbe, 0x14, 0x90, 0x8a,
};
static const unsigned char rs256_pk[259] = {
0x9e, 0x54, 0x78, 0xb2, 0x51, 0xbe, 0x19, 0x7c,
0xcb, 0x1a, 0x9a, 0xc3, 0x49, 0x2a, 0x2f, 0xfd,
0x99, 0x64, 0x76, 0xc6, 0xdb, 0xca, 0x38, 0x3f,
0xb0, 0x6a, 0xc9, 0xc0, 0x07, 0x9f, 0x5c, 0x4d,
0xfc, 0xd1, 0x01, 0x7f, 0x69, 0x65, 0xab, 0x9c,
0x2a, 0xc2, 0x95, 0xd9, 0x44, 0xf3, 0xea, 0x94,
0x6b, 0x25, 0x66, 0x54, 0x81, 0xee, 0x24, 0x1d,
0xe1, 0x7d, 0x7f, 0xbe, 0xea, 0x76, 0x90, 0x5c,
0xbf, 0x59, 0x22, 0xd3, 0xa0, 0x68, 0x1a, 0x65,
0x8b, 0x2f, 0xb6, 0xa8, 0x30, 0x2d, 0x26, 0x81,
0xfa, 0x9e, 0x59, 0xec, 0x2f, 0xee, 0x59, 0x39,
0xe2, 0x79, 0x19, 0x54, 0x54, 0xdf, 0x24, 0x83,
0xee, 0x61, 0x5a, 0x66, 0x24, 0x2b, 0x7b, 0xfb,
0x82, 0x66, 0xe4, 0x85, 0x18, 0x20, 0x76, 0xe5,
0x4a, 0xb6, 0xcb, 0xec, 0x43, 0xbe, 0xfd, 0xb0,
0x8f, 0xfd, 0x2f, 0x69, 0xda, 0x06, 0x9c, 0x09,
0x68, 0x7a, 0x94, 0x6c, 0xb7, 0x51, 0x6d, 0x4c,
0xf7, 0x13, 0xe8, 0xd5, 0x22, 0x6b, 0x1e, 0xba,
0xb9, 0x85, 0xe8, 0x5f, 0xa1, 0x66, 0xe3, 0x20,
0x75, 0x30, 0x11, 0xb5, 0xa3, 0xc3, 0xb0, 0x72,
0x08, 0xff, 0xa3, 0xbb, 0xf1, 0x32, 0x0b, 0x06,
0xc4, 0x12, 0xa3, 0x49, 0x30, 0x19, 0xb9, 0xfe,
0x69, 0x0c, 0xd6, 0xe1, 0x58, 0x36, 0xe6, 0x41,
0x22, 0x41, 0xbf, 0x96, 0x50, 0x35, 0x56, 0x0d,
0x92, 0x8c, 0x34, 0xea, 0x28, 0x91, 0x88, 0x9e,
0x8a, 0xaa, 0x36, 0xd0, 0x0f, 0xbe, 0x16, 0xde,
0x9d, 0x5f, 0x7b, 0xda, 0x52, 0xf7, 0xf1, 0xb6,
0x28, 0x10, 0x05, 0x8f, 0xb9, 0x19, 0x7a, 0xcf,
0x18, 0x9b, 0x40, 0xcd, 0xff, 0x78, 0xea, 0x61,
0x24, 0x3b, 0x80, 0x68, 0x04, 0x9b, 0x40, 0x07,
0x98, 0xd4, 0x94, 0xd1, 0x18, 0x44, 0xa5, 0xed,
0xee, 0x18, 0xc2, 0x25, 0x52, 0x66, 0x42, 0xdf,
0x01, 0x00, 0x01,
};
static const unsigned char cdh[32] = {
0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7,
0x82, 0x34, 0xaa, 0xca, 0x07, 0xa1, 0xf6, 0x56,
0x42, 0x1c, 0xb6, 0xf6, 0xb3, 0x00, 0x86, 0x52,
0x35, 0x2d, 0xa2, 0x62, 0x4a, 0xbe, 0x89, 0x76,
};
static const unsigned char authdata[39] = {
0x58, 0x25, 0x49, 0x96, 0x0d, 0xe5, 0x88, 0x0e,
0x8c, 0x68, 0x74, 0x34, 0x17, 0x0f, 0x64, 0x76,
0x60, 0x5b, 0x8f, 0xe4, 0xae, 0xb9, 0xa2, 0x86,
0x32, 0xc7, 0x99, 0x5c, 0xf3, 0xba, 0x83, 0x1d,
0x97, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03,
};
static const unsigned char sig[72] = {
0x30, 0x46, 0x02, 0x21, 0x00, 0xf6, 0xd1, 0xa3,
0xd5, 0x24, 0x2b, 0xde, 0xee, 0xa0, 0x90, 0x89,
0xcd, 0xf8, 0x9e, 0xbd, 0x6b, 0x4d, 0x55, 0x79,
0xe4, 0xc1, 0x42, 0x27, 0xb7, 0x9b, 0x9b, 0xa4,
0x0a, 0xe2, 0x47, 0x64, 0x0e, 0x02, 0x21, 0x00,
0xe5, 0xc9, 0xc2, 0x83, 0x47, 0x31, 0xc7, 0x26,
0xe5, 0x25, 0xb2, 0xb4, 0x39, 0xa7, 0xfc, 0x3d,
0x70, 0xbe, 0xe9, 0x81, 0x0d, 0x4a, 0x62, 0xa9,
0xab, 0x4a, 0x91, 0xc0, 0x7d, 0x2d, 0x23, 0x1e,
};
static void *
dummy_open(const char *path)
{
(void)path;
return (&fake_dev_handle);
}
static void
dummy_close(void *handle)
{
assert(handle == &fake_dev_handle);
}
static int
dummy_read(void *handle, unsigned char *buf, size_t len, int ms)
{
(void)handle;
(void)buf;
(void)len;
(void)ms;
abort();
/* NOTREACHED */
}
static int
dummy_write(void *handle, const unsigned char *buf, size_t len)
{
(void)handle;
(void)buf;
(void)len;
abort();
/* NOTREACHED */
}
static fido_assert_t *
alloc_assert(void)
{
fido_assert_t *a;
a = fido_assert_new();
assert(a != NULL);
return (a);
}
static void
free_assert(fido_assert_t *a)
{
fido_assert_free(&a);
assert(a == NULL);
}
static fido_dev_t *
alloc_dev(void)
{
fido_dev_t *d;
d = fido_dev_new();
assert(d != NULL);
return (d);
}
static void
free_dev(fido_dev_t *d)
{
fido_dev_free(&d);
assert(d == NULL);
}
static es256_pk_t *
alloc_es256_pk(void)
{
es256_pk_t *pk;
pk = es256_pk_new();
assert(pk != NULL);
return (pk);
}
static void
free_es256_pk(es256_pk_t *pk)
{
es256_pk_free(&pk);
assert(pk == NULL);
}
static rs256_pk_t *
alloc_rs256_pk(void)
{
rs256_pk_t *pk;
pk = rs256_pk_new();
assert(pk != NULL);
return (pk);
}
static void
free_rs256_pk(rs256_pk_t *pk)
{
rs256_pk_free(&pk);
assert(pk == NULL);
}
static eddsa_pk_t *
alloc_eddsa_pk(void)
{
eddsa_pk_t *pk;
pk = eddsa_pk_new();
assert(pk != NULL);
return (pk);
}
static void
free_eddsa_pk(eddsa_pk_t *pk)
{
eddsa_pk_free(&pk);
assert(pk == NULL);
}
static void
empty_assert(fido_dev_t *d, fido_assert_t *a, size_t idx)
{
es256_pk_t *es256;
rs256_pk_t *rs256;
eddsa_pk_t *eddsa;
assert(fido_assert_flags(a, idx) == 0);
assert(fido_assert_authdata_len(a, idx) == 0);
assert(fido_assert_authdata_ptr(a, idx) == NULL);
assert(fido_assert_authdata_raw_len(a, idx) == 0);
assert(fido_assert_authdata_raw_ptr(a, idx) == NULL);
assert(fido_assert_clientdata_hash_len(a) == 0);
assert(fido_assert_clientdata_hash_ptr(a) == NULL);
assert(fido_assert_id_len(a, idx) == 0);
assert(fido_assert_id_ptr(a, idx) == NULL);
assert(fido_assert_rp_id(a) == NULL);
assert(fido_assert_sig_len(a, idx) == 0);
assert(fido_assert_sig_ptr(a, idx) == NULL);
assert(fido_assert_user_display_name(a, idx) == NULL);
assert(fido_assert_user_icon(a, idx) == NULL);
assert(fido_assert_user_id_len(a, idx) == 0);
assert(fido_assert_user_id_ptr(a, idx) == NULL);
assert(fido_assert_user_name(a, idx) == NULL);
es256 = alloc_es256_pk();
rs256 = alloc_rs256_pk();
eddsa = alloc_eddsa_pk();
fido_dev_force_u2f(d);
assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_ES256,
NULL) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_ES256,
es256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, -1,
es256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_RS256,
rs256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_EDDSA,
eddsa) == FIDO_ERR_INVALID_ARGUMENT);
fido_dev_force_fido2(d);
assert(fido_dev_get_assert(d, a, NULL) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_dev_get_assert(d, a, "") == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_ES256,
NULL) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_ES256,
es256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, -1,
es256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_RS256,
rs256) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_verify(a, idx, COSE_EDDSA,
eddsa) == FIDO_ERR_INVALID_ARGUMENT);
free_es256_pk(es256);
free_rs256_pk(rs256);
free_eddsa_pk(eddsa);
}
static void
empty_assert_tests(void)
{
fido_assert_t *a;
fido_dev_t *d;
fido_dev_io_t io_f;
size_t i;
memset(&io_f, 0, sizeof(io_f));
a = alloc_assert();
d = alloc_dev();
io_f.open = dummy_open;
io_f.close = dummy_close;
io_f.read = dummy_read;
io_f.write = dummy_write;
assert(fido_dev_set_io_functions(d, &io_f) == FIDO_OK);
empty_assert(d, a, 0);
assert(fido_assert_count(a) == 0);
assert(fido_assert_set_count(a, 4) == FIDO_OK);
assert(fido_assert_count(a) == 4);
for (i = 0; i < 4; i++) {
empty_assert(d, a, i);
}
empty_assert(d, a, 10);
free_assert(a);
free_dev(d);
}
static void
valid_assert(void)
{
fido_assert_t *a;
es256_pk_t *es256;
rs256_pk_t *rs256;
eddsa_pk_t *eddsa;
a = alloc_assert();
es256 = alloc_es256_pk();
rs256 = alloc_rs256_pk();
eddsa = alloc_eddsa_pk();
assert(es256_pk_from_ptr(es256, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256, es256) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_RS256, rs256) == FIDO_ERR_INVALID_SIG);
assert(fido_assert_verify(a, 0, COSE_EDDSA, eddsa) == FIDO_ERR_INVALID_SIG);
free_assert(a);
free_es256_pk(es256);
free_rs256_pk(rs256);
free_eddsa_pk(eddsa);
}
static void
no_cdh(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_ARGUMENT);
free_assert(a);
free_es256_pk(pk);
}
static void
no_rp(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_ARGUMENT);
free_assert(a);
free_es256_pk(pk);
}
static void
no_authdata(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_ARGUMENT);
free_assert(a);
free_es256_pk(pk);
}
static void
no_sig(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_ARGUMENT);
free_assert(a);
free_es256_pk(pk);
}
static void
junk_cdh(void)
{
fido_assert_t *a;
es256_pk_t *pk;
unsigned char *junk;
junk = malloc(sizeof(cdh));
assert(junk != NULL);
memcpy(junk, cdh, sizeof(cdh));
junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, junk, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG);
free_assert(a);
free_es256_pk(pk);
free(junk);
}
static void
junk_rp(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "potato") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_PARAM);
free_assert(a);
free_es256_pk(pk);
}
static void
junk_authdata(void)
{
fido_assert_t *a;
unsigned char *junk;
junk = malloc(sizeof(authdata));
assert(junk != NULL);
memcpy(junk, authdata, sizeof(authdata));
junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, junk,
sizeof(authdata)) == FIDO_ERR_INVALID_ARGUMENT);
assert(fido_assert_authdata_ptr(a, 0) == NULL);
assert(fido_assert_authdata_len(a, 0) == 0);
assert(fido_assert_authdata_raw_ptr(a, 0) == NULL);
assert(fido_assert_authdata_raw_len(a, 0) == 0);
free_assert(a);
free(junk);
}
static void
junk_sig(void)
{
fido_assert_t *a;
es256_pk_t *pk;
unsigned char *junk;
junk = malloc(sizeof(sig));
assert(junk != NULL);
memcpy(junk, sig, sizeof(sig));
junk[0] = (unsigned char)~junk[0];
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, junk, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_ERR_INVALID_SIG);
free_assert(a);
free_es256_pk(pk);
free(junk);
}
static void
wrong_options(void)
{
fido_assert_t *a;
es256_pk_t *pk;
a = alloc_assert();
pk = alloc_es256_pk();
assert(es256_pk_from_ptr(pk, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert(fido_assert_set_clientdata_hash(a, cdh, sizeof(cdh)) == FIDO_OK);
assert(fido_assert_set_rp(a, "localhost") == FIDO_OK);
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_set_up(a, FIDO_OPT_TRUE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_sig(a, 0, sig, sizeof(sig)) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_PARAM);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_TRUE) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256,
pk) == FIDO_ERR_INVALID_PARAM);
assert(fido_assert_set_up(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_set_uv(a, FIDO_OPT_FALSE) == FIDO_OK);
assert(fido_assert_verify(a, 0, COSE_ES256, pk) == FIDO_OK);
free_assert(a);
free_es256_pk(pk);
}
/* cbor_serialize_alloc misuse */
static void
bad_cbor_serialize(void)
{
fido_assert_t *a;
a = alloc_assert();
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert(fido_assert_authdata_len(a, 0) == sizeof(authdata));
free_assert(a);
}
/* rs256 <-> EVP_PKEY transformations */
static void
rs256_PKEY(void)
{
rs256_pk_t *pk1, *pk2;
EVP_PKEY *pkey;
pk1 = alloc_rs256_pk();
pk2 = alloc_rs256_pk();
assert(rs256_pk_from_ptr(pk1, rs256_pk, sizeof(rs256_pk)) == FIDO_OK);
assert((pkey = rs256_pk_to_EVP_PKEY(pk1)) != NULL);
assert(rs256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK);
assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0);
free_rs256_pk(pk1);
free_rs256_pk(pk2);
EVP_PKEY_free(pkey);
}
/* es256 <-> EVP_PKEY transformations */
static void
es256_PKEY(void)
{
es256_pk_t *pk1, *pk2;
EVP_PKEY *pkey;
pk1 = alloc_es256_pk();
pk2 = alloc_es256_pk();
assert(es256_pk_from_ptr(pk1, es256_pk, sizeof(es256_pk)) == FIDO_OK);
assert((pkey = es256_pk_to_EVP_PKEY(pk1)) != NULL);
assert(es256_pk_from_EVP_PKEY(pk2, pkey) == FIDO_OK);
assert(memcmp(pk1, pk2, sizeof(*pk1)) == 0);
free_es256_pk(pk1);
free_es256_pk(pk2);
EVP_PKEY_free(pkey);
}
static void
raw_authdata(void)
{
fido_assert_t *a;
cbor_item_t *item;
struct cbor_load_result cbor_result;
const unsigned char *ptr;
unsigned char *cbor;
size_t len;
size_t cbor_len;
size_t alloclen;
a = alloc_assert();
assert(fido_assert_set_count(a, 1) == FIDO_OK);
assert(fido_assert_set_authdata(a, 0, authdata,
sizeof(authdata)) == FIDO_OK);
assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL);
assert((len = fido_assert_authdata_len(a, 0)) != 0);
assert((item = cbor_load(ptr, len, &cbor_result)) != NULL);
assert(cbor_result.read == len);
assert(cbor_isa_bytestring(item));
assert((ptr = fido_assert_authdata_raw_ptr(a, 0)) != NULL);
assert((len = fido_assert_authdata_raw_len(a, 0)) != 0);
assert(cbor_bytestring_length(item) == len);
assert(memcmp(ptr, cbor_bytestring_handle(item), len) == 0);
assert((len = fido_assert_authdata_len(a, 0)) != 0);
assert((cbor_len = cbor_serialize_alloc(item, &cbor, &alloclen)) == len);
assert((ptr = cbor_bytestring_handle(item)) != NULL);
assert((len = cbor_bytestring_length(item)) != 0);
assert(fido_assert_set_authdata_raw(a, 0, ptr, len) == FIDO_OK);
assert((ptr = fido_assert_authdata_ptr(a, 0)) != NULL);
assert((len = fido_assert_authdata_len(a, 0)) != 0);
assert(len == cbor_len);
assert(memcmp(cbor, ptr, len) == 0);
assert(cbor_len == sizeof(authdata));
assert(memcmp(cbor, authdata, cbor_len) == 0);
cbor_decref(&item);
free(cbor);
free_assert(a);
}
int
main(void)
{
fido_init(0);
empty_assert_tests();
valid_assert();
no_cdh();
no_rp();
no_authdata();
no_sig();
junk_cdh();
junk_rp();
junk_authdata();
junk_sig();
wrong_options();
bad_cbor_serialize();
rs256_PKEY();
es256_PKEY();
raw_authdata();
exit(0);
}

268
regress/compress.c Normal file
View File

@@ -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);
}

2662
regress/cred.c Normal file

File diff suppressed because it is too large Load Diff

439
regress/dev.c Normal file
View File

@@ -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);
}

159
regress/eddsa.c Normal file
View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2022 Yubico AB. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
* SPDX-License-Identifier: BSD-2-Clause
*/
#undef NDEBUG
#include <assert.h>
#include <string.h>
#define _FIDO_INTERNAL
#include <fido.h>
#include <fido/eddsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#define ASSERT_NOT_NULL(e) assert((e) != NULL)
#define ASSERT_NULL(e) assert((e) == NULL)
#define ASSERT_INVAL(e) assert((e) == FIDO_ERR_INVALID_ARGUMENT)
#define ASSERT_OK(e) assert((e) == FIDO_OK)
static const char ecdsa[] = \
"-----BEGIN PUBLIC KEY-----\n"
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOwiq14c80b7C1Jzsx5w1zMvk2GgW\n"
"5kfGMOKXjwF/U+51ZfBDKehs3ivdeXAJBkxIh7E3iA32s+HyNqk+ntl9fg==\n"
"-----END PUBLIC KEY-----\n";
static const char eddsa[] = \
"-----BEGIN PUBLIC KEY-----\n"
"MCowBQYDK2VwAyEADt/RHErAxAHxH9FUmsjOhQ2ALl6Y8nE0m3zQxkEE2iM=\n"
"-----END PUBLIC KEY-----\n";
static const unsigned char eddsa_raw[] = {
0x0e, 0xdf, 0xd1, 0x1c, 0x4a, 0xc0, 0xc4, 0x01,
0xf1, 0x1f, 0xd1, 0x54, 0x9a, 0xc8, 0xce, 0x85,
0x0d, 0x80, 0x2e, 0x5e, 0x98, 0xf2, 0x71, 0x34,
0x9b, 0x7c, 0xd0, 0xc6, 0x41, 0x04, 0xda, 0x23,
};
static EVP_PKEY *
EVP_PKEY_from_PEM(const char *ptr, size_t len)
{
BIO *bio = NULL;
EVP_PKEY *pkey = NULL;
if ((bio = BIO_new(BIO_s_mem())) == NULL) {
warnx("BIO_new");
goto out;
}
if (len > INT_MAX || BIO_write(bio, ptr, (int)len) != (int)len) {
warnx("BIO_write");
goto out;
}
if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)) == NULL)
warnx("PEM_read_bio_PUBKEY");
out:
BIO_free(bio);
return pkey;
}
static int
eddsa_pk_cmp(const char *ptr, size_t len)
{
EVP_PKEY *pkA = NULL;
EVP_PKEY *pkB = NULL;
eddsa_pk_t *k = NULL;
int r, ok = -1;
if ((pkA = EVP_PKEY_from_PEM(ptr, len)) == NULL) {
warnx("EVP_PKEY_from_PEM");
goto out;
}
if ((k = eddsa_pk_new()) == NULL) {
warnx("eddsa_pk_new");
goto out;
}
if ((r = eddsa_pk_from_EVP_PKEY(k, pkA)) != FIDO_OK) {
warnx("eddsa_pk_from_EVP_PKEY: 0x%x", r);
goto out;
}
if ((pkB = eddsa_pk_to_EVP_PKEY(k)) == NULL) {
warnx("eddsa_pk_to_EVP_PKEY");
goto out;
}
if ((r = EVP_PKEY_cmp(pkA, pkB)) != 1) {
warnx("EVP_PKEY_cmp: %d", r);
goto out;
}
ok = 0;
out:
EVP_PKEY_free(pkA);
EVP_PKEY_free(pkB);
eddsa_pk_free(&k);
return ok;
}
static void
invalid_key(void)
{
EVP_PKEY *pkey;
eddsa_pk_t *pk;
ASSERT_NOT_NULL((pkey = EVP_PKEY_from_PEM(ecdsa, sizeof(ecdsa))));
ASSERT_NOT_NULL((pk = eddsa_pk_new()));
ASSERT_INVAL(eddsa_pk_from_EVP_PKEY(pk, pkey));
EVP_PKEY_free(pkey);
eddsa_pk_free(&pk);
}
static void
valid_key(void)
{
EVP_PKEY *pkeyA = NULL;
EVP_PKEY *pkeyB = NULL;
eddsa_pk_t *pkA = NULL;
eddsa_pk_t *pkB = NULL;
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3070000f
/* incomplete support; test what we can */
ASSERT_NULL(EVP_PKEY_from_PEM(eddsa, sizeof(eddsa)));
ASSERT_NOT_NULL((pkB = eddsa_pk_new()));
ASSERT_INVAL(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw)));
ASSERT_NULL(eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw));
assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) < 0);
#else
ASSERT_NOT_NULL((pkeyA = EVP_PKEY_from_PEM(eddsa, sizeof(eddsa))));
ASSERT_NOT_NULL((pkA = eddsa_pk_new()));
ASSERT_NOT_NULL((pkB = eddsa_pk_new()));
ASSERT_OK(eddsa_pk_from_EVP_PKEY(pkA, pkeyA));
ASSERT_OK(eddsa_pk_from_ptr(pkB, eddsa_raw, sizeof(eddsa_raw)));
ASSERT_NOT_NULL((pkeyB = eddsa_pk_to_EVP_PKEY((const eddsa_pk_t *)eddsa_raw)));
assert(EVP_PKEY_cmp(pkeyA, pkeyB) == 1);
assert(eddsa_pk_cmp(eddsa, sizeof(eddsa)) == 0);
#endif
EVP_PKEY_free(pkeyA);
EVP_PKEY_free(pkeyB);
eddsa_pk_free(&pkA);
eddsa_pk_free(&pkB);
}
int
main(void)
{
fido_init(0);
invalid_key();
valid_key();
exit(0);
}

199
regress/es256.c Normal file
View File

@@ -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);
}

213
regress/es384.c Normal file
View File

@@ -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);
}

201
regress/rs256.c Normal file
View File

@@ -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);
}