mirror of
https://github.com/token2/fido2-manage.git
synced 2026-04-09 10:45:39 +00:00
Add files via upload
This commit is contained in:
57
regress/CMakeLists.txt
Normal file
57
regress/CMakeLists.txt
Normal 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
685
regress/assert.c
Normal 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
268
regress/compress.c
Normal 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
2662
regress/cred.c
Normal file
File diff suppressed because it is too large
Load Diff
439
regress/dev.c
Normal file
439
regress/dev.c
Normal 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
159
regress/eddsa.c
Normal 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
199
regress/es256.c
Normal 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
213
regress/es384.c
Normal 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
201
regress/rs256.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user