diff --git a/CMakeLists.txt b/CMakeLists.txt index 10125eb69..eeb857754 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,16 @@ if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN") list(APPEND LTC_C_FLAGS -no-undefined) endif() +if(MSVC) + cmake_push_check_state() + check_symbol_exists(BCryptGenRandom bcrypt.h BCRYPT_AVAILABLE) + cmake_pop_check_state() + if (BCRYPT_AVAILABLE) + target_link_libraries(${PROJECT_NAME} PRIVATE Bcrypt) + list(APPEND LTC_C_FLAGS -DLTC_WIN32_BCRYPT) + endif() +endif() + # If the user set the environment variables at generate-time, append them # in order to allow overriding our defaults. # ${LTC_CFLAGS} means the user passed it via sth like: @@ -153,6 +163,7 @@ if(WITH_LTM) target_link_libraries(${PROJECT_NAME} PUBLIC libtommath) list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DLTM_DESC) list(APPEND LTC_MPI_PROVIDERS_LIBS -ltommath) + list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtommath-dev) endif() # tomsfastmath if(WITH_TFM) @@ -165,6 +176,7 @@ if(WITH_TFM) target_link_libraries(${PROJECT_NAME} PUBLIC tomsfastmath) list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DTFM_DESC) list(APPEND LTC_MPI_PROVIDERS_LIBS -ltfm) + list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libtfm-dev) endif() # GNU MP if(WITH_GMP) @@ -177,10 +189,12 @@ if(WITH_GMP) target_link_libraries(${PROJECT_NAME} PUBLIC ${GMP_LIBRARIES}) list(APPEND LTC_MPI_PROVIDERS_CFLAGS -DGMP_DESC) list(APPEND LTC_MPI_PROVIDERS_LIBS -lgmp) + list(APPEND LTC_DEBIAN_MPI_PROVIDER_DEPENDS libgmp-dev) endif() list(JOIN LTC_MPI_PROVIDERS_CFLAGS " " MPI_PROVIDERS_CFLAGS) list(JOIN LTC_MPI_PROVIDERS_LIBS " " MPI_PROVIDERS_LIBS) +list(JOIN LTC_DEBIAN_MPI_PROVIDER_DEPENDS " " DEBIAN_MPI_PROVIDER_DEPENDS) #----------------------------------------------------------------------------- # demos&test targets @@ -204,7 +218,7 @@ set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") install(TARGETS ${PROJECT_NAME} EXPORT ${TARGETS_EXPORT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) @@ -295,13 +309,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") list(APPEND CPACK_GENERATOR FREEBSD) endif() +set(LTC_DEBIAN_SHARED_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}${PROJECT_VERSION_MAJOR}") + # general CPack config set(CPACK_PACKAGE_DIRECTORY ${CMAKE_BINARY_DIR}/packages/${DISTRO_PACK_PATH}) message(STATUS "CPack: packages will be generated under ${CPACK_PACKAGE_DIRECTORY}") if(BUILD_SHARED_LIBS) set(CPACK_PACKAGE_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}") + set(CPACK_DEBIAN_PACKAGE_NAME "${LTC_DEBIAN_SHARED_PACKAGE_NAME}") else() set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-devel") + set(CPACK_DEBIAN_LIBRARIES_PACKAGE_NAME "${PROJECT_NAME}${PACKAGE_NAME_SUFFIX}-dev") endif() set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibTomCrypt") @@ -314,15 +332,21 @@ set(CPACK_STRIP_FILES ON) # deb specific CPack config set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) -set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON) set(CPACK_DEBIAN_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION}) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) if(BUILD_SHARED_LIBS) set(CPACK_DEBIAN_PACKAGE_SECTION "libs") + set(CPACK_DEBIAN_PACKAGE_DEPENDS ${DEBIAN_MPI_PROVIDER_DEPENDS}) else() - set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}-dev") - set(CPACK_DEBIAN_PACKAGE_SECTION "devel") + set(CPACK_DEBIAN_PACKAGE_SECTION "libdevel") + set(CPACK_DEBIAN_PACKAGE_DEPENDS ${LTC_DEBIAN_SHARED_PACKAGE_NAME}) + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) + set(CPACK_COMPONENTS_ALL Libraries) endif() + # rpm specific CPack config set(CPACK_RPM_PACKAGE_RELEASE ${PACKAGE_RELEASE_VERSION}) set(CPACK_RPM_PACKAGE_ARCHITECTURE ${MACHINE_ARCH}) diff --git a/helper.pl b/helper.pl index d91ab167c..7262f0685 100755 --- a/helper.pl +++ b/helper.pl @@ -71,6 +71,7 @@ sub check_source { my $n = $1; push @{$troubles->{invalid_macro_name}}, "$lineno($n)" unless ($file eq 'src/headers/tomcrypt_cfg.h' && $n eq '__has_builtin') || + ($file eq 'src/headers/tomcrypt_cfg.h' && $n eq '_WIN32_WINNT') || ($file eq 'src/prngs/rng_get_bytes.c' && $n eq '_WIN32_WINNT'); } $lineno++; diff --git a/libtomcrypt.pc.in b/libtomcrypt.pc.in index f840a5451..ebc977d87 100644 --- a/libtomcrypt.pc.in +++ b/libtomcrypt.pc.in @@ -1,6 +1,5 @@ prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@ Name: LibTomCrypt diff --git a/makefile.shared b/makefile.shared index 2ac1e78a4..310840c99 100644 --- a/makefile.shared +++ b/makefile.shared @@ -93,8 +93,8 @@ endef $(foreach demo, $(strip $(DEMOS)), $(eval $(call DEMO_template,$(demo)))) install: $(call print-help,install,Installs the library + headers + pkg-config file) .common_install - sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,@CMAKE_INSTALL_LIBDIR@,lib,' \ - -e 's,@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@,include/tomcrypt,' \ + sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,^libdir=.*,libdir=$(LIBPATH),' \ + -e 's,^includedir=.*,includedir=$(INCPATH),' \ -e 's,@MPI_PROVIDERS_LIBS@,$(LTC_MPI_PROVIDERS_LIBS),' \ -e 's,@MPI_PROVIDERS_CFLAGS@,$(LTC_MPI_PROVIDERS_CFLAGS),' libtomcrypt.pc.in > libtomcrypt.pc install -p -d $(DESTDIR)$(LIBPATH)/pkgconfig diff --git a/makefile.unix b/makefile.unix index 31473a077..a46736c28 100644 --- a/makefile.unix +++ b/makefile.unix @@ -35,11 +35,15 @@ ARFLAGS = r RANLIB = ranlib CFLAGS = -O2 -DUSE_LTM -DLTM_DESC -I../libtommath EXTRALIBS = ../libtommath/libtommath.a +# pkg-config flags, added to libtomcrypt.pc on install time +PC_CFLAGS = -DLTM_DESC +PC_LIBS = -ltommath #Compilation flags LTC_CFLAGS = -Isrc/headers -Itests -DLTC_SOURCE $(CFLAGS) LTC_LDFLAGS = $(LDFLAGS) $(EXTRALIBS) VERSION=1.18.2-develop +VERSION_PC=1.18.2 #Libraries to be created (this makefile builds only static libraries) LIBMAIN_S =libtomcrypt.a @@ -320,7 +324,10 @@ install: $(LIBMAIN_S) @mkdir -p $(DESTDIR)$(INCPATH) $(DESTDIR)$(LIBPATH)/pkgconfig @cp $(LIBMAIN_S) $(DESTDIR)$(LIBPATH)/ @cp $(HEADERS_PUB) $(DESTDIR)$(INCPATH)/ - @sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION),' libtomcrypt.pc.in > $(DESTDIR)$(LIBPATH)/pkgconfig/libtomcrypt.pc + @sed -e 's,^prefix=.*,prefix=$(PREFIX),' -e 's,^Version:.*,Version: $(VERSION_PC),' -e 's,^libdir=.*,libdir=$(LIBPATH),' \ + -e 's,^includedir=.*,includedir=$(INCPATH),' \ + -e 's,@MPI_PROVIDERS_LIBS@,$(PC_LIBS),' \ + -e 's,@MPI_PROVIDERS_CFLAGS@,$(PC_CFLAGS),' libtomcrypt.pc.in > $(DESTDIR)$(LIBPATH)/pkgconfig/libtomcrypt.pc #Install useful tools install_bins: hashsum diff --git a/makefile_include.mk b/makefile_include.mk index 22f3fb1c3..f933b36b6 100644 --- a/makefile_include.mk +++ b/makefile_include.mk @@ -190,7 +190,7 @@ DEMOS = $(UNBROKEN_DEMOS) $(BROKEN_DEMOS) DESTDIR ?= PREFIX ?= /usr/local LIBPATH ?= $(PREFIX)/lib -INCPATH ?= $(PREFIX)/include +INCPATH ?= $(PREFIX)/include/libtomcrypt DATAPATH ?= $(PREFIX)/share/doc/libtomcrypt/pdf BINPATH ?= $(PREFIX)/bin diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index 2a024aa45..35af30083 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -79,15 +79,15 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** * use the portable [slower] macros. */ -/* detect x86/i386 32bit */ -#if defined(__i386__) || defined(__i386) || defined(_M_IX86) +/* detect x86/i386/ARM 32bit */ +#if defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_ARM) #define ENDIAN_LITTLE #define ENDIAN_32BITWORD #define LTC_FAST #endif -/* detect amd64/x64 */ -#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) +/* detect amd64/x64/arm64 */ +#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || defined(_M_ARM64) #define ENDIAN_LITTLE #define ENDIAN_64BITWORD #define LTC_FAST @@ -195,7 +195,8 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \ defined(__LITTLE_ENDIAN__) || \ defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ - defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) + defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \ + defined(_M_ARM) || defined(_M_ARM64) #define ENDIAN_LITTLE #else #error Cannot detect endianness @@ -219,7 +220,7 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \ defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ - defined(__LP64__) || defined(_LP64) || defined(__64BIT__) + defined(__LP64__) || defined(_LP64) || defined(__64BIT__) || defined(_M_ARM64) typedef unsigned ulong32; #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) #define ENDIAN_64BITWORD @@ -300,6 +301,21 @@ typedef unsigned long ltc_mp_digit; #define LTC_ALIGN(n) #endif +/* Choose Windows Vista as minimum Version if we're compiling with at least VS2019 + * This is done in order to test the bcrypt RNG and can still be overridden by the user. */ +#if defined(_MSC_VER) && _MSC_VER >= 1920 +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +# endif +# ifndef WINVER +# define WINVER 0x0600 +# endif +#endif + +#if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && !defined(LTC_WIN32_BCRYPT) +# define LTC_WIN32_BCRYPT +#endif + /* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code * before including `tomcrypt.h` to disable this functionality. */ diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index f0a65fef7..8575c1cc8 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -333,11 +333,14 @@ /* Greg's SOBER128 stream cipher based PRNG */ #define LTC_SOBER128 +#if !defined(_WIN32) && !defined(_WIN32_WCE) /* the *nix style /dev/random device */ #define LTC_DEVRANDOM /* try /dev/urandom before trying /dev/random * are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */ #define LTC_TRY_URANDOM_FIRST +#endif /* not Windows */ + /* rng_get_bytes() */ #define LTC_RNG_GET_BYTES /* rng_make_prng() */ diff --git a/src/math/fp/ltc_ecc_fp_mulmod.c b/src/math/fp/ltc_ecc_fp_mulmod.c index 5827bf3b0..9be2ebf16 100644 --- a/src/math/fp/ltc_ecc_fp_mulmod.c +++ b/src/math/fp/ltc_ecc_fp_mulmod.c @@ -1429,8 +1429,10 @@ int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen) * and the mu INTEGER */ cache_entry = XCALLOC(FP_ENTRIES*(2*(1U< 0) { --z; } - if (x + z > inlen) { + if (x + z > len) { return CRYPT_INVALID_PACKET; } diff --git a/src/prngs/rng_get_bytes.c b/src/prngs/rng_get_bytes.c index b07238ec7..9a1221021 100644 --- a/src/prngs/rng_get_bytes.c +++ b/src/prngs/rng_get_bytes.c @@ -82,12 +82,27 @@ static unsigned long s_rng_ansic(unsigned char *buf, unsigned long len, /* Try the Microsoft CSP */ #if defined(_WIN32) || defined(_WIN32_WCE) +#if defined(LTC_WIN32_BCRYPT) + +#include +#include +#pragma comment(lib, "bcrypt.lib") + +static unsigned long s_rng_win32(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + LTC_UNUSED_PARAM(callback); + + return BCRYPT_SUCCESS(BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) ? len : 0; +} + +#else + #ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0400 + #define _WIN32_WINNT 0x0501 #endif -#ifdef _WIN32_WCE - #define UNDER_CE - #define ARM +#ifndef WINVER + #define WINVER 0x0501 #endif #define WIN32_LEAN_AND_MEAN @@ -97,23 +112,23 @@ static unsigned long s_rng_ansic(unsigned char *buf, unsigned long len, static unsigned long s_rng_win32(unsigned char *buf, unsigned long len, void (*callback)(void)) { - HCRYPTPROV hProv = 0; LTC_UNUSED_PARAM(callback); - if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, - (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && - !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) - return 0; - - if (CryptGenRandom(hProv, len, buf) == TRUE) { - CryptReleaseContext(hProv, 0); - return len; - } else { - CryptReleaseContext(hProv, 0); - return 0; + + static HCRYPTPROV hProv = 0; + if (hProv == 0) { + HCRYPTPROV h = 0; + if (!CryptAcquireContextW(&h, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContextW(&h, NULL, MS_DEF_PROV_W, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) { + return 0; + } + hProv = h; } -} + return CryptGenRandom(hProv, (DWORD)len, (BYTE *)buf) == TRUE ? len : 0; +} +#endif /* Old WIN32 versions */ #endif /* WIN32 */ /** diff --git a/tests/der_test.c b/tests/der_test.c index 70683b81a..86adbcda4 100644 --- a/tests/der_test.c +++ b/tests/der_test.c @@ -11,6 +11,8 @@ int der_test(void) #else +#include + #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 2 #define LTC_DER_TESTS_PRINT_FLEXI #endif @@ -252,7 +254,7 @@ static void s_free(void *p) XFREE(p); } -static void s_der_tests_print_flexi(ltc_asn1_list* l, unsigned int level) +static void s_der_tests_print_flexi_i(ltc_asn1_list* l, unsigned int level) { char *buf = NULL; const char* name = NULL; @@ -435,15 +437,28 @@ static void s_der_tests_print_flexi(ltc_asn1_list* l, unsigned int level) } if (ostring) { - s_der_tests_print_flexi(ostring, level + 1); + s_der_tests_print_flexi_i(ostring, level + 1); der_free_sequence_flexi(ostring); } if (l->child) - s_der_tests_print_flexi(l->child, level + 1); + s_der_tests_print_flexi_i(l->child, level + 1); if (l->next) - s_der_tests_print_flexi(l->next, level); + s_der_tests_print_flexi_i(l->next, level); +} + +static void s_der_tests_print_flexi(ltc_asn1_list* l) +{ + fprintf(stderr, "\n\n"); + s_der_tests_print_flexi_i(l, 0); + fprintf(stderr, "\n\n"); +} + +#else +static void s_der_tests_print_flexi(ltc_asn1_list* l) +{ + LTC_UNUSED_PARAM(l); } #endif @@ -471,11 +486,7 @@ static void der_cacert_test(void) CHECK_ASN1_TYPE(decoded_list, LTC_ASN1_SEQUENCE); CHECK_ASN1_HAS_NO_DATA(decoded_list); -#ifdef LTC_DER_TESTS_PRINT_FLEXI - printf("\n\n--- test print start ---\n\n"); - s_der_tests_print_flexi(decoded_list, 0); - printf("\n\n--- test print end ---\n\n"); -#endif + s_der_tests_print_flexi(decoded_list); l = decoded_list; @@ -1086,7 +1097,7 @@ static int der_choice_n_custom_test(void) for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; } for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; } for (x = 0; x < sizeof(utf8buf)/sizeof(utf8buf[0]); x++) { utf8buf[x] = L'a'; } - integer = 1; + integer = 10000; boolean[0] = 1; for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; } DO(mp_init(&mpinteger)); @@ -1169,11 +1180,7 @@ static void s_der_decode_print(const void* p, unsigned long* plen) { ltc_asn1_list *list; DO(der_decode_sequence_flexi(p, plen, &list)); -#ifdef LTC_DER_TESTS_PRINT_FLEXI - fprintf(stderr, "\n\n"); - s_der_tests_print_flexi(list, 0); - fprintf(stderr, "\n\n"); -#endif + s_der_tests_print_flexi(list); der_sequence_free(list); } @@ -1342,11 +1349,7 @@ static void der_Xcode_test(void) i = sizeof(teletex_neg_int); DO(der_decode_sequence_flexi(teletex_neg_int, &i, &list)); -#ifdef LTC_DER_TESTS_PRINT_FLEXI - fprintf(stderr, "\n\n"); - s_der_tests_print_flexi(list, 0); - fprintf(stderr, "\n\n"); -#endif + s_der_tests_print_flexi(list); if (list->child == NULL || list->child->next == NULL) exit(EXIT_FAILURE); ttex_neg_int[0] = *list->child->next; @@ -1368,11 +1371,7 @@ static int s_der_decode_sequence_flexi(const void *in, unsigned long inlen, void { ltc_asn1_list** list = ctx; if (der_decode_sequence_flexi(in, &inlen, list) == CRYPT_OK) { -#ifdef LTC_DER_TESTS_PRINT_FLEXI - fprintf(stderr, "\n\n"); - s_der_tests_print_flexi(*list, 0); - fprintf(stderr, "\n\n"); -#endif + s_der_tests_print_flexi(*list); der_sequence_free(*list); } return CRYPT_OK; @@ -1400,7 +1399,9 @@ static void s_der_regression_test(void) "\xaa" /* One byte padding */ "\x04\x82\xff\xff"; /* Start OCTET sequence of length 0xffff */ /* (this will include the adjacent data into the decoded certificate) */ - unsigned long len; + static const unsigned char utf8_length[] = "\x0c\x02\x61\x61\x61"; + wchar_t wtmp[4]; + unsigned long len, outlen; void *x, *y; ltc_asn1_list seq[2]; ltc_asn1_list *l; @@ -1421,6 +1422,11 @@ static void s_der_regression_test(void) len = sizeof(issue_507); SHOULD_FAIL(der_decode_sequence_flexi(issue_507, &len, &l)); + + len = sizeof(utf8_length); + outlen = sizeof(wtmp)/sizeof(wtmp[0]); + DO(der_decode_utf8_string(utf8_length, len, wtmp, &outlen)); + ENSURE(outlen == 2); } static void der_toolong_test(void)