Files
wolfssl/tests/api.c
Anthony Hu d088fee72c Add cipher suite filtering when downgrade is disabled
When wolfSSL_SetVersion() is called to set a specific TLS version,
the downgrade flag is now set to 0. This causes wolfSSL_parse_cipher_list()
to no longer preserve cipher suites from the other TLS version group.

Previously, when using SSLv23 method and setting cipher suites for only
one TLS version (e.g., TLS 1.2), the library would preserve any existing
cipher suites from the other version (e.g., TLS 1.3) for OpenSSL API
compatibility. With this change, if a specific version is set via
wolfSSL_SetVersion(), only the cipher suites for that version are kept.
2026-01-21 18:01:01 -05:00

32339 lines
1.1 MiB

/* api.c API unit tests
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* For AES-CBC, input lengths can optionally be validated to be a
* multiple of the block size, by defining WOLFSSL_AES_CBC_LENGTH_CHECKS,
* also available via the configure option --enable-aescbc-length-checks.
*/
/*----------------------------------------------------------------------------*
| Includes
*----------------------------------------------------------------------------*/
#include <tests/unit.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/hash.h>
#if defined(WOLFSSL_STATIC_MEMORY)
#include <wolfssl/wolfcrypt/memory.h>
#endif
#ifdef WOLFSSL_ASNC_CRYPT
#include <wolfssl/wolfcrypt/async.h>
#endif
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h> /* wc_ecc_fp_free */
#ifdef WOLFSSL_SM2
#include <wolfssl/wolfcrypt/sm2.h>
#endif
#endif
#ifndef NO_ASN
#include <wolfssl/wolfcrypt/asn_public.h>
#endif
#include <stdlib.h>
#if defined(__linux__) || defined(__FreeBSD__)
#include <unistd.h>
#include <sys/wait.h>
#endif
#include <wolfssl/ssl.h> /* compatibility layer */
#include <wolfssl/error-ssl.h>
#include <wolfssl/test.h>
#include <tests/utils.h>
#include <testsuite/utils.h>
/* for testing compatibility layer callbacks */
#include "examples/server/server.h"
#ifndef NO_SIG_WRAPPER
#include <wolfssl/wolfcrypt/signature.h>
#endif
#ifdef WOLFSSL_SMALL_CERT_VERIFY
#include <wolfssl/wolfcrypt/asn.h>
#endif
#ifndef NO_DSA
#include <wolfssl/wolfcrypt/dsa.h>
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(OPENSSL_ALL)
#include <wolfssl/openssl/ssl.h>
#ifndef NO_ASN
/* for ASN_COMMON_NAME DN_tags enum */
#include <wolfssl/wolfcrypt/asn.h>
#endif
#ifdef HAVE_OCSP
#include <wolfssl/openssl/ocsp.h>
#endif
#endif
#ifdef OPENSSL_EXTRA
#include <wolfssl/openssl/cmac.h>
#include <wolfssl/openssl/x509v3.h>
#include <wolfssl/openssl/asn1.h>
#include <wolfssl/openssl/crypto.h>
#include <wolfssl/openssl/pkcs12.h>
#include <wolfssl/openssl/evp.h>
#include <wolfssl/openssl/dh.h>
#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/buffer.h>
#include <wolfssl/openssl/pem.h>
#include <wolfssl/openssl/ec.h>
#include <wolfssl/openssl/ecdh.h>
#include <wolfssl/openssl/engine.h>
#include <wolfssl/openssl/hmac.h>
#include <wolfssl/openssl/objects.h>
#include <wolfssl/openssl/rand.h>
#include <wolfssl/openssl/modes.h>
#include <wolfssl/openssl/fips_rand.h>
#include <wolfssl/openssl/kdf.h>
#include <wolfssl/openssl/x509_vfy.h>
#ifdef OPENSSL_ALL
#include <wolfssl/openssl/txt_db.h>
#include <wolfssl/openssl/lhash.h>
#endif
#ifndef NO_AES
#include <wolfssl/openssl/aes.h>
#endif
#ifndef NO_DES3
#include <wolfssl/openssl/des.h>
#endif
#ifndef NO_RC4
#include <wolfssl/openssl/rc4.h>
#endif
#ifdef HAVE_ECC
#include <wolfssl/openssl/ecdsa.h>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/openssl/ec25519.h>
#endif
#ifdef HAVE_ED25519
#include <wolfssl/openssl/ed25519.h>
#endif
#ifdef HAVE_CURVE448
#include <wolfssl/openssl/ec448.h>
#endif
#ifdef HAVE_ED448
#include <wolfssl/openssl/ed448.h>
#endif
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \
!defined(NO_SHA256) && !defined(RC_NO_RNG)
#include <wolfssl/wolfcrypt/srp.h>
#endif
#if (defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)) || \
defined(HAVE_SESSION_TICKET) || (defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \
defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \
defined(HAVE_ECH) || defined(HAVE_EX_DATA) || !defined(NO_SESSION_CACHE) \
|| !defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13)
/* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT,
* for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence
* number tracking */
#include "wolfssl/internal.h"
#endif
/* include misc.c here regardless of NO_INLINE, because misc.c implementations
* have default (hidden) visibility, and in the absence of visibility, it's
* benign to mask out the library implementation.
*/
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#include <tests/api/api.h>
#include <tests/api/api_decl.h>
/* Gather test declarations to include them in the testCases array */
#include <tests/api/test_md2.h>
#include <tests/api/test_md4.h>
#include <tests/api/test_md5.h>
#include <tests/api/test_sha.h>
#include <tests/api/test_sha256.h>
#include <tests/api/test_sha512.h>
#include <tests/api/test_sha3.h>
#include <tests/api/test_blake2.h>
#include <tests/api/test_sm3.h>
#include <tests/api/test_ripemd.h>
#include <tests/api/test_hash.h>
#include <tests/api/test_hmac.h>
#include <tests/api/test_cmac.h>
#include <tests/api/test_des3.h>
#include <tests/api/test_chacha.h>
#include <tests/api/test_poly1305.h>
#include <tests/api/test_chacha20_poly1305.h>
#include <tests/api/test_camellia.h>
#include <tests/api/test_arc4.h>
#include <tests/api/test_rc2.h>
#include <tests/api/test_aes.h>
#include <tests/api/test_ascon.h>
#include <tests/api/test_sm4.h>
#include <tests/api/test_wc_encrypt.h>
#include <tests/api/test_random.h>
#include <tests/api/test_wolfmath.h>
#include <tests/api/test_rsa.h>
#include <tests/api/test_dsa.h>
#include <tests/api/test_dh.h>
#include <tests/api/test_ecc.h>
#include <tests/api/test_sm2.h>
#include <tests/api/test_curve25519.h>
#include <tests/api/test_ed25519.h>
#include <tests/api/test_curve448.h>
#include <tests/api/test_ed448.h>
#include <tests/api/test_mlkem.h>
#include <tests/api/test_mldsa.h>
#include <tests/api/test_signature.h>
#include <tests/api/test_dtls.h>
#include <tests/api/test_ocsp.h>
#include <tests/api/test_evp.h>
#include <tests/api/test_tls_ext.h>
#include <tests/api/test_tls.h>
#include <tests/api/test_x509.h>
#include <tests/api/test_asn.h>
#include <tests/api/test_pkcs7.h>
#include <tests/api/test_pkcs12.h>
#include <tests/api/test_ossl_asn1.h>
#include <tests/api/test_ossl_bn.h>
#include <tests/api/test_ossl_bio.h>
#include <tests/api/test_ossl_dgst.h>
#include <tests/api/test_ossl_mac.h>
#include <tests/api/test_ossl_cipher.h>
#include <tests/api/test_ossl_rsa.h>
#include <tests/api/test_ossl_dh.h>
#include <tests/api/test_ossl_ec.h>
#include <tests/api/test_ossl_ecx.h>
#include <tests/api/test_ossl_dsa.h>
#include <tests/api/test_ossl_sk.h>
#include <tests/api/test_ossl_x509.h>
#include <tests/api/test_ossl_x509_ext.h>
#include <tests/api/test_ossl_x509_name.h>
#include <tests/api/test_ossl_x509_pk.h>
#include <tests/api/test_ossl_x509_vp.h>
#include <tests/api/test_ossl_x509_io.h>
#include <tests/api/test_ossl_x509_crypto.h>
#include <tests/api/test_ossl_x509_acert.h>
#include <tests/api/test_ossl_x509_info.h>
#include <tests/api/test_ossl_x509_str.h>
#include <tests/api/test_ossl_x509_lu.h>
#include <tests/api/test_ossl_pem.h>
#include <tests/api/test_ossl_rand.h>
#include <tests/api/test_ossl_obj.h>
#include <tests/api/test_ossl_p7p12.h>
#include <tests/api/test_evp_digest.h>
#include <tests/api/test_evp_cipher.h>
#include <tests/api/test_evp_pkey.h>
#include <tests/api/test_certman.h>
#include <tests/api/test_tls13.h>
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_RSA) && \
!defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(WOLFSSL_TIRTOS)
#define HAVE_SSL_MEMIO_TESTS_DEPENDENCIES
#endif
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || defined(SESSION_CERTS)
#ifdef OPENSSL_EXTRA
#define TEST_TLS_STATIC_MEMSZ (400000)
#else
#define TEST_TLS_STATIC_MEMSZ (320000)
#endif
#else
#define TEST_TLS_STATIC_MEMSZ (80000)
#endif
#endif
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
const char* currentTestName = NULL;
char tmpDirName[16];
int tmpDirNameSet = 0;
#endif
/*----------------------------------------------------------------------------*
| Constants
*----------------------------------------------------------------------------*/
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT))
static const char* bogusFile =
#ifdef _WIN32
"NUL"
#else
"/dev/null"
#endif
;
#endif /* !NO_FILESYSTEM && !NO_CERTS && (!NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT) */
enum {
TESTING_RSA = 1,
TESTING_ECC = 2
};
#ifdef WOLFSSL_QNX_CAAM
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
int testDevId = WOLFSSL_CAAM_DEVID;
#else
int testDevId = INVALID_DEVID;
#endif
#ifdef USE_WINDOWS_API
#define MESSAGE_TYPE_CAST char*
#else
#define MESSAGE_TYPE_CAST void*
#endif
/*----------------------------------------------------------------------------*
| BIO with fixed read/write size
*----------------------------------------------------------------------------*/
#if defined(OPENSSL_EXTRA) && !defined(NO_BIO)
static int wolfssl_bio_s_fixed_mem_write(WOLFSSL_BIO* bio, const char* data,
int len)
{
if ((bio == NULL) || (bio->ptr.mem_buf_data == NULL) || (data == NULL)) {
len = 0;
}
else {
if (bio->wrSz - bio->wrIdx < len) {
len = bio->wrSz - bio->wrIdx;
}
XMEMCPY(bio->ptr.mem_buf_data + bio->wrIdx, data, (size_t)len);
bio->wrIdx += len;
}
return len;
}
static int wolfssl_bio_s_fixed_mem_read(WOLFSSL_BIO* bio, char* data, int len)
{
if ((bio == NULL) || (bio->ptr.mem_buf_data == NULL) || (data == NULL)) {
len = 0;
}
else {
if (bio->wrSz - bio->rdIdx < len) {
len = bio->wrSz - bio->rdIdx;
}
XMEMCPY(data, bio->ptr.mem_buf_data + bio->rdIdx, (size_t)len);
bio->rdIdx += len;
}
return len;
}
WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_fixed_mem(void)
{
static WOLFSSL_BIO_METHOD meth;
meth.type = WOLFSSL_BIO_BIO;
XMEMCPY(meth.name, "Fixed Memory Size", 18);
meth.writeCb = wolfssl_bio_s_fixed_mem_write;
meth.readCb = wolfssl_bio_s_fixed_mem_read;
return &meth;
}
#endif
/*----------------------------------------------------------------------------*
| Setup
*----------------------------------------------------------------------------*/
static int test_wolfSSL_Init(void)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_Init(), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_wolfSSL_Cleanup(void)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_Cleanup(), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
/* Initialize the wolfCrypt state.
* POST: 0 success.
*/
static int test_wolfCrypt_Init(void)
{
EXPECT_DECLS;
ExpectIntEQ(wolfCrypt_Init(), 0);
return EXPECT_RESULT();
} /* END test_wolfCrypt_Init */
static int test_wolfCrypt_Cleanup(void)
{
EXPECT_DECLS;
ExpectIntEQ(wolfCrypt_Cleanup(), 0);
return EXPECT_RESULT();
}
#ifdef WOLFSSL_STATIC_MEMORY
#define TEST_LSM_STATIC_SIZE 440000
/* Create new bucket list, using the default list, adding
* one dang large buffer size. */
#define TEST_LSM_DEF_BUCKETS (WOLFMEM_DEF_BUCKETS+1)
#define TEST_LSM_BUCKETS WOLFMEM_BUCKETS,(LARGEST_MEM_BUCKET*2)
#define TEST_LSM_DIST WOLFMEM_DIST,1
#endif
static int test_wc_LoadStaticMemory_ex(void)
{
EXPECT_DECLS;
#ifdef WOLFSSL_STATIC_MEMORY
byte staticMemory[TEST_LSM_STATIC_SIZE];
word32 sizeList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_BUCKETS };
word32 distList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_DIST };
WOLFSSL_HEAP_HINT* heap;
/* For this test, the size and dist lists will be the ones configured
* for the build, or default. The value of WOLFMEM_DEF_BUCKETS is 9,
* so these lists are 10 long. For most tests, the value of
* WOLFMEM_DEF_BUCKETS is used. There's a test case where one is added
* to that, to make sure the list size is larger than
* WOLFMEM_MAX_BUCKETS. */
/* Pass in zero everything. */
ExpectIntEQ(wc_LoadStaticMemory_ex(NULL, 0, NULL, NULL, NULL, 0, 0, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Set the heap pointer to NULL. */
ExpectIntEQ(wc_LoadStaticMemory_ex(NULL,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory, (word32)sizeof(staticMemory),
0, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Set other pointer values to NULL one at a time. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, NULL, distList,
staticMemory, (word32)sizeof(staticMemory),
0, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, NULL,
staticMemory, (word32)sizeof(staticMemory),
0, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
NULL, (word32)sizeof(staticMemory),
0, 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Set the size of the static buffer to 0. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory, 0,
0, 1),
WC_NO_ERR_TRACE(BUFFER_E));
/* Set the size of the static buffer to one less than minimum allowed. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory,
(word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) - 1,
0, 1),
WC_NO_ERR_TRACE(BUFFER_E));
/* Set the size of the static buffer to exactly the minimum size. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory,
(word32)(sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)),
0, 1),
0);
wc_UnloadStaticMemory(heap);
/* Use more buckets than able. Success case. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS*2, sizeList, distList,
staticMemory, (word32)sizeof(staticMemory),
0, 1),
0);
wc_UnloadStaticMemory(heap);
/* Success case. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory, (word32)sizeof(staticMemory),
0, 1),
0);
wc_UnloadStaticMemory(heap);
#endif /* WOLFSSL_STATIC_MEMORY */
return EXPECT_RESULT();
}
static int test_wc_LoadStaticMemory_CTX(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(NO_WOLFSSL_CLIENT)
byte staticMemory[TEST_LSM_STATIC_SIZE];
word32 sizeList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_BUCKETS };
word32 distList[TEST_LSM_DEF_BUCKETS] = { TEST_LSM_DIST };
WOLFSSL_HEAP_HINT* heap;
WOLFSSL_CTX *ctx1 = NULL, *ctx2 = NULL;
/* Set the size of the static buffer to exactly the minimum size. */
heap = NULL;
ExpectIntEQ(wc_LoadStaticMemory_ex(&heap,
WOLFMEM_DEF_BUCKETS, sizeList, distList,
staticMemory, sizeof(staticMemory), 0, 1),
0);
/* Creating two WOLFSSL_CTX objects from the same heap hint and free'ing
* them should not cause issues. */
ExpectNotNull((ctx1 = wolfSSL_CTX_new_ex(wolfSSLv23_client_method_ex(heap),
heap)));
wolfSSL_CTX_free(ctx1);
ExpectNotNull((ctx2 = wolfSSL_CTX_new_ex(wolfSSLv23_client_method_ex(heap),
heap)));
wolfSSL_CTX_free(ctx2);
/* two CTX's at once */
ExpectNotNull((ctx1 = wolfSSL_CTX_new_ex(wolfSSLv23_client_method_ex(heap),
heap)));
ExpectNotNull((ctx2 = wolfSSL_CTX_new_ex(wolfSSLv23_client_method_ex(heap),
heap)));
wolfSSL_CTX_free(ctx1);
wolfSSL_CTX_free(ctx2);
wc_UnloadStaticMemory(heap);
#endif /* WOLFSSL_STATIC_MEMORY */
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Platform dependent function test
*----------------------------------------------------------------------------*/
static int test_fileAccess(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TEST_PLATFORMDEPEND) && !defined(NO_FILESYSTEM)
const char *fname[] = {
svrCertFile, svrKeyFile, caCertFile,
eccCertFile, eccKeyFile, eccRsaCertFile,
cliCertFile, cliCertDerFile, cliKeyFile,
dhParamFile,
cliEccKeyFile, cliEccCertFile, caEccCertFile, edCertFile, edKeyFile,
cliEdCertFile, cliEdKeyFile, caEdCertFile,
NULL
};
const char derfile[] = "./certs/server-cert.der";
XFILE f = XBADFILE;
size_t sz;
byte *buff = NULL;
int i;
ExpectTrue(XFOPEN("badfilename", "rb") == XBADFILE);
for (i=0; EXPECT_SUCCESS() && fname[i] != NULL ; i++) {
ExpectTrue((f = XFOPEN(fname[i], "rb")) != XBADFILE);
XFCLOSE(f);
}
ExpectTrue((f = XFOPEN(derfile, "rb")) != XBADFILE);
ExpectTrue(XFSEEK(f, 0, XSEEK_END) == 0);
ExpectIntGE(sz = (size_t) XFTELL(f), sizeof_server_cert_der_2048);
ExpectTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
ExpectTrue((buff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
ExpectTrue(XFREAD(buff, 1, sz, f) == sz);
ExpectIntEQ(XMEMCMP(server_cert_der_2048, buff, sz), 0);
XFREE(buff, NULL, DYNAMIC_TYPE_FILE);
XFCLOSE(f);
#endif
return EXPECT_RESULT();
}
static int test_wc_FreeCertList(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS12) && !defined(NO_ASN) && \
!defined(NO_PWDBASED) && !defined(NO_HMAC) && !defined(NO_CERTS) && \
defined(USE_CERT_BUFFERS_2048)
WC_DerCertList* list = NULL;
void* heap = NULL;
/* Test freeing a list with a single node */
list = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
heap, DYNAMIC_TYPE_PKCS);
ExpectNotNull(list);
if (list != NULL) {
list->buffer = (byte*)XMALLOC(10, heap, DYNAMIC_TYPE_PKCS);
ExpectNotNull(list->buffer);
if (list->buffer != NULL) {
list->bufferSz = 10;
list->next = NULL;
wc_FreeCertList(list, heap);
}
else {
XFREE(list, heap, DYNAMIC_TYPE_PKCS);
list = NULL;
}
}
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Method Allocators
*----------------------------------------------------------------------------*/
static int test_wolfSSL_Method_Allocators(void)
{
EXPECT_DECLS;
#define TEST_METHOD_ALLOCATOR(allocator, condition) \
do { \
WOLFSSL_METHOD *method = NULL; \
condition(method = allocator()); \
XFREE(method, 0, DYNAMIC_TYPE_METHOD); \
} while (0)
#define TEST_VALID_METHOD_ALLOCATOR(a) \
TEST_METHOD_ALLOCATOR(a, ExpectNotNull)
#define TEST_INVALID_METHOD_ALLOCATOR(a) \
TEST_METHOD_ALLOCATOR(a, ExpectNull)
#ifndef NO_TLS
#ifndef NO_OLD_TLS
#ifdef WOLFSSL_ALLOW_SSLV3
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_client_method);
#endif
#endif
#ifdef WOLFSSL_ALLOW_TLSV10
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_client_method);
#endif
#endif
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_client_method);
#endif
#endif /* !NO_OLD_TLS */
#ifndef WOLFSSL_NO_TLS12
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_client_method);
#endif
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_TLS13
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_client_method);
#endif
#endif /* WOLFSSL_TLS13 */
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_client_method);
#endif
#ifdef WOLFSSL_DTLS
#ifndef NO_OLD_TLS
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_client_method);
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
#ifndef NO_WOLFSSL_SERVER
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_client_method);
#endif
#endif
#endif /* WOLFSSL_DTLS */
#if !defined(NO_OLD_TLS) && defined(OPENSSL_EXTRA)
/* Stubs */
#ifndef NO_WOLFSSL_SERVER
TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_server_method);
#endif
#ifndef NO_WOLFSSL_CLIENT
TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_client_method);
#endif
#endif
/* Test Either Method (client or server) */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_method);
#ifndef NO_OLD_TLS
#ifdef WOLFSSL_ALLOW_TLSV10
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_method);
#endif
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_method);
#endif /* !NO_OLD_TLS */
#ifndef WOLFSSL_NO_TLS12
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_method);
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_TLS13
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_3_method);
#endif /* WOLFSSL_TLS13 */
#ifdef WOLFSSL_DTLS
TEST_VALID_METHOD_ALLOCATOR(wolfDTLS_method);
#ifndef NO_OLD_TLS
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_method);
#endif /* !NO_OLD_TLS */
#ifndef WOLFSSL_NO_TLS12
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_method);
#endif /* !WOLFSSL_NO_TLS12 */
#ifdef WOLFSSL_DTLS13
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_3_method);
#endif /* WOLFSSL_DTLS13 */
#endif /* WOLFSSL_DTLS */
#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
#endif /* !NO_TLS */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_DUAL_ALG_CERTS) && !defined(NO_FILESYSTEM)
/*----------------------------------------------------------------------------*
| Dual algorithm Certificate Tests
*----------------------------------------------------------------------------*/
#define LARGE_TEMP_SZ 4096
/* To better understand this, please see the X9.146 example in wolfssl-examples
* repo. */
static int do_dual_alg_root_certgen(byte **out, char *caKeyFile,
char *sapkiFile, char *altPrivFile)
{
EXPECT_DECLS;
FILE* file = NULL;
Cert newCert;
DecodedCert preTBS;
byte caKeyBuf[LARGE_TEMP_SZ];
word32 caKeySz = LARGE_TEMP_SZ;
byte sapkiBuf[LARGE_TEMP_SZ];
word32 sapkiSz = LARGE_TEMP_SZ;
byte altPrivBuf[LARGE_TEMP_SZ];
word32 altPrivSz = LARGE_TEMP_SZ;
byte altSigAlgBuf[LARGE_TEMP_SZ];
word32 altSigAlgSz = LARGE_TEMP_SZ;
byte scratchBuf[LARGE_TEMP_SZ];
word32 scratchSz = LARGE_TEMP_SZ;
byte preTbsBuf[LARGE_TEMP_SZ];
word32 preTbsSz = LARGE_TEMP_SZ;
byte altSigValBuf[LARGE_TEMP_SZ];
word32 altSigValSz = LARGE_TEMP_SZ;
byte *outBuf = NULL;
word32 outSz = LARGE_TEMP_SZ;
WC_RNG rng;
RsaKey caKey;
ecc_key altCaKey;
word32 idx = 0;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&caKey, 0, sizeof(RsaKey));
XMEMSET(&altCaKey, 0, sizeof(ecc_key));
ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_InitRng(&rng), 0);
XMEMSET(caKeyBuf, 0, caKeySz);
ExpectNotNull(file = fopen(caKeyFile, "rb"));
ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, caKeySz),
0);
XMEMSET(sapkiBuf, 0, sapkiSz);
ExpectNotNull(file = fopen(sapkiFile, "rb"));
ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
XMEMSET(altPrivBuf, 0, altPrivSz);
ExpectNotNull(file = fopen(altPrivFile, "rb"));
ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
wc_ecc_init(&altCaKey);
idx = 0;
ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
(word32)altPrivSz), 0);
XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
oidSigType, 0), 0);
wc_InitCert(&newCert);
strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
strncpy((char*)newCert.beforeDate, "\x18\x0f""20250101000000Z",
CTC_DATE_SIZE);
newCert.beforeDateSz = 17;
strncpy((char*)newCert.afterDate, "\x18\x0f""20493112115959Z",
CTC_DATE_SIZE);
newCert.afterDateSz = 17;
newCert.sigType = CTC_SHA256wRSA;
newCert.isCA = 1;
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "1.2.3.4.5",
(const byte *)"This is NOT a critical extension", 32), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.72", sapkiBuf,
sapkiSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.73", altSigAlgBuf,
altSigAlgSz), 0);
XMEMSET(scratchBuf, 0, scratchSz);
ExpectIntGT(scratchSz = wc_MakeSelfCert(&newCert, scratchBuf, scratchSz,
&caKey, &rng), 0);
wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);
XMEMSET(preTbsBuf, 0, preTbsSz);
ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
XMEMSET(altSigValBuf, 0, altSigValSz);
ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
&rng), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.74", altSigValBuf,
altSigValSz), 0);
/* Finally, generate the new certificate. */
if (outBuf != NULL) {
XMEMSET(outBuf, 0, outSz);
}
ExpectIntGT(outSz = wc_MakeSelfCert(&newCert, outBuf, outSz, &caKey, &rng),
0);
*out = outBuf;
wc_FreeRsaKey(&caKey);
wc_FreeRng(&rng);
wc_FreeDecodedCert(&preTBS);
return outSz;
}
static int do_dual_alg_server_certgen(byte **out, char *caKeyFile,
char *sapkiFile, char *altPrivFile,
char *serverKeyFile,
byte *caCertBuf, int caCertSz)
{
EXPECT_DECLS;
FILE* file = NULL;
Cert newCert;
DecodedCert preTBS;
byte serverKeyBuf[LARGE_TEMP_SZ];
word32 serverKeySz = LARGE_TEMP_SZ;
byte caKeyBuf[LARGE_TEMP_SZ];
word32 caKeySz = LARGE_TEMP_SZ;
byte sapkiBuf[LARGE_TEMP_SZ];
word32 sapkiSz = LARGE_TEMP_SZ;
byte altPrivBuf[LARGE_TEMP_SZ];
word32 altPrivSz = LARGE_TEMP_SZ;
byte altSigAlgBuf[LARGE_TEMP_SZ];
word32 altSigAlgSz = LARGE_TEMP_SZ;
byte scratchBuf[LARGE_TEMP_SZ];
word32 scratchSz = LARGE_TEMP_SZ;
byte preTbsBuf[LARGE_TEMP_SZ];
word32 preTbsSz = LARGE_TEMP_SZ;
byte altSigValBuf[LARGE_TEMP_SZ];
word32 altSigValSz = LARGE_TEMP_SZ;
byte *outBuf = NULL;
word32 outSz = LARGE_TEMP_SZ;
WC_RNG rng;
RsaKey caKey;
RsaKey serverKey;
ecc_key altCaKey;
word32 idx = 0;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&caKey, 0, sizeof(RsaKey));
XMEMSET(&serverKey, 0, sizeof(RsaKey));
XMEMSET(&altCaKey, 0, sizeof(ecc_key));
ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_InitRng(&rng), 0);
XMEMSET(serverKeyBuf, 0, serverKeySz);
ExpectNotNull(file = fopen(serverKeyFile, "rb"));
ExpectIntGT(serverKeySz = (word32)fread(serverKeyBuf, 1, serverKeySz, file),
0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&serverKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(serverKeyBuf, &idx, &serverKey,
(word32)serverKeySz), 0);
XMEMSET(caKeyBuf, 0, caKeySz);
ExpectNotNull(file = fopen(caKeyFile, "rb"));
ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey,
(word32)caKeySz), 0);
XMEMSET(sapkiBuf, 0, sapkiSz);
ExpectNotNull(file = fopen(sapkiFile, "rb"));
ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
XMEMSET(altPrivBuf, 0, altPrivSz);
ExpectNotNull(file = fopen(altPrivFile, "rb"));
ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
wc_ecc_init(&altCaKey);
idx = 0;
ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
(word32)altPrivSz), 0);
XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
oidSigType, 0), 0);
wc_InitCert(&newCert);
strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "server@wolfssl.com", CTC_NAME_SIZE);
strncpy((char*)newCert.beforeDate, "\x18\x0f""20250101000000Z",
CTC_DATE_SIZE);
newCert.beforeDateSz = 17;
strncpy((char*)newCert.afterDate, "\x18\x0f""20493112115959Z",
CTC_DATE_SIZE);
newCert.afterDateSz = 17;
newCert.sigType = CTC_SHA256wRSA;
newCert.isCA = 0;
ExpectIntEQ(wc_SetIssuerBuffer(&newCert, caCertBuf, caCertSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.72", sapkiBuf,
sapkiSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.73", altSigAlgBuf,
altSigAlgSz), 0);
XMEMSET(scratchBuf, 0, scratchSz);
ExpectIntGT(wc_MakeCert(&newCert, scratchBuf, scratchSz, &serverKey, NULL,
&rng), 0);
ExpectIntGT(scratchSz = wc_SignCert(newCert.bodySz, newCert.sigType,
scratchBuf, scratchSz, &caKey, NULL, &rng), 0);
wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);
XMEMSET(preTbsBuf, 0, preTbsSz);
ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
XMEMSET(altSigValBuf, 0, altSigValSz);
ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
&rng), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "2.5.29.74",
altSigValBuf, altSigValSz), 0);
/* Finally, generate the new certificate. */
if (outBuf != NULL) {
XMEMSET(outBuf, 0, outSz);
}
ExpectIntGT(wc_MakeCert(&newCert, outBuf, outSz, &serverKey, NULL, &rng),
0);
ExpectIntGT(outSz = wc_SignCert(newCert.bodySz, newCert.sigType, outBuf,
outSz, &caKey, NULL, &rng), 0);
*out = outBuf;
wc_FreeRsaKey(&caKey);
wc_FreeRsaKey(&serverKey);
wc_FreeRng(&rng);
wc_FreeDecodedCert(&preTBS);
return outSz;
}
static int do_dual_alg_tls13_connection(byte *caCert, word32 caCertSz,
byte *serverCert, word32 serverCertSz,
byte *serverKey, word32 serverKeySz,
int negative_test)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup_ex(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
caCert, caCertSz, serverCert, serverCertSz,
serverKey, serverKeySz), 0);
if (negative_test) {
ExpectTrue(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL) != 0);
}
else {
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
}
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
/**
* Function to generate a root certificate with dual algorithm support and
* configurable criticality for extensions and path length constraints.
*
* @param out [out] Pointer to store the generated certificate
* @param caKeyFile [in] Path to the CA key file
* @param sapkiFile [in] Path to the subject alternative public key info file
* @param altPrivFile [in] Path to the alternative private key file
* @param setCrit [in] Flag to set criticality of extensions (1=critical, 0=non-critical)
* @param setPathLen [in] Flag to set path length constraint (1=set, 0=don't set)
* @param pathLen [in] Path length value (only used if setPathLen=1)
* @return Size of the generated certificate or negative on error
*/
static int do_dual_alg_root_certgen_crit(byte **out, char *caKeyFile,
char *sapkiFile, char *altPrivFile,
int setCrit, int setPathLen, int pathLen)
{
EXPECT_DECLS;
FILE* file = NULL;
Cert newCert;
DecodedCert preTBS;
byte caKeyBuf[LARGE_TEMP_SZ];
word32 caKeySz = LARGE_TEMP_SZ;
byte sapkiBuf[LARGE_TEMP_SZ];
word32 sapkiSz = LARGE_TEMP_SZ;
byte altPrivBuf[LARGE_TEMP_SZ];
word32 altPrivSz = LARGE_TEMP_SZ;
byte altSigAlgBuf[LARGE_TEMP_SZ];
word32 altSigAlgSz = LARGE_TEMP_SZ;
byte scratchBuf[LARGE_TEMP_SZ];
word32 scratchSz = LARGE_TEMP_SZ;
byte preTbsBuf[LARGE_TEMP_SZ];
word32 preTbsSz = LARGE_TEMP_SZ;
byte altSigValBuf[LARGE_TEMP_SZ];
word32 altSigValSz = LARGE_TEMP_SZ;
byte *outBuf = NULL;
word32 outSz = LARGE_TEMP_SZ;
WC_RNG rng;
RsaKey caKey;
ecc_key altCaKey;
word32 idx = 0;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&caKey, 0, sizeof(RsaKey));
XMEMSET(&altCaKey, 0, sizeof(ecc_key));
ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_InitRng(&rng), 0);
XMEMSET(caKeyBuf, 0, caKeySz);
ExpectNotNull(file = fopen(caKeyFile, "rb"));
ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, caKeySz),
0);
XMEMSET(sapkiBuf, 0, sapkiSz);
ExpectNotNull(file = fopen(sapkiFile, "rb"));
ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
XMEMSET(altPrivBuf, 0, altPrivSz);
ExpectNotNull(file = fopen(altPrivFile, "rb"));
ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
wc_ecc_init(&altCaKey);
idx = 0;
ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
(word32)altPrivSz), 0);
XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
oidSigType, 0), 0);
wc_InitCert(&newCert);
strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
strncpy((char*)newCert.beforeDate, "\x18\x0f""20250101000000Z",
CTC_DATE_SIZE);
newCert.beforeDateSz = 17;
strncpy((char*)newCert.afterDate, "\x18\x0f""20493112115959Z",
CTC_DATE_SIZE);
newCert.afterDateSz = 17;
newCert.sigType = CTC_SHA256wRSA;
newCert.isCA = 1;
/* Set criticality of basic constraint extension if requested */
if (setCrit) {
newCert.basicConstCrit = 1;
}
/* Set pathlen if requested */
if (setPathLen) {
newCert.pathLen = pathLen;
newCert.pathLenSet = 1;
}
ExpectIntEQ(wc_SetCustomExtension(&newCert, 0, "1.2.3.4.5",
(const byte *)"This is NOT a critical extension", 32), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.72", sapkiBuf,
sapkiSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.73",
altSigAlgBuf, altSigAlgSz), 0);
XMEMSET(scratchBuf, 0, scratchSz);
ExpectIntGT(scratchSz = wc_MakeSelfCert(&newCert, scratchBuf, scratchSz,
&caKey, &rng), 0);
wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);
XMEMSET(preTbsBuf, 0, preTbsSz);
ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
XMEMSET(altSigValBuf, 0, altSigValSz);
ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
&rng), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.74",
altSigValBuf, altSigValSz), 0);
/* Finally, generate the new certificate. */
if (outBuf != NULL) {
XMEMSET(outBuf, 0, outSz);
ExpectIntGT(outSz = wc_MakeSelfCert(&newCert, outBuf, outSz, &caKey,
&rng), 0);
*out = outBuf;
}
else {
outSz = 0;
}
wc_FreeDecodedCert(&preTBS);
wc_ecc_free(&altCaKey);
wc_FreeRsaKey(&caKey);
wc_FreeRng(&rng);
return (int)outSz;
}
/**
* Function to generate a server certificate with dual algorithm support and
* configurable criticality for extensions and path length constraints.
*
* @param out [out] Pointer to store the generated certificate
* @param caKeyFile [in] Path to the CA key file
* @param sapkiFile [in] Path to the subject alternative public key info file
* @param altPrivFile [in] Path to the alternative private key file
* @param serverKeyFile [in] Path to the server key file
* @param caCertBuf [in] Buffer containing the CA certificate
* @param caCertSz [in] Size of the CA certificate buffer
* @param setCrit [in] Flag to set criticality of extensions (1=critical, 0=non-critical)
* @param setPathLen [in] Flag to set path length constraint (1=set, 0=don't set)
* @param pathLen [in] Path length value (only used if setPathLen=1)
* @return Size of the generated certificate or negative on error
*/
static int do_dual_alg_server_certgen_crit(byte **out, char *caKeyFile,
char *sapkiFile, char *altPrivFile,
char *serverKeyFile,
byte *caCertBuf, int caCertSz,
int setCrit)
{
EXPECT_DECLS;
FILE* file = NULL;
Cert newCert;
DecodedCert preTBS;
byte serverKeyBuf[LARGE_TEMP_SZ];
word32 serverKeySz = LARGE_TEMP_SZ;
byte caKeyBuf[LARGE_TEMP_SZ];
word32 caKeySz = LARGE_TEMP_SZ;
byte sapkiBuf[LARGE_TEMP_SZ];
word32 sapkiSz = LARGE_TEMP_SZ;
byte altPrivBuf[LARGE_TEMP_SZ];
word32 altPrivSz = LARGE_TEMP_SZ;
byte altSigAlgBuf[LARGE_TEMP_SZ];
word32 altSigAlgSz = LARGE_TEMP_SZ;
byte scratchBuf[LARGE_TEMP_SZ];
word32 scratchSz = LARGE_TEMP_SZ;
byte preTbsBuf[LARGE_TEMP_SZ];
word32 preTbsSz = LARGE_TEMP_SZ;
byte altSigValBuf[LARGE_TEMP_SZ];
word32 altSigValSz = LARGE_TEMP_SZ;
byte *outBuf = NULL;
word32 outSz = LARGE_TEMP_SZ;
WC_RNG rng;
RsaKey caKey;
RsaKey serverKey;
ecc_key altCaKey;
word32 idx = 0;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&caKey, 0, sizeof(RsaKey));
XMEMSET(&serverKey, 0, sizeof(RsaKey));
XMEMSET(&altCaKey, 0, sizeof(ecc_key));
ExpectNotNull(outBuf = (byte*)XMALLOC(outSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_InitRng(&rng), 0);
XMEMSET(serverKeyBuf, 0, serverKeySz);
ExpectNotNull(file = fopen(serverKeyFile, "rb"));
ExpectIntGT(serverKeySz = (word32)fread(serverKeyBuf, 1, serverKeySz, file),
0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&serverKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(serverKeyBuf, &idx, &serverKey,
serverKeySz), 0);
XMEMSET(caKeyBuf, 0, caKeySz);
ExpectNotNull(file = fopen(caKeyFile, "rb"));
ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0);
idx = 0;
ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, caKeySz), 0);
XMEMSET(sapkiBuf, 0, sapkiSz);
ExpectNotNull(file = fopen(sapkiFile, "rb"));
ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
XMEMSET(altPrivBuf, 0, altPrivSz);
ExpectNotNull(file = fopen(altPrivFile, "rb"));
ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0);
if (file) {
fclose(file);
file = NULL;
}
wc_ecc_init(&altCaKey);
idx = 0;
ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey,
(word32)altPrivSz), 0);
XMEMSET(altSigAlgBuf, 0, altSigAlgSz);
ExpectIntGT(altSigAlgSz = SetAlgoID(CTC_SHA256wECDSA, altSigAlgBuf,
oidSigType, 0), 0);
wc_InitCert(&newCert);
strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(newCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(newCert.subject.unit, "Engineering", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "server@wolfssl.com", CTC_NAME_SIZE);
strncpy((char*)newCert.beforeDate, "\x18\x0f""20250101000000Z",
CTC_DATE_SIZE);
newCert.beforeDateSz = 17;
strncpy((char*)newCert.afterDate, "\x18\x0f""20493112115959Z",
CTC_DATE_SIZE);
newCert.afterDateSz = 17;
newCert.sigType = CTC_SHA256wRSA;
newCert.isCA = 0;
ExpectIntEQ(wc_SetIssuerBuffer(&newCert, caCertBuf, caCertSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.72", sapkiBuf,
sapkiSz), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.73",
altSigAlgBuf, altSigAlgSz), 0);
XMEMSET(scratchBuf, 0, scratchSz);
ExpectIntGT(wc_MakeCert(&newCert, scratchBuf, scratchSz, &serverKey, NULL,
&rng), 0);
ExpectIntGT(scratchSz = wc_SignCert(newCert.bodySz, newCert.sigType,
scratchBuf, scratchSz, &caKey, NULL, &rng), 0);
wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0);
ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0);
XMEMSET(preTbsBuf, 0, preTbsSz);
ExpectIntGT(preTbsSz = wc_GeneratePreTBS(&preTBS, preTbsBuf, preTbsSz), 0);
XMEMSET(altSigValBuf, 0, altSigValSz);
ExpectIntGT(altSigValSz = wc_MakeSigWithBitStr(altSigValBuf, altSigValSz,
CTC_SHA256wECDSA, preTbsBuf, preTbsSz, ECC_TYPE, &altCaKey,
&rng), 0);
ExpectIntEQ(wc_SetCustomExtension(&newCert, setCrit, "2.5.29.74",
altSigValBuf, altSigValSz), 0);
/* Finally, generate the new certificate. */
if (outBuf != NULL) {
XMEMSET(outBuf, 0, outSz);
ExpectIntGT(outSz = wc_SignCert(newCert.bodySz, newCert.sigType, scratchBuf,
outSz, &caKey, NULL, &rng), 0);
*out = outBuf;
}
else {
outSz = 0;
}
wc_FreeDecodedCert(&preTBS);
wc_ecc_free(&altCaKey);
wc_FreeRsaKey(&serverKey);
wc_FreeRsaKey(&caKey);
wc_FreeRng(&rng);
return (int)outSz;
}
/**
* Test dual-alg ECDSA + ML-DSA with critical extensions and path length
* constraints:
* - keygen + certgen
*
* TLS tests not designed to pass with these extensions marked critical. No
* TLS connection.
* */
static int test_dual_alg_crit_ext_support(void)
{
EXPECT_DECLS;
/* Root CA and server keys will be the same. This is only appropriate for
* testing. */
char keyFile[] = "./certs/ca-key.der";
char sapkiFile[] = "./certs/ecc-keyPub.der";
char altPrivFile[] = "./certs/ecc-key.der";
byte *serverKey = NULL;
size_t serverKeySz = 0;
byte *root = NULL;
int rootSz = 0;
byte *server = NULL;
int serverSz = 0;
ExpectIntEQ(load_file(keyFile, &serverKey, &serverKeySz), 0);
/* Test with critical extensions and pathlen set to 1 */
if (EXPECT_SUCCESS()) {
rootSz = do_dual_alg_root_certgen_crit(&root, keyFile, sapkiFile,
altPrivFile, 1, 1, 1);
}
ExpectNotNull(root);
ExpectIntGT(rootSz, 0);
if (EXPECT_SUCCESS()) {
serverSz = do_dual_alg_server_certgen_crit(&server, keyFile, sapkiFile,
altPrivFile, keyFile, root, rootSz, 1);
}
ExpectNotNull(server);
ExpectIntGT(serverSz, 0);
XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
root = NULL;
XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
server = NULL;
/* Test with critical extensions and pathlen set to 0 */
if (EXPECT_SUCCESS()) {
rootSz = do_dual_alg_root_certgen_crit(&root, keyFile, sapkiFile,
altPrivFile, 1, 1, 0);
}
ExpectNotNull(root);
ExpectIntGT(rootSz, 0);
if (EXPECT_SUCCESS()) {
serverSz = do_dual_alg_server_certgen_crit(&server, keyFile, sapkiFile,
altPrivFile, keyFile, root, rootSz, 1);
}
ExpectNotNull(server);
ExpectIntGT(serverSz, 0);
XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
root = NULL;
XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
server = NULL;
/* Test with critical alt extensions and no pathlen set */
if (EXPECT_SUCCESS()) {
rootSz = do_dual_alg_root_certgen_crit(&root, keyFile, sapkiFile,
altPrivFile, 1, 0, 0);
}
ExpectNotNull(root);
ExpectIntGT(rootSz, 0);
if (EXPECT_SUCCESS()) {
serverSz = do_dual_alg_server_certgen_crit(&server, keyFile, sapkiFile,
altPrivFile, keyFile, root, rootSz, 0);
}
ExpectNotNull(server);
ExpectIntGT(serverSz, 0);
XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
free(serverKey);
return EXPECT_RESULT();
}
static int test_dual_alg_support(void)
{
EXPECT_DECLS;
/* Root CA and server keys will be the same. This is only appropriate for
* testing. */
char keyFile[] = "./certs/ca-key.der";
char sapkiFile[] = "./certs/ecc-keyPub.der";
char altPrivFile[] = "./certs/ecc-key.der";
char wrongPrivFile[] = "./certs/ecc-client-key.der";
byte *serverKey = NULL;
size_t serverKeySz = 0;
byte *root = NULL;
int rootSz = 0;
byte *server = NULL;
int serverSz = 0;
ExpectIntEQ(load_file(keyFile, &serverKey, &serverKeySz), 0);
/* Base normal case. */
if (EXPECT_SUCCESS()) {
rootSz = do_dual_alg_root_certgen(&root, keyFile, sapkiFile,
altPrivFile);
}
ExpectNotNull(root);
ExpectIntGT(rootSz, 0);
if (EXPECT_SUCCESS()) {
serverSz = do_dual_alg_server_certgen(&server, keyFile, sapkiFile,
altPrivFile, keyFile, root, rootSz);
}
ExpectNotNull(server);
ExpectIntGT(serverSz, 0);
ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
server, serverSz, serverKey, (word32)serverKeySz, 0),
TEST_SUCCESS);
XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
root = NULL;
XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
server = NULL;
/* Now we try a negative case. Note that we use wrongPrivFile to generate
* the alternative signature and then set negative_test to true for the
* call to do_dual_alg_tls13_connection(). Its expecting a failed connection
* because the signature won't verify. The exception is if
* WOLFSSL_TRUST_PEER_CERT is defined. In that case, no verification happens
* and this is no longer a negative test. */
if (EXPECT_SUCCESS()) {
rootSz = do_dual_alg_root_certgen(&root, keyFile, sapkiFile,
wrongPrivFile);
}
ExpectNotNull(root);
ExpectIntGT(rootSz, 0);
if (EXPECT_SUCCESS()) {
serverSz = do_dual_alg_server_certgen(&server, keyFile, sapkiFile,
wrongPrivFile, keyFile, root, rootSz);
}
ExpectNotNull(server);
ExpectIntGT(serverSz, 0);
#ifdef WOLFSSL_TRUST_PEER_CERT
ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
server, serverSz, serverKey, (word32)serverKeySz, 0),
TEST_SUCCESS);
#else
ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz,
server, serverSz, serverKey, (word32)serverKeySz, 1),
TEST_SUCCESS);
#endif
XFREE(root, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(server, NULL, DYNAMIC_TYPE_TMP_BUFFER);
free(serverKey);
return EXPECT_RESULT();
}
#else
static int test_dual_alg_support(void)
{
return TEST_SKIPPED;
}
static int test_dual_alg_crit_ext_support(void)
{
return TEST_SKIPPED;
}
#endif /* WOLFSSL_DUAL_ALG_CERTS && !NO_FILESYSTEM */
/**
* Test dual-alg ECDSA + ML-DSA:
* - keygen + certgen + cert manager load
* */
static int test_dual_alg_ecdsa_mldsa(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DUAL_ALG_CERTS) && defined(HAVE_DILITHIUM) && \
defined(HAVE_ECC) && !defined(WC_NO_RNG) && \
defined(WOLFSSL_WC_DILITHIUM) && \
!defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
!defined(WOLFSSL_DILITHIUM_NO_SIGN) && \
!defined(WOLFSSL_DILITHIUM_NO_VERIFY) && !defined(WOLFSSL_SMALL_STACK)
WOLFSSL_CERT_MANAGER * cm = NULL;
MlDsaKey alt_ca_key;
ecc_key ca_key;
WC_RNG rng;
int ret = 0;
DecodedCert d_cert;
Cert new_cert;
/* various tmp buffs. */
byte alt_pub_der[LARGE_TEMP_SZ];
word32 alt_pub_sz = LARGE_TEMP_SZ;
byte alt_sig_alg[LARGE_TEMP_SZ];
word32 alt_sig_alg_sz = LARGE_TEMP_SZ;
byte tbs_der[LARGE_TEMP_SZ];
word32 tbs_der_sz = LARGE_TEMP_SZ;
byte alt_sig[LARGE_TEMP_SZ];
word32 alt_sig_sz = LARGE_TEMP_SZ;
/* Intermediate der. */
byte der[LARGE_TEMP_SZ];
word32 der_sz = LARGE_TEMP_SZ;
/* The final der will be large because of ML-DSA signature. */
byte final_der[2 * LARGE_TEMP_SZ];
word32 final_der_sz = 2 * LARGE_TEMP_SZ;
XMEMSET(alt_pub_der, 0, alt_pub_sz);
XMEMSET(alt_sig_alg, 0, alt_sig_alg_sz);
XMEMSET(tbs_der, 0, tbs_der_sz);
XMEMSET(alt_sig, 0, alt_sig_sz);
XMEMSET(der, 0, der_sz);
XMEMSET(final_der, 0, final_der_sz);
ExpectIntEQ(wc_InitRng(&rng), 0);
/**
* ML-DSA key gen.
* */
ret = wc_MlDsaKey_Init(&alt_ca_key, NULL, INVALID_DEVID);
ExpectIntEQ(ret, 0);
ret = wc_MlDsaKey_SetParams(&alt_ca_key, WC_ML_DSA_44);
ExpectIntEQ(ret, 0);
ret = wc_MlDsaKey_MakeKey(&alt_ca_key, &rng);
ExpectIntEQ(ret, 0);
alt_pub_sz = wc_MlDsaKey_PublicKeyToDer(&alt_ca_key, alt_pub_der,
alt_pub_sz, 1);
ExpectIntGT(alt_pub_sz, 0);
alt_sig_alg_sz = SetAlgoID(CTC_SHA256wECDSA, alt_sig_alg, oidSigType, 0);
ExpectIntGT(alt_sig_alg_sz, 0);
/**
* ECC key gen.
* */
ret = wc_ecc_init(&ca_key);
ExpectIntEQ(ret, 0);
ret = wc_ecc_make_key(&rng, KEY32, &ca_key);
ExpectIntEQ(ret, 0);
/**
* Cert gen.
* */
wc_InitCert(&new_cert);
strncpy(new_cert.subject.country, "US", CTC_NAME_SIZE);
strncpy(new_cert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(new_cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(new_cert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(new_cert.subject.unit, "Engineering", CTC_NAME_SIZE);
strncpy(new_cert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(new_cert.subject.email, "root@wolfssl.com", CTC_NAME_SIZE);
new_cert.sigType = CTC_SHA256wECDSA;
new_cert.isCA = 1;
ret = wc_SetCustomExtension(&new_cert, 0, "1.2.3.4.5",
(const byte *)"This is NOT a critical extension", 32);
ExpectIntEQ(ret, 0);
ExpectIntEQ(wc_SetCustomExtension(&new_cert, 0, "2.5.29.72", alt_pub_der,
alt_pub_sz), 0);
ExpectIntEQ(wc_SetCustomExtension(&new_cert, 0, "2.5.29.73", alt_sig_alg,
alt_sig_alg_sz), 0);
ret = wc_MakeCert_ex(&new_cert, der, der_sz, ECC_TYPE, &ca_key, &rng);
ExpectIntGT(ret, 0);
der_sz = wc_SignCert_ex(new_cert.bodySz, new_cert.sigType, der, der_sz,
ECC_TYPE, &ca_key, &rng);
ExpectIntGT(der_sz, 0);
wc_InitDecodedCert(&d_cert, der, der_sz, 0);
ret = wc_ParseCert(&d_cert, CERT_TYPE, NO_VERIFY, NULL);
ExpectIntEQ(ret, 0);
tbs_der_sz = wc_GeneratePreTBS(&d_cert, tbs_der, tbs_der_sz);
ExpectIntGT(tbs_der_sz, 0);
alt_sig_sz = wc_MakeSigWithBitStr(alt_sig, alt_sig_sz,
CTC_ML_DSA_LEVEL2, tbs_der, tbs_der_sz,
ML_DSA_LEVEL2_TYPE, &alt_ca_key, &rng);
ExpectIntGT(alt_sig_sz, 0);
ret = wc_SetCustomExtension(&new_cert, 0, "2.5.29.74", alt_sig, alt_sig_sz);
ExpectIntEQ(ret, 0);
/* Finally generate the new certificate. */
ret = wc_MakeCert_ex(&new_cert, final_der, final_der_sz, ECC_TYPE, &ca_key,
&rng);
ExpectIntGT(ret, 0);
final_der_sz = wc_SignCert_ex(new_cert.bodySz, new_cert.sigType, final_der,
final_der_sz, ECC_TYPE, &ca_key, &rng);
ExpectIntGT(final_der_sz, 0);
cm = wolfSSL_CertManagerNew();
ExpectNotNull(cm);
/* Load the certificate into CertManager. */
if (cm != NULL && final_der_sz > 0) {
ret = wolfSSL_CertManagerLoadCABuffer(cm, final_der, final_der_sz,
WOLFSSL_FILETYPE_ASN1);
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
}
if (cm != NULL) {
wolfSSL_CertManagerFree(cm);
cm = NULL;
}
wc_FreeDecodedCert(&d_cert);
wc_ecc_free(&ca_key);
wc_MlDsaKey_Free(&alt_ca_key);
wc_FreeRng(&rng);
#endif /* WOLFSSL_DUAL_ALG_CERTS && DILITHIUM and more */
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Context
*----------------------------------------------------------------------------*/
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
static int test_wolfSSL_CTX_new(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx;
WOLFSSL_METHOD* method = NULL;
ExpectNull(ctx = wolfSSL_CTX_new(NULL));
ExpectNotNull(method = wolfSSLv23_server_method());
if (method != NULL)
ExpectNotNull(ctx = wolfSSL_CTX_new(method));
wolfSSL_CTX_free(ctx);
return EXPECT_RESULT();
}
#endif
#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_TLS) && \
(!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM)
static int test_for_double_Free(void)
{
EXPECT_DECLS;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
int skipTest = 0;
const char* testCertFile;
const char* testKeyFile;
char optionsCiphers[] = "RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA"
":NULL-SHA:NULL-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-PSK-AES256-GCM"
"-SHA384:DHE-PSK-AES128-GCM-SHA256:PSK-AES256-GCM-SHA384:PSK-AES128-GCM-SHA256:"
"DHE-PSK-AES256-CBC-SHA384:DHE-PSK-AES128-CBC-SHA256:PSK-AES256-CBC-SHA384:PSK-"
"AES128-CBC-SHA256:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:DHE-PSK-AES128-CCM:DHE"
"-PSK-AES256-CCM:PSK-AES128-CCM:PSK-AES256-CCM:PSK-AES128-CCM-8:PSK-AES256-CCM-"
"8:DHE-PSK-NULL-SHA384:DHE-PSK-NULL-SHA256:PSK-NULL-SHA384:PSK-NULL-SHA256:PSK-"
"NULL-SHA:AES128-CCM-8:AES256-CCM-8:ECDHE-ECDSA-"
"AES128-CCM:ECDHE-ECDSA-AES128-CCM-8:ECDHE-ECDSA-AES256-CCM-8:ECDHE-RSA-AES128-"
"SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-R"
"SA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA"
":AES128-SHA256:AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-"
"RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA"
":ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3"
"-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES"
"256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-E"
"CDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA25"
"6:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GC"
"M-SHA384:CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:CAMELLIA256-SHA:DHE-RSA-CAMEL"
"LIA256-SHA:CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:CAMELLIA256-SHA256:DH"
"E-RSA-CAMELLIA256-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECD"
"H-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECD"
"SA-AES256-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDHE-RSA-CHA"
"CHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-R"
"SA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-PO"
"LY1305-OLD:ECDHE-ECDSA-NULL-SHA:ECDHE-PSK-NULL-SHA256:ECDHE-PSK-A"
"ES128-CBC-SHA256:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHA"
"CHA20-POLY1305:EDH-RSA-DES-CBC3-SHA:TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-S"
"HA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-CCM-SHA256:TLS13-AES128-CCM-"
"8-SHA256:TLS13-SHA256-SHA256:TLS13-SHA384-SHA384";
/* OpenVPN uses a "blacklist" method to specify which ciphers NOT to use */
#ifdef OPENSSL_EXTRA
char openvpnCiphers[] = "DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:"
"!SRP:!kRSA:!aNULL:!eNULL";
#endif
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#else
skipTest = 1;
#endif
if (skipTest != 1) {
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* First test freeing SSL, then CTX */
wolfSSL_free(ssl);
ssl = NULL;
wolfSSL_CTX_free(ctx);
ctx = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Next test freeing CTX then SSL */
wolfSSL_CTX_free(ctx);
ctx = NULL;
wolfSSL_free(ssl);
ssl = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
/* Test setting ciphers at ctx level */
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, optionsCiphers));
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && defined(HAVE_AESGCM) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
/* only update TLSv13 suites */
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384"));
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(HAVE_AESGCM) && \
!defined(NO_SHA256) && !defined(WOLFSSL_NO_TLS12) && \
defined(WOLFSSL_AES_128) && !defined(NO_RSA)
/* only update pre-TLSv13 suites */
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx,
"ECDHE-RSA-AES128-GCM-SHA256"));
#endif
#ifdef OPENSSL_EXTRA
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, openvpnCiphers));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
wolfSSL_CTX_free(ctx);
ctx = NULL;
wolfSSL_free(ssl);
ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* test setting ciphers at SSL level */
ExpectTrue(wolfSSL_set_cipher_list(ssl, optionsCiphers));
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && defined(HAVE_AESGCM) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
/* only update TLSv13 suites */
ExpectTrue(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384"));
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(HAVE_AESGCM) && \
!defined(NO_SHA256) && !defined(WOLFSSL_NO_TLS12) && \
defined(WOLFSSL_AES_128) && !defined(NO_RSA)
/* only update pre-TLSv13 suites */
ExpectTrue(wolfSSL_set_cipher_list(ssl, "ECDHE-RSA-AES128-GCM-SHA256"));
#endif
wolfSSL_CTX_free(ctx);
ctx = NULL;
wolfSSL_free(ssl);
ssl = NULL;
}
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_CTX_set_cipher_list_bytes(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
(!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM) && \
!defined(NO_TLS)
const char* testCertFile;
const char* testKeyFile;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
const byte cipherList[] =
{
/* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ 0x00, 0x16,
/* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ 0x00, 0x39,
/* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ 0x00, 0x33,
/* TLS_DH_anon_WITH_AES_128_CBC_SHA */ 0x00, 0x34,
/* TLS_RSA_WITH_AES_256_CBC_SHA */ 0x00, 0x35,
/* TLS_RSA_WITH_AES_128_CBC_SHA */ 0x00, 0x2F,
/* TLS_RSA_WITH_NULL_MD5 */ 0x00, 0x01,
/* TLS_RSA_WITH_NULL_SHA */ 0x00, 0x02,
/* TLS_PSK_WITH_AES_256_CBC_SHA */ 0x00, 0x8d,
/* TLS_PSK_WITH_AES_128_CBC_SHA256 */ 0x00, 0xae,
/* TLS_PSK_WITH_AES_256_CBC_SHA384 */ 0x00, 0xaf,
/* TLS_PSK_WITH_AES_128_CBC_SHA */ 0x00, 0x8c,
/* TLS_PSK_WITH_NULL_SHA256 */ 0x00, 0xb0,
/* TLS_PSK_WITH_NULL_SHA384 */ 0x00, 0xb1,
/* TLS_PSK_WITH_NULL_SHA */ 0x00, 0x2c,
/* SSL_RSA_WITH_RC4_128_SHA */ 0x00, 0x05,
/* SSL_RSA_WITH_RC4_128_MD5 */ 0x00, 0x04,
/* SSL_RSA_WITH_3DES_EDE_CBC_SHA */ 0x00, 0x0A,
/* ECC suites, first byte is 0xC0 (ECC_BYTE) */
/* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ 0xC0, 0x14,
/* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */ 0xC0, 0x13,
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */ 0xC0, 0x0A,
/* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */ 0xC0, 0x09,
/* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ 0xC0, 0x11,
/* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */ 0xC0, 0x07,
/* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */ 0xC0, 0x12,
/* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */ 0xC0, 0x08,
/* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */ 0xC0, 0x27,
/* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256*/ 0xC0, 0x23,
/* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */ 0xC0, 0x28,
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384*/ 0xC0, 0x24,
/* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ 0xC0, 0x06,
/* TLS_ECDHE_PSK_WITH_NULL_SHA256 */ 0xC0, 0x3a,
/* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */ 0xC0, 0x37,
/* static ECDH, first byte is 0xC0 (ECC_BYTE) */
/* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */ 0xC0, 0x0F,
/* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */ 0xC0, 0x0E,
/* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */ 0xC0, 0x05,
/* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */ 0xC0, 0x04,
/* TLS_ECDH_RSA_WITH_RC4_128_SHA */ 0xC0, 0x0C,
/* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ 0xC0, 0x02,
/* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */ 0xC0, 0x0D,
/* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */ 0xC0, 0x03,
/* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */ 0xC0, 0x29,
/* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */ 0xC0, 0x25,
/* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */ 0xC0, 0x2A,
/* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */ 0xC0, 0x26,
/* WDM_WITH_NULL_SHA256 */ 0x00, 0xFE, /* wolfSSL DTLS Multicast */
/* SHA256 */
/* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ 0x00, 0x6b,
/* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ 0x00, 0x67,
/* TLS_RSA_WITH_AES_256_CBC_SHA256 */ 0x00, 0x3d,
/* TLS_RSA_WITH_AES_128_CBC_SHA256 */ 0x00, 0x3c,
/* TLS_RSA_WITH_NULL_SHA256 */ 0x00, 0x3b,
/* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */ 0x00, 0xb2,
/* TLS_DHE_PSK_WITH_NULL_SHA256 */ 0x00, 0xb4,
/* SHA384 */
/* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */ 0x00, 0xb3,
/* TLS_DHE_PSK_WITH_NULL_SHA384 */ 0x00, 0xb5,
/* AES-GCM */
/* TLS_RSA_WITH_AES_128_GCM_SHA256 */ 0x00, 0x9c,
/* TLS_RSA_WITH_AES_256_GCM_SHA384 */ 0x00, 0x9d,
/* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */ 0x00, 0x9e,
/* TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ 0x00, 0x9f,
/* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ 0x00, 0xa7,
/* TLS_PSK_WITH_AES_128_GCM_SHA256 */ 0x00, 0xa8,
/* TLS_PSK_WITH_AES_256_GCM_SHA384 */ 0x00, 0xa9,
/* TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 */ 0x00, 0xaa,
/* TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 */ 0x00, 0xab,
/* ECC AES-GCM, first byte is 0xC0 (ECC_BYTE) */
/* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */ 0xC0, 0x2b,
/* TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 */ 0xC0, 0x2c,
/* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */ 0xC0, 0x2d,
/* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */ 0xC0, 0x2e,
/* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */ 0xC0, 0x2f,
/* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 */ 0xC0, 0x30,
/* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */ 0xC0, 0x31,
/* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */ 0xC0, 0x32,
/* AES-CCM, first byte is 0xC0 but isn't ECC,
* also, in some of the other AES-CCM suites
* there will be second byte number conflicts
* with non-ECC AES-GCM */
/* TLS_RSA_WITH_AES_128_CCM_8 */ 0xC0, 0xa0,
/* TLS_RSA_WITH_AES_256_CCM_8 */ 0xC0, 0xa1,
/* TLS_ECDHE_ECDSA_WITH_AES_128_CCM */ 0xC0, 0xac,
/* TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ 0xC0, 0xae,
/* TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 */ 0xC0, 0xaf,
/* TLS_PSK_WITH_AES_128_CCM */ 0xC0, 0xa4,
/* TLS_PSK_WITH_AES_256_CCM */ 0xC0, 0xa5,
/* TLS_PSK_WITH_AES_128_CCM_8 */ 0xC0, 0xa8,
/* TLS_PSK_WITH_AES_256_CCM_8 */ 0xC0, 0xa9,
/* TLS_DHE_PSK_WITH_AES_128_CCM */ 0xC0, 0xa6,
/* TLS_DHE_PSK_WITH_AES_256_CCM */ 0xC0, 0xa7,
/* Camellia */
/* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */ 0x00, 0x41,
/* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */ 0x00, 0x84,
/* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ 0x00, 0xba,
/* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ 0x00, 0xc0,
/* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */ 0x00, 0x45,
/* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */ 0x00, 0x88,
/* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ 0x00, 0xbe,
/* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ 0x00, 0xc4,
/* chacha20-poly1305 suites first byte is 0xCC (CHACHA_BYTE) */
/* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xa8,
/* TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xa9,
/* TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xaa,
/* TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xac,
/* TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xab,
/* TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 */ 0xCC, 0xad,
/* chacha20-poly1305 earlier version of nonce and padding (CHACHA_BYTE) */
/* TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 */ 0xCC, 0x13,
/* TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 */ 0xCC, 0x14,
/* TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 */ 0xCC, 0x15,
/* ECDHE_PSK RFC8442, first byte is 0xD0 (ECDHE_PSK_BYTE) */
/* TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 */ 0xD0, 0x01,
/* TLS v1.3 cipher suites */
/* TLS_AES_128_GCM_SHA256 */ 0x13, 0x01,
/* TLS_AES_256_GCM_SHA384 */ 0x13, 0x02,
/* TLS_CHACHA20_POLY1305_SHA256 */ 0x13, 0x03,
/* TLS_AES_128_CCM_SHA256 */ 0x13, 0x04,
/* TLS_AES_128_CCM_8_SHA256 */ 0x13, 0x05,
/* TLS v1.3 Integrity only cipher suites - 0xC0 (ECC) first byte */
/* TLS_SHA256_SHA256 */ 0xC0, 0xB4,
/* TLS_SHA384_SHA384 */ 0xC0, 0xB5
};
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#endif
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_set_cipher_list_bytes(ctx, &cipherList[0U],
sizeof(cipherList)));
wolfSSL_CTX_free(ctx);
ctx = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectTrue(wolfSSL_set_cipher_list_bytes(ssl, &cipherList[0U],
sizeof(cipherList)));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* (OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES) &&
(!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) && (!NO_RSA || HAVE_ECC) */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_TLS12) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
/* Helper function to check if TLS 1.3 suites exist in the suites list */
static int suites_has_tls13(const byte* suites, word16 suiteSz)
{
word16 i;
for (i = 0; i < suiteSz; i += 2) {
if (suites[i] == 0x13) { /* TLS13_BYTE */
return 1;
}
}
return 0;
}
/* Helper function to check if TLS 1.2 (non-1.3) suites exist in the suites list */
static int suites_has_tls12(const byte* suites, word16 suiteSz)
{
word16 i;
for (i = 0; i < suiteSz; i += 2) {
if (suites[i] != 0x13) { /* Not TLS13_BYTE */
return 1;
}
}
return 0;
}
#endif
/* Test 1: SSLv23 + set TLS 1.2 cipher -> TLS 1.3 suites should still be there */
static int test_wolfSSL_set_cipher_list_tls12_keeps_tls13(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_TLS12) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
defined(HAVE_ECC)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Set only a TLS 1.2 cipher suite */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ECDHE-RSA-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
/* TLS 1.3 suites should still be present (downgrade is enabled) */
ExpectNotNull(ssl->suites);
ExpectTrue(suites_has_tls13(ssl->suites->suites, ssl->suites->suiteSz));
/* The TLS 1.2 suite we set should also be there */
ExpectTrue(suites_has_tls12(ssl->suites->suites, ssl->suites->suiteSz));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test 2: SSLv23 + set TLS 1.3 cipher -> TLS 1.2 suites should still be there */
static int test_wolfSSL_set_cipher_list_tls13_keeps_tls12(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_TLS12) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Set only a TLS 1.3 cipher suite */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS_AES_128_GCM_SHA256"),
WOLFSSL_SUCCESS);
/* TLS 1.2 suites should still be present (downgrade is enabled) */
ExpectNotNull(ssl->suites);
ExpectTrue(suites_has_tls12(ssl->suites->suites, ssl->suites->suiteSz));
/* The TLS 1.3 suite we set should also be there */
ExpectTrue(suites_has_tls13(ssl->suites->suites, ssl->suites->suiteSz));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test 3: SSLv23 + SetVersion(TLS 1.2) + set TLS 1.2 cipher -> only that cipher */
static int test_wolfSSL_set_cipher_list_tls12_with_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_TLS12) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
defined(HAVE_ECC)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Set protocol version to TLS 1.2 (this disables downgrade) */
ExpectIntEQ(wolfSSL_SetVersion(ssl, WOLFSSL_TLSV1_2), WOLFSSL_SUCCESS);
/* Set only a TLS 1.2 cipher suite */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ECDHE-RSA-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
/* Should have only TLS 1.2 suites (no TLS 1.3) since downgrade is disabled */
ExpectNotNull(ssl->suites);
ExpectFalse(suites_has_tls13(ssl->suites->suites, ssl->suites->suiteSz));
/* Should have the TLS 1.2 suite we set */
ExpectTrue(suites_has_tls12(ssl->suites->suites, ssl->suites->suiteSz));
/* Should have exactly one cipher suite (2 bytes) */
ExpectIntEQ(ssl->suites->suiteSz, 2);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test 4: SSLv23 + SetVersion(TLS 1.3) + set TLS 1.3 cipher -> only that cipher */
static int test_wolfSSL_set_cipher_list_tls13_with_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_TLS12) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Set protocol version to TLS 1.3 (this disables downgrade) */
ExpectIntEQ(wolfSSL_SetVersion(ssl, WOLFSSL_TLSV1_3), WOLFSSL_SUCCESS);
/* Set only a TLS 1.3 cipher suite */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS_AES_128_GCM_SHA256"),
WOLFSSL_SUCCESS);
/* Should have only TLS 1.3 suites (no TLS 1.2) since downgrade is disabled */
ExpectNotNull(ssl->suites);
ExpectFalse(suites_has_tls12(ssl->suites->suites, ssl->suites->suiteSz));
/* Should have the TLS 1.3 suite we set */
ExpectTrue(suites_has_tls13(ssl->suites->suites, ssl->suites->suiteSz));
/* Should have exactly one cipher suite (2 bytes) */
ExpectIntEQ(ssl->suites->suiteSz, 2);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_certificate(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
defined(WOLFSSL_HAPROXY)
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
X509* x509 = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectNotNull(x509 = wolfSSL_X509_new());
/* Negative tests. */
ExpectIntEQ(SSL_CTX_use_certificate(NULL, NULL), 0);
ExpectIntEQ(SSL_CTX_use_certificate(ctx, NULL), 0);
ExpectIntEQ(SSL_CTX_use_certificate(NULL, x509), 0);
/* Empty certificate */
ExpectIntEQ(SSL_CTX_use_certificate(ctx, x509), 0);
wolfSSL_X509_free(x509);
wolfSSL_CTX_free(ctx);
#endif /* !NO_TLS && (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) */
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_certificate_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* invalid context */
ExpectFalse(wolfSSL_CTX_use_certificate_file(NULL, svrCertFile,
CERT_FILETYPE));
/* invalid cert file */
ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, bogusFile,
CERT_FILETYPE));
/* invalid cert type */
ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, 9999));
#ifdef NO_RSA
/* rsa needed */
ExpectFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
#else
/* success */
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
static int test_wolfSSL_CTX_use_certificate_ASN1(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_WOLFSSL_SERVER) && !defined(NO_ASN) && \
!defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* Failure cases. */
ExpectIntEQ(SSL_CTX_use_certificate_ASN1(NULL, 0, NULL ),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx , 0, NULL ),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_certificate_ASN1(NULL, 0, server_cert_der_2048),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx , 0, server_cert_der_2048),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_certificate_ASN1(ctx, sizeof_server_cert_der_2048,
server_cert_der_2048), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#endif /* (OPENSSL_ALL || WOLFSSL_ASIO) && !NO_RSA */
/* Test function for wolfSSL_CTX_use_certificate_buffer. Load cert into
* context using buffer.
* PRE: NO_CERTS not defined; USE_CERT_BUFFERS_2048 defined; compile with
* --enable-testcert flag.
*/
static int test_wolfSSL_CTX_use_certificate_buffer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_WOLFSSL_SERVER) && \
defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
WOLFSSL_CTX* ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* Invalid parameters. */
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(NULL, NULL, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, NULL, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(NULL, server_cert_der_2048,
0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx,
server_cert_der_2048, sizeof_server_cert_der_2048,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
} /* END test_wolfSSL_CTX_use_certificate_buffer */
static int test_wolfSSL_use_certificate_buffer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT) && \
defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Invalid parameters. */
ExpectIntEQ(wolfSSL_use_certificate_buffer(NULL, NULL, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl, NULL, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
ExpectIntEQ(wolfSSL_use_certificate_buffer(NULL, client_cert_der_2048, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl, client_cert_der_2048, 0,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
ExpectIntEQ(wolfSSL_use_certificate_buffer(ssl,
client_cert_der_2048, sizeof_client_cert_der_2048,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_PrivateKey_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* invalid context */
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(NULL, svrKeyFile,
CERT_FILETYPE));
/* invalid key file */
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, bogusFile,
CERT_FILETYPE));
/* invalid key type */
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, 9999));
/* invalid key format */
#ifdef WOLFSSL_PEM_TO_DER
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, "./certs/dh-priv-2048.pem",
WOLFSSL_FILETYPE_PEM));
#else
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, "./certs/dh-priv-2048.der",
WOLFSSL_FILETYPE_ASN1));
#endif
/* success */
#ifdef NO_RSA
/* rsa needed */
ExpectFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
#else
/* success */
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_RSAPrivateKey_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER) && defined(OPENSSL_EXTRA)
WOLFSSL_CTX *ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* invalid context */
ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(NULL, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* invalid key file */
ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, bogusFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* invalid key type */
ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile, 9999),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* success */
#ifdef NO_RSA
/* rsa needed */
ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#else
/* success */
ExpectIntEQ(wolfSSL_CTX_use_RSAPrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_use_RSAPrivateKey_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT) && defined(OPENSSL_EXTRA)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = SSL_new(ctx));
/* invalid context */
ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(NULL, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* invalid key file */
ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, bogusFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* invalid key type */
ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile, 9999),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* success */
#ifdef NO_RSA
/* rsa needed */
ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#else
/* success */
ExpectIntEQ(wolfSSL_use_RSAPrivateKey_file(ssl, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_PrivateKey(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER) && defined(OPENSSL_EXTRA)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL_EVP_PKEY* pkey = NULL;
const unsigned char* p;
(void)p;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* No data. */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#if defined(USE_CERT_BUFFERS_2048)
#if !defined(NO_RSA)
p = client_key_der_2048;
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p,
sizeof_client_key_der_2048));
#if defined(WOLFSSL_KEY_GEN)
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
#ifndef NO_DSA
p = dsa_key_der_2048;
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_DSA, NULL, &p,
sizeof_dsa_key_der_2048));
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
defined(WOLFSSL_CERT_GEN))
/* Not supported in ProcessBuffer. */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
#else
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
#if !defined(NO_DH) && defined(OPENSSL_ALL) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
p = dh_ffdhe_statickey_der_2048;
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_DH, NULL, &p,
sizeof_dh_ffdhe_statickey_der_2048));
/* Not supported. */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#endif /* USE_CERT_BUFFERS_2048 */
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
p = ecc_clikey_der_256;
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &p,
sizeof_ecc_clikey_der_256));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WOLFSSL_SUCCESS);
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
#endif
ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
(unsigned char*)"01234567012345670123456701234567", 32));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(ctx, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* test both file and buffer versions along with unloading trusted peer certs */
static int test_wolfSSL_CTX_trust_peer_cert(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_TRUST_PEER_CERT) && \
!defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL* ssl = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
#if !defined(NO_FILESYSTEM)
/* invalid file */
ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, NULL,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, bogusFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_CTX_trust_peer_cert(ctx, cliCertFile,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* success */
ExpectIntEQ(wolfSSL_CTX_trust_peer_cert(ctx, cliCertFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* unload cert */
ExpectIntNE(wolfSSL_CTX_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_Unload_trust_peers(ctx), WOLFSSL_SUCCESS);
/* invalid file */
ExpectIntNE(wolfSSL_trust_peer_cert(ssl, NULL,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_trust_peer_cert(ssl, bogusFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_trust_peer_cert(ssl, cliCertFile,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* success */
ExpectIntEQ(wolfSSL_trust_peer_cert(ssl, cliCertFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_LOCAL_X509_STORE
/* unload cert */
ExpectIntNE(wolfSSL_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_Unload_trust_peers(ssl), WOLFSSL_SUCCESS);
#endif
#endif
/* Test of loading certs from buffers */
/* invalid buffer */
ExpectIntNE(wolfSSL_CTX_trust_peer_buffer(ctx, NULL, -1,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* success */
#ifdef USE_CERT_BUFFERS_1024
ExpectIntEQ(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_1024,
sizeof_client_cert_der_1024, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
#ifdef USE_CERT_BUFFERS_2048
ExpectIntEQ(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_2048,
sizeof_client_cert_der_2048, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
/* unload cert */
ExpectIntNE(wolfSSL_CTX_Unload_trust_peers(NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_Unload_trust_peers(ctx), WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_load_verify_locations(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX *ctx = NULL;
#ifndef NO_RSA
WOLFSSL_CERT_MANAGER* cm = NULL;
#ifdef PERSIST_CERT_CACHE
int cacheSz = 0;
unsigned char* cache = NULL;
int used = 0;
#ifndef NO_FILESYSTEM
const char* cacheFile = "./tests/cert_cache.tmp";
#endif
int i;
int t;
int* p;
#endif
#endif
#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS) && \
defined(WOLFSSL_PEM_TO_DER)
const char* load_certs_path = "./certs/external";
const char* load_no_certs_path = "./examples";
const char* load_expired_path = "./certs/test/expired";
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
/* invalid arguments */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(NULL, caCertFile, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, NULL, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* invalid ca file */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, bogusFile, NULL),
WS_RETURN_CODE(WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));
#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS) && \
((defined(WOLFSSL_QT) || defined(WOLFSSL_IGNORE_BAD_CERT_PATH)) && \
!(WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR))
/* invalid path */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, NULL, bogusFile),
WS_RETURN_CODE(WC_NO_ERR_TRACE(BAD_PATH_ERROR),WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));
#endif
#if defined(WOLFSSL_QT) || defined(WOLFSSL_IGNORE_BAD_CERT_PATH)
/* test ignoring the invalid path */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, bogusFile,
WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR), WOLFSSL_SUCCESS);
#endif
/* load ca cert */
#ifdef NO_RSA
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
WS_RETURN_CODE(WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E),WC_NO_ERR_TRACE(WOLFSSL_FAILURE)));
#else /* Skip the following test without RSA certs. */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
WOLFSSL_SUCCESS);
#ifdef PERSIST_CERT_CACHE
/* Get cert cache size */
ExpectIntGT(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), 0);
ExpectNotNull(cache = (byte*)XMALLOC((size_t)cacheSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, -1, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, -1, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, cacheSz, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, NULL, -1, &used),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(NULL, cache, cacheSz, &used),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, NULL, cacheSz, &used),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, -1, &used),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz - 10, &used),
WC_NO_ERR_TRACE(BUFFER_E));
ExpectIntEQ(wolfSSL_CTX_memsave_cert_cache(ctx, cache, cacheSz, &used), 1);
ExpectIntEQ(cacheSz, used);
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, -1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, -1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, -1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, NULL, cacheSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(NULL, cache, cacheSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, NULL, cacheSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, -1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Smaller than header. */
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, 1), WC_NO_ERR_TRACE(BUFFER_E));
for (i = 1; i < cacheSz; i++) {
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz - i),
WC_NO_ERR_TRACE(BUFFER_E));
}
if (EXPECT_SUCCESS()) {
/* Modify header for bad results! */
p = (int*)cache;
/* version */
t = p[0]; p[0] = 0xff;
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
p[0] = t; p++;
/* rows */
t = p[0]; p[0] = 0xff;
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
p[0] = t; p++;
/* columns[0] */
t = p[0]; p[0] = -1;
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
WC_NO_ERR_TRACE(PARSE_ERROR));
p[0] = t; p += CA_TABLE_SIZE;
/* signerSz*/
t = p[0]; p[0] = 0xff;
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz),
WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
p[0] = t;
}
ExpectIntEQ(wolfSSL_CTX_memrestore_cert_cache(ctx, cache, cacheSz), 1);
ExpectIntEQ(cacheSz = wolfSSL_CTX_get_cert_cache_memsize(ctx), used);
#ifndef NO_FILESYSTEM
ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_save_cert_cache(NULL, cacheFile), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_save_cert_cache(ctx, cacheFile), 1);
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(NULL, cacheFile), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "no-file"),
WC_NO_ERR_TRACE(WOLFSSL_BAD_FILE));
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, cacheFile), 1);
/* File contents is not a cache. */
ExpectIntEQ(wolfSSL_CTX_restore_cert_cache(ctx, "./certs/ca-cert.pem"),
WC_NO_ERR_TRACE(CACHE_MATCH_ERROR));
#endif
XFREE(cache, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
/* Test unloading CA's */
ExpectIntEQ(wolfSSL_CTX_UnloadCAs(ctx), WOLFSSL_SUCCESS);
#ifdef PERSIST_CERT_CACHE
/* Verify no certs (result is less than cacheSz) */
ExpectIntGT(cacheSz, wolfSSL_CTX_get_cert_cache_memsize(ctx));
#endif
/* load ca cert again */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, NULL),
WOLFSSL_SUCCESS);
/* Test getting CERT_MANAGER */
ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(ctx));
/* Test unloading CA's using CM */
ExpectIntEQ(wolfSSL_CertManagerUnloadCAs(cm), WOLFSSL_SUCCESS);
#ifdef PERSIST_CERT_CACHE
/* Verify no certs (result is less than cacheSz) */
ExpectIntGT(cacheSz, wolfSSL_CTX_get_cert_cache_memsize(ctx));
#endif
#endif
#if !defined(NO_WOLFSSL_DIR) && !defined(WOLFSSL_TIRTOS) && \
defined(WOLFSSL_PEM_TO_DER)
/* Test loading CA certificates using a path */
#ifdef NO_RSA
/* failure here okay since certs in external directory are RSA */
ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
WOLFSSL_LOAD_FLAG_PEM_CA_ONLY), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
WOLFSSL_LOAD_FLAG_PEM_CA_ONLY), WOLFSSL_SUCCESS);
#endif
/* Test loading path with no files */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
load_no_certs_path, WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* Test loading expired CA certificates */
#ifdef NO_RSA
ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
load_expired_path,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY | WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL,
load_expired_path,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY | WOLFSSL_LOAD_FLAG_PEM_CA_ONLY),
WOLFSSL_SUCCESS);
#endif
/* Test loading CA certificates and ignoring all errors */
#ifdef NO_RSA
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
WOLFSSL_LOAD_FLAG_IGNORE_ERR), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#else
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, load_certs_path,
WOLFSSL_LOAD_FLAG_IGNORE_ERR), WOLFSSL_SUCCESS);
#endif
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_load_system_CA_certs(void)
{
int res = TEST_SKIPPED;
#if defined(WOLFSSL_SYS_CA_CERTS) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(NO_TLS) && (!defined(NO_RSA) || defined(HAVE_ECC)) && \
defined(WOLFSSL_PEM_TO_DER)
WOLFSSL_CTX* ctx;
byte dirValid = 0;
int ret = 0;
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
if (ctx == NULL) {
fprintf(stderr, "wolfSSL_CTX_new failed.\n");
ret = -1;
}
if (ret == 0) {
#if defined(USE_WINDOWS_API) || defined(__APPLE__) || \
defined(NO_WOLFSSL_DIR)
dirValid = 1;
#else
word32 numDirs;
const char** caDirs = wolfSSL_get_system_CA_dirs(&numDirs);
if (caDirs == NULL || numDirs == 0) {
fprintf(stderr, "wolfSSL_get_system_CA_dirs failed.\n");
ret = -1;
}
else {
ReadDirCtx dirCtx;
word32 i;
for (i = 0; i < numDirs; ++i) {
if (wc_ReadDirFirst(&dirCtx, caDirs[i], NULL) == 0) {
/* Directory isn't empty. */
dirValid = 1;
wc_ReadDirClose(&dirCtx);
break;
}
}
}
#endif
}
/*
* If the directory isn't empty, we should be able to load CA
* certs from it. On Windows/Mac, we assume the CA cert stores are
* usable.
*/
if (ret == 0 && dirValid && wolfSSL_CTX_load_system_CA_certs(ctx) !=
WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_CTX_load_system_CA_certs failed.\n");
ret = -1;
}
#ifdef OPENSSL_EXTRA
if (ret == 0 &&
wolfSSL_CTX_set_default_verify_paths(ctx) != WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_CTX_set_default_verify_paths failed.\n");
ret = -1;
}
#endif /* OPENSSL_EXTRA */
wolfSSL_CTX_free(ctx);
res = TEST_RES_CHECK(ret == 0);
#endif /* WOLFSSL_SYS_CA_CERTS && !NO_WOLFSSL_CLIENT */
return res;
}
static int test_wolfSSL_CheckOCSPResponse(void)
{
EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && \
!defined(NO_RSA) && !defined(NO_SHA)
const char* responseFile = "./certs/ocsp/test-response.der";
const char* responseMultiFile = "./certs/ocsp/test-multi-response.der";
const char* responseNoInternFile =
"./certs/ocsp/test-response-nointern.der";
const char* caFile = "./certs/ocsp/root-ca-cert.pem";
OcspResponse* res = NULL;
byte data[4096];
const unsigned char* pt;
int dataSz = 0; /* initialize to mitigate spurious maybe-uninitialized from
* gcc sanitizer with --enable-heapmath.
*/
XFILE f = XBADFILE;
WOLFSSL_OCSP_BASICRESP* bs = NULL;
WOLFSSL_X509_STORE* st = NULL;
WOLFSSL_X509* issuer = NULL;
ExpectTrue((f = XFOPEN(responseFile, "rb")) != XBADFILE);
ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
pt = data;
ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));
ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile,
SSL_FILETYPE_PEM));
ExpectNotNull(st = wolfSSL_X509_STORE_new());
ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res));
ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0), WOLFSSL_SUCCESS);
wolfSSL_OCSP_BASICRESP_free(bs);
bs = NULL;
wolfSSL_OCSP_RESPONSE_free(res);
res = NULL;
wolfSSL_X509_STORE_free(st);
st = NULL;
wolfSSL_X509_free(issuer);
issuer = NULL;
/* check loading a response with optional certs */
ExpectTrue((f = XFOPEN(responseNoInternFile, "rb")) != XBADFILE);
ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
f = XBADFILE;
pt = data;
ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));
wolfSSL_OCSP_RESPONSE_free(res);
res = NULL;
/* check loading a response with multiple certs */
{
WOLFSSL_CERT_MANAGER* cm = NULL;
OcspEntry *entry = NULL;
CertStatus* status = NULL;
OcspRequest* request = NULL;
byte serial1[] = {0x01};
byte serial[] = {0x02};
byte issuerHash[] = {
0x44, 0xA8, 0xDB, 0xD1, 0xBC, 0x97, 0x0A, 0x83,
0x3B, 0x5B, 0x31, 0x9A, 0x4C, 0xB8, 0xD2, 0x52,
0x37, 0x15, 0x8A, 0x88
};
byte issuerKeyHash[] = {
0x73, 0xB0, 0x1C, 0xA4, 0x2F, 0x82, 0xCB, 0xCF,
0x47, 0xA5, 0x38, 0xD7, 0xB0, 0x04, 0x82, 0x3A,
0x7E, 0x72, 0x15, 0x21
};
ExpectNotNull(entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL,
DYNAMIC_TYPE_OPENSSL));
ExpectNotNull(status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
DYNAMIC_TYPE_OPENSSL));
if (entry != NULL)
XMEMSET(entry, 0, sizeof(OcspEntry));
if (status != NULL)
XMEMSET(status, 0, sizeof(CertStatus));
ExpectNotNull(request = wolfSSL_OCSP_REQUEST_new());
ExpectNotNull(request->serial = (byte*)XMALLOC(sizeof(serial), NULL,
DYNAMIC_TYPE_OCSP_REQUEST));
if (request != NULL && request->serial != NULL) {
request->serialSz = sizeof(serial);
XMEMCPY(request->serial, serial, sizeof(serial));
XMEMCPY(request->issuerHash, issuerHash, sizeof(issuerHash));
XMEMCPY(request->issuerKeyHash, issuerKeyHash,
sizeof(issuerKeyHash));
}
ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
ExpectIntEQ(wolfSSL_CertManagerEnableOCSP(cm, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caFile, NULL),
WOLFSSL_SUCCESS);
ExpectTrue((f = XFOPEN(responseMultiFile, "rb")) != XBADFILE);
ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
f = XBADFILE;
ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS);
ExpectNotNull(entry->status);
if (request != NULL && request->serial != NULL)
XMEMCPY(request->serial, serial1, sizeof(serial1));
ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
dataSz, NULL, status, entry, request), WOLFSSL_SUCCESS);
/* store both status's in the entry to check that "next" is not
* overwritten */
if (EXPECT_SUCCESS() && status != NULL && entry != NULL) {
status->next = entry->status;
entry->status = status;
}
if (request != NULL && request->serial != NULL)
XMEMCPY(request->serial, serial, sizeof(serial));
ExpectIntEQ(wolfSSL_CertManagerCheckOCSPResponse(cm, data,
dataSz, NULL, entry->status, entry, request), WOLFSSL_SUCCESS);
ExpectNotNull(entry->status->next);
/* compare the status found */
ExpectIntEQ(status->serialSz, entry->status->serialSz);
ExpectIntEQ(XMEMCMP(status->serial, entry->status->serial,
status->serialSz), 0);
if (status != NULL && entry != NULL && entry->status != status) {
XFREE(status, NULL, DYNAMIC_TYPE_OPENSSL);
}
wolfSSL_OCSP_CERTID_free(entry);
wolfSSL_OCSP_REQUEST_free(request);
wolfSSL_CertManagerFree(cm);
}
/* FIPS v2 and below don't support long salts. */
#if defined(WC_RSA_PSS) && \
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2))) && (!defined(HAVE_SELFTEST) || \
(defined(HAVE_SELFTEST_VERSION) && (HAVE_SELFTEST_VERSION > 2)))
{
const char* responsePssFile = "./certs/ocsp/test-response-rsapss.der";
/* check loading a response with RSA-PSS signature */
ExpectTrue((f = XFOPEN(responsePssFile, "rb")) != XBADFILE);
ExpectIntGT(dataSz = (word32)XFREAD(data, 1, sizeof(data), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
pt = data;
ExpectNotNull(res = wolfSSL_d2i_OCSP_RESPONSE(NULL, &pt, dataSz));
/* try to verify the response */
ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caFile,
SSL_FILETYPE_PEM));
ExpectNotNull(st = wolfSSL_X509_STORE_new());
ExpectIntEQ(wolfSSL_X509_STORE_add_cert(st, issuer), WOLFSSL_SUCCESS);
ExpectNotNull(bs = wolfSSL_OCSP_response_get1_basic(res));
ExpectIntEQ(wolfSSL_OCSP_basic_verify(bs, NULL, st, 0),
WOLFSSL_SUCCESS);
wolfSSL_OCSP_BASICRESP_free(bs);
wolfSSL_OCSP_RESPONSE_free(res);
wolfSSL_X509_STORE_free(st);
wolfSSL_X509_free(issuer);
}
#endif
#endif /* HAVE_OCSP */
return EXPECT_RESULT();
}
static int test_wolfSSL_FPKI(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_FPKI) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
XFILE f = XBADFILE;
const char* fpkiCert = "./certs/fpki-cert.der";
const char* fpkiCertPolCert = "./certs/fpki-certpol-cert.der";
DecodedCert cert;
byte buf[4096];
byte* uuid = NULL;
byte* fascn = NULL;
word32 fascnSz;
word32 uuidSz;
int bytes = 0;
ExpectTrue((f = XFOPEN(fpkiCert, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
ExpectIntEQ(wc_GetFASCNFromCert(&cert, NULL, &fascnSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(fascn = (byte*)XMALLOC(fascnSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_GetFASCNFromCert(&cert, fascn, &fascnSz), 0);
XFREE(fascn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
fascn = NULL;
ExpectIntEQ(wc_GetUUIDFromCert(&cert, NULL, &uuidSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(uuid = (byte*)XMALLOC(uuidSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_GetUUIDFromCert(&cert, uuid, &uuidSz), 0);
XFREE(uuid, NULL, DYNAMIC_TYPE_TMP_BUFFER);
uuid = NULL;
wc_FreeDecodedCert(&cert);
XMEMSET(buf, 0, 4096);
fascnSz = uuidSz = bytes = 0;
f = XBADFILE;
ExpectTrue((f = XFOPEN(fpkiCertPolCert, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
ExpectIntEQ(wc_GetFASCNFromCert(&cert, NULL, &fascnSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(fascn = (byte*)XMALLOC(fascnSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_GetFASCNFromCert(&cert, fascn, &fascnSz), 0);
XFREE(fascn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ExpectIntEQ(wc_GetUUIDFromCert(&cert, NULL, &uuidSz), WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(uuid = (byte*)XMALLOC(uuidSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(wc_GetUUIDFromCert(&cert, uuid, &uuidSz), 0);
XFREE(uuid, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeDecodedCert(&cert);
#endif
return EXPECT_RESULT();
}
/* use RID in confuncture with other names to test parsing of unknown other
* names */
static int test_wolfSSL_OtherName(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_FILESYSTEM)
XFILE f = XBADFILE;
const char* ridCert = "./certs/rid-cert.der";
DecodedCert cert;
byte buf[4096];
int bytes = 0;
ExpectTrue((f = XFOPEN(ridCert, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, 0, NULL), 0);
wc_FreeDecodedCert(&cert);
#endif
return EXPECT_RESULT();
}
#ifdef HAVE_CERT_CHAIN_VALIDATION
#ifndef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
static int test_wolfSSL_CertRsaPss(void)
{
EXPECT_DECLS;
/* FIPS v2 and below don't support long salts. */
#if !defined(NO_RSA) && defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM) && \
(!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2))) && (!defined(HAVE_SELFTEST) || \
(defined(HAVE_SELFTEST_VERSION) && (HAVE_SELFTEST_VERSION > 2)))
XFILE f = XBADFILE;
#ifndef NO_SHA256
const char* rsaPssSha256Cert = "./certs/rsapss/ca-rsapss.der";
#ifdef WOLFSSL_PEM_TO_DER
const char* rsaPssRootSha256Cert = "./certs/rsapss/root-rsapss.pem";
#else
const char* rsaPssRootSha256Cert = "./certs/rsapss/root-rsapss.der";
#endif
#endif
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_PSS_LONG_SALT) && \
RSA_MAX_SIZE >= 3072
const char* rsaPssSha384Cert = "./certs/rsapss/ca-3072-rsapss.der";
#endif
#if defined(WOLFSSL_SHA384) && RSA_MAX_SIZE >= 3072
#ifdef WOLFSSL_PEM_TO_DER
const char* rsaPssRootSha384Cert = "./certs/rsapss/root-3072-rsapss.pem";
#else
const char* rsaPssRootSha384Cert = "./certs/rsapss/root-3072-rsapss.der";
#endif
#endif
DecodedCert cert;
byte buf[4096];
int bytes = 0;
WOLFSSL_CERT_MANAGER* cm = NULL;
ExpectNotNull(cm = wolfSSL_CertManagerNew());
#ifndef NO_SHA256
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CertManagerLoadCA(cm, rsaPssRootSha256Cert, NULL));
#endif
#if defined(WOLFSSL_SHA384) && RSA_MAX_SIZE >= 3072
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CertManagerLoadCA(cm, rsaPssRootSha384Cert, NULL));
#endif
#ifndef NO_SHA256
ExpectTrue((f = XFOPEN(rsaPssSha256Cert, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm), 0);
wc_FreeDecodedCert(&cert);
#endif
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_PSS_LONG_SALT) && \
RSA_MAX_SIZE >= 3072
ExpectTrue((f = XFOPEN(rsaPssSha384Cert, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, VERIFY, cm), 0);
wc_FreeDecodedCert(&cert);
#endif
wolfSSL_CertManagerFree(cm);
(void)buf;
(void)bytes;
#endif
return EXPECT_RESULT();
}
#endif /* WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
#endif /* HAVE_CERT_CHAIN_VALIDATION */
static int test_wolfSSL_CTX_load_verify_locations_ex(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
WOLFSSL_CTX* ctx = NULL;
#ifdef WOLFSSL_PEM_TO_DER
const char* ca_cert = "./certs/ca-cert.pem";
const char* ca_expired_cert = "./certs/test/expired/expired-ca.pem";
#else
const char* ca_cert = "./certs/ca-cert.der";
const char* ca_expired_cert = "./certs/test/expired/expired-ca.der";
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
/* test good CA */
ExpectTrue(WOLFSSL_SUCCESS ==
wolfSSL_CTX_load_verify_locations_ex(ctx, ca_cert, NULL,
WOLFSSL_LOAD_FLAG_NONE));
/* test expired CA */
#if !defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_ASN_TIME)
ExpectIntNE(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#endif
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx, ca_expired_cert, NULL,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_load_verify_buffer_ex(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_RSA) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx;
const char* ca_expired_cert_file = "./certs/test/expired/expired-ca.der";
byte ca_expired_cert[TWOK_BUF];
word32 sizeof_ca_expired_cert = 0;
XFILE fp = XBADFILE;
#ifndef NO_WOLFSSL_CLIENT
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#else
ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#endif
ExpectNotNull(ctx);
#if defined(USE_CERT_BUFFERS_2048)
/* test good CA */
ExpectTrue(WOLFSSL_SUCCESS ==
wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_cert_der_2048,
sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1, 0,
WOLFSSL_LOAD_FLAG_NONE));
#endif
/* load expired CA */
XMEMSET(ca_expired_cert, 0, sizeof(ca_expired_cert));
ExpectTrue((fp = XFOPEN(ca_expired_cert_file, "rb")) != XBADFILE);
ExpectIntGT(sizeof_ca_expired_cert = (word32)XFREAD(ca_expired_cert, 1,
sizeof(ca_expired_cert), fp), 0);
if (fp != XBADFILE)
XFCLOSE(fp);
/* test expired CA failure */
#if !defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_ASN_TIME)
ExpectIntNE(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
WOLFSSL_LOAD_FLAG_NONE), WOLFSSL_SUCCESS);
#endif
/* test expired CA success */
ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WOLFSSL_SUCCESS);
/* Fail when ctx is NULL. */
ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(NULL, ca_expired_cert,
sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 0,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Load as modified cert - bad initial length. */
ca_expired_cert[2] = 0x7f;
ExpectIntEQ(wolfSSL_CTX_load_verify_buffer_ex(ctx, ca_expired_cert,
sizeof_ca_expired_cert, WOLFSSL_FILETYPE_ASN1, 1,
WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY), WC_NO_ERR_TRACE(ASN_PARSE_E));
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_load_verify_chain_buffer_format(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && defined(OPENSSL_EXTRA) && \
defined(USE_CERT_BUFFERS_2048) && (WOLFSSL_MIN_RSA_BITS <= 1024) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
/* Public key 140 bytes??? */
ExpectIntEQ(wolfSSL_CTX_load_verify_chain_buffer_format(ctx,
ca_cert_chain_der, sizeof_ca_cert_chain_der, WOLFSSL_FILETYPE_ASN1),
WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add1_chain_cert(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && \
defined(KEEP_OUR_CERT) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX* ctx;
WOLFSSL* ssl = NULL;
const char *certChain[] = {
"./certs/intermediate/client-int-cert.pem",
"./certs/intermediate/ca-int2-cert.pem",
"./certs/intermediate/ca-int-cert.pem",
"./certs/ca-cert.pem",
NULL
};
const char** cert;
WOLFSSL_X509* x509 = NULL;
WOLF_STACK_OF(X509)* chain = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectNotNull(x509 = wolfSSL_X509_new());
ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 0);
ExpectIntEQ(SSL_CTX_add0_chain_cert(ctx, x509), 0);
ExpectIntEQ(SSL_add1_chain_cert(ssl, x509), 0);
ExpectIntEQ(SSL_add0_chain_cert(ssl, x509), 0);
wolfSSL_X509_free(x509);
x509 = NULL;
for (cert = certChain; EXPECT_SUCCESS() && *cert != NULL; cert++) {
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert,
WOLFSSL_FILETYPE_PEM));
/* Do negative tests once */
if (cert == certChain) {
/* Negative tests. */
ExpectIntEQ(SSL_CTX_add1_chain_cert(NULL, NULL), 0);
ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, NULL), 0);
ExpectIntEQ(SSL_CTX_add1_chain_cert(NULL, x509), 0);
ExpectIntEQ(SSL_CTX_add0_chain_cert(NULL, NULL), 0);
ExpectIntEQ(SSL_CTX_add0_chain_cert(ctx, NULL), 0);
ExpectIntEQ(SSL_CTX_add0_chain_cert(NULL, x509), 0);
}
ExpectIntEQ(SSL_CTX_add1_chain_cert(ctx, x509), 1);
X509_free(x509);
x509 = NULL;
}
for (cert = certChain; EXPECT_SUCCESS() && *cert != NULL; cert++) {
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(*cert,
WOLFSSL_FILETYPE_PEM));
/* Do negative tests once */
if (cert == certChain) {
/* Negative tests. */
ExpectIntEQ(SSL_add1_chain_cert(NULL, NULL), 0);
ExpectIntEQ(SSL_add1_chain_cert(ssl, NULL), 0);
ExpectIntEQ(SSL_add1_chain_cert(NULL, x509), 0);
ExpectIntEQ(SSL_add0_chain_cert(NULL, NULL), 0);
ExpectIntEQ(SSL_add0_chain_cert(ssl, NULL), 0);
ExpectIntEQ(SSL_add0_chain_cert(NULL, x509), 0);
}
ExpectIntEQ(SSL_add1_chain_cert(ssl, x509), 1);
X509_free(x509);
x509 = NULL;
}
ExpectIntEQ(SSL_CTX_get0_chain_certs(ctx, &chain), 1);
ExpectIntEQ(sk_X509_num(chain), 3);
ExpectIntEQ(SSL_get0_chain_certs(ssl, &chain), 1);
ExpectIntEQ(sk_X509_num(chain), 3);
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_certificate_chain_buffer_format(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA) && \
(!defined(NO_FILESYSTEM) || defined(USE_CERT_BUFFERS_2048))
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_FILESYSTEM
const char* cert = svrCertFile;
unsigned char* buf = NULL;
size_t len = 0;
ExpectIntEQ(load_file(cert, &buf, &len), 0);
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Invalid parameters. */
#ifndef NO_FILESYSTEM
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(NULL,
NULL, 0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
NULL, 0, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(ASN_PARSE_E));
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(NULL, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_PEM_TO_DER
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, NULL, 0),
WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
#endif
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(NULL, buf,
(sword32)len), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(NULL, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_PEM_TO_DER
ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, NULL, 0),
WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
#endif
ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(NULL, buf, (sword32)len),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, buf,
(sword32)len, CERT_FILETYPE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx, buf, (sword32)len),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, buf, (sword32)len),
WOLFSSL_SUCCESS);
#endif /* !NO_FILESYSTEM */
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(NULL,
server_cert_der_2048, sizeof_server_cert_der_2048,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
server_cert_der_2048, sizeof_server_cert_der_2048,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_PEM_TO_DER
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_buffer(ctx,
server_cert_der_2048, sizeof_server_cert_der_2048),
WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
ExpectIntEQ(wolfSSL_use_certificate_chain_buffer(ssl, server_cert_der_2048,
sizeof_server_cert_der_2048), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#ifndef NO_FILESYSTEM
if (buf != NULL) {
free(buf);
}
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_use_certificate_chain_file_format(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_RSA) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
const char* server_chain_der = "./certs/server-cert-chain.der";
const char* client_single_pem = cliCertFile;
WOLFSSL_CTX* ctx = NULL;
(void)server_chain_der;
(void)client_single_pem;
(void)ctx;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file_format(ctx,
server_chain_der, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file_format(ctx,
client_single_pem, CERT_FILETYPE), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_use_certificate_chain_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
const char* server_chain_der = "./certs/server-cert-chain.der";
const char* client_single_pem = cliCertFile;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
(void)server_chain_der;
(void)client_single_pem;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* Invalid parameters. */
ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(NULL, NULL,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl, NULL,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(NULL,
server_chain_der, WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_chain_file(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_use_certificate_chain_file(NULL, client_single_pem),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_PEM_TO_DER
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, server_chain_der),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl,
server_chain_der, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_certificate_chain_file_format(ssl,
client_single_pem, CERT_FILETYPE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl, client_single_pem),
WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_SetTmpDH_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_DH) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX *ctx = NULL;
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
#if defined(WOLFSSL_PEM_TO_DER)
const char* dsaParamFile = "./certs/dsaparams.pem";
#else
const char* dsaParamFile = "./certs/dsaparams.der";
#endif
#endif
(void)ctx;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
/* invalid context */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(NULL,
dhParamFile, CERT_FILETYPE));
/* invalid dhParamFile file */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
NULL, CERT_FILETYPE));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
bogusFile, CERT_FILETYPE));
/* success */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile,
CERT_FILETYPE));
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dsaParamFile,
CERT_FILETYPE));
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_SetTmpDH_buffer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_DH) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX *ctx = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
/* invalid context */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL,
dh_key_der_2048, sizeof_dh_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
/* invalid dhParamFile file */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL, NULL,
0, WOLFSSL_FILETYPE_ASN1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, NULL,
0, WOLFSSL_FILETYPE_ASN1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
dsa_key_der_2048, sizeof_dsa_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
/* invalid file format */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
dh_key_der_2048, sizeof_dh_key_der_2048, -1));
/* success */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
dh_key_der_2048, sizeof_dh_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wc_DhSetNamedKey(void)
{
EXPECT_DECLS;
#if !defined(HAVE_SELFTEST) && !defined(NO_DH) && \
!defined(WOLFSSL_NO_MALLOC) && defined(HAVE_FFDHE) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0))
DhKey *key = NULL;
key = (DhKey*)XMALLOC(sizeof(DhKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
ExpectNotNull(key);
if (key != NULL){
#ifdef HAVE_FFDHE_2048
if (wc_InitDhKey_ex(key, HEAP_HINT, INVALID_DEVID) == 0){
ExpectIntEQ(wc_DhSetNamedKey(key, WC_FFDHE_2048), 0);
ExpectIntEQ(wc_DhGetNamedKeyMinSize(WC_FFDHE_2048), 29);
wc_FreeDhKey(key);
}
#endif
#ifdef HAVE_FFDHE_3072
if (wc_InitDhKey_ex(key, HEAP_HINT, INVALID_DEVID) == 0){
ExpectIntEQ(wc_DhSetNamedKey(key, WC_FFDHE_3072), 0);
ExpectIntEQ(wc_DhGetNamedKeyMinSize(WC_FFDHE_3072), 34);
wc_FreeDhKey(key);
}
#endif
#ifdef HAVE_FFDHE_4096
if (wc_InitDhKey_ex(key, HEAP_HINT, INVALID_DEVID) == 0){
ExpectIntEQ(wc_DhSetNamedKey(key, WC_FFDHE_4096), 0);
ExpectIntEQ(wc_DhGetNamedKeyMinSize(WC_FFDHE_4096), 39);
wc_FreeDhKey(key);
}
#endif
#ifdef HAVE_FFDHE_6144
if (wc_InitDhKey_ex(key, HEAP_HINT, INVALID_DEVID) == 0){
ExpectIntEQ(wc_DhSetNamedKey(key, WC_FFDHE_6144), 0);
ExpectIntEQ(wc_DhGetNamedKeyMinSize(WC_FFDHE_6144), 46);
wc_FreeDhKey(key);
}
#endif
#ifdef HAVE_FFDHE_8192
if (wc_InitDhKey_ex(key, HEAP_HINT, INVALID_DEVID) == 0){
ExpectIntEQ(wc_DhSetNamedKey(key, WC_FFDHE_8192), 0);
ExpectIntEQ(wc_DhGetNamedKeyMinSize(WC_FFDHE_8192), 52);
wc_FreeDhKey(key);
}
#endif
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_SetMinMaxDhKey_Sz(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_DH) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX *ctx;
(void)ctx;
#ifndef NO_WOLFSSL_CLIENT
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#else
ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#endif
ExpectNotNull(ctx);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072));
ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 2048));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
dh_key_der_2048, sizeof_dh_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024));
ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_CTX_SetTmpDH_buffer(ctx,
dh_key_der_2048, sizeof_dh_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 2048));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx,
dh_key_der_2048, sizeof_dh_key_der_2048,
WOLFSSL_FILETYPE_ASN1));
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_der_load_verify_locations(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_DER_LOAD) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
const char* derCert = "./certs/server-cert.der";
const char* nullPath = NULL;
const char* invalidPath = "./certs/this-cert-does-not-exist.der";
const char* emptyPath = "";
/* der load Case 1 ctx NULL */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
/* Case 2 filePath NULL */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, nullPath,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* Case 3 invalid format */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* Case 4 filePath not valid */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, invalidPath,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* Case 5 filePath empty */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, emptyPath,
WOLFSSL_FILETYPE_ASN1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_RSA
/* Case 6 success case */
ExpectIntEQ(wolfSSL_CTX_der_load_verify_locations(ctx, derCert,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_enable_disable(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
#ifdef HAVE_CRL
ExpectIntEQ(wolfSSL_CTX_DisableCRL(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifdef HAVE_OCSP
ExpectIntEQ(wolfSSL_CTX_DisableOCSP(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
ExpectIntEQ(wolfSSL_CTX_DisableOCSPStapling(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_EnableOCSPMustStaple(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifdef HAVE_EXTENDED_MASTER
ExpectIntEQ(wolfSSL_CTX_DisableExtendedMasterSecret(ctx), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#ifdef HAVE_EXTENDED_MASTER
ExpectIntEQ(wolfSSL_CTX_DisableExtendedMasterSecret(ctx), WOLFSSL_SUCCESS);
#endif
#elif !defined(NO_WOLFSSL_SERVER)
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#ifdef HAVE_CRL
ExpectIntEQ(wolfSSL_CTX_DisableCRL(ctx), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, 0), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_OCSP
ExpectIntEQ(wolfSSL_CTX_DisableOCSP(ctx), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_URL_OVERRIDE),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL),
WOLFSSL_SUCCESS);
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
ExpectIntEQ(wolfSSL_CTX_DisableOCSPStapling(ctx), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_DisableOCSPMustStaple(ctx), WOLFSSL_SUCCESS);
#endif
wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* !NO_CERTS && !NO_CERTS */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_ticket_API(void)
{
EXPECT_DECLS;
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \
!defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
void *userCtx = (void*)"this is my ctx";
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_set_TicketEncCtx(ctx, userCtx));
ExpectTrue(userCtx == wolfSSL_CTX_get_TicketEncCtx(ctx));
wolfSSL_CTX_free(ctx);
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_set_TicketEncCtx(NULL, userCtx));
ExpectNull(wolfSSL_CTX_get_TicketEncCtx(NULL));
#endif /* HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER && !NO_TLS */
return EXPECT_RESULT();
}
static int test_wolfSSL_set_minmax_proto_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_TLS)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
(void)ssl;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set_min_proto_version(ssl, 0), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set_max_proto_version(ssl, 0), SSL_SUCCESS);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, 0), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, 0), SSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) && \
defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_set_max_proto_version_on_result(WOLFSSL* ssl)
{
EXPECT_DECLS;
ExpectStrEQ(wolfSSL_get_version(ssl), "TLSv1.2");
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_max_proto_version_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
/* Set TLS 1.2 */
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION),
WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
/* Test using wolfSSL_CTX_set_max_proto_version to limit the version below
* what was set at ctx creation. */
static int test_wolfSSL_CTX_set_max_proto_version(void)
{
EXPECT_DECLS;
test_ssl_cbf client_cbs;
test_ssl_cbf server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfTLS_client_method;
server_cbs.method = wolfTLS_server_method;
server_cbs.ctx_ready = test_wolfSSL_CTX_set_max_proto_version_ctx_ready;
client_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result;
server_cbs.on_result = test_wolfSSL_CTX_set_max_proto_version_on_result;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CTX_set_max_proto_version(void)
{
return TEST_SKIPPED;
}
#endif
/*----------------------------------------------------------------------------*
| SSL
*----------------------------------------------------------------------------*/
static int test_server_wolfSSL_new(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER) && !defined(NO_RSA)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL_CTX *ctx_nocert = NULL;
WOLFSSL *ssl = NULL;
ExpectNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
/* invalid context */
ExpectNull(ssl = wolfSSL_new(NULL));
#if !defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_QT) && \
!defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_INIT_CTX_KEY)
ExpectNull(ssl = wolfSSL_new(ctx_nocert));
#endif
/* success */
ExpectNotNull(ssl = wolfSSL_new(ctx));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
wolfSSL_CTX_free(ctx_nocert);
#endif
return EXPECT_RESULT();
}
static int test_client_wolfSSL_new(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_RSA)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL_CTX *ctx_nocert = NULL;
WOLFSSL *ssl = NULL;
ExpectNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectTrue(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
/* invalid context */
ExpectNull(ssl = wolfSSL_new(NULL));
/* success */
ExpectNotNull(ssl = wolfSSL_new(ctx_nocert));
wolfSSL_free(ssl);
ssl = NULL;
/* success */
ExpectNotNull(ssl = wolfSSL_new(ctx));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
wolfSSL_CTX_free(ctx_nocert);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_SetTmpDH_file(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_SERVER) && !defined(NO_DH)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
#ifdef WOLFSSL_PEM_TO_DER
const char* dhX942ParamFile = "./certs/x942dh2048.pem";
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
const char* dsaParamFile = "./certs/dsaparams.pem";
#endif
#else
const char* dhX942ParamFile = "./certs/x942dh2048.der";
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
const char* dsaParamFile = "./certs/dsaparams.der";
#endif
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#ifndef NO_RSA
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
#elif defined(HAVE_ECC)
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
CERT_FILETYPE));
#elif defined(HAVE_ED25519)
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, edCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, edKeyFile,
CERT_FILETYPE));
#elif defined(HAVE_ED448)
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, ed448CertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile,
CERT_FILETYPE));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* invalid ssl */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(NULL,
dhParamFile, CERT_FILETYPE));
/* invalid dhParamFile file */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
NULL, CERT_FILETYPE));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
bogusFile, CERT_FILETYPE));
/* success */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl, dhParamFile,
CERT_FILETYPE));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl, dhX942ParamFile,
CERT_FILETYPE));
#if defined(WOLFSSL_WPAS) && !defined(NO_DSA)
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dsaParamFile,
CERT_FILETYPE));
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_SetTmpDH_buffer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_WOLFSSL_SERVER) && \
!defined(NO_DH)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* invalid ssl */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
/* invalid dhParamFile file */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, NULL,
0, WOLFSSL_FILETYPE_ASN1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, NULL, 0,
WOLFSSL_FILETYPE_ASN1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dsa_key_der_2048,
sizeof_dsa_key_der_2048, WOLFSSL_FILETYPE_ASN1));
/* success */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_SetMinMaxDhKey_Sz(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_WOLFSSL_SERVER) && \
!defined(NO_DH)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL_CTX *ctx2 = NULL;
WOLFSSL *ssl = NULL;
WOLFSSL *ssl2 = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072));
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectNotNull(ctx2 = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_buffer(ctx2, server_cert_der_2048,
sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx2, server_key_der_2048,
sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024));
ExpectNotNull(ssl2 = wolfSSL_new(ctx2));
ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 2048));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 3072));
ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 2048));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 1024));
ExpectIntEQ(WC_NO_ERR_TRACE(DH_KEY_SIZE_E), wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1));
wolfSSL_free(ssl2);
wolfSSL_CTX_free(ctx2);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version
* allowed.
* POST: return 1 on success.
*/
static int test_wolfSSL_SetMinVersion(void)
{
int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
int failFlag = WOLFSSL_SUCCESS;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
int itr;
#ifndef NO_OLD_TLS
const int versions[] = {
#ifdef WOLFSSL_ALLOW_TLSV10
WOLFSSL_TLSV1,
#endif
WOLFSSL_TLSV1_1,
WOLFSSL_TLSV1_2};
#elif !defined(WOLFSSL_NO_TLS12)
const int versions[] = { WOLFSSL_TLSV1_2 };
#else
const int versions[] = { WOLFSSL_TLSV1_3 };
#endif
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
ssl = wolfSSL_new(ctx);
for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++) {
if (wolfSSL_SetMinVersion(ssl, *(versions + itr)) != WOLFSSL_SUCCESS) {
failFlag = WOLFSSL_FAILURE;
}
}
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
res = TEST_RES_CHECK(failFlag == WOLFSSL_SUCCESS);
#endif
return res;
} /* END test_wolfSSL_SetMinVersion */
#include <wolfssl/openssl/pem.h>
/*----------------------------------------------------------------------------*
| IO
*----------------------------------------------------------------------------*/
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) || \
defined(HAVE_IO_TESTS_DEPENDENCIES)
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
byte server_side_msg1[WC_MAX_DIGEST_SIZE]; /* msg sent by server */
byte server_side_msg2[WC_MAX_DIGEST_SIZE]; /* msg received from client */
byte client_side_msg1[WC_MAX_DIGEST_SIZE]; /* msg sent by client */
byte client_side_msg2[WC_MAX_DIGEST_SIZE]; /* msg received from server */
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
/* TODO: Expand and enable this when EVP_chacha20_poly1305 is supported */
#if defined(HAVE_SESSION_TICKET) && defined(OPENSSL_EXTRA) && \
defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
typedef struct openssl_key_ctx {
byte name[WOLFSSL_TICKET_NAME_SZ]; /* server name */
byte key[WOLFSSL_TICKET_KEY_SZ]; /* cipher key */
byte hmacKey[WOLFSSL_TICKET_NAME_SZ]; /* hmac key */
byte iv[WOLFSSL_TICKET_IV_SZ]; /* cipher iv */
} openssl_key_ctx;
static THREAD_LS_T openssl_key_ctx myOpenSSLKey_ctx;
static THREAD_LS_T WC_RNG myOpenSSLKey_rng;
static WC_INLINE int OpenSSLTicketInit(void)
{
int ret = wc_InitRng(&myOpenSSLKey_rng);
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.name,
sizeof(myOpenSSLKey_ctx.name));
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.key,
sizeof(myOpenSSLKey_ctx.key));
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.hmacKey,
sizeof(myOpenSSLKey_ctx.hmacKey));
if (ret != 0) return ret;
ret = wc_RNG_GenerateBlock(&myOpenSSLKey_rng, myOpenSSLKey_ctx.iv,
sizeof(myOpenSSLKey_ctx.iv));
if (ret != 0) return ret;
return 0;
}
static int myTicketEncCbOpenSSL(WOLFSSL* ssl,
byte name[WOLFSSL_TICKET_NAME_SZ],
byte iv[WOLFSSL_TICKET_IV_SZ],
WOLFSSL_EVP_CIPHER_CTX *ectx,
WOLFSSL_HMAC_CTX *hctx, int enc) {
(void)ssl;
if (enc) {
XMEMCPY(name, myOpenSSLKey_ctx.name, sizeof(myOpenSSLKey_ctx.name));
XMEMCPY(iv, myOpenSSLKey_ctx.iv, sizeof(myOpenSSLKey_ctx.iv));
}
else if (XMEMCMP(name, myOpenSSLKey_ctx.name,
sizeof(myOpenSSLKey_ctx.name)) != 0 ||
XMEMCMP(iv, myOpenSSLKey_ctx.iv,
sizeof(myOpenSSLKey_ctx.iv)) != 0) {
return 0;
}
HMAC_Init_ex(hctx, myOpenSSLKey_ctx.hmacKey, WOLFSSL_TICKET_NAME_SZ, EVP_sha256(), NULL);
if (enc)
EVP_EncryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, myOpenSSLKey_ctx.key, iv);
else
EVP_DecryptInit_ex(ectx, EVP_aes_256_cbc(), NULL, myOpenSSLKey_ctx.key, iv);
return 1;
}
static WC_INLINE void OpenSSLTicketCleanup(void)
{
wc_FreeRng(&myOpenSSLKey_rng);
}
#endif
#endif
/* helper functions */
#ifdef HAVE_SSL_MEMIO_TESTS_DEPENDENCIES
static WC_INLINE int test_ssl_memio_write_cb(WOLFSSL *ssl, char *data, int sz,
void *ctx)
{
struct test_ssl_memio_ctx *test_ctx;
byte *buf;
int *len;
int *msg_sizes;
int *msg_count;
test_ctx = (struct test_ssl_memio_ctx*)ctx;
if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
buf = test_ctx->c_buff;
len = &test_ctx->c_len;
msg_sizes = test_ctx->c_msg_sizes;
msg_count = &test_ctx->c_msg_count;
}
else {
buf = test_ctx->s_buff;
len = &test_ctx->s_len;
msg_sizes = test_ctx->s_msg_sizes;
msg_count = &test_ctx->s_msg_count;
}
if ((unsigned)(*len + sz) > TEST_SSL_MEMIO_BUF_SZ)
return WOLFSSL_CBIO_ERR_WANT_WRITE;
if (*msg_count >= TEST_MEMIO_MAX_MSGS)
return WOLFSSL_CBIO_ERR_WANT_WRITE;
XMEMCPY(buf + *len, data, sz);
msg_sizes[*msg_count] = sz;
(*msg_count)++;
*len += sz;
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
{
/* This can be imported into Wireshark by transforming the file with
* od -Ax -tx1 -v test_output.dump > test_output.dump.hex
* And then loading test_output.dump.hex into Wireshark using the
* "Import from Hex Dump..." option ion and selecting the TCP
* encapsulation option. */
char dump_file_name[64];
WOLFSSL_BIO *dump_file;
sprintf(dump_file_name, "%s/%s.dump", tmpDirName, currentTestName);
dump_file = wolfSSL_BIO_new_file(dump_file_name, "a");
if (dump_file != NULL) {
(void)wolfSSL_BIO_write(dump_file, data, sz);
wolfSSL_BIO_free(dump_file);
}
}
#endif
return sz;
}
static WC_INLINE int test_ssl_memio_read_cb(WOLFSSL *ssl, char *data, int sz,
void *ctx)
{
struct test_ssl_memio_ctx *test_ctx;
int read_sz;
byte *buf;
int *len;
int *msg_sizes;
int *msg_count;
int *msg_pos;
int is_dtls;
test_ctx = (struct test_ssl_memio_ctx*)ctx;
is_dtls = wolfSSL_dtls(ssl);
if (wolfSSL_GetSide(ssl) == WOLFSSL_SERVER_END) {
buf = test_ctx->s_buff;
len = &test_ctx->s_len;
msg_sizes = test_ctx->s_msg_sizes;
msg_count = &test_ctx->s_msg_count;
msg_pos = &test_ctx->s_msg_pos;
}
else {
buf = test_ctx->c_buff;
len = &test_ctx->c_len;
msg_sizes = test_ctx->c_msg_sizes;
msg_count = &test_ctx->c_msg_count;
msg_pos = &test_ctx->c_msg_pos;
}
if (*len == 0 || *msg_pos >= *msg_count)
return WOLFSSL_CBIO_ERR_WANT_READ;
/* Calculate how much we can read from current message */
read_sz = msg_sizes[*msg_pos];
if (read_sz > sz)
read_sz = sz;
if (read_sz > *len)
return WOLFSSL_CBIO_ERR_GENERAL;
/* Copy data from current message */
XMEMCPY(data, buf, (size_t)read_sz);
/* remove the read data from the buffer */
XMEMMOVE(buf, buf + read_sz, (size_t)(*len - read_sz));
*len -= read_sz;
msg_sizes[*msg_pos] -= read_sz;
/* if we are on dtls, discard the rest of the message */
if (is_dtls && msg_sizes[*msg_pos] > 0) {
XMEMMOVE(buf, buf + msg_sizes[*msg_pos], (size_t)(*len - msg_sizes[*msg_pos]));
*len -= msg_sizes[*msg_pos];
msg_sizes[*msg_pos] = 0;
}
/* If we've read the entire message */
if (msg_sizes[*msg_pos] == 0) {
/* Move to next message */
(*msg_pos)++;
if (*msg_pos >= *msg_count) {
*msg_pos = 0;
*msg_count = 0;
}
}
return read_sz;
}
int test_ssl_memio_setup(test_ssl_memio_ctx *ctx)
{
EXPECT_DECLS_NO_MSGS(-2000);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
int c_sharedCtx = 0;
int s_sharedCtx = 0;
#endif
const char* clientCertFile = cliCertFile;
const char* clientKeyFile = cliKeyFile;
const char* serverCertFile = svrCertFile;
const char* serverKeyFile = svrKeyFile;
/********************************
* Create WOLFSSL_CTX for client.
********************************/
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (ctx->c_ctx != NULL) {
c_sharedCtx = ctx->c_cb.isSharedCtx;
}
else
#endif
{
WOLFSSL_METHOD* method = NULL;
if (ctx->c_cb.method != NULL) {
method = ctx->c_cb.method();
}
else {
method = wolfSSLv23_client_method();
}
ExpectNotNull(ctx->c_ctx = wolfSSL_CTX_new(method));
}
wolfSSL_SetIORecv(ctx->c_ctx, test_ssl_memio_read_cb);
wolfSSL_SetIOSend(ctx->c_ctx, test_ssl_memio_write_cb);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx->c_ctx, PasswordCallBack);
#endif
if (ctx->c_cb.caPemFile == NULL)
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
caCertFile, 0), WOLFSSL_SUCCESS);
else if (*ctx->c_cb.caPemFile != '\0')
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx,
ctx->c_cb.caPemFile, 0), WOLFSSL_SUCCESS);
if (ctx->c_cb.certPemFile != NULL) {
clientCertFile = ctx->c_cb.certPemFile;
}
if (ctx->c_cb.keyPemFile != NULL) {
clientKeyFile = ctx->c_cb.keyPemFile;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!c_sharedCtx)
#endif
{
if (*clientCertFile != '\0') {
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->c_ctx,
clientCertFile), WOLFSSL_SUCCESS);
}
if (*clientKeyFile != '\0') {
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->c_ctx, clientKeyFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
}
}
#ifdef HAVE_CRL
if (ctx->c_cb.crlPemFile != NULL) {
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx->c_ctx, WOLFSSL_CRL_CHECKALL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx->c_ctx, ctx->c_cb.crlPemFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
}
#endif
if (ctx->c_ciphers != NULL) {
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx->c_ctx, ctx->c_ciphers),
WOLFSSL_SUCCESS);
}
if (ctx->c_cb.ctx_ready != NULL) {
ExpectIntEQ(ctx->c_cb.ctx_ready(ctx->c_ctx), TEST_SUCCESS);
}
/********************************
* Create WOLFSSL_CTX for server.
********************************/
if (ctx->s_ctx != NULL) {
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
s_sharedCtx = 1;
#endif
ctx->s_cb.isSharedCtx = 1;
}
else
{
WOLFSSL_METHOD* method = NULL;
if (ctx->s_cb.method != NULL) {
method = ctx->s_cb.method();
}
else {
method = wolfSSLv23_server_method();
}
ExpectNotNull(ctx->s_ctx = wolfSSL_CTX_new(method));
ctx->s_cb.isSharedCtx = 0;
}
if (!ctx->s_cb.ticNoInit && (ctx->s_ctx != NULL)) {
#if defined(HAVE_SESSION_TICKET) && \
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
OpenSSLTicketInit();
wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx->s_ctx, myTicketEncCbOpenSSL);
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
TicketInit();
wolfSSL_CTX_set_TicketEncCb(ctx->s_ctx, myTicketEncCb);
#endif
#endif
}
wolfSSL_SetIORecv(ctx->s_ctx, test_ssl_memio_read_cb);
wolfSSL_SetIOSend(ctx->s_ctx, test_ssl_memio_write_cb);
wolfSSL_CTX_set_verify(ctx->s_ctx, WOLFSSL_VERIFY_PEER |
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
if (ctx->s_cb.caPemFile == NULL)
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx,
cliCertFile, 0), WOLFSSL_SUCCESS);
else if (*ctx->s_cb.caPemFile != '\0')
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx,
ctx->s_cb.caPemFile, 0), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack);
#endif
if (ctx->s_cb.certPemFile != NULL) {
serverCertFile = ctx->s_cb.certPemFile;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!s_sharedCtx)
#endif
{
if (*serverCertFile != '\0') {
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx->s_ctx,
serverCertFile), WOLFSSL_SUCCESS);
}
}
if (ctx->s_cb.keyPemFile != NULL) {
serverKeyFile = ctx->s_cb.keyPemFile;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!s_sharedCtx)
#endif
{
if (*serverKeyFile != '\0') {
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx->s_ctx, serverKeyFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
}
}
if (ctx->s_ciphers != NULL) {
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx->s_ctx, ctx->s_ciphers),
WOLFSSL_SUCCESS);
}
if (ctx->s_cb.ctx_ready != NULL) {
ExpectIntEQ(ctx->s_cb.ctx_ready(ctx->s_ctx), TEST_SUCCESS);
}
/****************************
* Create WOLFSSL for client.
****************************/
ExpectNotNull(ctx->c_ssl = wolfSSL_new(ctx->c_ctx));
wolfSSL_SetIOWriteCtx(ctx->c_ssl, ctx);
wolfSSL_SetIOReadCtx(ctx->c_ssl, ctx);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (c_sharedCtx) {
if (*clientCertFile != '\0') {
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->c_ssl,
clientCertFile), WOLFSSL_SUCCESS);
}
if (*clientKeyFile != '\0') {
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->c_ssl, clientKeyFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
}
}
#endif
if (ctx->c_cb.ssl_ready != NULL) {
ExpectIntEQ(ctx->c_cb.ssl_ready(ctx->c_ssl), TEST_SUCCESS);
}
/****************************
* Create WOLFSSL for server.
****************************/
ExpectNotNull(ctx->s_ssl = wolfSSL_new(ctx->s_ctx));
wolfSSL_SetIOWriteCtx(ctx->s_ssl, ctx);
wolfSSL_SetIOReadCtx(ctx->s_ssl, ctx);
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (s_sharedCtx) {
if (*serverCertFile != '\0') {
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ctx->s_ssl,
serverCertFile), WOLFSSL_SUCCESS);
}
if (*serverKeyFile != '\0') {
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ctx->s_ssl, serverKeyFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
}
}
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
wolfSSL_SetTmpDH_file(ctx->s_ssl, dhParamFile, CERT_FILETYPE);
#elif !defined(NO_DH)
/* will repick suites with DHE, higher priority than PSK */
SetDH(ctx->s_ssl);
#endif
if (ctx->s_cb.ssl_ready != NULL) {
ExpectIntEQ(ctx->s_cb.ssl_ready(ctx->s_ssl), TEST_SUCCESS);
}
return EXPECT_RESULT();
}
int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
int* rounds)
{
int handshake_complete = 0;
int hs_c = 0;
int hs_s = 0;
int failing_s = 0;
int failing_c = 0;
int ret;
int err;
if (rounds != NULL) {
*rounds = 0;
}
while ((!handshake_complete) && (max_rounds > 0)) {
if (!hs_c) {
wolfSSL_SetLoggingPrefix("client");
ret = wolfSSL_connect(ctx->c_ssl);
wolfSSL_SetLoggingPrefix(NULL);
if (ret == WOLFSSL_SUCCESS) {
hs_c = 1;
}
else {
err = wolfSSL_get_error(ctx->c_ssl, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
failing_c = 1;
hs_c = 1;
if (failing_c && failing_s) {
break;
}
}
}
}
if (!hs_s) {
wolfSSL_SetLoggingPrefix("server");
ret = wolfSSL_accept(ctx->s_ssl);
wolfSSL_SetLoggingPrefix(NULL);
if (ret == WOLFSSL_SUCCESS) {
hs_s = 1;
}
else {
err = wolfSSL_get_error(ctx->s_ssl, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
failing_s = 1;
hs_s = 1;
if (failing_c && failing_s) {
break;
}
}
}
}
handshake_complete = hs_c && hs_s;
max_rounds--;
if (rounds != NULL) {
*rounds += 1;
}
}
if (!handshake_complete || failing_c || failing_s) {
return TEST_FAIL;
}
return TEST_SUCCESS;
}
static int test_ssl_memio_read_write(test_ssl_memio_ctx* ctx)
{
EXPECT_DECLS_NO_MSGS(-3000);
char input[1024];
int idx = 0;
const char* msg_c = "hello wolfssl!";
int msglen_c = (int)XSTRLEN(msg_c);
const char* msg_s = "I hear you fa shizzle!";
int msglen_s = (int)XSTRLEN(msg_s);
if (ctx->c_msg != NULL) {
msg_c = ctx->c_msg;
msglen_c = ctx->c_msglen;
}
if (ctx->s_msg != NULL) {
msg_s = ctx->s_msg;
msglen_s = ctx->s_msglen;
}
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_write(ctx->c_ssl, msg_c, msglen_c), msglen_c);
wolfSSL_SetLoggingPrefix("server");
ExpectIntGT(idx = wolfSSL_read(ctx->s_ssl, input, sizeof(input) - 1), 0);
if (idx >= 0) {
input[idx] = '\0';
}
ExpectIntGT(fprintf(stderr, "Client message: %s\n", input), 0);
ExpectIntEQ(wolfSSL_write(ctx->s_ssl, msg_s, msglen_s), msglen_s);
ctx->s_cb.return_code = EXPECT_RESULT();
wolfSSL_SetLoggingPrefix("client");
ExpectIntGT(idx = wolfSSL_read(ctx->c_ssl, input, sizeof(input) - 1), 0);
wolfSSL_SetLoggingPrefix(NULL);
if (idx >= 0) {
input[idx] = '\0';
}
ExpectIntGT(fprintf(stderr, "Server response: %s\n", input), 0);
ctx->c_cb.return_code = EXPECT_RESULT();
if (ctx->c_cb.on_result != NULL) {
ExpectIntEQ(ctx->c_cb.on_result(ctx->c_ssl), TEST_SUCCESS);
}
if (ctx->s_cb.on_result != NULL) {
ExpectIntEQ(ctx->s_cb.on_result(ctx->s_ssl), TEST_SUCCESS);
}
return EXPECT_RESULT();
}
void test_ssl_memio_cleanup(test_ssl_memio_ctx* ctx)
{
ctx->c_cb.last_err = wolfSSL_get_error(ctx->c_ssl, 0);
ctx->s_cb.last_err = wolfSSL_get_error(ctx->s_ssl, 0);
if (ctx->c_cb.on_cleanup != NULL) {
ctx->c_cb.on_cleanup(ctx->c_ssl);
}
if (ctx->s_cb.on_cleanup != NULL) {
ctx->s_cb.on_cleanup(ctx->s_ssl);
}
wolfSSL_shutdown(ctx->s_ssl);
wolfSSL_shutdown(ctx->c_ssl);
wolfSSL_free(ctx->s_ssl);
wolfSSL_free(ctx->c_ssl);
if (ctx->c_cb.on_ctx_cleanup != NULL) {
ctx->c_cb.on_ctx_cleanup(ctx->c_ctx);
}
if (!ctx->c_cb.isSharedCtx) {
wolfSSL_CTX_free(ctx->c_ctx);
ctx->c_ctx = NULL;
}
if (ctx->s_cb.on_ctx_cleanup != NULL) {
ctx->s_cb.on_ctx_cleanup(ctx->s_ctx);
}
if (!ctx->s_cb.isSharedCtx) {
wolfSSL_CTX_free(ctx->s_ctx);
ctx->s_ctx = NULL;
}
if (!ctx->s_cb.ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
TicketCleanup();
#endif
#endif
}
}
static int test_wolfSSL_client_server_nofail_memio_ex(test_ssl_cbf* client_cb,
test_ssl_cbf* server_cb, cbType client_on_handshake,
cbType server_on_handshake)
{
/* We use EXPECT_DECLS_NO_MSGS() here because this helper routine is used
* for numerous but varied expected-to-fail scenarios that should not emit
* error messages on the expected failures. Instead, we return a distinct
* code for each failure point, allowing the caller to assert on a
* particular mode of expected failure. On success, the usual TEST_SUCCESS
* is returned.
*/
EXPECT_DECLS_NO_MSGS(-1000);
struct test_ssl_memio_ctx test_ctx;
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
size_t msg_len;
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
XMEMCPY(&test_ctx.c_cb, client_cb, sizeof(test_ssl_cbf));
XMEMCPY(&test_ctx.s_cb, server_cb, sizeof(test_ssl_cbf));
test_ctx.c_ctx = client_cb->ctx;
test_ctx.s_ctx = server_cb->ctx;
test_ctx.c_cb.return_code = EXPECT_FAILURE_CODEPOINT_ID;
test_ctx.s_cb.return_code = EXPECT_FAILURE_CODEPOINT_ID;
ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
ExpectIntEQ(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
if (client_on_handshake != NULL) {
ExpectIntEQ(client_on_handshake(test_ctx.c_ctx, test_ctx.c_ssl),
TEST_SUCCESS);
}
if (server_on_handshake != NULL) {
ExpectIntEQ(server_on_handshake(test_ctx.s_ctx, test_ctx.s_ssl),
TEST_SUCCESS);
}
if (client_cb->on_handshake != NULL) {
ExpectIntEQ(client_cb->on_handshake(&test_ctx.c_ctx, &test_ctx.c_ssl),
TEST_SUCCESS);
}
if (server_cb->on_handshake != NULL) {
ExpectIntEQ(server_cb->on_handshake(&test_ctx.s_ctx, &test_ctx.s_ssl),
TEST_SUCCESS);
}
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
XMEMSET(server_side_msg2, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_peer_finished(test_ctx.s_ssl, server_side_msg2,
WC_MAX_DIGEST_SIZE);
ExpectIntGE(msg_len, 0);
XMEMSET(server_side_msg1, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_finished(test_ctx.s_ssl, server_side_msg1,
WC_MAX_DIGEST_SIZE);
ExpectIntGE(msg_len, 0);
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
ExpectIntEQ(test_ssl_memio_read_write(&test_ctx), TEST_SUCCESS);
test_ssl_memio_cleanup(&test_ctx);
client_cb->return_code = test_ctx.c_cb.return_code;
client_cb->last_err = test_ctx.c_cb.last_err;
server_cb->return_code = test_ctx.s_cb.return_code;
server_cb->last_err = test_ctx.s_cb.last_err;
return EXPECT_RESULT();
}
int test_wolfSSL_client_server_nofail_memio(test_ssl_cbf* client_cb,
test_ssl_cbf* server_cb, cbType client_on_handshake)
{
return (test_wolfSSL_client_server_nofail_memio_ex(client_cb, server_cb,
client_on_handshake, NULL));
}
#endif
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#ifdef WOLFSSL_SESSION_EXPORT
#ifdef WOLFSSL_DTLS
/* set up function for sending session information */
static int test_export(WOLFSSL* inSsl, byte* buf, word32 sz, void* userCtx)
{
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
AssertNotNull(inSsl);
AssertNotNull(buf);
AssertIntNE(0, sz);
/* Set ctx to DTLS 1.2 */
ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
AssertNotNull(ctx);
ssl = wolfSSL_new(ctx);
AssertNotNull(ssl);
AssertIntGE(wolfSSL_dtls_import(ssl, buf, sz), 0);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
(void)userCtx;
return 0;
}
#endif
/* returns negative value on fail and positive (including 0) on success */
static int nonblocking_accept_read(void* args, WOLFSSL* ssl, SOCKET_T* sockfd)
{
int ret, err, loop_count, count, timeout = 10;
char msg[] = "I hear you fa shizzle!";
char input[1024];
loop_count = ((func_args*)args)->argc;
#ifdef WOLFSSL_ASYNC_CRYPT
err = 0; /* Reset error */
#endif
do {
#ifdef WOLFSSL_ASYNC_CRYPT
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
if (ret < 0) { break; } else if (ret == 0) { continue; }
}
#endif
ret = wolfSSL_accept(ssl);
err = wolfSSL_get_error(ssl, 0);
if (err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
int select_ret;
err = WC_PENDING_E;
select_ret = tcp_select(*sockfd, timeout);
if (select_ret == TEST_TIMEOUT) {
return WOLFSSL_FATAL_ERROR;
}
}
} while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string(err, buff));
return ret;
}
for (count = 0; count < loop_count; count++) {
int select_ret;
select_ret = tcp_select(*sockfd, timeout);
if (select_ret == TEST_TIMEOUT) {
ret = WOLFSSL_FATAL_ERROR;
break;
}
do {
ret = wolfSSL_read(ssl, input, sizeof(input)-1);
if (ret > 0) {
input[ret] = '\0';
fprintf(stderr, "Client message: %s\n", input);
}
} while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);
do {
if ((ret = wolfSSL_write(ssl, msg, sizeof(msg))) != sizeof(msg)) {
return WOLFSSL_FATAL_ERROR;
}
err = wolfSSL_get_error(ssl, ret);
} while (err == WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_SUCCESS);
}
return ret;
}
#endif /* WOLFSSL_SESSION_EXPORT */
THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
{
SOCKET_T sockfd = 0;
SOCKET_T clientfd = 0;
word16 port;
callback_functions* cbf;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
func_args* opts = (func_args*)args;
char msg[] = "I hear you fa shizzle!";
char input[1024];
int idx;
int ret, err = 0;
int sharedCtx = 0;
int doUdp = 0;
SOCKADDR_IN_T cliAddr;
socklen_t cliLen;
const char* certFile = svrCertFile;
const char* keyFile = svrKeyFile;
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
size_t msg_len = 0;
#endif
wolfSSL_SetLoggingPrefix("server");
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
opts->return_code = TEST_FAIL;
cbf = opts->callbacks;
if (cbf != NULL && cbf->ctx) {
ctx = cbf->ctx;
sharedCtx = 1;
}
else
{
WOLFSSL_METHOD* method = NULL;
if (cbf != NULL && cbf->method != NULL) {
method = cbf->method();
}
else {
method = wolfSSLv23_server_method();
}
ctx = wolfSSL_CTX_new(method);
}
if (ctx == NULL) {
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
if (cbf == NULL || !cbf->ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
OpenSSLTicketInit();
wolfSSL_CTX_set_tlsext_ticket_key_cb(ctx, myTicketEncCbOpenSSL);
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
TicketInit();
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif
#endif
}
#if defined(USE_WINDOWS_API)
port = opts->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
!defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
/* Let tcp_listen assign port */
port = 0;
#else
/* Use default port */
port = wolfSSLPort;
#endif
if (cbf != NULL)
doUdp = cbf->doUdp;
/* do it here to detect failure */
tcp_accept(
&sockfd, &clientfd, opts, port, 0, doUdp, 0, 0, 1, 0, 0);
if (doUdp) {
cliLen = sizeof(cliAddr);
idx = (int)recvfrom(sockfd, input, sizeof(input), MSG_PEEK,
(struct sockaddr*)&cliAddr, &cliLen);
AssertIntGT(idx, 0);
}
else {
CloseSocket(sockfd);
}
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
if (wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0)
!= WOLFSSL_SUCCESS) {
/*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
goto done;
}
if (cbf != NULL && cbf->certPemFile != NULL)
certFile = cbf->certPemFile;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, certFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_CTX_use_certificate_file(ctx, certFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load server cert chain file, "
"Please run from wolfSSL home dir");*/
goto done;
}
if (cbf != NULL && cbf->keyPemFile != NULL)
keyFile = cbf->keyPemFile;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_CTX_use_PrivateKey_file(ctx, keyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load server key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#ifdef HAVE_CRL
if (cbf != NULL && cbf->crlPemFile != NULL) {
if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS)
goto done;
if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, CERT_FILETYPE)
!= WOLFSSL_SUCCESS)
goto done;
}
#endif
/* call ctx setup callback */
if (cbf != NULL && cbf->ctx_ready != NULL) {
cbf->ctx_ready(ctx);
}
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
goto done;
}
if (doUdp) {
err = wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
if (err != WOLFSSL_SUCCESS)
goto done;
}
#ifdef WOLFSSL_SESSION_EXPORT
/* only add in more complex nonblocking case with session export tests */
if (args && opts->argc > 0) {
/* set as nonblock and time out for waiting on read/write */
tcp_set_nonblocking(&clientfd);
wolfSSL_dtls_set_using_nonblock(ssl, 1);
}
#endif
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (sharedCtx && wolfSSL_use_certificate_file(ssl, certFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_use_certificate_file(ssl, certFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load server cert chain file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, keyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_use_PrivateKey_file(ssl, keyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load server key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
wolfSSL_SetTmpDH_file(ssl, dhParamFile, CERT_FILETYPE);
#elif !defined(NO_DH)
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
#endif
/* call ssl setup callback */
if (cbf != NULL && cbf->ssl_ready != NULL) {
cbf->ssl_ready(ssl);
}
#ifdef WOLFSSL_SESSION_EXPORT
/* only add in more complex nonblocking case with session export tests */
if (opts->argc > 0) {
ret = nonblocking_accept_read(args, ssl, &clientfd);
if (ret >= 0) {
opts->return_code = TEST_SUCCESS;
}
#ifdef WOLFSSL_TIRTOS
Task_yield();
#endif
goto done;
}
#endif
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_negotiate(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
/*err_sys("SSL_accept failed");*/
goto done;
}
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
XMEMSET(server_side_msg2, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_peer_finished(ssl, server_side_msg2, WC_MAX_DIGEST_SIZE);
AssertIntGE(msg_len, 0);
XMEMSET(server_side_msg1, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_finished(ssl, server_side_msg1, WC_MAX_DIGEST_SIZE);
AssertIntGE(msg_len, 0);
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
idx = wolfSSL_read(ssl, input, sizeof(input)-1);
if (idx > 0) {
input[idx] = '\0';
fprintf(stderr, "Client message: %s\n", input);
}
else if (idx < 0) {
goto done;
}
if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
/*err_sys("SSL_write failed");*/
goto done;
}
if (cbf != NULL && cbf->on_result != NULL)
cbf->on_result(ssl);
#ifdef WOLFSSL_TIRTOS
Task_yield();
#endif
opts->return_code = TEST_SUCCESS;
done:
if (cbf != NULL)
cbf->last_err = err;
if (cbf != NULL && cbf->on_cleanup != NULL)
cbf->on_cleanup(ssl);
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
if (!sharedCtx)
wolfSSL_CTX_free(ctx);
CloseSocket(clientfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
if (cbf == NULL || !cbf->ticNoInit) {
#if defined(HAVE_SESSION_TICKET) && \
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
TicketCleanup();
#endif
#endif
}
wolfSSL_SetLoggingPrefix(NULL);
WOLFSSL_RETURN_FROM_THREAD(0);
}
#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
!defined(WOLFSSL_NO_TLS12)
static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args)
{
SOCKET_T sockfd;
SOCKET_T clientfd = -1;
word16 port;
callback_functions* cbf;
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
char msg[] = "I hear you fa shizzle!";
char input[1024];
int idx;
int ret, err = 0;
int sharedCtx = 0;
func_args* opts = (func_args*)args;
int loop_count = opts->argc;
int count = 0;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
opts->return_code = TEST_FAIL;
cbf = opts->callbacks;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (cbf != NULL && cbf->ctx) {
ctx = cbf->ctx;
sharedCtx = 1;
}
else
#endif
{
WOLFSSL_METHOD* method = NULL;
if (cbf != NULL && cbf->method != NULL) {
method = cbf->method();
}
else {
method = wolfSSLv23_server_method();
}
ctx = wolfSSL_CTX_new(method);
}
#if defined(USE_WINDOWS_API)
port = opts->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
!defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
/* Let tcp_listen assign port */
port = 0;
#else
/* Use default port */
port = wolfSSLPort;
#endif
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
if (wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0)
!= WOLFSSL_SUCCESS) {
/*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
/*err_sys("can't load server cert chain file, "
"Please run from wolfSSL home dir");*/
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
/*err_sys("can't load server key file, "
"Please run from wolfSSL home dir");*/
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
/* call ctx setup callback */
if (cbf != NULL && cbf->ctx_ready != NULL) {
cbf->ctx_ready(ctx);
}
while (count != loop_count) {
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
signal_ready(opts->signal);
goto done;
}
if (sharedCtx && wolfSSL_use_certificate_file(ssl, svrCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
/*err_sys("can't load server cert chain file, "
"Please run from wolfSSL home dir");*/
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, svrKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
/*err_sys("can't load server key file, "
"Please run from wolfSSL home dir");*/
/* Release the wait for TCP ready. */
signal_ready(opts->signal);
goto done;
}
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
wolfSSL_SetTmpDH_file(ssl, dhParamFile, CERT_FILETYPE);
#elif !defined(NO_DH)
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
#endif
/* call ssl setup callback */
if (cbf != NULL && cbf->ssl_ready != NULL) {
cbf->ssl_ready(ssl);
}
/* do it here to detect failure */
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0,
0);
CloseSocket(sockfd);
if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_accept(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string(err, buff));
/*err_sys("SSL_accept failed");*/
goto done;
}
idx = wolfSSL_read(ssl, input, sizeof(input)-1);
if (idx > 0) {
input[idx] = '\0';
fprintf(stderr, "Client message: %s\n", input);
}
if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
/*err_sys("SSL_write failed");*/
goto done;
}
/* free ssl for this connection */
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl); ssl = NULL;
CloseSocket(clientfd);
clientfd = -1;
count++;
}
#ifdef WOLFSSL_TIRTOS
Task_yield();
#endif
opts->return_code = TEST_SUCCESS;
done:
if (ssl != NULL) {
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
}
if (!sharedCtx)
wolfSSL_CTX_free(ctx);
if (clientfd != SOCKET_INVALID)
CloseSocket(clientfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && !defined(WOLFSSL_TLS13) */
int test_client_nofail(void* args, cbType cb)
{
#if !defined(NO_WOLFSSL_CLIENT)
SOCKET_T sockfd = 0;
callback_functions* cbf;
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
WOLFSSL_CIPHER* cipher;
char msg[64] = "hello wolfssl!";
char reply[1024];
int input;
int msgSz = (int)XSTRLEN(msg);
int ret, err = 0;
int cipherSuite;
int sharedCtx = 0;
int doUdp = 0;
const char* cipherName1, *cipherName2;
wolfSSL_SetLoggingPrefix("client");
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
((func_args*)args)->return_code = TEST_FAIL;
cbf = ((func_args*)args)->callbacks;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (cbf != NULL && cbf->ctx) {
ctx = cbf->ctx;
sharedCtx = cbf->isSharedCtx;
}
else
#endif
{
WOLFSSL_METHOD* method = NULL;
if (cbf != NULL && cbf->method != NULL) {
method = cbf->method();
}
else {
method = wolfSSLv23_client_method();
}
ctx = wolfSSL_CTX_new(method);
}
if (cbf != NULL)
doUdp = cbf->doUdp;
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
/* Do connect here so server detects failures */
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
doUdp, 0, NULL);
/* Connect the socket so that we don't have to set the peer later on */
if (doUdp)
udp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port);
if (wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0) != WOLFSSL_SUCCESS)
{
/* err_sys("can't load ca file, Please run from wolfSSL home dir");*/
goto done;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load client cert file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load client key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#ifdef WOLFSSL_SRTP
/* make sure that NULL (error condition) returns 1 */
if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, NULL) != 1) {
goto done;
}
#endif
#ifdef HAVE_CRL
if (cbf != NULL && cbf->crlPemFile != NULL) {
if (wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS)
goto done;
if (wolfSSL_CTX_LoadCRLFile(ctx, cbf->crlPemFile, CERT_FILETYPE)
!= WOLFSSL_SUCCESS)
goto done;
}
#endif
/* call ctx setup callback */
if (cbf != NULL && cbf->ctx_ready != NULL) {
cbf->ctx_ready(ctx);
}
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
goto done;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (sharedCtx && wolfSSL_use_certificate_file(ssl, cliCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_use_certificate_file(ssl, cliCertFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load client cert file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#else
if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
#endif
/*err_sys("can't load client key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
#ifdef WOLFSSL_SRTP
/* make sure that NULL (error condition) returns 1 */
if (wolfSSL_set_tlsext_use_srtp(ssl, NULL) != 1) {
goto done;
}
#endif
if (!doUdp) {
if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
}
else {
#ifdef WOLFSSL_DTLS
if (wolfSSL_set_dtls_fd_connected(ssl, sockfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
#else
goto done;
#endif
}
/* call ssl setup callback */
if (cbf != NULL && cbf->ssl_ready != NULL) {
cbf->ssl_ready(ssl);
}
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_negotiate(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
/*err_sys("SSL_connect failed");*/
goto done;
}
/* test the various get cipher methods */
/* Internal cipher suite names */
cipherSuite = wolfSSL_get_current_cipher_suite(ssl);
cipherName1 = wolfSSL_get_cipher_name(ssl);
cipherName2 = wolfSSL_get_cipher_name_from_suite(
(byte)(cipherSuite >> 8), cipherSuite & 0xFF);
AssertStrEQ(cipherName1, cipherName2);
/* IANA Cipher Suites Names */
/* Unless WOLFSSL_CIPHER_INTERNALNAME or NO_ERROR_STRINGS,
then it's the internal cipher suite name */
cipher = wolfSSL_get_current_cipher(ssl);
cipherName1 = wolfSSL_CIPHER_get_name(cipher);
cipherName2 = wolfSSL_get_cipher(ssl);
AssertStrEQ(cipherName1, cipherName2);
#if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
!defined(WOLFSSL_QT)
cipherName1 = wolfSSL_get_cipher_name_iana_from_suite(
(byte)(cipherSuite >> 8), cipherSuite & 0xFF);
AssertStrEQ(cipherName1, cipherName2);
#endif
if (cb != NULL)
(cb)(ctx, ssl);
if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
/*err_sys("SSL_write failed");*/
goto done;
}
input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
if (input > 0) {
reply[input] = '\0';
fprintf(stderr, "Server response: %s\n", reply);
}
if (cbf != NULL && cbf->on_result != NULL)
cbf->on_result(ssl);
((func_args*)args)->return_code = TEST_SUCCESS;
done:
if (cbf != NULL)
cbf->last_err = err;
if (cbf != NULL && cbf->on_cleanup != NULL)
cbf->on_cleanup(ssl);
wolfSSL_free(ssl);
if (!sharedCtx)
wolfSSL_CTX_free(ctx);
CloseSocket(sockfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
#else
(void)args;
(void)cb;
#endif /* !NO_WOLFSSL_CLIENT */
wolfSSL_SetLoggingPrefix(NULL);
return 0;
}
void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb,
callback_functions* server_cb, cbType client_on_handshake)
{
func_args client_args;
func_args server_args;
tcp_ready ready;
THREAD_TYPE serverThread;
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
server_args.callbacks = server_cb;
client_args.signal = &ready;
client_args.callbacks = client_cb;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
test_client_nofail(&client_args, client_on_handshake);
join_thread(serverThread);
client_cb->return_code = client_args.return_code;
server_cb->return_code = server_args.return_code;
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
}
void test_wolfSSL_client_server_nofail(callback_functions* client_cb,
callback_functions* server_cb)
{
test_wolfSSL_client_server_nofail_ex(client_cb, server_cb, NULL);
}
#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
!defined(WOLFSSL_NO_TLS12) && !defined(NO_WOLFSSL_CLIENT)
static void test_client_reuse_WOLFSSLobj(void* args, cbType cb,
void* server_args)
{
SOCKET_T sockfd = 0;
callback_functions* cbf;
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
WOLFSSL_SESSION* session = NULL;
char msg[64] = "hello wolfssl!";
char reply[1024];
int input;
int msgSz = (int)XSTRLEN(msg);
int ret, err = 0;
int sharedCtx = 0;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
((func_args*)args)->return_code = TEST_FAIL;
cbf = ((func_args*)args)->callbacks;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
if (cbf != NULL && cbf->ctx) {
ctx = cbf->ctx;
sharedCtx = 1;
}
else
#endif
{
WOLFSSL_METHOD* method = NULL;
if (cbf != NULL && cbf->method != NULL) {
method = cbf->method();
}
else {
method = wolfSSLv23_client_method();
}
ctx = wolfSSL_CTX_new(method);
}
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
/* Do connect here so server detects failures */
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
0, 0, NULL);
if (wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0) !=
WOLFSSL_SUCCESS) {
/* err_sys("can't load ca file, Please run from wolfSSL home dir");*/
goto done;
}
if (!sharedCtx && wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
/*err_sys("can't load client cert file, "
"Please run from wolfSSL home dir");*/
goto done;
}
if (!sharedCtx && wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
/*err_sys("can't load client key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
/* call ctx setup callback */
if (cbf != NULL && cbf->ctx_ready != NULL) {
cbf->ctx_ready(ctx);
}
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
goto done;
}
/* keep handshake resources for reusing WOLFSSL obj */
wolfSSL_KeepArrays(ssl);
if (wolfSSL_KeepHandshakeResources(ssl)) {
/* err_sys("SSL_KeepHandshakeResources failed"); */
goto done;
}
if (sharedCtx && wolfSSL_use_certificate_file(ssl, cliCertFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
/*err_sys("can't load client cert file, "
"Please run from wolfSSL home dir");*/
goto done;
}
if (sharedCtx && wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
/*err_sys("can't load client key file, "
"Please run from wolfSSL home dir");*/
goto done;
}
if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
/* call ssl setup callback */
if (cbf != NULL && cbf->ssl_ready != NULL) {
cbf->ssl_ready(ssl);
}
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_connect(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string(err, buff));
/*err_sys("SSL_connect failed");*/
goto done;
}
/* Build first session */
if (cb != NULL)
cb(ctx, ssl);
if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
/*err_sys("SSL_write failed");*/
goto done;
}
input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
if (input > 0) {
reply[input] = '\0';
fprintf(stderr, "Server response: %s\n", reply);
}
/* Session Resumption by reusing WOLFSSL object */
wolfSSL_set_quiet_shutdown(ssl, 1);
if (wolfSSL_shutdown(ssl) != WOLFSSL_SUCCESS) {
/* err_sys ("SSL shutdown failed"); */
goto done;
}
session = wolfSSL_get1_session(ssl);
if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
wolfSSL_SESSION_free(session);
/* err_sys ("SSL_clear failed"); */
goto done;
}
wolfSSL_set_session(ssl, session);
wolfSSL_SESSION_free(session);
session = NULL;
/* close socket once */
CloseSocket(sockfd);
sockfd = 0;
/* wait until server ready */
wait_tcp_ready((func_args*)server_args);
fprintf(stderr, "session resumption\n");
/* Do re-connect */
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
0, 0, NULL);
if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
/*err_sys("SSL_set_fd failed");*/
goto done;
}
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_connect(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string(err, buff));
/*err_sys("SSL_connect failed");*/
goto done;
}
/* Build first session */
if (cb != NULL)
cb(ctx, ssl);
if (wolfSSL_write(ssl, msg, msgSz) != msgSz) {
/*err_sys("SSL_write failed");*/
goto done;
}
input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
if (input > 0) {
reply[input] = '\0';
fprintf(stderr, "Server response: %s\n", reply);
}
((func_args*)args)->return_code = TEST_SUCCESS;
done:
wolfSSL_free(ssl);
if (!sharedCtx)
wolfSSL_CTX_free(ctx);
CloseSocket(sockfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
return;
}
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) &&
!defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_CLIENT) */
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)) && \
defined(HAVE_ALPN) && defined(HAVE_SNI) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_BIO)
#define HAVE_ALPN_PROTOS_SUPPORT
#endif
/* Generic TLS client / server with callbacks for API unit tests
* Used by SNI / ALPN / crypto callback helper functions */
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
(defined(HAVE_SNI) || defined(HAVE_ALPN) || defined(WOLF_CRYPTO_CB) || \
defined(HAVE_ALPN_PROTOS_SUPPORT)) || defined(WOLFSSL_STATIC_MEMORY)
#define ENABLE_TLS_CALLBACK_TEST
#endif
#if defined(ENABLE_TLS_CALLBACK_TEST) || \
(defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT))
/* TLS server for API unit testing - generic */
static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
{
callback_functions* callbacks = ((func_args*)args)->callbacks;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
SOCKET_T sfd = 0;
SOCKET_T cfd = 0;
word16 port;
char msg[] = "I hear you fa shizzle!";
int len = (int) XSTRLEN(msg);
char input[1024];
int idx;
int ret, err = 0;
((func_args*)args)->return_code = TEST_FAIL;
#if defined(USE_WINDOWS_API)
port = ((func_args*)args)->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
!defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
/* Let tcp_listen assign port */
port = 0;
#else
/* Use default port */
port = wolfSSLPort;
#endif
#ifdef WOLFSSL_DTLS
if (callbacks->method == wolfDTLS_server_method
#ifdef WOLFSSL_STATIC_MEMORY
|| callbacks->method_ex == wolfDTLS_server_method_ex
#endif
#ifndef NO_OLD_TLS
|| callbacks->method == wolfDTLSv1_server_method
#ifdef WOLFSSL_STATIC_MEMORY
|| callbacks->method_ex == wolfDTLSv1_server_method_ex
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
|| callbacks->method == wolfDTLSv1_2_server_method
#ifdef WOLFSSL_STATIC_MEMORY
|| callbacks->method_ex == wolfDTLSv1_2_server_method_ex
#endif
#endif
#ifdef WOLFSSL_DTLS13
|| callbacks->method == wolfDTLSv1_3_server_method
#ifdef WOLFSSL_STATIC_MEMORY
|| callbacks->method_ex == wolfDTLSv1_3_server_method_ex
#endif
#endif
) {
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0, 0, 0);
}
else
#endif
{
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
}
#ifdef WOLFSSL_STATIC_MEMORY
if (callbacks->method_ex != NULL && callbacks->mem != NULL &&
callbacks->memSz > 0) {
ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex,
callbacks->mem, callbacks->memSz, 0, 1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "CTX static new failed %d\n", ret);
goto cleanup;
}
}
#else
ctx = wolfSSL_CTX_new(callbacks->method());
#endif
if (ctx == NULL) {
fprintf(stderr, "CTX new failed\n");
goto cleanup;
}
/* set defaults */
if (callbacks->caPemFile == NULL)
callbacks->caPemFile = cliCertFile;
if (callbacks->certPemFile == NULL)
callbacks->certPemFile = svrCertFile;
if (callbacks->keyPemFile == NULL)
callbacks->keyPemFile = svrKeyFile;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
wolfSSL_CTX_SetDevId(ctx, callbacks->devId);
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
if (callbacks->method == wolfDTLSv1_2_server_method) {
if (wolfSSL_CTX_dtls_set_export(ctx, test_export) != WOLFSSL_SUCCESS)
goto cleanup;
}
#endif
if (wolfSSL_CTX_load_verify_locations(ctx, callbacks->caPemFile, 0) !=
WOLFSSL_SUCCESS) {
goto cleanup;
}
if (wolfSSL_CTX_use_certificate_file(ctx, callbacks->certPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (wolfSSL_CTX_use_PrivateKey_file(ctx, callbacks->keyPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
#ifdef HAVE_CRL
if (callbacks->crlPemFile != NULL) {
if (wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
}
#endif
if (callbacks->ctx_ready)
callbacks->ctx_ready(ctx);
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
fprintf(stderr, "SSL new failed\n");
goto cleanup;
}
if (wolfSSL_dtls(ssl)) {
SOCKADDR_IN_T cliAddr;
socklen_t cliLen;
cliLen = sizeof(cliAddr);
idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK,
(struct sockaddr*)&cliAddr, &cliLen);
if (idx <= 0) {
goto cleanup;
}
wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
}
else {
CloseSocket(sfd);
}
if (wolfSSL_set_fd(ssl, cfd) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (callbacks->loadToSSL) {
wolfSSL_SetDevId(ssl, callbacks->devId);
if (wolfSSL_use_certificate_file(ssl, callbacks->certPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (wolfSSL_use_PrivateKey_file(ssl, callbacks->keyPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
}
#ifdef NO_PSK
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
wolfSSL_SetTmpDH_file(ssl, dhParamFile, CERT_FILETYPE);
#elif !defined(NO_DH)
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
#endif
#endif
if (callbacks->ssl_ready)
callbacks->ssl_ready(ssl);
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_accept(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "accept error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
/*err_sys("SSL_accept failed");*/
}
else {
WOLFSSL_ASYNC_WHILE_PENDING(idx = wolfSSL_read(ssl, input, sizeof(input)-1),
idx <= 0);
if (idx > 0) {
input[idx] = 0;
fprintf(stderr, "Client message: %s\n", input);
}
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_write(ssl, msg, len),
len != ret);
if (len != ret) {
goto cleanup;
}
#if defined(WOLFSSL_SESSION_EXPORT) && !defined(HAVE_IO_POOL) && \
defined(WOLFSSL_DTLS)
if (wolfSSL_dtls(ssl)) {
byte* import;
word32 sz;
wolfSSL_dtls_export(ssl, NULL, &sz);
import = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (import == NULL) {
goto cleanup;
}
idx = wolfSSL_dtls_export(ssl, import, &sz);
if (idx < 0) {
goto cleanup;
}
if (wolfSSL_dtls_import(ssl, import, idx) < 0) {
goto cleanup;
}
XFREE(import, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
#ifdef WOLFSSL_TIRTOS
Task_yield();
#endif
((func_args*)args)->return_code = TEST_SUCCESS;
}
if (callbacks->on_result)
callbacks->on_result(ssl);
wolfSSL_shutdown(ssl);
cleanup:
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(cfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
/* TLS Client for API unit testing - generic */
static void run_wolfssl_client(void* args)
{
callback_functions* callbacks = ((func_args*)args)->callbacks;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
SOCKET_T sfd = 0;
char msg[] = "hello wolfssl server!";
int len = (int) XSTRLEN(msg);
char input[1024];
int ret, err = 0;
((func_args*)args)->return_code = TEST_FAIL;
/* set defaults */
if (callbacks->caPemFile == NULL)
callbacks->caPemFile = caCertFile;
if (callbacks->certPemFile == NULL)
callbacks->certPemFile = cliCertFile;
if (callbacks->keyPemFile == NULL)
callbacks->keyPemFile = cliKeyFile;
#ifdef WOLFSSL_STATIC_MEMORY
if (callbacks->method_ex != NULL && callbacks->mem != NULL &&
callbacks->memSz > 0) {
ret = wolfSSL_CTX_load_static_memory(&ctx, callbacks->method_ex,
callbacks->mem, callbacks->memSz, 0, 1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "CTX static new failed %d\n", ret);
goto cleanup;
}
}
#else
ctx = wolfSSL_CTX_new(callbacks->method());
#endif
if (ctx == NULL) {
fprintf(stderr, "CTX new failed\n");
goto cleanup;
}
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
if (!callbacks->loadToSSL) {
wolfSSL_CTX_SetDevId(ctx, callbacks->devId);
}
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
if (wolfSSL_CTX_load_verify_locations(ctx, callbacks->caPemFile, 0) !=
WOLFSSL_SUCCESS) {
goto cleanup;
}
if (!callbacks->loadToSSL) {
if (wolfSSL_CTX_use_certificate_file(ctx, callbacks->certPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (wolfSSL_CTX_use_PrivateKey_file(ctx, callbacks->keyPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
}
#ifdef HAVE_CRL
if (callbacks->crlPemFile != NULL) {
if (wolfSSL_CTX_LoadCRLFile(ctx, callbacks->crlPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
}
#endif
if (callbacks->ctx_ready)
callbacks->ctx_ready(ctx);
ssl = wolfSSL_new(ctx);
if (wolfSSL_dtls(ssl)) {
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port,
1, 0, ssl);
}
else {
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port,
0, 0, ssl);
}
if (wolfSSL_set_fd(ssl, sfd) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (callbacks->loadToSSL) {
wolfSSL_SetDevId(ssl, callbacks->devId);
if (wolfSSL_use_certificate_file(ssl, callbacks->certPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
if (wolfSSL_use_PrivateKey_file(ssl, callbacks->keyPemFile,
CERT_FILETYPE) != WOLFSSL_SUCCESS) {
goto cleanup;
}
}
if (callbacks->ssl_ready)
callbacks->ssl_ready(ssl);
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_connect(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
/*err_sys("SSL_connect failed");*/
}
else {
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_write(ssl, msg, len),
ret != len);
if (len != ret)
goto cleanup;
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_read(ssl, input, sizeof(input)-1),
ret <= 0);
if (ret > 0) {
input[ret] = '\0'; /* null term */
fprintf(stderr, "Server response: %s\n", input);
}
((func_args*)args)->return_code = TEST_SUCCESS;
}
if (callbacks->on_result)
callbacks->on_result(ssl);
cleanup:
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(sfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
}
#endif /* ENABLE_TLS_CALLBACK_TEST */
static int test_wolfSSL_read_write(void)
{
EXPECT_DECLS;
#ifndef NO_SHA256
/* The unit testing for read and write shall happen simultaneously, since
* one can't do anything with one without the other. (Except for a failure
* test case.) This function will call all the others that will set up,
* execute, and report their test findings.
*
* Set up the success case first. This function will become the template
* for the other tests. This should eventually be renamed
*
* The success case isn't interesting, how can this fail?
* - Do not give the client context a CA certificate. The connect should
* fail. Do not need server for this?
* - Using NULL for the ssl object on server. Do not need client for this.
* - Using NULL for the ssl object on client. Do not need server for this.
* - Good ssl objects for client and server. Client write() without server
* read().
* - Good ssl objects for client and server. Server write() without client
* read().
* - Forgetting the password callback?
*/
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
client_args.signal = &ready;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
test_client_nofail(&client_args, NULL);
join_thread(serverThread);
ExpectTrue(client_args.return_code);
ExpectTrue(server_args.return_code);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_read_write_ex(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char *test_str = "test";
int test_str_size;
size_t count;
byte buf[255];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfSSLv23_client_method, wolfSSLv23_server_method), 0);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
test_str_size = XSTRLEN("test") + 1;
ExpectIntEQ(wolfSSL_write_ex(ssl_c, test_str, test_str_size, &count),
WOLFSSL_SUCCESS);
ExpectIntEQ(count, test_str_size);
count = 0;
ExpectIntEQ(wolfSSL_read_ex(ssl_s, buf, sizeof(buf), &count), WOLFSSL_SUCCESS);
ExpectIntEQ(count, test_str_size);
ExpectIntEQ(XSTRCMP((char*)buf, test_str), 0);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return TEST_SUCCESS;
}
static int test_wolfSSL_reuse_WOLFSSLobj(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) && \
!defined(WOLFSSL_NO_TLS12)
/* The unit test for session resumption by reusing WOLFSSL object.
* WOLFSSL object is not cleared after first session. It reuse the object
* for second connection.
*/
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
callback_functions client_cbf;
callback_functions server_cbf;
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
client_cbf.method = wolfTLSv1_2_client_method;
server_cbf.method = wolfTLSv1_2_server_method;
client_args.callbacks = &client_cbf;
server_args.callbacks = &server_cbf;
server_args.signal = &ready;
client_args.signal = &ready;
/* the var is used for loop number */
server_args.argc = 2;
start_thread(test_server_loop, &server_args, &serverThread);
wait_tcp_ready(&server_args);
test_client_reuse_WOLFSSLobj(&client_args, NULL, &server_args);
join_thread(serverThread);
ExpectTrue(client_args.return_code);
ExpectTrue(server_args.return_code);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SESSION_CACHE) &&
* !defined(WOLFSSL_TLS13) */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_1_ctx_ready(
WOLFSSL_CTX* ctx)
{
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_USE_PREVERIFY;
wolfSSL_CTX_set_verify_depth(ctx, 2);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_CTX_verifyDepth_ServerClient_1(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
#ifdef WOLFSSL_TLS13
client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
client_cbf.ctx_ready =
test_wolfSSL_CTX_verifyDepth_ServerClient_1_ctx_ready;
/* test case 1 verify depth is equal to peer chain */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_2_ctx_ready(
WOLFSSL_CTX* ctx)
{
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_OVERRIDE_ERROR;
wolfSSL_CTX_set_verify_depth(ctx, 0);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_CTX_verifyDepth_ServerClient_2(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
#ifdef WOLFSSL_TLS13
client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
client_cbf.ctx_ready =
test_wolfSSL_CTX_verifyDepth_ServerClient_2_ctx_ready;
/* test case 2
* verify depth is zero, number of peer's chain is 2.
* verify result becomes MAX_CHAIN_ERROR, but it is overridden in
* callback.
*/
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CTX_verifyDepth_ServerClient_3_ctx_ready(
WOLFSSL_CTX* ctx)
{
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_USE_PREVERIFY;
wolfSSL_CTX_set_verify_depth(ctx, 0);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_CTX_verifyDepth_ServerClient_3(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
#ifdef WOLFSSL_TLS13
client_cbf.method = wolfTLSv1_3_client_method;
#endif /* WOLFSSL_TLS13 */
client_cbf.ctx_ready =
test_wolfSSL_CTX_verifyDepth_ServerClient_3_ctx_ready;
/* test case 3
* verify depth is zero, number of peer's chain is 2
* verify result becomes MAX_CHAIN_ERRO. call-back returns failure.
* therefore, handshake becomes failure.
*/
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), -1001);
ExpectIntEQ(client_cbf.return_code, -1000);
ExpectIntEQ(server_cbf.return_code, -1000);
ExpectIntEQ(client_cbf.last_err, WC_NO_ERR_TRACE(MAX_CHAIN_ERROR));
ExpectIntEQ(server_cbf.last_err, WC_NO_ERR_TRACE(FATAL_ERROR));
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
return EXPECT_RESULT();
}
#if defined(OPENSSL_ALL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_ECC) && !defined(NO_AES) && !defined(NO_SHA256)
static int test_wolfSSL_CTX_set_cipher_list_server_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "DEFAULT:!NULL"));
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_cipher_list_client_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256"));
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_CTX_set_cipher_list(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_ECC) && !defined(NO_AES) && !defined(NO_SHA256)
#if !defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX* ctxClient = NULL;
WOLFSSL* sslClient = NULL;
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
server_cbf.method = wolfTLSv1_2_server_method;
server_cbf.ctx_ready = test_wolfSSL_CTX_set_cipher_list_server_ctx_ready;
client_cbf.method = wolfTLSv1_2_client_method;
client_cbf.ctx_ready = test_wolfSSL_CTX_set_cipher_list_client_ctx_ready;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
/* check with cipher string that has '+' */
ExpectNotNull((ctxClient = wolfSSL_CTX_new(wolfTLSv1_2_client_method())));
/* Use trailing : with nothing to test for ASAN */
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctxClient, "ECDHE+AESGCM:"));
ExpectNotNull((sslClient = wolfSSL_new(ctxClient)));
/* check for the existence of an ECDHE ECDSA cipher suite */
if (EXPECT_SUCCESS()) {
int i = 0;
int found = 0;
const char* suite;
WOLF_STACK_OF(WOLFSSL_CIPHER)* sk = NULL;
WOLFSSL_CIPHER* current;
ExpectNotNull((sk = wolfSSL_get_ciphers_compat(sslClient)));
do {
current = wolfSSL_sk_SSL_CIPHER_value(sk, i++);
if (current) {
suite = wolfSSL_CIPHER_get_name(current);
if (suite && XSTRSTR(suite, "ECDSA")) {
found = 1;
break;
}
}
} while (current);
ExpectIntEQ(found, 1);
}
wolfSSL_free(sslClient);
wolfSSL_CTX_free(ctxClient);
#endif /* !WOLFSSL_NO_TLS12 */
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_HAVE_TLS_UNIQUE)
static int test_wolfSSL_get_finished_client_on_handshake(WOLFSSL_CTX* ctx,
WOLFSSL* ssl)
{
EXPECT_DECLS;
size_t msg_len;
(void)ctx;
/* get_finished test */
/* 1. get own sent message */
XMEMSET(client_side_msg1, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_finished(ssl, client_side_msg1, WC_MAX_DIGEST_SIZE);
ExpectIntGE(msg_len, 0);
/* 2. get peer message */
XMEMSET(client_side_msg2, 0, WC_MAX_DIGEST_SIZE);
msg_len = wolfSSL_get_peer_finished(ssl, client_side_msg2, WC_MAX_DIGEST_SIZE);
ExpectIntGE(msg_len, 0);
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_get_finished(void)
{
EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_HAVE_TLS_UNIQUE)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, test_wolfSSL_get_finished_client_on_handshake),
TEST_SUCCESS);
/* test received msg vs sent msg */
ExpectIntEQ(0, XMEMCMP(client_side_msg1, server_side_msg2, WC_MAX_DIGEST_SIZE));
ExpectIntEQ(0, XMEMCMP(client_side_msg2, server_side_msg1, WC_MAX_DIGEST_SIZE));
#endif /* HAVE_SSL_MEMIO_TESTS_DEPENDENCIES && WOLFSSL_HAVE_TLS_UNIQUE */
return EXPECT_RESULT();
}
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
!defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
!defined(NO_SESSION_CACHE)
/* Sessions to restore/store */
static WOLFSSL_SESSION* test_wolfSSL_CTX_add_session_client_sess;
static WOLFSSL_SESSION* test_wolfSSL_CTX_add_session_server_sess;
static WOLFSSL_CTX* test_wolfSSL_CTX_add_session_server_ctx;
static void test_wolfSSL_CTX_add_session_ctx_ready(WOLFSSL_CTX* ctx)
{
/* Don't store sessions. Lookup is still enabled. */
AssertIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
AssertIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
}
static void test_wolfSSL_CTX_add_session_on_result(WOLFSSL* ssl)
{
WOLFSSL_SESSION** sess;
#ifdef WOLFSSL_MUTEX_INITIALIZER
static wolfSSL_Mutex m = WOLFSSL_MUTEX_INITIALIZER(m);
(void)wc_LockMutex(&m);
#endif
if (wolfSSL_is_server(ssl))
sess = &test_wolfSSL_CTX_add_session_server_sess;
else
sess = &test_wolfSSL_CTX_add_session_client_sess;
if (*sess == NULL) {
#ifdef NO_SESSION_CACHE_REF
*sess = wolfSSL_get1_session(ssl);
AssertNotNull(*sess);
#else
/* Test for backwards compatibility */
if (wolfSSL_is_server(ssl)) {
*sess = wolfSSL_get1_session(ssl);
AssertNotNull(*sess);
}
else {
*sess = wolfSSL_get_session(ssl);
AssertNotNull(*sess);
}
#endif
/* Now save the session in the internal store to make it available
* for lookup. For TLS 1.3, we can't save the session without
* WOLFSSL_TICKET_HAVE_ID because there is no way to retrieve the
* session from cache. */
if (wolfSSL_is_server(ssl)
#ifndef WOLFSSL_TICKET_HAVE_ID
&& wolfSSL_version(ssl) != TLS1_3_VERSION
#endif
)
AssertIntEQ(wolfSSL_CTX_add_session(wolfSSL_get_SSL_CTX(ssl),
*sess), WOLFSSL_SUCCESS);
}
else {
/* If we have a session retrieved then remaining connections should be
* resuming on that session */
AssertIntEQ(wolfSSL_session_reused(ssl), 1);
}
#ifdef WOLFSSL_MUTEX_INITIALIZER
wc_UnLockMutex(&m);
#endif
/* Save CTX to be able to decrypt tickets */
if (wolfSSL_is_server(ssl) &&
test_wolfSSL_CTX_add_session_server_ctx == NULL) {
test_wolfSSL_CTX_add_session_server_ctx = wolfSSL_get_SSL_CTX(ssl);
AssertNotNull(test_wolfSSL_CTX_add_session_server_ctx);
AssertIntEQ(wolfSSL_CTX_up_ref(wolfSSL_get_SSL_CTX(ssl)),
WOLFSSL_SUCCESS);
}
#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
wolfSSL_session_reused(ssl))
#endif
{
/* With WOLFSSL_TICKET_HAVE_ID the peer certs should be available
* for all connections. TLS 1.3 only has tickets so if we don't
* include the session id in the ticket then the certificates
* will not be available on resumption. */
#ifdef KEEP_PEER_CERT
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
AssertNotNull(peer);
wolfSSL_X509_free(peer);
#endif
AssertNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
#ifdef OPENSSL_EXTRA
AssertNotNull(SSL_SESSION_get0_peer(*sess));
#endif
}
#endif /* SESSION_CERTS */
}
static void test_wolfSSL_CTX_add_session_ssl_ready(WOLFSSL* ssl)
{
/* Set the session to reuse for the client */
AssertIntEQ(wolfSSL_set_session(ssl,
test_wolfSSL_CTX_add_session_client_sess), WOLFSSL_SUCCESS);
}
#endif
static int test_wolfSSL_CTX_add_session(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
!defined(SINGLE_THREADED) && defined(WOLFSSL_TLS13) && \
!defined(NO_SESSION_CACHE)
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
callback_functions client_cb;
callback_functions server_cb;
method_provider methods[][2] = {
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
!defined(NO_DES3))
/* Without AES there are almost no ciphersuites available. This leads
* to no ciphersuites being available and an error. */
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method },
#endif
#ifndef WOLFSSL_NO_TLS12
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method },
#endif
/* Needs the default ticket callback since it is tied to the
* connection context and this makes it easy to carry over the ticket
* crypto context between connections */
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
defined(HAVE_SESSION_TICKET)
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method },
#endif
};
const size_t methodsLen = sizeof(methods)/sizeof(*methods);
size_t i, j;
for (i = 0; i < methodsLen; i++) {
/* First run creates a connection while the second+ run will attempt
* to resume the connection. The trick is that the internal cache
* is turned off. wolfSSL_CTX_add_session should put the session in
* the cache anyway. */
test_wolfSSL_CTX_add_session_client_sess = NULL;
test_wolfSSL_CTX_add_session_server_sess = NULL;
test_wolfSSL_CTX_add_session_server_ctx = NULL;
#ifdef NO_SESSION_CACHE_REF
for (j = 0; j < 4; j++) {
#else
/* The session may be overwritten in this case. Do only one resumption
* to stop this test from failing intermittently. */
for (j = 0; j < 2; j++) {
#endif
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = methods[i][0];
server_cb.method = methods[i][1];
server_args.signal = &ready;
server_args.callbacks = &server_cb;
client_args.signal = &ready;
client_args.callbacks = &client_cb;
if (test_wolfSSL_CTX_add_session_server_ctx != NULL) {
server_cb.ctx = test_wolfSSL_CTX_add_session_server_ctx;
server_cb.isSharedCtx = 1;
}
server_cb.ctx_ready = test_wolfSSL_CTX_add_session_ctx_ready;
client_cb.ctx_ready = test_wolfSSL_CTX_add_session_ctx_ready;
if (j != 0)
client_cb.ssl_ready = test_wolfSSL_CTX_add_session_ssl_ready;
server_cb.on_result = test_wolfSSL_CTX_add_session_on_result;
client_cb.on_result = test_wolfSSL_CTX_add_session_on_result;
server_cb.ticNoInit = 1; /* Use default builtin */
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
test_client_nofail(&client_args, NULL);
join_thread(serverThread);
ExpectTrue(client_args.return_code);
ExpectTrue(server_args.return_code);
FreeTcpReady(&ready);
if (EXPECT_FAIL())
break;
}
wolfSSL_SESSION_free(test_wolfSSL_CTX_add_session_client_sess);
wolfSSL_SESSION_free(test_wolfSSL_CTX_add_session_server_sess);
wolfSSL_CTX_free(test_wolfSSL_CTX_add_session_server_ctx);
if (EXPECT_FAIL())
break;
}
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
/* twcase - prefix for test_wolfSSL_CTX_add_session_ext */
/* Sessions to restore/store */
static WOLFSSL_SESSION* twcase_server_first_session_ptr;
static WOLFSSL_SESSION* twcase_client_first_session_ptr;
static WOLFSSL_CTX* twcase_server_current_ctx_ptr;
static int twcase_new_session_called = 0;
static int twcase_remove_session_called = 0;
static int twcase_get_session_called = 0;
/* Test default, SESSIONS_PER_ROW*SESSION_ROWS = 3*11, see ssl.c */
#define SESSION_CACHE_SIZE 33
typedef struct {
const byte* key; /* key, altSessionID, session ID, NULL if empty */
WOLFSSL_SESSION* value;
} hashTable_entry;
typedef struct {
hashTable_entry entries[SESSION_CACHE_SIZE]; /* hash slots */
size_t capacity; /* size of entries */
size_t length; /* number of items in the hash table */
wolfSSL_Mutex htLock; /* lock */
}hashTable;
static hashTable server_sessionCache;
static int twcase_new_sessionCb(WOLFSSL *ssl, WOLFSSL_SESSION *sess)
{
int i;
unsigned int len;
(void)ssl;
/*
* This example uses a hash table.
* Steps you should take for a non-demo code:
* - acquire a lock for the file named according to the session id
* - open the file
* - encrypt and write the SSL_SESSION object to the file
* - release the lock
*
* Return:
* 0: The callback does not wish to hold a reference of the sess
* 1: The callback wants to hold a reference of the sess. The callback is
* now also responsible for calling wolfSSL_SESSION_free() on sess.
*/
if (sess == NULL)
return 0;
if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
return 0;
}
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
if (server_sessionCache.entries[i].value == NULL) {
server_sessionCache.entries[i].key = SSL_SESSION_get_id(sess, &len);
server_sessionCache.entries[i].value = sess;
server_sessionCache.length++;
break;
}
}
++twcase_new_session_called;
wc_UnLockMutex(&server_sessionCache.htLock);
fprintf(stderr, "\t\ttwcase_new_session_called %d\n",
twcase_new_session_called);
return 1;
}
static void twcase_remove_sessionCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
{
int i;
(void)ctx;
(void)sess;
if (sess == NULL)
return;
/*
* This example uses a hash table.
* Steps you should take for a non-demo code:
* - acquire a lock for the file named according to the session id
* - remove the file
* - release the lock
*/
if (wc_LockMutex(&server_sessionCache.htLock) != 0) {
return;
}
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
if (server_sessionCache.entries[i].key != NULL &&
XMEMCMP(server_sessionCache.entries[i].key,
sess->sessionID, SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
server_sessionCache.entries[i].value = NULL;
server_sessionCache.entries[i].key = NULL;
server_sessionCache.length--;
break;
}
}
++twcase_remove_session_called;
wc_UnLockMutex(&server_sessionCache.htLock);
fprintf(stderr, "\t\ttwcase_remove_session_called %d\n",
twcase_remove_session_called);
}
static WOLFSSL_SESSION *twcase_get_sessionCb(WOLFSSL *ssl,
const unsigned char *id, int len, int *ref)
{
int i;
(void)ssl;
(void)id;
(void)len;
/*
* This example uses a hash table.
* Steps you should take for a non-demo code:
* - acquire a lock for the file named according to the session id in the
* 2nd arg
* - read and decrypt contents of file and create a new SSL_SESSION
* - object release the lock
* - return the new session object
*/
fprintf(stderr, "\t\ttwcase_get_session_called %d\n",
++twcase_get_session_called);
/* This callback want to retain a copy of the object. If we want wolfSSL to
* be responsible for the pointer then set to 0. */
*ref = 1;
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
if (server_sessionCache.entries[i].key != NULL &&
XMEMCMP(server_sessionCache.entries[i].key, id,
SSL_MAX_SSL_SESSION_ID_LENGTH) == 0) {
return server_sessionCache.entries[i].value;
}
}
return NULL;
}
static int twcase_get_sessionCb_cleanup(void)
{
int i;
int cnt = 0;
/* If twcase_get_sessionCb sets *ref = 1, the application is responsible
* for freeing sessions */
for (i = 0; i < SESSION_CACHE_SIZE; i++) {
if (server_sessionCache.entries[i].value != NULL) {
wolfSSL_SESSION_free(server_sessionCache.entries[i].value);
cnt++;
}
}
fprintf(stderr, "\t\ttwcase_get_sessionCb_cleanup freed %d sessions\n",
cnt);
return TEST_SUCCESS;
}
static int twcase_cache_intOff_extOff(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
/* off - Disable internal cache */
ExpectIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
ExpectIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
/* off - Do not setup external cache */
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return EXPECT_RESULT();
}
static int twcase_cache_intOn_extOff(WOLFSSL_CTX* ctx)
{
/* on - internal cache is on by default */
/* off - Do not setup external cache */
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return TEST_SUCCESS;
}
static int twcase_cache_intOff_extOn(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
/* off - Disable internal cache */
ExpectIntEQ(wolfSSL_CTX_set_session_cache_mode(ctx,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
ExpectIntEQ(wolfSSL_CTX_get_session_cache_mode(ctx) &
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE,
WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE);
#endif
/* on - Enable external cache */
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return EXPECT_RESULT();
}
static int twcase_cache_intOn_extOn(WOLFSSL_CTX* ctx)
{
/* on - internal cache is on by default */
/* on - Enable external cache */
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return TEST_SUCCESS;
}
static int twcase_cache_intOn_extOn_noTicket(WOLFSSL_CTX* ctx)
{
/* on - internal cache is on by default */
/* on - Enable external cache */
wolfSSL_CTX_sess_set_new_cb(ctx, twcase_new_sessionCb);
wolfSSL_CTX_sess_set_remove_cb(ctx, twcase_remove_sessionCb);
wolfSSL_CTX_sess_set_get_cb(ctx, twcase_get_sessionCb);
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TICKET);
/* Require both peers to provide certs */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return TEST_SUCCESS;
}
static int twcase_server_sess_ctx_pre_shutdown(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_SESSION** sess;
if (wolfSSL_is_server(ssl))
sess = &twcase_server_first_session_ptr;
else
return TEST_SUCCESS;
if (*sess == NULL) {
ExpectNotNull(*sess = wolfSSL_get1_session(ssl));
/* Now save the session in the internal store to make it available
* for lookup. For TLS 1.3, we can't save the session without
* WOLFSSL_TICKET_HAVE_ID because there is no way to retrieve the
* session from cache. */
if (wolfSSL_is_server(ssl)
#ifndef WOLFSSL_TICKET_HAVE_ID
&& wolfSSL_version(ssl) != TLS1_3_VERSION
&& wolfSSL_version(ssl) != DTLS1_3_VERSION
#endif
) {
ExpectIntEQ(wolfSSL_CTX_add_session(wolfSSL_get_SSL_CTX(ssl),
*sess), WOLFSSL_SUCCESS);
}
}
/* Save CTX to be able to decrypt tickets */
if (twcase_server_current_ctx_ptr == NULL) {
ExpectNotNull(twcase_server_current_ctx_ptr = wolfSSL_get_SSL_CTX(ssl));
ExpectIntEQ(wolfSSL_CTX_up_ref(wolfSSL_get_SSL_CTX(ssl)),
WOLFSSL_SUCCESS);
}
#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
wolfSSL_session_reused(ssl))
#endif
{
/* With WOLFSSL_TICKET_HAVE_ID the peer certs should be available
* for all connections. TLS 1.3 only has tickets so if we don't
* include the session id in the ticket then the certificates
* will not be available on resumption. */
#ifdef KEEP_PEER_CERT
WOLFSSL_X509* peer = NULL;
ExpectNotNull(peer = wolfSSL_get_peer_certificate(ssl));
wolfSSL_X509_free(peer);
#endif
ExpectNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
}
#endif
return EXPECT_RESULT();
}
static int twcase_client_sess_ctx_pre_shutdown(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_SESSION** sess;
sess = &twcase_client_first_session_ptr;
if (*sess == NULL) {
ExpectNotNull(*sess = wolfSSL_get1_session(ssl));
}
else {
/* If we have a session retrieved then remaining connections should be
* resuming on that session */
ExpectIntEQ(wolfSSL_session_reused(ssl), 1);
}
#ifdef SESSION_CERTS
#ifndef WOLFSSL_TICKET_HAVE_ID
if (wolfSSL_version(ssl) != TLS1_3_VERSION &&
wolfSSL_session_reused(ssl))
#endif
{
#ifdef KEEP_PEER_CERT
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
ExpectNotNull(peer);
wolfSSL_X509_free(peer);
#endif
ExpectNotNull(wolfSSL_SESSION_get_peer_chain(*sess));
#ifdef OPENSSL_EXTRA
ExpectNotNull(wolfSSL_SESSION_get0_peer(*sess));
#endif
}
#endif
return EXPECT_RESULT();
}
static int twcase_client_set_sess_ssl_ready(WOLFSSL* ssl)
{
EXPECT_DECLS;
/* Set the session to reuse for the client */
ExpectNotNull(ssl);
ExpectNotNull(twcase_client_first_session_ptr);
ExpectIntEQ(wolfSSL_set_session(ssl,twcase_client_first_session_ptr),
WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
struct test_add_session_ext_params {
method_provider client_meth;
method_provider server_meth;
const char* tls_version;
};
static int test_wolfSSL_CTX_add_session_ext(
struct test_add_session_ext_params* param)
{
EXPECT_DECLS;
/* Test the default 33 sessions */
int j;
/* Clear cache before starting */
wolfSSL_CTX_flush_sessions(NULL, -1);
XMEMSET(&server_sessionCache, 0, sizeof(hashTable));
if (wc_InitMutex(&server_sessionCache.htLock) != 0)
return BAD_MUTEX_E;
server_sessionCache.capacity = SESSION_CACHE_SIZE;
fprintf(stderr, "\tBegin %s\n", param->tls_version);
for (j = 0; j < 5; j++) {
int tls13 = XSTRSTR(param->tls_version, "TLSv1_3") != NULL;
int dtls = XSTRSTR(param->tls_version, "DTLS") != NULL;
test_ssl_cbf client_cb;
test_ssl_cbf server_cb;
(void)dtls;
/* Test five cache configurations */
twcase_client_first_session_ptr = NULL;
twcase_server_first_session_ptr = NULL;
twcase_server_current_ctx_ptr = NULL;
twcase_new_session_called = 0;
twcase_remove_session_called = 0;
twcase_get_session_called = 0;
/* connection 1 - first connection */
fprintf(stderr, "\tconnect: %s: j=%d\n", param->tls_version, j);
XMEMSET(&client_cb, 0, sizeof(client_cb));
XMEMSET(&server_cb, 0, sizeof(server_cb));
client_cb.method = param->client_meth;
server_cb.method = param->server_meth;
if (dtls)
client_cb.doUdp = server_cb.doUdp = 1;
/* Setup internal and external cache */
switch (j) {
case 0:
/* SSL_OP_NO_TICKET stateful ticket case */
server_cb.ctx_ready = twcase_cache_intOn_extOn_noTicket;
break;
case 1:
server_cb.ctx_ready = twcase_cache_intOn_extOn;
break;
case 2:
server_cb.ctx_ready = twcase_cache_intOff_extOn;
break;
case 3:
server_cb.ctx_ready = twcase_cache_intOn_extOff;
break;
case 4:
server_cb.ctx_ready = twcase_cache_intOff_extOff;
break;
}
client_cb.ctx_ready = twcase_cache_intOff_extOff;
/* Add session to internal cache and save SSL session for testing */
server_cb.on_result = twcase_server_sess_ctx_pre_shutdown;
/* Save client SSL session for testing */
client_cb.on_result = twcase_client_sess_ctx_pre_shutdown;
server_cb.ticNoInit = 1; /* Use default builtin */
/* Don't free/release ctx */
server_cb.ctx = twcase_server_current_ctx_ptr;
server_cb.isSharedCtx = 1;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
&server_cb, NULL), TEST_SUCCESS);
ExpectIntEQ(twcase_get_session_called, 0);
if (EXPECT_FAIL()) {
wolfSSL_SESSION_free(twcase_client_first_session_ptr);
wolfSSL_SESSION_free(twcase_server_first_session_ptr);
wolfSSL_CTX_free(twcase_server_current_ctx_ptr);
break;
}
switch (j) {
case 0:
case 1:
case 2:
/* cache cannot be searched with out a connection */
/* Add a new session */
ExpectIntEQ(twcase_new_session_called, 1);
/* In twcase_server_sess_ctx_pre_shutdown
* wolfSSL_CTX_add_session which evicts the existing session
* in cache and adds it back in */
ExpectIntLE(twcase_remove_session_called, 1);
break;
case 3:
case 4:
/* no external cache */
ExpectIntEQ(twcase_new_session_called, 0);
ExpectIntEQ(twcase_remove_session_called, 0);
break;
}
/* connection 2 - session resume */
fprintf(stderr, "\tresume: %s: j=%d\n", param->tls_version, j);
twcase_new_session_called = 0;
twcase_remove_session_called = 0;
twcase_get_session_called = 0;
server_cb.on_result = 0;
client_cb.on_result = 0;
server_cb.ticNoInit = 1; /* Use default builtin */
server_cb.ctx = twcase_server_current_ctx_ptr;
/* try session resumption */
client_cb.ssl_ready = twcase_client_set_sess_ssl_ready;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
&server_cb, NULL), TEST_SUCCESS);
/* Clear cache before checking */
wolfSSL_CTX_flush_sessions(NULL, -1);
switch (j) {
case 0:
if (tls13) {
/* (D)TLSv1.3 stateful case */
/* cache hit */
/* DTLS accesses cache once for stateless parsing and
* once for stateful parsing */
ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
/* (D)TLSv1.3 creates a new ticket,
* updates both internal and external cache */
ExpectIntEQ(twcase_new_session_called, 1);
/* A new session ID is created for a new ticket */
ExpectIntEQ(twcase_remove_session_called, 2);
}
else {
/* non (D)TLSv1.3 case, no update */
/* DTLS accesses cache once for stateless parsing and
* once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
ExpectIntEQ(twcase_get_session_called, 1);
#endif
ExpectIntEQ(twcase_new_session_called, 0);
/* Called on session added in
* twcase_server_sess_ctx_pre_shutdown */
ExpectIntEQ(twcase_remove_session_called, 1);
}
break;
case 1:
if (tls13) {
/* (D)TLSv1.3 case */
/* cache hit */
ExpectIntEQ(twcase_get_session_called, 1);
/* (D)TLSv1.3 creates a new ticket,
* updates both internal and external cache */
ExpectIntEQ(twcase_new_session_called, 1);
/* Called on session added in
* twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
ExpectIntEQ(twcase_remove_session_called, 1);
}
else {
/* non (D)TLSv1.3 case */
/* cache hit */
/* DTLS accesses cache once for stateless parsing and
* once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
ExpectIntEQ(twcase_get_session_called, 1);
#endif
ExpectIntEQ(twcase_new_session_called, 0);
/* Called on session added in
* twcase_server_sess_ctx_pre_shutdown */
ExpectIntEQ(twcase_remove_session_called, 1);
}
break;
case 2:
if (tls13) {
/* (D)TLSv1.3 case */
/* cache hit */
ExpectIntEQ(twcase_get_session_called, 1);
/* (D)TLSv1.3 creates a new ticket,
* updates both internal and external cache */
ExpectIntEQ(twcase_new_session_called, 1);
/* Called on session added in
* twcase_server_sess_ctx_pre_shutdown and by wolfSSL */
ExpectIntEQ(twcase_remove_session_called, 1);
}
else {
/* non (D)TLSv1.3 case */
/* cache hit */
/* DTLS accesses cache once for stateless parsing and
* once for stateful parsing */
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
ExpectIntEQ(twcase_get_session_called, !dtls ? 1 : 2);
#else
ExpectIntEQ(twcase_get_session_called, 1);
#endif
ExpectIntEQ(twcase_new_session_called, 0);
/* Called on session added in
* twcase_server_sess_ctx_pre_shutdown */
ExpectIntEQ(twcase_remove_session_called, 1);
}
break;
case 3:
case 4:
/* no external cache */
ExpectIntEQ(twcase_get_session_called, 0);
ExpectIntEQ(twcase_new_session_called, 0);
ExpectIntEQ(twcase_remove_session_called, 0);
break;
}
wolfSSL_SESSION_free(twcase_client_first_session_ptr);
wolfSSL_SESSION_free(twcase_server_first_session_ptr);
wolfSSL_CTX_free(twcase_server_current_ctx_ptr);
if (EXPECT_FAIL())
break;
}
twcase_get_sessionCb_cleanup();
XMEMSET(&server_sessionCache.entries, 0,
sizeof(server_sessionCache.entries));
fprintf(stderr, "\tEnd %s\n", param->tls_version);
wc_FreeMutex(&server_sessionCache.htLock);
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_CTX_add_session_ext_tls13(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID)
struct test_add_session_ext_params param[1] = {
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls13(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID)
#ifdef WOLFSSL_DTLS13
struct test_add_session_ext_params param[1] = {
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_tls12(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#ifndef WOLFSSL_NO_TLS12
struct test_add_session_ext_params param[1] = {
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls12(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#ifndef WOLFSSL_NO_TLS12
#ifdef WOLFSSL_DTLS
struct test_add_session_ext_params param[1] = {
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_tls11(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
!defined(NO_DES3))
struct test_add_session_ext_params param[1] = {
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_session_ext_dtls1(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_EXT_CACHE) && \
defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
defined(OPENSSL_EXTRA) && defined(SESSION_CERTS) && \
defined(HAVE_SESSION_TICKET) && \
!defined(TITAN_SESSION_CACHE) && \
!defined(HUGE_SESSION_CACHE) && \
!defined(BIG_SESSION_CACHE) && \
!defined(MEDIUM_SESSION_CACHE)
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
!defined(NO_DES3))
#ifdef WOLFSSL_DTLS
struct test_add_session_ext_params param[1] = {
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" }
};
ExpectIntEQ(test_wolfSSL_CTX_add_session_ext(param), TEST_SUCCESS);
#endif
#endif
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT)
/* canned export of a session using older version 3 */
static unsigned char version_3[] = {
0xA5, 0xA3, 0x01, 0x88, 0x00, 0x3c, 0x00, 0x01,
0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30,
0x05, 0x09, 0x0A, 0x01, 0x01, 0x00, 0x0D, 0x05,
0xFE, 0xFD, 0x01, 0x25, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01,
0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x05,
0x12, 0xCF, 0x22, 0xA1, 0x9F, 0x1C, 0x39, 0x1D,
0x31, 0x11, 0x12, 0x1D, 0x11, 0x18, 0x0D, 0x0B,
0xF3, 0xE1, 0x4D, 0xDC, 0xB1, 0xF1, 0x39, 0x98,
0x91, 0x6C, 0x48, 0xE5, 0xED, 0x11, 0x12, 0xA0,
0x00, 0xF2, 0x25, 0x4C, 0x09, 0x26, 0xD1, 0x74,
0xDF, 0x23, 0x40, 0x15, 0x6A, 0x42, 0x2A, 0x26,
0xA5, 0xAC, 0x56, 0xD5, 0x4A, 0x20, 0xB7, 0xE9,
0xEF, 0xEB, 0xAF, 0xA8, 0x1E, 0x23, 0x7C, 0x04,
0xAA, 0xA1, 0x6D, 0x92, 0x79, 0x7B, 0xFA, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x0C, 0x79, 0x7B, 0xFA, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA1, 0x6D,
0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00,
0x10, 0x00, 0x10, 0x08, 0x02, 0x05, 0x08, 0x01,
0x30, 0x28, 0x00, 0x00, 0x0F, 0x00, 0x02, 0x00,
0x09, 0x31, 0x32, 0x37, 0x2E, 0x30, 0x2E, 0x30,
0x2E, 0x31, 0xED, 0x4F
};
#endif /* defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) */
static int test_wolfSSL_dtls_export(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT)
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
callback_functions server_cbf;
callback_functions client_cbf;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
/* set using dtls */
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
server_cbf.method = wolfDTLSv1_2_server_method;
client_cbf.method = wolfDTLSv1_2_client_method;
server_args.callbacks = &server_cbf;
client_args.callbacks = &client_cbf;
server_args.signal = &ready;
client_args.signal = &ready;
start_thread(run_wolfssl_server, &server_args, &serverThread);
wait_tcp_ready(&server_args);
run_wolfssl_client(&client_args);
join_thread(serverThread);
ExpectTrue(client_args.return_code);
ExpectTrue(server_args.return_code);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
if (EXPECT_SUCCESS()) {
SOCKET_T sockfd = 0;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
char msg[64] = "hello wolfssl!";
char reply[1024];
int msgSz = (int)XSTRLEN(msg);
byte *session, *window;
unsigned int sessionSz = 0;
unsigned int windowSz = 0;
#ifndef TEST_IPV6
struct sockaddr_in peerAddr;
#else
struct sockaddr_in6 peerAddr;
#endif /* TEST_IPV6 */
int i;
/* Set ctx to DTLS 1.2 */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* test importing version 3 */
ExpectIntGE(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
/* test importing bad length and bad version */
version_3[2]++;
ExpectIntLT(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
version_3[2]--; version_3[1] = 0XA0;
ExpectIntLT(wolfSSL_dtls_import(ssl, version_3, sizeof(version_3)), 0);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
/* check storing client state after connection and storing window only */
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
/* set using dtls */
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
server_cbf.method = wolfDTLSv1_2_server_method;
server_cbf.doUdp = 1;
server_args.callbacks = &server_cbf;
server_args.argc = 3; /* set loop_count to 3 */
server_args.signal = &ready;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
/* create and connect with client */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 1, 0, NULL);
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
/* store server information connected too */
XMEMSET(&peerAddr, 0, sizeof(peerAddr));
#ifndef TEST_IPV6
peerAddr.sin_family = AF_INET;
ExpectIntEQ(XINET_PTON(AF_INET, wolfSSLIP, &peerAddr.sin_addr),1);
peerAddr.sin_port = XHTONS(server_args.signal->port);
#else
peerAddr.sin6_family = AF_INET6;
ExpectIntEQ(
XINET_PTON(AF_INET6, wolfSSLIP, &peerAddr.sin6_addr),1);
peerAddr.sin6_port = XHTONS(server_args.signal->port);
#endif
ExpectIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls_export(ssl, NULL, &sessionSz), 0);
session = (byte*)XMALLOC(sessionSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
ExpectIntGT(wolfSSL_dtls_export(ssl, session, &sessionSz), 0);
ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
ExpectIntGT(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
ExpectIntEQ(wolfSSL_dtls_export_state_only(ssl, NULL, &windowSz), 0);
window = (byte*)XMALLOC(windowSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
ExpectIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
wolfSSL_free(ssl);
for (i = 1; EXPECT_SUCCESS() && i < server_args.argc; i++) {
/* restore state */
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntGT(wolfSSL_dtls_import(ssl, session, sessionSz), 0);
ExpectIntGT(wolfSSL_dtls_import(ssl, window, windowSz), 0);
ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls_set_peer(ssl, &peerAddr, sizeof(peerAddr)),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
ExpectIntGE(wolfSSL_read(ssl, reply, sizeof(reply)), 0);
ExpectIntGT(wolfSSL_dtls_export_state_only(ssl, window, &windowSz), 0);
wolfSSL_free(ssl);
}
XFREE(session, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(window, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_CTX_free(ctx);
fprintf(stderr, "done and waiting for server\n");
join_thread(serverThread);
ExpectIntEQ(server_args.return_code, TEST_SUCCESS);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
}
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_NO_TLS12)
#ifdef WOLFSSL_TLS13
static const byte canned_client_tls13_session_v4[] = {
0xA7, 0xA4, 0x01, 0x18, 0x00, 0x41, 0x00, 0x00,
0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
0x01, 0x0A, 0x0F, 0x10, 0x01, 0x02, 0x09, 0x00,
0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00,
0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0x11, 0x01, 0x01, 0x00, 0x20, 0x84, 0x4F, 0x18,
0xD8, 0xC1, 0x24, 0xD8, 0xBB, 0x17, 0x9E, 0x31,
0xA3, 0xF8, 0xA7, 0x3C, 0xBA, 0xEC, 0xFA, 0xB4,
0x7F, 0xC5, 0x78, 0xEB, 0x6D, 0xE3, 0x2B, 0x7B,
0x94, 0xBE, 0x20, 0x11, 0x7E, 0x17, 0x10, 0xA7,
0x10, 0x19, 0xEC, 0x62, 0xCC, 0xBE, 0xF5, 0x01,
0x35, 0x3C, 0xEA, 0xEF, 0x44, 0x3C, 0x40, 0xA2,
0xBC, 0x18, 0x43, 0xA1, 0xA1, 0x65, 0x5C, 0x48,
0xE2, 0xF9, 0x38, 0xEB, 0x11, 0x10, 0x72, 0x7C,
0x78, 0x22, 0x13, 0x3B, 0x19, 0x40, 0xF0, 0x73,
0xBE, 0x96, 0x14, 0x78, 0x26, 0xB9, 0x6B, 0x2E,
0x72, 0x22, 0x0D, 0x90, 0x94, 0xDD, 0x78, 0x77,
0xFC, 0x0C, 0x2E, 0x63, 0x6E, 0xF0, 0x0C, 0x35,
0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0, 0x6F,
0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A, 0xA0,
0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x35, 0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0,
0x6F, 0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A,
0xA0, 0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06,
0x00, 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x10,
0x00, 0x10, 0x07, 0x02, 0x04, 0x00, 0x00, 0x20,
0x28, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03
};
static const byte canned_client_tls13_session_v5[] = {
0xa7, 0xa5, 0x01, 0x19, 0x00, 0x42, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80,
0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x0a, 0x0f, 0x10,
0x01, 0x02, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04,
0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00,
0x00, 0x11, 0x01, 0x01, 0x00, 0x20, 0x84, 0x4f, 0x18, 0xd8, 0xc1, 0x24,
0xd8, 0xbb, 0x17, 0x9e, 0x31, 0xa3, 0xf8, 0xa7, 0x3c, 0xba, 0xec, 0xfa,
0xb4, 0x7f, 0xc5, 0x78, 0xeb, 0x6d, 0xe3, 0x2b, 0x7b, 0x94, 0xbe, 0x20,
0x11, 0x7e, 0x17, 0x10, 0xa7, 0x10, 0x19, 0xec, 0x62, 0xcc, 0xbe, 0xf5,
0x01, 0x35, 0x3c, 0xea, 0xef, 0x44, 0x3c, 0x40, 0xa2, 0xbc, 0x18, 0x43,
0xa1, 0xa1, 0x65, 0x5c, 0x48, 0xe2, 0xf9, 0x38, 0xeb, 0x11, 0x10, 0x72,
0x7c, 0x78, 0x22, 0x13, 0x3b, 0x19, 0x40, 0xf0, 0x73, 0xbe, 0x96, 0x14,
0x78, 0x26, 0xb9, 0x6b, 0x2e, 0x72, 0x22, 0x0d, 0x90, 0x94, 0xdd, 0x78,
0x77, 0xfc, 0x0c, 0x2e, 0x63, 0x6e, 0xf0, 0x0c, 0x35, 0x41, 0xcd, 0xf3,
0x49, 0x31, 0x08, 0xd0, 0x6f, 0x02, 0x3d, 0xc1, 0xd3, 0xb7, 0xee, 0x3a,
0xa0, 0x8e, 0xa1, 0x4d, 0xc3, 0x2e, 0x5e, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x35, 0x41, 0xcd, 0xf3, 0x49, 0x31, 0x08,
0xd0, 0x6f, 0x02, 0x3d, 0xc1, 0xd3, 0xb7, 0xee, 0x3a, 0xa0, 0x8e, 0xa1,
0x4d, 0xc3, 0x2e, 0x5e, 0x06, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0c, 0x00,
0x10, 0x00, 0x10, 0x07, 0x02, 0x04, 0x00, 0x00, 0x20, 0x28, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
};
static const byte canned_server_tls13_session[] = {
0xA7, 0xA4, 0x01, 0x18, 0x00, 0x41, 0x01, 0x00,
0x01, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
0x01, 0x0A, 0x0F, 0x10, 0x01, 0x02, 0x00, 0x0F,
0x05, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00,
0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x11, 0x01, 0x01, 0x00, 0x20, 0x84, 0x4F, 0x18,
0xD8, 0xC1, 0x24, 0xD8, 0xBB, 0x17, 0x9E, 0x31,
0xA3, 0xF8, 0xA7, 0x3C, 0xBA, 0xEC, 0xFA, 0xB4,
0x7F, 0xC5, 0x78, 0xEB, 0x6D, 0xE3, 0x2B, 0x7B,
0x94, 0xBE, 0x20, 0x11, 0x7E, 0x17, 0x10, 0xA7,
0x10, 0x19, 0xEC, 0x62, 0xCC, 0xBE, 0xF5, 0x01,
0x35, 0x3C, 0xEA, 0xEF, 0x44, 0x3C, 0x40, 0xA2,
0xBC, 0x18, 0x43, 0xA1, 0xA1, 0x65, 0x5C, 0x48,
0xE2, 0xF9, 0x38, 0xEB, 0x11, 0x10, 0x72, 0x7C,
0x78, 0x22, 0x13, 0x3B, 0x19, 0x40, 0xF0, 0x73,
0xBE, 0x96, 0x14, 0x78, 0x26, 0xB9, 0x6B, 0x2E,
0x72, 0x22, 0x0D, 0x90, 0x94, 0xDD, 0x78, 0x77,
0xFC, 0x0C, 0x2E, 0x63, 0x6E, 0xF0, 0x0C, 0x35,
0x41, 0xCD, 0xF3, 0x49, 0x31, 0x08, 0xD0, 0x6F,
0x02, 0x3D, 0xC1, 0xD3, 0xB7, 0xEE, 0x3A, 0xA0,
0x8E, 0xA1, 0x4D, 0xC3, 0x2E, 0x5E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0xD3, 0xB7, 0xEE, 0x3A, 0xA0, 0x8E, 0xA1, 0x4D,
0xC3, 0x2E, 0x5E, 0x06, 0x35, 0x41, 0xCD, 0xF3,
0x49, 0x31, 0x08, 0xD0, 0x6F, 0x02, 0x3D, 0xC1,
0x00, 0x10, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x10,
0x00, 0x10, 0x07, 0x02, 0x04, 0x00, 0x00, 0x20,
0x28, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04
};
#endif /* WOLFSSL_TLS13 */
static const byte canned_client_session_v4[] = {
0xA7, 0xA4, 0x01, 0x40, 0x00, 0x41, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0x27, 0x0A, 0x0D, 0x10, 0x01, 0x01, 0x0A, 0x00,
0x05, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x00,
0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x0A, 0x01, 0x01, 0x00, 0x20, 0x69, 0x11, 0x6D,
0x97, 0x15, 0x6E, 0x52, 0x27, 0xD6, 0x1D, 0x1D,
0xF5, 0x0D, 0x59, 0xA5, 0xAC, 0x2E, 0x8C, 0x0E,
0xCB, 0x26, 0x1E, 0xE2, 0xCE, 0xBB, 0xCE, 0xE1,
0x7D, 0xD7, 0xEF, 0xA5, 0x44, 0x80, 0x2A, 0xDE,
0xBB, 0x75, 0xB0, 0x1D, 0x75, 0x17, 0x20, 0x4C,
0x08, 0x05, 0x1B, 0xBA, 0x60, 0x1F, 0x6C, 0x91,
0x8C, 0xAA, 0xBB, 0xE5, 0xA3, 0x0B, 0x12, 0x3E,
0xC0, 0x35, 0x43, 0x1D, 0xE2, 0x10, 0xE2, 0x02,
0x92, 0x4B, 0x8F, 0x05, 0xA9, 0x4B, 0xCC, 0x90,
0xC3, 0x0E, 0xC2, 0x0F, 0xE9, 0x33, 0x85, 0x9B,
0x3C, 0x19, 0x21, 0xD5, 0x62, 0xE5, 0xE1, 0x17,
0x8F, 0x8C, 0x19, 0x52, 0xD8, 0x59, 0x10, 0x2D,
0x20, 0x6F, 0xBA, 0xC1, 0x1C, 0xD1, 0x82, 0xC7,
0x32, 0x1B, 0xBB, 0xCC, 0x30, 0x03, 0xD7, 0x3A,
0xC8, 0x18, 0xED, 0x58, 0xC8, 0x11, 0xFE, 0x71,
0x9C, 0x71, 0xD8, 0x6B, 0xE0, 0x25, 0x64, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
0x00, 0x00, 0x06, 0x01, 0x04, 0x08, 0x01, 0x20,
0x28, 0x00, 0x09, 0xE1, 0x50, 0x70, 0x02, 0x2F,
0x7E, 0xDA, 0xBD, 0x40, 0xC5, 0x58, 0x87, 0xCE,
0x43, 0xF3, 0xC5, 0x8F, 0xA1, 0x59, 0x93, 0xEF,
0x7E, 0xD3, 0xD0, 0xB5, 0x87, 0x1D, 0x81, 0x54,
0x14, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03
};
static const byte canned_client_session_v5[] = {
0xa7, 0xa5, 0x01, 0x41, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x27, 0x0a, 0x0d, 0x10,
0x01, 0x01, 0x0a, 0x00, 0x05, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03,
0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
0x00, 0x0a, 0x01, 0x01, 0x00, 0x20, 0x69, 0x11, 0x6d, 0x97, 0x15, 0x6e,
0x52, 0x27, 0xd6, 0x1d, 0x1d, 0xf5, 0x0d, 0x59, 0xa5, 0xac, 0x2e, 0x8c,
0x0e, 0xcb, 0x26, 0x1e, 0xe2, 0xce, 0xbb, 0xce, 0xe1, 0x7d, 0xd7, 0xef,
0xa5, 0x44, 0x80, 0x2a, 0xde, 0xbb, 0x75, 0xb0, 0x1d, 0x75, 0x17, 0x20,
0x4c, 0x08, 0x05, 0x1b, 0xba, 0x60, 0x1f, 0x6c, 0x91, 0x8c, 0xaa, 0xbb,
0xe5, 0xa3, 0x0b, 0x12, 0x3e, 0xc0, 0x35, 0x43, 0x1d, 0xe2, 0x10, 0xe2,
0x02, 0x92, 0x4b, 0x8f, 0x05, 0xa9, 0x4b, 0xcc, 0x90, 0xc3, 0x0e, 0xc2,
0x0f, 0xe9, 0x33, 0x85, 0x9b, 0x3c, 0x19, 0x21, 0xd5, 0x62, 0xe5, 0xe1,
0x17, 0x8f, 0x8c, 0x19, 0x52, 0xd8, 0x59, 0x10, 0x2d, 0x20, 0x6f, 0xba,
0xc1, 0x1c, 0xd1, 0x82, 0xc7, 0x32, 0x1b, 0xbb, 0xcc, 0x30, 0x03, 0xd7,
0x3a, 0xc8, 0x18, 0xed, 0x58, 0xc8, 0x11, 0xfe, 0x71, 0x9c, 0x71, 0xd8,
0x6b, 0xe0, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x06,
0x01, 0x04, 0x08, 0x01, 0x20, 0x28, 0x00, 0x09, 0xe1, 0x50, 0x70, 0x02,
0x2f, 0x7e, 0xda, 0xbd, 0x40, 0xc5, 0x58, 0x87, 0xce, 0x43, 0xf3, 0xc5,
0x8f, 0xa1, 0x59, 0x93, 0xef, 0x7e, 0xd3, 0xd0, 0xb5, 0x87, 0x1d, 0x81,
0x54, 0x14, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
};
static const byte canned_server_session[] = {
0xA7, 0xA4, 0x01, 0x40, 0x00, 0x41, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0x27, 0x08, 0x0F, 0x10, 0x01, 0x01, 0x00, 0x11,
0x05, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x00,
0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x0A, 0x01, 0x01, 0x00, 0x20, 0x69, 0x11, 0x6D,
0x97, 0x15, 0x6E, 0x52, 0x27, 0xD6, 0x1D, 0x1D,
0xF5, 0x0D, 0x59, 0xA5, 0xAC, 0x2E, 0x8C, 0x0E,
0xCB, 0x26, 0x1E, 0xE2, 0xCE, 0xBB, 0xCE, 0xE1,
0x7D, 0xD7, 0xEF, 0xA5, 0x44, 0x80, 0x2A, 0xDE,
0xBB, 0x75, 0xB0, 0x1D, 0x75, 0x17, 0x20, 0x4C,
0x08, 0x05, 0x1B, 0xBA, 0x60, 0x1F, 0x6C, 0x91,
0x8C, 0xAA, 0xBB, 0xE5, 0xA3, 0x0B, 0x12, 0x3E,
0xC0, 0x35, 0x43, 0x1D, 0xE2, 0x10, 0xE2, 0x02,
0x92, 0x4B, 0x8F, 0x05, 0xA9, 0x4B, 0xCC, 0x90,
0xC3, 0x0E, 0xC2, 0x0F, 0xE9, 0x33, 0x85, 0x9B,
0x3C, 0x19, 0x21, 0xD5, 0x62, 0xE5, 0xE1, 0x17,
0x8F, 0x8C, 0x19, 0x52, 0xD8, 0x59, 0x10, 0x2D,
0x20, 0x6F, 0xBA, 0xC1, 0x1C, 0xD1, 0x82, 0xC7,
0x32, 0x1B, 0xBB, 0xCC, 0x30, 0x03, 0xD7, 0x3A,
0xC8, 0x18, 0xED, 0x58, 0xC8, 0x11, 0xFE, 0x71,
0x9C, 0x71, 0xD8, 0x6B, 0xE0, 0x25, 0x64, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
0x00, 0x00, 0x06, 0x01, 0x04, 0x08, 0x01, 0x20,
0x28, 0x00, 0xC5, 0x8F, 0xA1, 0x59, 0x93, 0xEF,
0x7E, 0xD3, 0xD0, 0xB5, 0x87, 0x1D, 0x81, 0x54,
0x14, 0x63, 0x09, 0xE1, 0x50, 0x70, 0x02, 0x2F,
0x7E, 0xDA, 0xBD, 0x40, 0xC5, 0x58, 0x87, 0xCE,
0x43, 0xF3, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04
};
static THREAD_RETURN WOLFSSL_THREAD tls_export_server(void* args)
{
SOCKET_T sockfd = 0;
SOCKET_T clientfd = 0;
word16 port;
callback_functions* cbf;
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
char msg[] = "I hear you fa shizzle!";
char input[1024];
int idx;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
((func_args*)args)->return_code = TEST_FAIL;
cbf = ((func_args*)args)->callbacks;
#if defined(USE_WINDOWS_API)
port = ((func_args*)args)->signal->port;
#elif defined(NO_MAIN_DRIVER) && !defined(WOLFSSL_SNIFFER) && \
!defined(WOLFSSL_MDK_SHELL) && !defined(WOLFSSL_TIRTOS)
/* Let tcp_listen assign port */
port = 0;
#else
/* Use default port */
port = wolfSSLPort;
#endif
/* do it here to detect failure */
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
CloseSocket(sockfd);
{
WOLFSSL_METHOD* method = NULL;
if (cbf != NULL && cbf->method != NULL) {
method = cbf->method();
}
else {
method = wolfTLSv1_2_server_method();
}
ctx = wolfSSL_CTX_new(method);
}
if (ctx == NULL) {
goto done;
}
wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA256");
/* call ctx setup callback */
if (cbf != NULL && cbf->ctx_ready != NULL) {
cbf->ctx_ready(ctx);
}
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
goto done;
}
wolfSSL_set_fd(ssl, clientfd);
/* call ssl setup callback */
if (cbf != NULL && cbf->ssl_ready != NULL) {
cbf->ssl_ready(ssl);
}
idx = wolfSSL_read(ssl, input, sizeof(input)-1);
if (idx > 0) {
input[idx] = '\0';
fprintf(stderr, "Client message export/import: %s\n", input);
}
else {
fprintf(stderr, "ret = %d error = %d\n", idx,
wolfSSL_get_error(ssl, idx));
goto done;
}
if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) {
/*err_sys("SSL_write failed");*/
WOLFSSL_RETURN_FROM_THREAD(0);
}
#ifdef WOLFSSL_TIRTOS
Task_yield();
#endif
((func_args*)args)->return_code = TEST_SUCCESS;
done:
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(clientfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
#if defined(HAVE_SESSION_TICKET) && \
((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
#if defined(OPENSSL_EXTRA) && defined(HAVE_AESGCM)
OpenSSLTicketCleanup();
#elif defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
TicketCleanup();
#endif
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
static void load_tls12_canned_server(WOLFSSL* ssl)
{
int clientfd = wolfSSL_get_fd(ssl);
AssertIntEQ(wolfSSL_tls_import(ssl, canned_server_session,
sizeof(canned_server_session)), sizeof(canned_server_session));
wolfSSL_set_fd(ssl, clientfd);
}
#ifdef WOLFSSL_TLS13
static void load_tls13_canned_server(WOLFSSL* ssl)
{
int clientfd = wolfSSL_get_fd(ssl);
AssertIntEQ(wolfSSL_tls_import(ssl, canned_server_tls13_session,
sizeof(canned_server_tls13_session)),
sizeof(canned_server_tls13_session));
wolfSSL_set_fd(ssl, clientfd);
}
#endif
/* v is for version WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wolfSSL_tls_export_run(method_provider server_method,
method_provider client_method, ssl_callback ssl_ready,
const byte* clientSession, int clientSessionSz, int cmpSess)
{
EXPECT_DECLS;
SOCKET_T sockfd = 0;
WOLFSSL_CTX* ctx = 0;
WOLFSSL* ssl = 0;
char msg[64] = "hello wolfssl!";
char reply[1024];
word32 replySz;
int msgSz = (int)XSTRLEN(msg);
tcp_ready ready;
func_args server_args;
THREAD_TYPE serverThread;
callback_functions server_cbf;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
(void)cmpSess;
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
server_cbf.method = server_method;
server_cbf.ssl_ready = ssl_ready;
ExpectNotNull(ctx = wolfSSL_CTX_new(client_method()));
server_args.callbacks = &server_cbf;
server_args.signal = &ready;
start_thread(tls_export_server, &server_args, &serverThread);
wait_tcp_ready(&server_args);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
ExpectIntEQ(wolfSSL_tls_import(ssl, clientSession, clientSessionSz),
clientSessionSz);
replySz = sizeof(reply);
ExpectIntGT(wolfSSL_tls_export(ssl, (byte*)reply, &replySz), 0);
#if !defined(NO_PSK) && defined(HAVE_ANON)
if (cmpSess) {
/* index 20 has is setting if PSK was on and 49 is if anon is allowed */
ExpectIntEQ(replySz, clientSessionSz);
ExpectBufEQ(reply, clientSession, replySz);
}
#endif
wolfSSL_set_fd(ssl, sockfd);
ExpectIntEQ(wolfSSL_write(ssl, msg, msgSz), msgSz);
ExpectIntGT(wolfSSL_read(ssl, reply, sizeof(reply)-1), 0);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(sockfd);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
&& defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
join_thread(serverThread);
ExpectIntEQ(server_args.return_code, TEST_SUCCESS);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_tls_export(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SESSION_EXPORT) && !defined(WOLFSSL_NO_TLS12)
EXPECT_TEST(test_wolfSSL_tls_export_run(wolfTLSv1_2_server_method,
wolfTLSv1_2_client_method, load_tls12_canned_server,
canned_client_session_v4, sizeof(canned_client_session_v4), 0));
EXPECT_TEST(test_wolfSSL_tls_export_run(wolfTLSv1_2_server_method,
wolfTLSv1_2_client_method, load_tls12_canned_server,
canned_client_session_v5, sizeof(canned_client_session_v5), 1));
#ifdef WOLFSSL_TLS13
EXPECT_TEST(test_wolfSSL_tls_export_run(wolfTLSv1_3_server_method,
wolfTLSv1_3_client_method, load_tls13_canned_server,
canned_client_tls13_session_v4, sizeof(canned_client_tls13_session_v4),
0));
EXPECT_TEST(test_wolfSSL_tls_export_run(wolfTLSv1_3_server_method,
wolfTLSv1_3_client_method, load_tls13_canned_server,
canned_client_tls13_session_v5, sizeof(canned_client_tls13_session_v5),
1));
#endif
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| TLS extensions tests
*----------------------------------------------------------------------------*/
#ifdef ENABLE_TLS_CALLBACK_TEST
/* Connection test runner - generic */
static void test_wolfSSL_client_server(callback_functions* client_callbacks,
callback_functions* server_callbacks)
{
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
StartTCP();
client_args.callbacks = client_callbacks;
server_args.callbacks = server_callbacks;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
/* RUN Server side */
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
client_args.signal = &ready;
start_thread(run_wolfssl_server, &server_args, &serverThread);
wait_tcp_ready(&server_args);
/* RUN Client side */
run_wolfssl_client(&client_args);
join_thread(serverThread);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdCloseSession(Task_self());
#endif
client_callbacks->return_code = client_args.return_code;
server_callbacks->return_code = server_args.return_code;
}
#endif /* ENABLE_TLS_CALLBACK_TEST */
#ifdef HAVE_SNI
static int test_wolfSSL_UseSNI_params(void)
{
EXPECT_DECLS;
#if !defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);
ExpectNotNull(ctx);
ExpectNotNull(ssl);
/* invalid [ctx|ssl] */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(NULL, 0, "ctx", 3));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI( NULL, 0, "ssl", 3));
/* invalid type */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, (byte)-1, "ctx", 3));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI( ssl, (byte)-1, "ssl", 3));
/* invalid data */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, 0, NULL, 3));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSNI( ssl, 0, NULL, 3));
/* success case */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, 0, "ctx", 3));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSNI( ssl, 0, "ssl", 3));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
/* BEGIN of connection tests callbacks */
static void use_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
}
static void use_SNI_at_ssl(WOLFSSL* ssl)
{
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
}
static void different_SNI_at_ssl(WOLFSSL* ssl)
{
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "ww2.wolfssl.com", 15));
}
static void use_SNI_WITH_CONTINUE_at_ssl(WOLFSSL* ssl)
{
use_SNI_at_ssl(ssl);
wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
WOLFSSL_SNI_CONTINUE_ON_MISMATCH);
}
static void use_SNI_WITH_FAKE_ANSWER_at_ssl(WOLFSSL* ssl)
{
use_SNI_at_ssl(ssl);
wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
WOLFSSL_SNI_ANSWER_ON_MISMATCH);
}
static void use_MANDATORY_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
use_SNI_at_ctx(ctx);
wolfSSL_CTX_SNI_SetOptions(ctx, WOLFSSL_SNI_HOST_NAME,
WOLFSSL_SNI_ABORT_ON_ABSENCE);
}
static void use_MANDATORY_SNI_at_ssl(WOLFSSL* ssl)
{
use_SNI_at_ssl(ssl);
wolfSSL_SNI_SetOptions(ssl, WOLFSSL_SNI_HOST_NAME,
WOLFSSL_SNI_ABORT_ON_ABSENCE);
}
static void use_PSEUDO_MANDATORY_SNI_at_ctx(WOLFSSL_CTX* ctx)
{
use_SNI_at_ctx(ctx);
wolfSSL_CTX_SNI_SetOptions(ctx, WOLFSSL_SNI_HOST_NAME,
WOLFSSL_SNI_ANSWER_ON_MISMATCH | WOLFSSL_SNI_ABORT_ON_ABSENCE);
}
static void verify_UNKNOWN_SNI_on_server(WOLFSSL* ssl)
{
AssertIntEQ(WC_NO_ERR_TRACE(UNKNOWN_SNI_HOST_NAME_E),
wolfSSL_get_error(ssl, 0));
}
static void verify_SNI_ABSENT_on_server(WOLFSSL* ssl)
{
AssertIntEQ(WC_NO_ERR_TRACE(SNI_ABSENT_ERROR), wolfSSL_get_error(ssl, 0));
}
static void verify_SNI_no_matching(WOLFSSL* ssl)
{
byte type = WOLFSSL_SNI_HOST_NAME;
void* request = (void*) &type; /* to be overwritten */
AssertIntEQ(WOLFSSL_SNI_NO_MATCH, wolfSSL_SNI_Status(ssl, type));
AssertNotNull(request);
AssertIntEQ(0, wolfSSL_SNI_GetRequest(ssl, type, &request));
AssertNull(request);
}
static void verify_SNI_real_matching(WOLFSSL* ssl)
{
byte type = WOLFSSL_SNI_HOST_NAME;
void* request = NULL;
AssertIntEQ(WOLFSSL_SNI_REAL_MATCH, wolfSSL_SNI_Status(ssl, type));
AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, &request));
AssertNotNull(request);
AssertStrEQ("www.wolfssl.com", (char*)request);
}
static void verify_SNI_fake_matching(WOLFSSL* ssl)
{
byte type = WOLFSSL_SNI_HOST_NAME;
void* request = NULL;
AssertIntEQ(WOLFSSL_SNI_FAKE_MATCH, wolfSSL_SNI_Status(ssl, type));
AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, &request));
AssertNotNull(request);
AssertStrEQ("ww2.wolfssl.com", (char*)request);
}
static void verify_FATAL_ERROR_on_client(WOLFSSL* ssl)
{
AssertIntEQ(WC_NO_ERR_TRACE(FATAL_ERROR), wolfSSL_get_error(ssl, 0));
}
/* END of connection tests callbacks */
static int test_wolfSSL_UseSNI_connection(void)
{
int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
callback_functions client_cb;
callback_functions server_cb;
size_t i;
#ifdef WOLFSSL_STATIC_MEMORY
byte cliMem[TEST_TLS_STATIC_MEMSZ];
byte svrMem[TEST_TLS_STATIC_MEMSZ];
#endif
struct {
method_provider client_meth;
method_provider server_meth;
#ifdef WOLFSSL_STATIC_MEMORY
wolfSSL_method_func client_meth_ex;
wolfSSL_method_func server_meth_ex;
#endif
} methods[] = {
#if defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_TLS13)
{wolfSSLv23_client_method, wolfSSLv23_server_method
#ifdef WOLFSSL_STATIC_MEMORY
,wolfSSLv23_client_method_ex, wolfSSLv23_server_method_ex
#endif
},
#endif
#ifndef WOLFSSL_NO_TLS12
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method
#ifdef WOLFSSL_STATIC_MEMORY
,wolfTLSv1_2_client_method_ex, wolfTLSv1_2_server_method_ex
#endif
},
#endif
#ifdef WOLFSSL_TLS13
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method
#ifdef WOLFSSL_STATIC_MEMORY
,wolfTLSv1_3_client_method_ex, wolfTLSv1_3_server_method_ex
#endif
},
#endif
};
size_t methodsSz = sizeof(methods) / sizeof(*methods);
for (i = 0; i < methodsSz; i++) {
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = methods[i].client_meth;
server_cb.method = methods[i].server_meth;
client_cb.devId = testDevId;
server_cb.devId = testDevId;
#ifdef WOLFSSL_STATIC_MEMORY
client_cb.method_ex = methods[i].client_meth_ex;
server_cb.method_ex = methods[i].server_meth_ex;
client_cb.mem = cliMem;
client_cb.memSz = (word32)sizeof(cliMem);
server_cb.mem = svrMem;
server_cb.memSz = (word32)sizeof(svrMem);;
#endif
/* success case at ctx */
fprintf(stderr, "\n\tsuccess case at ctx\n");
client_cb.ctx_ready = use_SNI_at_ctx; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
server_cb.ctx_ready = use_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case at ssl */
fprintf(stderr, "\tsuccess case at ssl\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_SNI_at_ssl; client_cb.on_result = verify_SNI_real_matching;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_real_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* default mismatch behavior */
fprintf(stderr, "\tdefault mismatch behavior\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = verify_FATAL_ERROR_on_client;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_UNKNOWN_SNI_on_server;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* continue on mismatch */
fprintf(stderr, "\tcontinue on mismatch\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_CONTINUE_at_ssl; server_cb.on_result = verify_SNI_no_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* fake answer on mismatch */
fprintf(stderr, "\tfake answer on mismatch\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_SNI_WITH_FAKE_ANSWER_at_ssl; server_cb.on_result = verify_SNI_fake_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* sni abort - success */
fprintf(stderr, "\tsni abort - success\n");
client_cb.ctx_ready = use_SNI_at_ctx; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_real_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* sni abort - abort when absent (ctx) */
fprintf(stderr, "\tsni abort - abort when absent (ctx)\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = verify_FATAL_ERROR_on_client;
server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_ABSENT_on_server;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* sni abort - abort when absent (ssl) */
fprintf(stderr, "\tsni abort - abort when absent (ssl)\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = verify_FATAL_ERROR_on_client;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_MANDATORY_SNI_at_ssl; server_cb.on_result = verify_SNI_ABSENT_on_server;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* sni abort - success when overwritten */
fprintf(stderr, "\tsni abort - success when overwritten\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
server_cb.ctx_ready = use_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = use_SNI_at_ssl; server_cb.on_result = verify_SNI_no_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* sni abort - success when allowing mismatches */
fprintf(stderr, "\tsni abort - success when allowing mismatches\n");
client_cb.ctx_ready = NULL; client_cb.ssl_ready = different_SNI_at_ssl; client_cb.on_result = NULL;
server_cb.ctx_ready = use_PSEUDO_MANDATORY_SNI_at_ctx; server_cb.ssl_ready = NULL; server_cb.on_result = verify_SNI_fake_matching;
test_wolfSSL_client_server(&client_cb, &server_cb);
}
res = TEST_RES_CHECK(1);
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
return res;
}
static int test_wolfSSL_SNI_GetFromBuffer(void)
{
EXPECT_DECLS;
byte buff[] = { /* www.paypal.com */
0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x60, 0x03, 0x03, 0x5c,
0xc4, 0xb3, 0x8c, 0x87, 0xef, 0xa4, 0x09, 0xe0, 0x02, 0xab, 0x86, 0xca,
0x76, 0xf0, 0x9e, 0x01, 0x65, 0xf6, 0xa6, 0x06, 0x13, 0x1d, 0x0f, 0xa5,
0x79, 0xb0, 0xd4, 0x77, 0x22, 0xeb, 0x1a, 0x00, 0x00, 0x16, 0x00, 0x6b,
0x00, 0x67, 0x00, 0x39, 0x00, 0x33, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35,
0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x13, 0x00, 0x11, 0x00, 0x00, 0x0e, 0x77, 0x77, 0x77,
0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x02, 0x01
};
byte buff2[] = { /* api.textmate.org */
0x16, 0x03, 0x01, 0x00, 0xc6, 0x01, 0x00, 0x00, 0xc2, 0x03, 0x03, 0x52,
0x8b, 0x7b, 0xca, 0x69, 0xec, 0x97, 0xd5, 0x08, 0x03, 0x50, 0xfe, 0x3b,
0x99, 0xc3, 0x20, 0xce, 0xa5, 0xf6, 0x99, 0xa5, 0x71, 0xf9, 0x57, 0x7f,
0x04, 0x38, 0xf6, 0x11, 0x0b, 0xb8, 0xd3, 0x00, 0x00, 0x5e, 0x00, 0xff,
0xc0, 0x24, 0xc0, 0x23, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x07, 0xc0, 0x08,
0xc0, 0x28, 0xc0, 0x27, 0xc0, 0x14, 0xc0, 0x13, 0xc0, 0x11, 0xc0, 0x12,
0xc0, 0x26, 0xc0, 0x25, 0xc0, 0x2a, 0xc0, 0x29, 0xc0, 0x05, 0xc0, 0x04,
0xc0, 0x02, 0xc0, 0x03, 0xc0, 0x0f, 0xc0, 0x0e, 0xc0, 0x0c, 0xc0, 0x0d,
0x00, 0x3d, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x35,
0x00, 0x0a, 0x00, 0x67, 0x00, 0x6b, 0x00, 0x33, 0x00, 0x39, 0x00, 0x16,
0x00, 0xaf, 0x00, 0xae, 0x00, 0x8d, 0x00, 0x8c, 0x00, 0x8a, 0x00, 0x8b,
0x00, 0xb1, 0x00, 0xb0, 0x00, 0x2c, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x3b,
0x00, 0x00, 0x00, 0x15, 0x00, 0x13, 0x00, 0x00, 0x10, 0x61, 0x70, 0x69,
0x2e, 0x74, 0x65, 0x78, 0x74, 0x6d, 0x61, 0x74, 0x65, 0x2e, 0x6f, 0x72,
0x67, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x0c, 0x00,
0x0a, 0x05, 0x01, 0x04, 0x01, 0x02, 0x01, 0x04, 0x03, 0x02, 0x03
};
byte buff3[] = { /* no sni extension */
0x16, 0x03, 0x03, 0x00, 0x4d, 0x01, 0x00, 0x00, 0x49, 0x03, 0x03, 0xea,
0xa1, 0x9f, 0x60, 0xdd, 0x52, 0x12, 0x13, 0xbd, 0x84, 0x34, 0xd5, 0x1c,
0x38, 0x25, 0xa8, 0x97, 0xd2, 0xd5, 0xc6, 0x45, 0xaf, 0x1b, 0x08, 0xe4,
0x1e, 0xbb, 0xdf, 0x9d, 0x39, 0xf0, 0x65, 0x00, 0x00, 0x16, 0x00, 0x6b,
0x00, 0x67, 0x00, 0x39, 0x00, 0x33, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35,
0x00, 0x2f, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x0a,
0x00, 0x0d, 0x00, 0x06, 0x00, 0x04, 0x04, 0x01, 0x02, 0x01
};
byte buff4[] = { /* last extension has zero size */
0x16, 0x03, 0x01, 0x00, 0xba, 0x01, 0x00, 0x00,
0xb6, 0x03, 0x03, 0x83, 0xa3, 0xe6, 0xdc, 0x16, 0xa1, 0x43, 0xe9, 0x45,
0x15, 0xbd, 0x64, 0xa9, 0xb6, 0x07, 0xb4, 0x50, 0xc6, 0xdd, 0xff, 0xc2,
0xd3, 0x0d, 0x4f, 0x36, 0xb4, 0x41, 0x51, 0x61, 0xc1, 0xa5, 0x9e, 0x00,
0x00, 0x28, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x07, 0xc0, 0x11,
0x00, 0x33, 0x00, 0x32, 0x00, 0x39, 0x00, 0x9c, 0x00, 0x2f, 0x00, 0x35,
0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x65, 0xff, 0x01,
0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00,
0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00,
0x00, 0x33, 0x74, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x19, 0x06,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33, 0x08, 0x73, 0x70, 0x64, 0x79, 0x2f,
0x33, 0x2e, 0x31, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31,
0x75, 0x50, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x01, 0x05, 0x01, 0x02,
0x01, 0x04, 0x03, 0x05, 0x03, 0x02, 0x03, 0x04, 0x02, 0x02, 0x02, 0x00,
0x12, 0x00, 0x00
};
byte buff5[] = { /* SSL v2.0 client hello */
0x00, 0x2b, 0x01, 0x03, 0x01, 0x00, 0x09, 0x00, 0x00,
/* dummy bytes below, just to pass size check */
0xb6, 0x03, 0x03, 0x83, 0xa3, 0xe6, 0xdc, 0x16, 0xa1, 0x43, 0xe9, 0x45,
0x15, 0xbd, 0x64, 0xa9, 0xb6, 0x07, 0xb4, 0x50, 0xc6, 0xdd, 0xff, 0xc2,
0xd3, 0x0d, 0x4f, 0x36, 0xb4, 0x41, 0x51, 0x61, 0xc1, 0xa5, 0x9e, 0x00,
};
byte result[32] = {0};
word32 length = 32;
ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff4, sizeof(buff4),
0, result, &length));
ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff3, sizeof(buff3),
0, result, &length));
ExpectIntEQ(0, wolfSSL_SNI_GetFromBuffer(buff2, sizeof(buff2),
1, result, &length));
ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
0, result, &length));
buff[0] = 0x16;
ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
0, result, &length));
buff[1] = 0x03;
ExpectIntEQ(WC_NO_ERR_TRACE(SNI_UNSUPPORTED), wolfSSL_SNI_GetFromBuffer(buff,
sizeof(buff), 0, result, &length));
buff[2] = 0x03;
ExpectIntEQ(WC_NO_ERR_TRACE(INCOMPLETE_DATA), wolfSSL_SNI_GetFromBuffer(buff,
sizeof(buff), 0, result, &length));
buff[4] = 0x64;
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buff, sizeof(buff),
0, result, &length));
if (EXPECT_SUCCESS())
result[length] = 0;
ExpectStrEQ("www.paypal.com", (const char*) result);
length = 32;
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buff2, sizeof(buff2),
0, result, &length));
if (EXPECT_SUCCESS())
result[length] = 0;
ExpectStrEQ("api.textmate.org", (const char*) result);
/* SSL v2.0 tests */
ExpectIntEQ(WC_NO_ERR_TRACE(SNI_UNSUPPORTED), wolfSSL_SNI_GetFromBuffer(buff5,
sizeof(buff5), 0, result, &length));
buff5[2] = 0x02;
ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
sizeof(buff5), 0, result, &length));
buff5[2] = 0x01; buff5[6] = 0x08;
ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
sizeof(buff5), 0, result, &length));
buff5[6] = 0x09; buff5[8] = 0x01;
ExpectIntEQ(WC_NO_ERR_TRACE(BUFFER_ERROR), wolfSSL_SNI_GetFromBuffer(buff5,
sizeof(buff5), 0, result, &length));
return EXPECT_RESULT();
}
#endif /* HAVE_SNI */
#endif /* HAVE_IO_TESTS_DEPENDENCIES */
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
/* Dummy peer functions to satisfy the exporter/importer */
static int test_wolfSSL_dtls_export_peers_get_peer(WOLFSSL* ssl, char* ip,
int* ipSz, unsigned short* port, int* fam)
{
(void)ssl;
ip[0] = -1;
*ipSz = 1;
*port = 1;
*fam = 2;
return 1;
}
static int test_wolfSSL_dtls_export_peers_set_peer(WOLFSSL* ssl, char* ip,
int ipSz, unsigned short port, int fam)
{
(void)ssl;
if (ip[0] != -1 || ipSz != 1 || port != 1 || fam != 2)
return 0;
return 1;
}
static int test_wolfSSL_dtls_export_peers_on_handshake(WOLFSSL_CTX **ctx,
WOLFSSL **ssl)
{
EXPECT_DECLS;
unsigned char* sessionBuf = NULL;
unsigned int sessionSz = 0;
void* ioWriteCtx = wolfSSL_GetIOWriteCtx(*ssl);
void* ioReadCtx = wolfSSL_GetIOReadCtx(*ssl);
wolfSSL_CTX_SetIOGetPeer(*ctx, test_wolfSSL_dtls_export_peers_get_peer);
wolfSSL_CTX_SetIOSetPeer(*ctx, test_wolfSSL_dtls_export_peers_set_peer);
ExpectIntGE(wolfSSL_dtls_export(*ssl, NULL, &sessionSz), 0);
ExpectNotNull(sessionBuf =
(unsigned char*)XMALLOC(sessionSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntGE(wolfSSL_dtls_export(*ssl, sessionBuf, &sessionSz), 0);
wolfSSL_free(*ssl);
*ssl = NULL;
ExpectNotNull(*ssl = wolfSSL_new(*ctx));
ExpectIntGE(wolfSSL_dtls_import(*ssl, sessionBuf, sessionSz), 0);
wolfSSL_SetIOWriteCtx(*ssl, ioWriteCtx);
wolfSSL_SetIOReadCtx(*ssl, ioReadCtx);
XFREE(sessionBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_dtls_export_peers(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_SESSION_EXPORT) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
size_t i, j;
struct test_params {
method_provider client_meth;
method_provider server_meth;
const char* dtls_version;
} params[] = {
#ifndef NO_OLD_TLS
{wolfDTLSv1_client_method, wolfDTLSv1_server_method, "1.0"},
#endif
{wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "1.2"},
/* TODO DTLS 1.3 exporting not supported
#ifdef WOLFSSL_DTLS13
{wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "1.3"},
#endif
*/
};
for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
for (j = 0; j <= 3; j++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
printf("\n\tTesting DTLS %s connection;", params[i].dtls_version);
client_cbf.method = params[i].client_meth;
server_cbf.method = params[i].server_meth;
if (j & 0x1) {
client_cbf.on_handshake =
test_wolfSSL_dtls_export_peers_on_handshake;
printf(" With client export;");
}
if (j & 0x2) {
server_cbf.on_handshake =
test_wolfSSL_dtls_export_peers_on_handshake;
printf(" With server export;");
}
printf("\n");
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
if (!EXPECT_SUCCESS())
break;
}
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_UseTrustedCA(void)
{
EXPECT_DECLS;
#if defined(HAVE_TRUSTED_CA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \
&& !defined(NO_RSA)
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
byte id[20];
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
#else
ExpectNotNull((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())));
#endif
ExpectNotNull((ssl = wolfSSL_new(ctx)));
XMEMSET(id, 0, sizeof(id));
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(NULL, 0, NULL, 0));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_CERT_SHA1+1, NULL, 0));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_CERT_SHA1, NULL, 0));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_CERT_SHA1, id, 5));
#ifdef NO_SHA
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id)));
#endif
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_X509_NAME, id, 0));
/* success cases */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_PRE_AGREED, NULL, 0));
#ifndef NO_SHA
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_KEY_SHA1, id, sizeof(id)));
#endif
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTrustedCA(ssl,
WOLFSSL_TRUSTED_CA_X509_NAME, id, 5));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* !NO_TLS && (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) */
#endif /* HAVE_TRUSTED_CA */
return EXPECT_RESULT();
}
static int test_wolfSSL_UseMaxFragment(void)
{
EXPECT_DECLS;
#if defined(HAVE_MAX_FRAGMENT) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
#ifndef NO_WOLFSSL_SERVER
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#else
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#endif
WOLFSSL *ssl = NULL;
#ifdef OPENSSL_EXTRA
int (*UseMaxFragment)(SSL *s, unsigned char mode);
int (*CTX_UseMaxFragment)(SSL_CTX *c, unsigned char mode);
#else
int (*UseMaxFragment)(WOLFSSL *s, unsigned char mode);
int (*CTX_UseMaxFragment)(WOLFSSL_CTX *c, unsigned char mode);
#endif
#ifndef NO_WOLFSSL_SERVER
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
#endif
ExpectNotNull(ctx);
ExpectNotNull(ssl = wolfSSL_new(ctx));
#ifdef OPENSSL_EXTRA
CTX_UseMaxFragment = SSL_CTX_set_tlsext_max_fragment_length;
UseMaxFragment = SSL_set_tlsext_max_fragment_length;
#else
UseMaxFragment = wolfSSL_UseMaxFragment;
CTX_UseMaxFragment = wolfSSL_CTX_UseMaxFragment;
#endif
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(NULL, WOLFSSL_MFL_2_9));
ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment( NULL, WOLFSSL_MFL_2_9));
ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_MIN-1));
ExpectIntNE(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_MAX+1));
ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment(ssl, WOLFSSL_MFL_MIN-1));
ExpectIntNE(WOLFSSL_SUCCESS, UseMaxFragment(ssl, WOLFSSL_MFL_MAX+1));
/* success case */
#ifdef OPENSSL_EXTRA
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_8));
#else
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_8));
#endif
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_9));
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_10));
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_11));
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_12));
#ifdef OPENSSL_EXTRA
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_13));
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), UseMaxFragment( ssl, WOLFSSL_MFL_2_8));
#else
ExpectIntEQ(WOLFSSL_SUCCESS, CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_13));
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_8));
#endif
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_9));
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_10));
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_11));
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_12));
#ifdef OPENSSL_EXTRA
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), UseMaxFragment( ssl, WOLFSSL_MFL_2_13));
#else
ExpectIntEQ(WOLFSSL_SUCCESS, UseMaxFragment( ssl, WOLFSSL_MFL_2_13));
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#if defined(OPENSSL_EXTRA) && defined(HAVE_MAX_FRAGMENT) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
/* check negotiated max fragment size */
{
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_UseMaxFragment(ssl_c, WOLFSSL_MFL_2_8),
WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
#ifndef NO_SESSION_CACHE
ExpectIntEQ(SSL_SESSION_get_max_fragment_length(
wolfSSL_get_session(ssl_c)), WOLFSSL_MFL_2_8);
#endif
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
}
#endif
#endif /* !NO_TLS && (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) */
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_UseTruncatedHMAC(void)
{
EXPECT_DECLS;
#if defined(HAVE_TRUNCATED_HMAC) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
#ifndef NO_WOLFSSL_SERVER
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#else
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#endif
WOLFSSL *ssl = NULL;
ExpectNotNull(ctx);
#ifndef NO_WOLFSSL_SERVER
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM));
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(NULL));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseTruncatedHMAC(NULL));
/* success case */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(ctx));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseTruncatedHMAC(ssl));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_UseSupportedCurve(void)
{
EXPECT_DECLS;
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(NO_TLS)
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);
ExpectNotNull(ctx);
ExpectNotNull(ssl);
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS,
wolfSSL_CTX_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSupportedCurve(ctx, 0));
ExpectIntNE(WOLFSSL_SUCCESS,
wolfSSL_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSupportedCurve(ssl, 0));
/* success case */
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP256R1));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_ALPN) && defined(HAVE_IO_TESTS_DEPENDENCIES)
static void verify_ALPN_FATAL_ERROR_on_client(WOLFSSL* ssl)
{
AssertIntEQ(WC_NO_ERR_TRACE(UNKNOWN_ALPN_PROTOCOL_NAME_E), wolfSSL_get_error(ssl, 0));
}
static void use_ALPN_all(WOLFSSL* ssl)
{
/* http/1.1,spdy/1,spdy/2,spdy/3 */
char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}
static void use_ALPN_all_continue(WOLFSSL* ssl)
{
/* http/1.1,spdy/1,spdy/2,spdy/3 */
char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, alpn_list, sizeof(alpn_list),
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
}
static void use_ALPN_one(WOLFSSL* ssl)
{
/* spdy/2 */
char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}
static void use_ALPN_unknown(WOLFSSL* ssl)
{
/* http/2.0 */
char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
}
static void use_ALPN_unknown_continue(WOLFSSL* ssl)
{
/* http/2.0 */
char proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x32, 0x2e, 0x30};
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, proto, sizeof(proto),
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
}
static void verify_ALPN_not_matching_spdy3(WOLFSSL* ssl)
{
/* spdy/3 */
char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
char *proto = NULL;
word16 protoSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
/* check value */
AssertIntNE(1, sizeof(nego_proto) == protoSz);
if (proto) {
AssertIntNE(0, XMEMCMP(nego_proto, proto, sizeof(nego_proto)));
}
}
static void verify_ALPN_not_matching_continue(WOLFSSL* ssl)
{
char *proto = NULL;
word16 protoSz = 0;
AssertIntEQ(WC_NO_ERR_TRACE(WOLFSSL_ALPN_NOT_FOUND),
wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
/* check value */
AssertIntEQ(1, (0 == protoSz));
AssertIntEQ(1, (NULL == proto));
}
static void verify_ALPN_matching_http1(WOLFSSL* ssl)
{
/* http/1.1 */
char nego_proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
char *proto;
word16 protoSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void verify_ALPN_matching_spdy2(WOLFSSL* ssl)
{
/* spdy/2 */
char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
char *proto;
word16 protoSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void verify_ALPN_client_list(WOLFSSL* ssl)
{
/* http/1.1,spdy/1,spdy/2,spdy/3 */
char alpn_list[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x31, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x32, 0x2c,
0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
char *clist = NULL;
word16 clistSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_GetPeerProtocol(ssl, &clist,
&clistSz));
/* check value */
AssertIntEQ(1, sizeof(alpn_list) == clistSz);
AssertIntEQ(0, XMEMCMP(alpn_list, clist, clistSz));
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_ALPN_FreePeerProtocol(ssl, &clist));
}
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
/* ALPN select callback, success with spdy/2 */
static int select_ALPN_spdy2(WOLFSSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg)
{
/* spdy/2 */
const char proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
(void)ssl;
(void)arg;
/* adding +1 since LEN byte comes first */
if (inlen < sizeof(proto) + 1) {
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
if (XMEMCMP(in + 1, proto, sizeof(proto)) == 0) {
*out = in + 1;
*outlen = (unsigned char)sizeof(proto);
return SSL_TLSEXT_ERR_OK;
}
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
/* ALPN select callback, force failure */
static int select_ALPN_failure(WOLFSSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg)
{
(void)ssl;
(void)out;
(void)outlen;
(void)in;
(void)inlen;
(void)arg;
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
static void use_ALPN_spdy2_callback(WOLFSSL* ssl)
{
wolfSSL_set_alpn_select_cb(ssl, select_ALPN_spdy2, NULL);
}
static void use_ALPN_failure_callback(WOLFSSL* ssl)
{
wolfSSL_set_alpn_select_cb(ssl, select_ALPN_failure, NULL);
}
#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY | QUIC */
static int test_wolfSSL_UseALPN_connection(void)
{
int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
callback_functions client_cb;
callback_functions server_cb;
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = wolfSSLv23_client_method;
server_cb.method = wolfSSLv23_server_method;
client_cb.devId = testDevId;
server_cb.devId = testDevId;
/* success case same list */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_matching_http1;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case only one for server */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_one; server_cb.on_result = verify_ALPN_matching_spdy2;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case only one for client */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_one; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_matching_spdy2;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case none for client */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = NULL; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = NULL;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case mismatch behavior but option 'continue' set */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all_continue; client_cb.on_result = verify_ALPN_not_matching_continue;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_unknown_continue; server_cb.on_result = NULL;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* success case read protocol send by client */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_one; server_cb.on_result = verify_ALPN_client_list;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* mismatch behavior with same list
* the first and only this one must be taken */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_all; server_cb.on_result = verify_ALPN_not_matching_spdy3;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* default mismatch behavior */
client_cb.ctx_ready = NULL; client_cb.ssl_ready = use_ALPN_all; client_cb.on_result = NULL;
server_cb.ctx_ready = NULL; server_cb.ssl_ready = use_ALPN_unknown; server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
test_wolfSSL_client_server(&client_cb, &server_cb);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
/* WOLFSSL-level ALPN select callback tests */
/* Callback: success (one protocol, spdy/2) */
client_cb.ctx_ready = NULL;
client_cb.ssl_ready = use_ALPN_one;
client_cb.on_result = verify_ALPN_matching_spdy2;
server_cb.ctx_ready = NULL;
server_cb.ssl_ready = use_ALPN_spdy2_callback;
server_cb.on_result = verify_ALPN_matching_spdy2;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* Callback: failure (one client protocol, spdy/2) */
client_cb.ctx_ready = NULL;
client_cb.ssl_ready = use_ALPN_one;
client_cb.on_result = NULL;
server_cb.ctx_ready = NULL;
server_cb.ssl_ready = use_ALPN_failure_callback;
server_cb.on_result = verify_ALPN_FATAL_ERROR_on_client;
test_wolfSSL_client_server(&client_cb, &server_cb);
#endif /* OPENSSL_ALL | NGINX | HAPROXY | LIGHTY */
res = TEST_RES_CHECK(1);
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
return res;
}
static int test_wolfSSL_UseALPN_params(void)
{
EXPECT_DECLS;
#ifndef NO_WOLFSSL_CLIENT
/* "http/1.1" */
char http1[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
/* "spdy/1" */
char spdy1[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x31};
/* "spdy/2" */
char spdy2[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x32};
/* "spdy/3" */
char spdy3[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
char buff[256];
word32 idx;
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);
ExpectNotNull(ctx);
ExpectNotNull(ssl);
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS,
wolfSSL_UseALPN(NULL, http1, sizeof(http1),
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, NULL, 0,
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
/* success case */
/* http1 only */
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_UseALPN(ssl, http1, sizeof(http1),
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
/* http1, spdy1 */
XMEMCPY(buff, http1, sizeof(http1));
idx = sizeof(http1);
buff[idx++] = ',';
XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
idx += sizeof(spdy1);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
/* http1, spdy2, spdy1 */
XMEMCPY(buff, http1, sizeof(http1));
idx = sizeof(http1);
buff[idx++] = ',';
XMEMCPY(buff+idx, spdy2, sizeof(spdy2));
idx += sizeof(spdy2);
buff[idx++] = ',';
XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
idx += sizeof(spdy1);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
/* spdy3, http1, spdy2, spdy1 */
XMEMCPY(buff, spdy3, sizeof(spdy3));
idx = sizeof(spdy3);
buff[idx++] = ',';
XMEMCPY(buff+idx, http1, sizeof(http1));
idx += sizeof(http1);
buff[idx++] = ',';
XMEMCPY(buff+idx, spdy2, sizeof(spdy2));
idx += sizeof(spdy2);
buff[idx++] = ',';
XMEMCPY(buff+idx, spdy1, sizeof(spdy1));
idx += sizeof(spdy1);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#endif /* HAVE_ALPN */
#ifdef HAVE_ALPN_PROTOS_SUPPORT
static void CTX_set_alpn_protos(SSL_CTX *ctx)
{
unsigned char p[] = {
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
6, 's', 'p', 'd', 'y', '/', '2',
6, 's', 'p', 'd', 'y', '/', '1',
};
unsigned char p_len = sizeof(p);
int ret;
ret = SSL_CTX_set_alpn_protos(ctx, p, p_len);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(ret, 0);
#else
AssertIntEQ(ret, SSL_SUCCESS);
#endif
}
static void set_alpn_protos(SSL* ssl)
{
unsigned char p[] = {
6, 's', 'p', 'd', 'y', '/', '3',
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
6, 's', 'p', 'd', 'y', '/', '2',
6, 's', 'p', 'd', 'y', '/', '1',
};
unsigned char p_len = sizeof(p);
int ret;
ret = SSL_set_alpn_protos(ssl, p, p_len);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(ret, 0);
#else
AssertIntEQ(ret, SSL_SUCCESS);
#endif
}
static void verify_alpn_matching_spdy3(WOLFSSL* ssl)
{
/* "spdy/3" */
char nego_proto[] = {0x73, 0x70, 0x64, 0x79, 0x2f, 0x33};
const unsigned char *proto;
unsigned int protoSz = 0;
SSL_get0_alpn_selected(ssl, &proto, &protoSz);
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static void verify_alpn_matching_http1(WOLFSSL* ssl)
{
/* "http/1.1" */
char nego_proto[] = {0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31};
const unsigned char *proto;
unsigned int protoSz = 0;
SSL_get0_alpn_selected(ssl, &proto, &protoSz);
/* check value */
AssertIntEQ(1, sizeof(nego_proto) == protoSz);
AssertIntEQ(0, XMEMCMP(nego_proto, proto, protoSz));
}
static int test_wolfSSL_set_alpn_protos(void)
{
int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
callback_functions client_cb;
callback_functions server_cb;
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = wolfSSLv23_client_method;
server_cb.method = wolfSSLv23_server_method;
client_cb.devId = testDevId;
server_cb.devId = testDevId;
/* use CTX_alpn_protos */
client_cb.ctx_ready = CTX_set_alpn_protos;
client_cb.ssl_ready = NULL;
client_cb.on_result = NULL;
server_cb.ctx_ready = CTX_set_alpn_protos;
server_cb.ssl_ready = NULL;
server_cb.on_result = verify_alpn_matching_http1;
test_wolfSSL_client_server(&client_cb, &server_cb);
/* use set_alpn_protos */
client_cb.ctx_ready = NULL;
client_cb.ssl_ready = set_alpn_protos;
client_cb.on_result = NULL;
server_cb.ctx_ready = NULL;
server_cb.ssl_ready = set_alpn_protos;
server_cb.on_result = verify_alpn_matching_spdy3;
test_wolfSSL_client_server(&client_cb, &server_cb);
res = TEST_SUCCESS;
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
return res;
}
#endif /* HAVE_ALPN_PROTOS_SUPPORT */
static int test_wolfSSL_wolfSSL_UseSecureRenegotiation(void)
{
EXPECT_DECLS;
#if defined(HAVE_SECURE_RENEGOTIATION) && !defined(NO_WOLFSSL_CLIENT) && \
!defined(NO_TLS)
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);
ExpectNotNull(ctx);
ExpectNotNull(ssl);
/* error cases */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(NULL));
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(NULL));
/* success cases */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test reconnecting with a different ciphersuite after a renegotiation. */
static int test_wolfSSL_SCR_Reconnect(void)
{
EXPECT_DECLS;
#if defined(HAVE_SECURE_RENEGOTIATION) && \
defined(BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) && \
defined(BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
byte data;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
test_ctx.c_ciphers = "ECDHE-RSA-AES256-GCM-SHA384";
test_ctx.s_ciphers =
"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305";
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_c));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_UseSecureRenegotiation(ctx_s));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_c));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSecureRenegotiation(ssl_s));
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
/* WOLFSSL_FATAL_ERROR since it will block */
ExpectIntEQ(wolfSSL_Rehandshake(ssl_s), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_read(ssl_c, &data, 1), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_free(ssl_s);
ssl_s = NULL;
wolfSSL_CTX_free(ctx_c);
ctx_c = NULL;
test_ctx.c_ciphers = "ECDHE-RSA-CHACHA20-POLY1305";
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_s);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_s);
wolfSSL_CTX_free(ctx_c);
#endif
return EXPECT_RESULT();
}
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
/* Called when writing. */
static int DummySend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
(void)ssl;
(void)buf;
(void)sz;
(void)ctx;
/* Force error return from wolfSSL_accept_TLSv13(). */
return WANT_WRITE;
}
/* Called when reading. */
static int BufferInfoRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
WOLFSSL_BUFFER_INFO* msg = (WOLFSSL_BUFFER_INFO*)ctx;
int len = (int)msg->length;
(void)ssl;
(void)sz;
/* Pass back as much of message as will fit in buffer. */
if (len > sz)
len = sz;
XMEMCPY(buf, msg->buffer, len);
/* Move over returned data. */
msg->buffer += len;
msg->length -= (word32)len;
/* Amount actually copied. */
return len;
}
#endif
/* Test the detection of duplicate known TLS extensions.
* Specifically in a ClientHello.
*/
static int test_tls_ext_duplicate(void)
{
EXPECT_DECLS;
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
const unsigned char clientHelloDupTlsExt[] = {
0x16, 0x03, 0x03, 0x00, 0x6a, 0x01, 0x00, 0x00,
0x66, 0x03, 0x03, 0xf4, 0x65, 0xbd, 0x22, 0xfe,
0x6e, 0xab, 0x66, 0xdd, 0xcf, 0xe9, 0x65, 0x55,
0xe8, 0xdf, 0xc3, 0x8e, 0x4b, 0x00, 0xbc, 0xf8,
0x23, 0x57, 0x1b, 0xa0, 0xc8, 0xa9, 0xe2, 0x8c,
0x91, 0x6e, 0xf9, 0x20, 0xf7, 0x5c, 0xc5, 0x5b,
0x75, 0x8c, 0x47, 0x0a, 0x0e, 0xc4, 0x1a, 0xda,
0xef, 0x75, 0xe5, 0x21, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x01,
0x00, 0x9e, 0x01, 0x00,
/* Extensions - duplicate signature algorithms. */
0x00, 0x19, 0x00, 0x0d,
0x00, 0x04, 0x00, 0x02, 0x04, 0x01, 0x00, 0x0d,
0x00, 0x04, 0x00, 0x02, 0x04, 0x01,
/* Supported Versions extension for TLS 1.3. */
0x00, 0x2b,
0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03
};
WOLFSSL_BUFFER_INFO msg;
const char* testCertFile;
const char* testKeyFile;
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
/* Read from 'msg'. */
wolfSSL_SetIORecv(ctx, BufferInfoRecv);
/* No where to send to - dummy sender. */
wolfSSL_SetIOSend(ctx, DummySend);
ssl = wolfSSL_new(ctx);
ExpectNotNull(ssl);
msg.buffer = (unsigned char*)clientHelloDupTlsExt;
msg.length = (unsigned int)sizeof(clientHelloDupTlsExt);
wolfSSL_SetIOReadCtx(ssl, &msg);
ExpectIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
/* can return duplicate ext error or socket error if the peer closed down
* while sending alert */
if (wolfSSL_get_error(ssl, 0) != WC_NO_ERR_TRACE(SOCKET_ERROR_E)) {
ExpectIntEQ(wolfSSL_get_error(ssl, 0), WC_NO_ERR_TRACE(DUPLICATE_TLS_EXT_E));
}
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Test TLS connection abort when legacy version field indicates TLS 1.3 or
* higher. Based on test_tls_ext_duplicate() but with legacy version modified
* to 0x0304.
*/
static int test_tls_bad_legacy_version(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_ALLOW_BAD_TLS_LEGACY_VERSION)
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
/* This buffer (prior to Extensions) is exactly the same as the buffer in
* test_tls_ext_duplicate() except the 11th byte is set to 0x04. That
* change means the legacy protocol version field is invalid. That will be
* caught before the dulplicate signature algorithms extension. */
const unsigned char clientHelloBadLegacyVersion[] = {
0x16, 0x03, 0x03, 0x00, 0x6a, 0x01, 0x00, 0x00,
0x66, 0x03, 0x04, 0xf4, 0x65, 0xbd, 0x22, 0xfe,
0x6e, 0xab, 0x66, 0xdd, 0xcf, 0xe9, 0x65, 0x55,
0xe8, 0xdf, 0xc3, 0x8e, 0x4b, 0x00, 0xbc, 0xf8,
0x23, 0x57, 0x1b, 0xa0, 0xc8, 0xa9, 0xe2, 0x8c,
0x91, 0x6e, 0xf9, 0x20, 0xf7, 0x5c, 0xc5, 0x5b,
0x75, 0x8c, 0x47, 0x0a, 0x0e, 0xc4, 0x1a, 0xda,
0xef, 0x75, 0xe5, 0x21, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x01,
0x00, 0x9e, 0x01, 0x00,
/* Extensions */
0x00, 0x19, 0x00, 0x0d,
0x00, 0x04, 0x00, 0x02, 0x04, 0x01, 0x00, 0x15,
0x00, 0x04, 0x00, 0x02, 0x04, 0x01,
/* Supported Versions extension for TLS 1.3. */
0x00, 0x2b,
0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03
};
WOLFSSL_BUFFER_INFO msg;
const char* testCertFile;
const char* testKeyFile;
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
CERT_FILETYPE));
/* Read from 'msg'. */
wolfSSL_SetIORecv(ctx, BufferInfoRecv);
/* No where to send to - dummy sender. */
wolfSSL_SetIOSend(ctx, DummySend);
ssl = wolfSSL_new(ctx);
ExpectNotNull(ssl);
msg.buffer = (unsigned char*)clientHelloBadLegacyVersion;
msg.length = (unsigned int)sizeof(clientHelloBadLegacyVersion);
wolfSSL_SetIOReadCtx(ssl, &msg);
ExpectIntNE(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
/* Connection should fail due to bad legacy version field. When that
* happens the return code is VERSION_ERROR but that gets transformed into
* SOCKET_ERROR_E. */
ExpectIntEQ(wolfSSL_get_error(ssl, 0), WC_NO_ERR_TRACE(SOCKET_ERROR_E));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| X509 Tests
*----------------------------------------------------------------------------*/
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_PWDBASED) && \
(!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_MD5)
#define TEST_PKCS8_ENC
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_TLS)
/* used to keep track if FailTestCallback was called */
static int failTestCallbackCalled = 0;
static WC_INLINE int FailTestCallBack(char* passwd, int sz, int rw, void* userdata)
{
(void)passwd;
(void)sz;
(void)rw;
(void)userdata;
/* mark called, test_wolfSSL_no_password_cb() will check and fail if set */
failTestCallbackCalled = 1;
return -1;
}
#endif
static int test_wolfSSL_no_password_cb(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
byte buff[FOURK_BUF];
const char eccPkcs8PrivKeyDerFile[] = "./certs/ecc-privkeyPkcs8.der";
const char eccPkcs8PrivKeyPemFile[] = "./certs/ecc-privkeyPkcs8.pem";
XFILE f = XBADFILE;
int bytes = 0;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLS_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLS_server_method()));
#endif
wolfSSL_CTX_set_default_passwd_cb(ctx, FailTestCallBack);
ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyDerFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectIntLE(bytes, sizeof(buff));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyPemFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
ExpectIntLE(bytes, sizeof(buff));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
/* Password callback should not be called by default */
ExpectIntEQ(failTestCallbackCalled, 0);
#endif
return EXPECT_RESULT();
}
#if defined(TEST_PKCS8_ENC) && !defined(NO_TLS)
/* for PKCS8 test case */
static int PKCS8TestCallBack(char* passwd, int sz, int rw, void* userdata)
{
int flag = 0;
(void)rw;
if (userdata != NULL) {
flag = *((int*)userdata); /* user set data */
}
switch (flag) {
case 1: /* flag set for specific WOLFSSL_CTX structure, note userdata
* can be anything the user wishes to be passed to the callback
* associated with the WOLFSSL_CTX */
XSTRNCPY(passwd, "yassl123", sz);
return 8;
default:
return BAD_FUNC_ARG;
}
}
#endif /* TEST_PKCS8_ENC && !NO_TLS */
/* Testing functions dealing with PKCS8 */
static int test_wolfSSL_PKCS8(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) && \
!defined(WOLFCRYPT_ONLY) && !defined(NO_TLS) && \
(!defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13))
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
byte buff[FOURK_BUF];
byte der[FOURK_BUF];
#ifndef NO_RSA
#ifdef WOLFSSL_PEM_TO_DER
const char serverKeyPkcs8PemFile[] = "./certs/server-keyPkcs8.pem";
#endif
const char serverKeyPkcs8DerFile[] = "./certs/server-keyPkcs8.der";
#endif
#ifdef WOLFSSL_PEM_TO_DER
const char eccPkcs8PrivKeyPemFile[] = "./certs/ecc-privkeyPkcs8.pem";
#endif
#ifdef HAVE_ECC
const char eccPkcs8PrivKeyDerFile[] = "./certs/ecc-privkeyPkcs8.der";
#endif
XFILE f = XBADFILE;
int bytes = 0;
WOLFSSL_CTX* ctx = NULL;
#if defined(HAVE_ECC) && !defined(NO_CODING) && !defined(WOLFSSL_NO_PEM)
int ret;
ecc_key key;
word32 x = 0;
#endif
#ifdef TEST_PKCS8_ENC
#if !defined(NO_RSA) && !defined(NO_SHA)
const char serverKeyPkcs8EncPemFile[] = "./certs/server-keyPkcs8Enc.pem";
const char serverKeyPkcs8EncDerFile[] = "./certs/server-keyPkcs8Enc.der";
#endif
#if defined(HAVE_ECC) && !defined(NO_SHA)
const char eccPkcs8EncPrivKeyPemFile[] = "./certs/ecc-keyPkcs8Enc.pem";
const char eccPkcs8EncPrivKeyDerFile[] = "./certs/ecc-keyPkcs8Enc.der";
#endif
int flag;
#endif
(void)der;
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#endif
#else
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
#endif
#ifdef TEST_PKCS8_ENC
wolfSSL_CTX_set_default_passwd_cb(ctx, PKCS8TestCallBack);
wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)&flag);
flag = 1; /* used by password callback as return code */
#if !defined(NO_RSA) && !defined(NO_SHA)
#if defined(WOLFSSL_PEM_TO_DER)
/* test loading PEM PKCS8 encrypted file */
ExpectTrue((f = XFOPEN(serverKeyPkcs8EncPemFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* this next case should fail because of password callback return code */
flag = 0; /* used by password callback as return code */
ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */
ExpectIntGT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
"yassl123"), 0);
/* test that error value is returned with a bad password */
ExpectIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
"bad"), 0);
#endif
/* test loading PEM PKCS8 encrypted file */
ExpectTrue((f = XFOPEN(serverKeyPkcs8EncDerFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
flag = 1; /* used by password callback as return code */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* this next case should fail because of password callback return code */
flag = 0; /* used by password callback as return code */
ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#endif /* !NO_RSA && !NO_SHA */
#if defined(HAVE_ECC) && !defined(NO_SHA)
#if defined(WOLFSSL_PEM_TO_DER)
/* test loading PEM PKCS8 encrypted ECC Key file */
ExpectTrue((f = XFOPEN(eccPkcs8EncPrivKeyPemFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
flag = 1; /* used by password callback as return code */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* this next case should fail because of password callback return code */
flag = 0; /* used by password callback as return code */
ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */
ExpectIntGT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
"yassl123"), 0);
/* test that error value is returned with a bad password */
ExpectIntLT(wc_KeyPemToDer(buff, bytes, der, (word32)sizeof(der),
"bad"), 0);
#endif
/* test loading DER PKCS8 encrypted ECC Key file */
ExpectTrue((f = XFOPEN(eccPkcs8EncPrivKeyDerFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
flag = 1; /* used by password callback as return code */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* this next case should fail because of password callback return code */
flag = 0; /* used by password callback as return code */
ExpectIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* leave flag as "okay" */
flag = 1;
#endif /* HAVE_ECC && !NO_SHA */
#endif /* TEST_PKCS8_ENC */
#ifndef NO_RSA
/* test loading ASN.1 (DER) PKCS8 private key file (not encrypted) */
ExpectTrue((f = XFOPEN(serverKeyPkcs8DerFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_PEM_TO_DER
/* test loading PEM PKCS8 private key file (not encrypted) */
ExpectTrue((f = XFOPEN(serverKeyPkcs8PemFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif
#endif /* !NO_RSA */
#ifdef WOLFSSL_PEM_TO_DER
/* Test PKCS8 PEM ECC key no crypt */
ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyPemFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
#endif
#ifdef HAVE_ECC
#ifdef WOLFSSL_PEM_TO_DER
/* Test PKCS8 PEM ECC key no crypt */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
/* decrypt PKCS8 PEM to key in DER format */
ExpectIntGT((bytes = wc_KeyPemToDer(buff, bytes, der,
(word32)sizeof(der), NULL)), 0);
ret = wc_ecc_init(&key);
if (ret == 0) {
ret = wc_EccPrivateKeyDecode(der, &x, &key, (word32)bytes);
wc_ecc_free(&key);
}
ExpectIntEQ(ret, 0);
#endif
/* Test PKCS8 DER ECC key no crypt */
ExpectTrue((f = XFOPEN(eccPkcs8PrivKeyDerFile, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
/* Test using a PKCS8 ECC PEM */
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buff, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
#else
#ifdef WOLFSSL_PEM_TO_DER
/* if HAVE_ECC is not defined then BEGIN EC PRIVATE KEY is not found */
ExpectIntEQ((bytes = wc_KeyPemToDer(buff, bytes, der,
(word32)sizeof(der), NULL)), WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER));
#endif
#endif /* HAVE_ECC */
wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* !NO_FILESYSTEM && !NO_ASN && HAVE_PKCS8 */
return EXPECT_RESULT();
}
static int test_wolfSSL_PKCS8_ED25519(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && defined(HAVE_AES_CBC) && \
defined(WOLFSSL_AES_256) && \
defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED25519) && \
defined(HAVE_ED25519_KEY_IMPORT)
const byte encPrivKey[] = \
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAheCGLmWGh7+AICCAAw\n"
"DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEC4L5P6GappsTyhOOoQfvh8EQJMX\n"
"OAdlsYKCOcFo4djg6AI1lRdeBRwVFWkha7gBdoCJOzS8wDvTbYcJMPvANu5ft3nl\n"
"2L9W4v7swXkV+X+a1ww=\n"
"-----END ENCRYPTED PRIVATE KEY-----\n";
const char password[] = "abcdefghijklmnopqrstuvwxyz";
byte der[FOURK_BUF];
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
#endif
int bytes;
XMEMSET(der, 0, sizeof(der));
ExpectIntGT((bytes = wc_KeyPemToDer(encPrivKey, sizeof(encPrivKey), der,
(word32)sizeof(der), password)), 0);
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif /* !NO_TLS && (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) */
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_PKCS8_ED448(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && defined(HAVE_PKCS8) && defined(HAVE_AES_CBC) && \
defined(WOLFSSL_AES_256) && \
defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED448) && \
defined(HAVE_ED448_KEY_IMPORT)
const byte encPrivKey[] = \
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjSbZKnG4EPggICCAAw\n"
"DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEFvCFWBBHBlJBsYleBJlJWcEUNC7\n"
"Tf5pZviT5Btar4D/MNg6BsQHSDf5KW4ix871EsgDY2Zz+euaoWspiMntz7gU+PQu\n"
"T/JJcbD2Ly8BbE3l5WHMifAQqNLxJBfXrHkfYtAo\n"
"-----END ENCRYPTED PRIVATE KEY-----\n";
const char password[] = "abcdefghijklmnopqrstuvwxyz";
byte der[FOURK_BUF];
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
#endif
int bytes;
XMEMSET(der, 0, sizeof(der));
ExpectIntGT((bytes = wc_KeyPemToDer(encPrivKey, sizeof(encPrivKey), der,
(word32)sizeof(der), password)), 0);
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, bytes,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif /* !NO_TLS && (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) */
#endif
return EXPECT_RESULT();
}
/* Testing functions dealing with PKCS5 */
static int test_wolfSSL_PKCS5(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_SHA) && !defined(NO_PWDBASED)
#ifdef HAVE_FIPS /* Password minimum length is 14 (112-bit) in FIPS MODE */
const char* passwd = "myfipsPa$$W0rd";
#else
const char *passwd = "pass1234";
#endif
const unsigned char *salt = (unsigned char *)"salt1234";
unsigned char *out = (unsigned char *)XMALLOC(WC_SHA_DIGEST_SIZE, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
int ret = 0;
ExpectNotNull(out);
ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC_SHA1(passwd,(int)XSTRLEN(passwd), salt,
(int)XSTRLEN((const char *) salt), 10, WC_SHA_DIGEST_SIZE,out),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_SHA512
ExpectIntEQ(ret = PKCS5_PBKDF2_HMAC(passwd,(int)XSTRLEN(passwd), salt,
(int)XSTRLEN((const char *) salt), 10, wolfSSL_EVP_sha512(),
WC_SHA_DIGEST_SIZE, out), SSL_SUCCESS);
#endif
XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_SHA) */
return EXPECT_RESULT();
}
/* test parsing URI from certificate */
static int test_wolfSSL_URI(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) \
&& (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
defined(OPENSSL_EXTRA))
WOLFSSL_X509* x509 = NULL;
const char uri[] = "./certs/client-uri-cert.pem";
const char urn[] = "./certs/client-absolute-urn.pem";
const char badUri[] = "./certs/client-relative-uri.pem";
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(uri,
WOLFSSL_FILETYPE_PEM));
wolfSSL_FreeX509(x509);
x509 = NULL;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(urn,
WOLFSSL_FILETYPE_PEM));
wolfSSL_FreeX509(x509);
x509 = NULL;
#if !defined(IGNORE_NAME_CONSTRAINTS) && !defined(WOLFSSL_NO_ASN_STRICT) \
&& !defined(WOLFSSL_FPKI)
ExpectNull(x509 = wolfSSL_X509_load_certificate_file(badUri,
WOLFSSL_FILETYPE_PEM));
#else
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(badUri,
WOLFSSL_FILETYPE_PEM));
#endif
wolfSSL_FreeX509(x509);
#endif
return EXPECT_RESULT();
}
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
/* create certificate with version 2 */
static int test_set_x509_badversion(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
WOLFSSL_X509 *x509 = NULL, *x509v2 = NULL;
WOLFSSL_EVP_PKEY *priv = NULL, *pub = NULL;
unsigned char *der = NULL, *key = NULL, *pt;
char *header = NULL, *name = NULL;
int derSz;
long keySz;
XFILE fp = XBADFILE;
WOLFSSL_ASN1_TIME *notBefore = NULL, *notAfter = NULL;
time_t t;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue((fp = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
ExpectIntEQ(wolfSSL_PEM_read(fp, &name, &header, &key, &keySz),
WOLFSSL_SUCCESS);
if (fp != XBADFILE)
XFCLOSE(fp);
pt = key;
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
(const unsigned char**)&pt, keySz));
/* create the version 2 certificate */
ExpectNotNull(x509v2 = X509_new());
ExpectIntEQ(wolfSSL_X509_set_version(x509v2, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_set_subject_name(x509v2,
wolfSSL_X509_get_subject_name(x509)), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509v2,
wolfSSL_X509_get_issuer_name(x509)), WOLFSSL_SUCCESS);
ExpectNotNull(pub = wolfSSL_X509_get_pubkey(x509));
ExpectIntEQ(X509_set_pubkey(x509v2, pub), WOLFSSL_SUCCESS);
t = time(NULL);
ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
ExpectTrue(wolfSSL_X509_set_notBefore(x509v2, notBefore));
ExpectTrue(wolfSSL_X509_set_notAfter(x509v2, notAfter));
ExpectIntGT(wolfSSL_X509_sign(x509v2, priv, EVP_sha256()), 0);
derSz = wolfSSL_i2d_X509(x509v2, &der);
ExpectIntGT(derSz, 0);
ExpectIntEQ(wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS);
/* TODO: Replace with API call */
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(name, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL_X509_free(x509);
wolfSSL_X509_free(x509v2);
wolfSSL_EVP_PKEY_free(priv);
wolfSSL_EVP_PKEY_free(pub);
wolfSSL_ASN1_TIME_free(notBefore);
wolfSSL_ASN1_TIME_free(notAfter);
return EXPECT_RESULT();
}
/* override certificate version error */
static int test_override_x509(int preverify, WOLFSSL_X509_STORE_CTX* store)
{
EXPECT_DECLS;
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
ExpectIntEQ(store->error, WC_NO_ERR_TRACE(ASN_VERSION_E));
#else
ExpectIntEQ(store->error, 0);
#endif
ExpectIntEQ((int)wolfSSL_X509_get_version(store->current_cert), 1);
(void)preverify;
return EXPECT_RESULT() == TEST_SUCCESS;
}
/* set verify callback that will override bad certificate version */
static int test_set_override_x509(WOLFSSL_CTX* ctx)
{
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, test_override_x509);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_X509_TLS_version_test_1(void)
{
EXPECT_DECLS;
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
/* test server rejects a client certificate that is not version 3 */
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.ctx_ready = &test_set_x509_badversion;
#ifndef WOLFSSL_NO_TLS12
func_cb_client.method = wolfTLSv1_2_client_method;
#else
func_cb_client.method = wolfTLSv1_3_client_method;
#endif
#ifndef WOLFSSL_NO_TLS12
func_cb_server.method = wolfTLSv1_2_server_method;
#else
func_cb_server.method = wolfTLSv1_3_server_method;
#endif
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);
#else
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_TLS_version_test_2(void)
{
EXPECT_DECLS;
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.ctx_ready = &test_set_x509_badversion;
func_cb_server.ctx_ready = &test_set_override_x509;
#ifndef WOLFSSL_NO_TLS12
func_cb_client.method = wolfTLSv1_2_client_method;
#else
func_cb_client.method = wolfTLSv1_3_client_method;
#endif
#ifndef WOLFSSL_NO_TLS12
func_cb_server.method = wolfTLSv1_2_server_method;
#else
func_cb_server.method = wolfTLSv1_3_server_method;
#endif
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
#endif
return EXPECT_RESULT();
}
/* Testing function wolfSSL_CTX_SetMinVersion; sets the minimum downgrade
* version allowed.
* POST: 1 on success.
*/
static int test_wolfSSL_CTX_SetMinVersion(void)
{
int res = TEST_SKIPPED;
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
int failFlag = WOLFSSL_SUCCESS;
WOLFSSL_CTX* ctx;
int itr;
#ifndef NO_OLD_TLS
const int versions[] = {
#ifdef WOLFSSL_ALLOW_TLSV10
WOLFSSL_TLSV1,
#endif
WOLFSSL_TLSV1_1,
WOLFSSL_TLSV1_2 };
#elif !defined(WOLFSSL_NO_TLS12)
const int versions[] = { WOLFSSL_TLSV1_2 };
#elif defined(WOLFSSL_TLS13)
const int versions[] = { WOLFSSL_TLSV1_3 };
#else
const int versions[0];
#endif
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++) {
if (wolfSSL_CTX_SetMinVersion(ctx, *(versions + itr))
!= WOLFSSL_SUCCESS) {
failFlag = WOLFSSL_FAILURE;
}
}
wolfSSL_CTX_free(ctx);
res = TEST_RES_CHECK(failFlag == WOLFSSL_SUCCESS);
#endif
return res;
} /* END test_wolfSSL_CTX_SetMinVersion */
/*----------------------------------------------------------------------------*
| OCSP Stapling
*----------------------------------------------------------------------------*/
/* Testing wolfSSL_UseOCSPStapling function. OCSP stapling eliminates the need
* need to contact the CA, lowering the cost of cert revocation checking.
* PRE: HAVE_OCSP and HAVE_CERTIFICATE_STATUS_REQUEST
* POST: 1 returned for success.
*/
static int test_wolfSSL_UseOCSPStapling(void)
{
EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && defined(HAVE_OCSP) && \
!defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#endif
#else
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_UseOCSPStapling(NULL, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
#else
ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
} /* END test_wolfSSL_UseOCSPStapling */
/* Testing OCSP stapling version 2, wolfSSL_UseOCSPStaplingV2 function. OCSP
* stapling eliminates the need to contact the CA and lowers cert revocation
* check.
* PRE: HAVE_CERTIFICATE_STATUS_REQUEST_V2 and HAVE_OCSP defined.
*/
static int test_wolfSSL_UseOCSPStaplingV2(void)
{
EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && defined(HAVE_OCSP) && \
!defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#endif
#else
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(NULL, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifndef NO_WOLFSSL_CLIENT
ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
#else
ExpectIntEQ(wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
} /* END test_wolfSSL_UseOCSPStaplingV2 */
/*----------------------------------------------------------------------------*
| Multicast Tests
*----------------------------------------------------------------------------*/
static int test_wolfSSL_mcast(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_MULTICAST) && \
(defined(WOLFSSL_TLS13) || defined(WOLFSSL_SNIFFER))
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
byte preMasterSecret[512];
byte clientRandom[32];
byte serverRandom[32];
byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */
byte buf[256];
word16 newId;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
ExpectIntEQ(wolfSSL_CTX_mcast_set_member_id(ctx, 0), WOLFSSL_SUCCESS);
ExpectNotNull(ssl = wolfSSL_new(ctx));
XMEMSET(preMasterSecret, 0x23, sizeof(preMasterSecret));
XMEMSET(clientRandom, 0xA5, sizeof(clientRandom));
XMEMSET(serverRandom, 0x5A, sizeof(serverRandom));
ExpectIntEQ(wolfSSL_set_secret(ssl, 23, preMasterSecret,
sizeof(preMasterSecret), clientRandom, serverRandom, suite),
WOLFSSL_SUCCESS);
ExpectIntLE(wolfSSL_mcast_read(ssl, &newId, buf, sizeof(buf)), 0);
ExpectIntLE(newId, 100);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* WOLFSSL_DTLS && WOLFSSL_MULTICAST && (WOLFSSL_TLS13 ||
* WOLFSSL_SNIFFER) */
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Wolfcrypt
*----------------------------------------------------------------------------*/
/*
* Testing wc_SetKeyUsage()
*/
static int test_wc_SetKeyUsage(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && !defined(HAVE_FIPS)
Cert myCert;
ExpectIntEQ(wc_InitCert(&myCert), 0);
ExpectIntEQ(wc_SetKeyUsage(&myCert, "keyEncipherment,keyAgreement"), 0);
ExpectIntEQ(wc_SetKeyUsage(&myCert, "digitalSignature,nonRepudiation"), 0);
ExpectIntEQ(wc_SetKeyUsage(&myCert, "contentCommitment,encipherOnly"), 0);
ExpectIntEQ(wc_SetKeyUsage(&myCert, "decipherOnly"), 0);
ExpectIntEQ(wc_SetKeyUsage(&myCert, "cRLSign,keyCertSign"), 0);
/* Test bad args. */
ExpectIntEQ(wc_SetKeyUsage(NULL, "decipherOnly"), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_SetKeyUsage(&myCert, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_SetKeyUsage(&myCert, ""), WC_NO_ERR_TRACE(KEYUSAGE_E));
ExpectIntEQ(wc_SetKeyUsage(&myCert, ","), WC_NO_ERR_TRACE(KEYUSAGE_E));
ExpectIntEQ(wc_SetKeyUsage(&myCert, "digitalSignature, cRLSign"),
WC_NO_ERR_TRACE(KEYUSAGE_E));
#endif
return EXPECT_RESULT();
} /* END test_wc_SetKeyUsage */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
static void sample_mutex_cb (int flag, int type, const char* file, int line)
{
(void)flag;
(void)type;
(void)file;
(void)line;
}
#endif
/*
* Testing wc_LockMutex_ex
*/
static int test_wc_LockMutex_ex(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
int flag = CRYPTO_LOCK;
int type = 0;
const char* file = "./test-LockMutex_ex.txt";
int line = 0;
/* without SetMutexCb */
ExpectIntEQ(wc_LockMutex_ex(flag, type, file, line), WC_NO_ERR_TRACE(BAD_STATE_E));
/* with SetMutexCb */
ExpectIntEQ(wc_SetMutexCb(sample_mutex_cb), 0);
ExpectIntEQ(wc_LockMutex_ex(flag, type, file, line), 0);
ExpectIntEQ(wc_SetMutexCb(NULL), 0);
#endif
return EXPECT_RESULT();
} /* End test_wc_LockMutex_ex*/
/*
* Testing wc_SetMutexCb
*/
static int test_wc_SetMutexCb(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
ExpectIntEQ(wc_SetMutexCb(sample_mutex_cb), 0);
ExpectIntEQ(wc_SetMutexCb(NULL), 0);
#endif
return EXPECT_RESULT();
} /* End test_wc_SetMutexCb*/
/*
* Testing ToTraditional
*/
static int test_ToTraditional(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && (defined(HAVE_PKCS8) || defined(HAVE_PKCS12)) && \
(defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)) && !defined(NO_FILESYSTEM)
XFILE f = XBADFILE;
byte input[TWOK_BUF];
word32 sz = 0;
ExpectTrue((f = XFOPEN("./certs/server-keyPkcs8.der", "rb")) != XBADFILE);
ExpectTrue((sz = (word32)XFREAD(input, 1, sizeof(input), f)) > 0);
if (f != XBADFILE)
XFCLOSE(f);
/* Good case */
ExpectIntGT(ToTraditional(input, sz), 0);
/* Bad cases */
ExpectIntEQ(ToTraditional(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(ToTraditional(NULL, sz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#ifdef WOLFSSL_ASN_TEMPLATE
ExpectIntEQ(ToTraditional(input, 0), WC_NO_ERR_TRACE(BUFFER_E));
#else
ExpectIntEQ(ToTraditional(input, 0), WC_NO_ERR_TRACE(ASN_PARSE_E));
#endif
#endif
return EXPECT_RESULT();
} /* End test_ToTraditional*/
/*
* Testing wc_SetSubjectBuffer
*/
static int test_wc_SetSubjectBuffer(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
Cert cert;
XFILE file = XBADFILE;
byte* der = NULL;
word32 derSz;
derSz = FOURK_BUF;
ExpectNotNull(der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectTrue((file = XFOPEN("./certs/ca-cert.der", "rb")) != XBADFILE);
ExpectTrue((derSz = (word32)XFREAD(der, 1, FOURK_BUF, file)) > 0);
if (file != XBADFILE)
XFCLOSE(file);
ExpectIntEQ(wc_InitCert(&cert), 0);
ExpectIntEQ(wc_SetSubjectBuffer(&cert, der, (int)derSz), 0);
ExpectIntEQ(wc_SetSubjectBuffer(NULL, der, (int)derSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXPECT_RESULT();
} /* End test_wc_SetSubjectBuffer*/
/*
* Testing wc_SetSubjectKeyIdFromPublicKey_ex
*/
static int test_wc_SetSubjectKeyIdFromPublicKey_ex(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
WC_RNG rng;
Cert cert;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
RsaKey rsaKey;
int bits = 2048;
#endif
#if defined(HAVE_ECC)
ecc_key eccKey;
int ret;
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
ed25519_key ed25519Key;
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
ed448_key ed448Key;
#endif
#ifndef HAVE_FIPS
ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, testDevId), 0);
#else
ExpectIntEQ(wc_InitRng(&rng), 0);
#endif
ExpectIntEQ(wc_InitCert(&cert), 0);
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
/* RSA */
XMEMSET(&rsaKey, 0, sizeof(RsaKey));
ExpectIntEQ(wc_InitRsaKey(&rsaKey, HEAP_HINT), 0);
ExpectIntEQ(MAKE_RSA_KEY(&rsaKey, bits, WC_RSA_EXPONENT, &rng), 0);
ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, RSA_TYPE, &rsaKey),
0);
DoExpectIntEQ(wc_FreeRsaKey(&rsaKey), 0);
#endif
#if defined(HAVE_ECC)
/* ECC */
XMEMSET(&eccKey, 0, sizeof(ecc_key));
ExpectIntEQ(wc_ecc_init(&eccKey), 0);
ret = wc_ecc_make_key(&rng, KEY14, &eccKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &eccKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
ExpectIntEQ(ret, 0);
ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ECC_TYPE, &eccKey),
0);
DoExpectIntEQ(wc_ecc_free(&eccKey), 0);
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
/* ED25519 */
XMEMSET(&ed25519Key, 0, sizeof(ed25519_key));
ExpectIntEQ(wc_ed25519_init(&ed25519Key), 0);
ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519Key), 0);
ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED25519_TYPE,
&ed25519Key), 0);
wc_ed25519_free(&ed25519Key);
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
/* ED448 */
XMEMSET(&ed448Key, 0, sizeof(ed448_key));
ExpectIntEQ(wc_ed448_init(&ed448Key), 0);
ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448Key), 0);
ExpectIntEQ(wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED448_TYPE,
&ed448Key), 0);
wc_ed448_free(&ed448Key);
#endif
wc_FreeRng(&rng);
DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* WOLFSSL_CERT_EXT && WOLFSSL_CERT_GEN */
return EXPECT_RESULT();
} /* End test_wc_SetSubjectKeyIdFromPublicKey_ex*/
/*
* Testing wc_SetAuthKeyIdFromPublicKey_ex
*/
static int test_wc_SetAuthKeyIdFromPublicKey_ex(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
WC_RNG rng;
Cert cert;
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
RsaKey rsaKey;
int bits = 2048;
#endif
#if defined(HAVE_ECC)
ecc_key eccKey;
int ret;
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
ed25519_key ed25519Key;
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
ed448_key ed448Key;
#endif
#ifndef HAVE_FIPS
ExpectIntEQ(wc_InitRng_ex(&rng, HEAP_HINT, testDevId), 0);
#else
ExpectIntEQ(wc_InitRng(&rng), 0);
#endif
ExpectIntEQ(wc_InitCert(&cert), 0);
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
/* RSA */
XMEMSET(&rsaKey, 0, sizeof(RsaKey));
ExpectIntEQ(wc_InitRsaKey(&rsaKey, HEAP_HINT), 0);
ExpectIntEQ(MAKE_RSA_KEY(&rsaKey, bits, WC_RSA_EXPONENT, &rng), 0);
ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, RSA_TYPE, &rsaKey), 0);
DoExpectIntEQ(wc_FreeRsaKey(&rsaKey), 0);
#endif
#if defined(HAVE_ECC)
/* ECC */
XMEMSET(&eccKey, 0, sizeof(ecc_key));
ExpectIntEQ(wc_ecc_init(&eccKey), 0);
ret = wc_ecc_make_key(&rng, KEY14, &eccKey);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &eccKey.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
ExpectIntEQ(ret, 0);
ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ECC_TYPE, &eccKey), 0);
DoExpectIntEQ(wc_ecc_free(&eccKey), 0);
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
/* ED25519 */
XMEMSET(&ed25519Key, 0, sizeof(ed25519_key));
ExpectIntEQ(wc_ed25519_init(&ed25519Key), 0);
ExpectIntEQ(wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &ed25519Key), 0);
ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED25519_TYPE,
&ed25519Key), 0);
wc_ed25519_free(&ed25519Key);
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)
/* ED448 */
XMEMSET(&ed448Key, 0, sizeof(ed448_key));
ExpectIntEQ(wc_ed448_init(&ed448Key), 0);
ExpectIntEQ(wc_ed448_make_key(&rng, ED448_KEY_SIZE, &ed448Key), 0);
ExpectIntEQ(wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED448_TYPE, &ed448Key),
0);
wc_ed448_free(&ed448Key);
#endif
DoExpectIntEQ(wc_FreeRng(&rng), 0);
#endif /* defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)*/
return EXPECT_RESULT();
} /* End test_wc_SetAuthKeyIdFromPublicKey_ex*/
static int test_wolfSSL_lhash(void)
{
EXPECT_DECLS;
#ifdef OPENSSL_ALL
const char testStr[] = "Like a true nature's child\n"
"We were born\n"
"Born to be wild";
#ifdef NO_SHA
ExpectIntEQ(lh_strhash(testStr), 0xf9dc8a43);
#else
ExpectIntEQ(lh_strhash(testStr), 0x5b7541dc);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wc_PemToDer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM)
int ret;
DerBuffer* pDer = NULL;
const char* ca_cert = "./certs/server-cert.pem";
const char* trusted_cert = "./certs/test/ossl-trusted-cert.pem";
byte* cert_buf = NULL;
size_t cert_sz = 0;
int eccKey = 0;
EncryptedInfo info;
XMEMSET(&info, 0, sizeof(info));
ExpectIntEQ(ret = load_file(ca_cert, &cert_buf, &cert_sz), 0);
ExpectIntEQ(ret = wc_PemToDer(cert_buf, (long int)cert_sz, CERT_TYPE, &pDer, NULL,
&info, &eccKey), 0);
wc_FreeDer(&pDer);
pDer = NULL;
if (cert_buf != NULL) {
free(cert_buf);
cert_buf = NULL;
}
/* Test that -----BEGIN TRUSTED CERTIFICATE----- banner parses OK */
ExpectIntEQ(ret = load_file(trusted_cert, &cert_buf, &cert_sz), 0);
ExpectIntEQ(ret = wc_PemToDer(cert_buf, (long int)cert_sz, TRUSTED_CERT_TYPE, &pDer, NULL,
&info, &eccKey), 0);
wc_FreeDer(&pDer);
pDer = NULL;
if (cert_buf != NULL) {
free(cert_buf);
cert_buf = NULL;
}
#ifdef HAVE_ECC
{
const char* ecc_private_key = "./certs/ecc-privOnlyKey.pem";
byte key_buf[256] = {0};
/* Test fail of loading a key with cert type */
ExpectIntEQ(load_file(ecc_private_key, &cert_buf, &cert_sz), 0);
key_buf[0] = '\n';
ExpectNotNull(XMEMCPY(key_buf + 1, cert_buf, cert_sz));
ExpectIntNE((ret = wc_PemToDer(key_buf, (long int)cert_sz + 1, CERT_TYPE,
&pDer, NULL, &info, &eccKey)), 0);
#ifdef OPENSSL_EXTRA
ExpectIntEQ((ret = wc_PemToDer(key_buf, cert_sz + 1, PRIVATEKEY_TYPE,
&pDer, NULL, &info, &eccKey)), 0);
#endif
wc_FreeDer(&pDer);
if (cert_buf != NULL)
free(cert_buf);
}
#endif
#endif
return EXPECT_RESULT();
}
static int test_wc_AllocDer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS)
DerBuffer* pDer = NULL;
word32 testSize = 1024;
ExpectIntEQ(wc_AllocDer(NULL, testSize, CERT_TYPE, HEAP_HINT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AllocDer(&pDer, testSize, CERT_TYPE, HEAP_HINT), 0);
ExpectNotNull(pDer);
wc_FreeDer(&pDer);
#endif
return EXPECT_RESULT();
}
static int test_wc_CertPemToDer(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM)
const char* ca_cert = "./certs/ca-cert.pem";
byte* cert_buf = NULL;
size_t cert_sz = 0;
size_t cert_dersz = 0;
byte* cert_der = NULL;
ExpectIntEQ(load_file(ca_cert, &cert_buf, &cert_sz), 0);
cert_dersz = cert_sz; /* DER will be smaller than PEM */
ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
ExpectIntGE(wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der,
(int)cert_dersz, CERT_TYPE), 0);
ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, NULL, -1, CERT_TYPE),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, NULL, -1, CERT_TYPE),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, cert_der, -1, CERT_TYPE),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, NULL, (int)cert_dersz,
CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(NULL, (int)cert_sz, cert_der,
(int)cert_dersz, CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, NULL,
(int)cert_dersz, CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der, -1,
CERT_TYPE), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
if (cert_der != NULL)
free(cert_der);
if (cert_buf != NULL)
free(cert_buf);
#endif
return EXPECT_RESULT();
}
static int test_wc_KeyPemToDer(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
int ret = 0;
const byte cert_buf[] = \
"-----BEGIN PRIVATE KEY-----\n"
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMG5KgWxP002pA\n"
"QJIdA4H5N0oM1Wf0LrHcos5RYUlrHDkC2b5p2BUpVRPmgDAFD2+8leim98x0BvcB\n"
"k48TNzrVynuwyVEY664+iQyzEBO5v27HPRydOddprbLCvRO036XINGIjauy1jHFi\n"
"HaDVx3bexSwgp9aefUGAszFXi4q1J4GacV7Cr2b/wBqUHqWv4ZXPu6R9/UYngTkD\n"
"UDJL5gLlLfcLzNyyodKPHPCIAKdWn6mSVdcHk8XVpK4y9lgz4E7YDWA6ohKZgWgG\n"
"2RDha8CMilFMDgYa0G0SiS9g3PQx0qh3AMXJJsKSVhScFCZufAE0kV6KvjP7jAqP\n"
"XBiSkRGPAgMBAAECggEAW7hmRyY2jRX2UMJThrM9VIs6fRLnYI0dQ0tsEJj536ay\n"
"nevQjArc05KWW0Yujg+WRDZPcry3RUqd9Djlmhp/F3Si6dpF1b+PMS3wJYVrf9Sd\n"
"SO5W7faArU4vnyBNe0HnY1Ta5xSVI65lg1RSIs88RTZwsooJwXYDGf0shq0/21CE\n"
"V8HOb27DDYNcEnm35lzaONjFnMqQQT2Vs9anRrPiSEXNleEvTgLVXZtGTyCGTz6v\n"
"x86Y8eSWL9YNHvPE1I+mDPuocfSR7eRNgRu7SK3mn94W5mqd7Ns072YKX/2XN1mO\n"
"66+ZFHO6v4dK1u7cSjuwrU1EhLHpUsgDz6Bna5InyQKBgQDv5l8RPy8UneKSADaf\n"
"M5L/5675I/5t4nqVjvbnQje00YveLTAEjlJBNR93Biln3sYgnvNamYDCxyEuUZ/I\n"
"S/vmBL9PoxfGZow4FcsIBOEbIn3E0SYJgCBNWthquUvGpKsYDnThJuhO+1cVmxAJ\n"
"BUOjLFnJYHM0a+Vmk9GexT2OBwKBgQDZzkUBOK7Im3eiYytFocUJyhqMH30d49X9\n"
"ujC7kGw4UWAqVe7YCSvlBa8nzWpRWK2kRpu3M0272RU0V4geyWqT+nr/SvRRPtNP\n"
"F5dY8l3yR7hjtSejqqjOfBcZT6ETJxI4tiG0+Nl5BlfM5M+0nxnkWpRcHuOR3j79\n"
"YUFERyN+OQKBgQCjlOKeUAc6d65W/+4/AFvsQ378Q57qLtSHxsR1TKHPmlNVXFqx\n"
"wJo1/JNIBduWCEHxXHF0BdfW+RGXE/FwEt/hKLuLAhrkHmjelX2sKieU6R/5ZOQa\n"
"9lMQbDHGFDOncAF6leD85hriQGBRSzrT69MDIOrYdfwYcroqCAGX0cb3YQKBgQC8\n"
"iIFQylj5SyHmjcMSNjKSA8CxFDzAV8yPIdE3Oo+CvGXqn5HsrRuy1hXE9VmXapR8\n"
"A6ackSszdHiXY0FvrNe1mfdH7wDHJwPQjdIzazCJHS3uGQxj7sDKY7226ie6pXJv\n"
"ZrCMr2/IBAaSVGm6ppHKCeIsT4ybYm7R85KEYLPHeQKBgBeJOMBinXQfWN/1jT9b\n"
"6Ywrutvp2zP8hVxQGSZJ0WG4iewZyFLsPUlbWRXOSYNPElHmdD0ZomdLVm+lSpAA\n"
"XSH5FJ/IFCwqq7Eft6Gf8NFRV+NjPMUny+PnjHe4oFP8YK/Ek22K3ttNG8Hw69Aw\n"
"AQue5o6oVfhgLiJzMdo/77gw\n"
"-----END PRIVATE KEY-----\n";
const int cert_sz = sizeof(cert_buf);
const char cert_pw[] = "password";
int cert_dersz = 0;
byte* cert_der = NULL;
/* Bad arg: Cert buffer is NULL */
ExpectIntEQ(wc_KeyPemToDer(NULL, cert_sz, cert_der, cert_dersz, ""),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Bad arg: Cert DER buffer non-NULL but size zero (or less) */
ExpectIntEQ(wc_KeyPemToDer(cert_buf, cert_sz, (byte*)&cert_der, 0, ""),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Test normal operation */
cert_dersz = cert_sz; /* DER will be smaller than PEM */
ExpectNotNull(cert_der = (byte*)malloc((size_t)cert_dersz));
ExpectIntGE(ret = wc_KeyPemToDer(cert_buf, cert_sz, cert_der, cert_dersz,
cert_pw), 0);
ExpectIntLE(ret, cert_sz);
if (cert_der != NULL) {
free(cert_der);
cert_der = NULL;
}
/* Test NULL for DER buffer to return needed DER buffer size */
ExpectIntGT(ret = wc_KeyPemToDer(cert_buf, cert_sz, NULL, 0, ""), 0);
ExpectIntLE(ret, cert_sz);
if (EXPECT_SUCCESS())
cert_dersz = ret;
ExpectNotNull(cert_der = (byte*)malloc((size_t)cert_dersz));
ExpectIntGE(ret = wc_KeyPemToDer(cert_buf, cert_sz, cert_der, cert_dersz,
cert_pw), 0);
ExpectIntLE(ret, cert_sz);
if (cert_der != NULL)
free(cert_der);
#endif
return EXPECT_RESULT();
}
static int test_wc_PubKeyPemToDer(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_PEM_TO_DER) && !defined(NO_FILESYSTEM) && \
(defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
int ret = 0;
const char* key = "./certs/ecc-client-keyPub.pem";
byte* cert_buf = NULL;
size_t cert_sz = 0, cert_dersz = 0;
byte* cert_der = NULL;
ExpectIntEQ(wc_PubKeyPemToDer(cert_buf, (int)cert_sz,
cert_der, (int)cert_dersz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(load_file(key, &cert_buf, &cert_sz), 0);
cert_dersz = cert_sz; /* DER will be smaller than PEM */
ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
ExpectIntGE(wc_PubKeyPemToDer(cert_buf, (int)cert_sz, cert_der,
(int)cert_dersz), 0);
if (cert_der != NULL) {
free(cert_der);
cert_der = NULL;
}
/* Test NULL for DER buffer to return needed DER buffer size */
ExpectIntGT(ret = wc_PubKeyPemToDer(cert_buf, (int)cert_sz, NULL, 0), 0);
ExpectIntLE(ret, cert_sz);
cert_dersz = (size_t)ret;
ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
ExpectIntGE(wc_PubKeyPemToDer(cert_buf, (int)cert_sz, cert_der,
(int)cert_dersz), 0);
if (cert_der != NULL) {
free(cert_der);
}
if (cert_buf != NULL) {
free(cert_buf);
}
#endif
return EXPECT_RESULT();
}
static int test_wc_PemPubKeyToDer(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && \
(defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER))
const char* key = "./certs/ecc-client-keyPub.pem";
size_t cert_dersz = 1024;
byte* cert_der = NULL;
ExpectIntGE(wc_PemPubKeyToDer(NULL, cert_der, (int)cert_dersz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
ExpectIntGE(wc_PemPubKeyToDer(key, cert_der, (int)cert_dersz), 0);
if (cert_der != NULL) {
free(cert_der);
}
#endif
return EXPECT_RESULT();
}
static int test_wc_GetPubKeyDerFromCert(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) || defined(HAVE_ECC)
int ret;
word32 idx = 0;
byte keyDer[TWOK_BUF]; /* large enough for up to RSA 2048 */
word32 keyDerSz = (word32)sizeof(keyDer);
DecodedCert decoded;
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
byte certBuf[6000]; /* for PEM and CSR, client-cert.pem is 5-6kB */
word32 certBufSz = sizeof(certBuf);
#endif
#if ((!defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024)) || \
defined(WOLFSSL_CERT_REQ)) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
XFILE fp = XBADFILE;
#endif
#ifndef NO_RSA
RsaKey rsaKey;
#if defined(USE_CERT_BUFFERS_2048)
byte* rsaCertDer = (byte*)client_cert_der_2048;
word32 rsaCertDerSz = sizeof_client_cert_der_2048;
#elif defined(USE_CERT_BUFFERS_1024)
byte* rsaCertDer = (byte*)client_cert_der_1024;
word32 rsaCertDerSz = sizeof_client_cert_der_1024;
#else
unsigned char rsaCertDer[TWOK_BUF];
word32 rsaCertDerSz;
#endif
#endif
#ifdef HAVE_ECC
ecc_key eccKey;
#if defined(USE_CERT_BUFFERS_256)
byte* eccCert = (byte*)cliecc_cert_der_256;
word32 eccCertSz = sizeof_cliecc_cert_der_256;
#else
unsigned char eccCert[ONEK_BUF];
word32 eccCertSz;
XFILE fp2 = XBADFILE;
#endif
#endif
#ifndef NO_RSA
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE);
ExpectIntGT(rsaCertDerSz = (word32)XFREAD(rsaCertDer, 1, sizeof(rsaCertDer),
fp), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
#endif
/* good test case - RSA DER cert */
wc_InitDecodedCert(&decoded, rsaCertDer, rsaCertDerSz, NULL);
ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
ExpectIntEQ(ret, 0);
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
if (ret == 0) {
wc_FreeRsaKey(&rsaKey);
}
/* test LENGTH_ONLY_E case */
keyDerSz = 0;
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, NULL, &keyDerSz),
WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectIntGT(keyDerSz, 0);
/* bad args: DecodedCert NULL */
ExpectIntEQ(wc_GetPubKeyDerFromCert(NULL, keyDer, &keyDerSz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* bad args: output key buff size */
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* bad args: zero size output key buffer */
keyDerSz = 0;
ExpectIntEQ(ret = wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
wc_FreeDecodedCert(&decoded);
/* Certificate Request Tests */
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
{
XMEMSET(certBuf, 0, sizeof(certBuf));
ExpectTrue((fp = XFOPEN("./certs/csr.signed.der", "rb")) != XBADFILE);
ExpectIntGT(certBufSz = (word32)XFREAD(certBuf, 1, certBufSz, fp), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
}
wc_InitDecodedCert(&decoded, certBuf, certBufSz, NULL);
ExpectIntEQ(wc_ParseCert(&decoded, CERTREQ_TYPE, VERIFY, NULL), 0);
/* good test case - RSA DER certificate request */
keyDerSz = sizeof(keyDer);
ExpectIntEQ(ret = wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz),
0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
ExpectIntEQ(ret, 0);
idx = 0;
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
if (ret == 0) {
wc_FreeRsaKey(&rsaKey);
}
wc_FreeDecodedCert(&decoded);
}
#endif /* WOLFSSL_CERT_REQ */
#endif /* NO_RSA */
#ifdef HAVE_ECC
#ifndef USE_CERT_BUFFERS_256
ExpectTrue((fp2 = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
XBADFILE);
ExpectIntGT(eccCertSz = (word32)XFREAD(eccCert, 1, ONEK_BUF, fp2), 0);
if (fp2 != XBADFILE) {
XFCLOSE(fp2);
}
#endif
wc_InitDecodedCert(&decoded, eccCert, eccCertSz, NULL);
ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);
/* good test case - ECC */
XMEMSET(keyDer, 0, sizeof(keyDer));
keyDerSz = sizeof(keyDer);
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_ecc_init(&eccKey);
ExpectIntEQ(ret, 0);
idx = 0; /* reset idx to 0, used above in RSA case */
ExpectIntEQ(wc_EccPublicKeyDecode(keyDer, &idx, &eccKey, keyDerSz), 0);
if (ret == 0) {
wc_ecc_free(&eccKey);
}
/* test LENGTH_ONLY_E case */
keyDerSz = 0;
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, NULL, &keyDerSz),
WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectIntGT(keyDerSz, 0);
wc_FreeDecodedCert(&decoded);
#endif
#endif /* !NO_RSA || HAVE_ECC */
return EXPECT_RESULT();
}
static int test_wc_GetSubjectPubKeyInfoDerFromCert(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) || defined(HAVE_ECC)
int ret;
word32 idx = 0;
byte keyDer[TWOK_BUF]; /* large enough for up to RSA 2048 */
word32 keyDerSz = (word32)sizeof(keyDer);
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
byte certBuf[6000]; /* for PEM and CSR, client-cert.pem is 5-6kB */
word32 certBufSz = sizeof(certBuf);
#endif
#if ((!defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024)) || \
defined(WOLFSSL_CERT_REQ)) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
XFILE fp = XBADFILE;
#endif
#ifndef NO_RSA
RsaKey rsaKey;
#if defined(USE_CERT_BUFFERS_2048)
byte* rsaCertDer = (byte*)client_cert_der_2048;
word32 rsaCertDerSz = sizeof_client_cert_der_2048;
#elif defined(USE_CERT_BUFFERS_1024)
byte* rsaCertDer = (byte*)client_cert_der_1024;
word32 rsaCertDerSz = sizeof_client_cert_der_1024;
#else
unsigned char rsaCertDer[TWOK_BUF];
word32 rsaCertDerSz;
#endif
#endif
#ifdef HAVE_ECC
ecc_key eccKey;
#if defined(USE_CERT_BUFFERS_256)
byte* eccCert = (byte*)cliecc_cert_der_256;
word32 eccCertSz = sizeof_cliecc_cert_der_256;
#else
unsigned char eccCert[ONEK_BUF];
word32 eccCertSz;
XFILE fp2 = XBADFILE;
#endif
#endif
#ifndef NO_RSA
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE);
ExpectIntGT(rsaCertDerSz = (word32)XFREAD(rsaCertDer, 1, sizeof(rsaCertDer),
fp), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
#endif
/* good test case - RSA DER cert */
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer, rsaCertDerSz,
keyDer, &keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
ExpectIntEQ(ret, 0);
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
if (ret == 0) {
wc_FreeRsaKey(&rsaKey);
}
/* bad args: certDer */
keyDerSz = (word32)sizeof(keyDer);
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(NULL, rsaCertDerSz, keyDer,
&keyDerSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* bad args: 0 sized certSz */
keyDerSz = (word32)sizeof(keyDer);
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer, 0, keyDer,
&keyDerSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* bad args: NULL inout size */
ExpectIntEQ(ret = wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer,
rsaCertDerSz, keyDer,
NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Certificate Request Tests */
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
{
XMEMSET(certBuf, 0, sizeof(certBuf));
ExpectTrue((fp = XFOPEN("./certs/csr.signed.der", "rb")) != XBADFILE);
ExpectIntGT(certBufSz = (word32)XFREAD(certBuf, 1, certBufSz, fp), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
}
/* good test case - RSA DER certificate request */
keyDerSz = sizeof(keyDer);
ExpectIntEQ(ret = wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer,
rsaCertDerSz,
keyDer,
&keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
ExpectIntEQ(ret, 0);
idx = 0;
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
if (ret == 0) {
wc_FreeRsaKey(&rsaKey);
}
}
#endif /* WOLFSSL_CERT_REQ */
#endif /* NO_RSA */
#ifdef HAVE_ECC
#ifndef USE_CERT_BUFFERS_256
ExpectTrue((fp2 = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
XBADFILE);
ExpectIntGT(eccCertSz = (word32)XFREAD(eccCert, 1, ONEK_BUF, fp2), 0);
if (fp2 != XBADFILE) {
XFCLOSE(fp2);
}
#endif
/* good test case - ECC */
XMEMSET(keyDer, 0, sizeof(keyDer));
keyDerSz = sizeof(keyDer);
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(eccCert, eccCertSz, keyDer,
&keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* sanity check, verify we can import DER public key */
ret = wc_ecc_init(&eccKey);
ExpectIntEQ(ret, 0);
idx = 0; /* reset idx to 0, used above in RSA case */
ExpectIntEQ(wc_EccPublicKeyDecode(keyDer, &idx, &eccKey, keyDerSz), 0);
if (ret == 0) {
wc_ecc_free(&eccKey);
}
#endif
#endif /* !NO_RSA || HAVE_ECC */
return EXPECT_RESULT();
}
static int test_wc_CheckCertSigPubKey(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
!defined(NO_RSA) && defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_ECC)
int ret = 0;
const char* ca_cert = "./certs/ca-cert.pem";
byte* cert_buf = NULL;
size_t cert_sz = 0;
byte* cert_der = NULL;
word32 cert_dersz = 0;
byte keyDer[TWOK_BUF]; /* large enough for up to RSA 2048 */
word32 keyDerSz = (word32)sizeof(keyDer);
DecodedCert decoded;
ExpectIntEQ(load_file(ca_cert, &cert_buf, &cert_sz), 0);
cert_dersz = (word32)cert_sz; /* DER will be smaller than PEM */
ExpectNotNull(cert_der = (byte*)malloc(cert_dersz));
ExpectIntGE(ret = wc_CertPemToDer(cert_buf, (int)cert_sz, cert_der,
(int)cert_dersz, CERT_TYPE), 0);
wc_InitDecodedCert(&decoded, cert_der, cert_dersz, NULL);
ExpectIntEQ(wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL), 0);
ExpectIntEQ(wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz), 0);
ExpectIntGT(keyDerSz, 0);
/* Good test case. */
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer,
keyDerSz, RSAk), 0);
/* No certificate. */
ExpectIntEQ(wc_CheckCertSigPubKey(NULL, cert_dersz, NULL, keyDer, keyDerSz,
ECDSAk), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Bad cert size. */
ExpectIntNE(ret = wc_CheckCertSigPubKey(cert_der, 0, NULL, keyDer, keyDerSz,
RSAk), 0);
ExpectTrue(ret == WC_NO_ERR_TRACE(ASN_PARSE_E) || ret == WC_NO_ERR_TRACE(BUFFER_E));
/* No public key. */
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, NULL,
keyDerSz, RSAk), WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
/* Bad public key size. */
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, 0,
RSAk), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* Wrong aglo. */
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer,
keyDerSz, ECDSAk), WC_NO_ERR_TRACE(ASN_PARSE_E));
wc_FreeDecodedCert(&decoded);
if (cert_der != NULL)
free(cert_der);
if (cert_buf != NULL)
free(cert_buf);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_ext_d2i(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
X509* x509 = NULL;
ExpectNotNull(x509 = wolfSSL_X509_new());
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_basic_constraints,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_subject_alt_name,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_authority_key_identifier,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_subject_key_identifier,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_key_usage,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_crl_distribution_points,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_ext_key_usage,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_info_access,
NULL, NULL));
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_certificate_policies,
NULL, NULL));
/* Invalid NID for an extension. */
ExpectNull(wolfSSL_X509_get_ext_d2i(x509, NID_description,
NULL, NULL));
wolfSSL_X509_free(x509);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_certs(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
!defined(NO_TLS) && !defined(NO_RSA)
X509* x509ext = NULL;
X509* x509 = NULL;
#ifdef OPENSSL_ALL
WOLFSSL_X509_EXTENSION* ext = NULL;
ASN1_OBJECT* obj = NULL;
#endif
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
STACK_OF(ASN1_OBJECT)* sk = NULL;
ASN1_STRING* asn1_str = NULL;
AUTHORITY_KEYID* akey = NULL;
WOLFSSL_STACK* skid = NULL;
BASIC_CONSTRAINTS* bc = NULL;
int crit = 0;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(SSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(SSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(SSL_CTX_check_private_key(ctx), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(SSL_CTX_check_private_key(ctx), SSL_SUCCESS);
#endif
ExpectNotNull(ssl = SSL_new(ctx));
/* Invalid parameters. */
ExpectIntEQ(SSL_use_certificate_file(NULL, NULL, WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_use_certificate_file(ssl, NULL, WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate_file(NULL, "./certs/server-cert.pem",
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_PK_CALLBACKS
ExpectIntEQ((int)SSL_set_tlsext_debug_arg(ssl, NULL), WOLFSSL_SUCCESS);
#endif /* HAVE_PK_CALLBACKS */
/* Invalid parameters. */
ExpectNotNull(x509 = wolfSSL_X509_new());
ExpectIntEQ(SSL_use_certificate(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate(NULL, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* No data in certificate. */
ExpectIntEQ(SSL_use_certificate(ssl, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_X509_free(x509);
x509 = NULL;
/* create and use x509 */
ExpectNull(wolfSSL_X509_load_certificate_file(cliCertFileExt, -1));
ExpectNull(wolfSSL_X509_load_certificate_file("/tmp/badfile",
WOLFSSL_FILETYPE_PEM));
ExpectNull(wolfSSL_X509_load_certificate_file(NULL, WOLFSSL_FILETYPE_PEM));
ExpectNull(wolfSSL_X509_load_certificate_file(cliCertFileExt,
WOLFSSL_FILETYPE_ASN1));
#ifdef OPENSSL_ALL
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
WOLFSSL_FILETYPE_PEM));
#endif
ExpectNotNull(x509ext = wolfSSL_X509_load_certificate_file(cliCertFileExt,
WOLFSSL_FILETYPE_PEM));
ExpectIntEQ(SSL_use_certificate(ssl, x509ext), WOLFSSL_SUCCESS);
#if !defined(NO_CHECK_PRIVATE_KEY)
/* with loading in a new cert the check on private key should now fail */
ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
#if defined(USE_CERT_BUFFERS_2048)
/* Invalid parameters. */
ExpectIntEQ(SSL_use_certificate_ASN1(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate_ASN1(ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate_ASN1(NULL,
(unsigned char*)server_cert_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* No data. */
ExpectIntEQ(SSL_use_certificate_ASN1(ssl,
(unsigned char*)server_cert_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_certificate_ASN1(ssl,
(unsigned char*)server_cert_der_2048,
sizeof_server_cert_der_2048), WOLFSSL_SUCCESS);
#endif
#if !defined(NO_SHA) && !defined(NO_SHA256) && !defined(NO_PWDBASED)
/************* Get Digest of Certificate ******************/
{
byte digest[64]; /* max digest size */
word32 digestSz;
X509* x509Empty = NULL;
XMEMSET(digest, 0, sizeof(digest));
ExpectIntEQ(X509_digest(NULL, wolfSSL_EVP_sha1(), digest, &digestSz),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_digest(x509ext, NULL, digest, &digestSz),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha1(), NULL, &digestSz),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha1(), digest, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha1(), digest, &digestSz),
WOLFSSL_SUCCESS);
ExpectIntEQ(X509_digest(x509ext, wolfSSL_EVP_sha256(), digest,
&digestSz), WOLFSSL_SUCCESS);
ExpectNotNull(x509Empty = wolfSSL_X509_new());
ExpectIntEQ(X509_digest(x509Empty, wolfSSL_EVP_sha256(), digest,
&digestSz), WOLFSSL_FAILURE);
wolfSSL_X509_free(x509Empty);
}
#endif /* !NO_SHA && !NO_SHA256 && !NO_PWDBASED */
#if !defined(NO_SHA) && !defined(NO_SHA256) && !defined(NO_PWDBASED)
/************* Get Digest of Certificate ******************/
{
byte digest[64]; /* max digest size */
word32 digestSz;
X509* x509Empty = NULL;
XMEMSET(digest, 0, sizeof(digest));
ExpectIntEQ(X509_pubkey_digest(NULL, wolfSSL_EVP_sha1(), digest,
&digestSz), WOLFSSL_FAILURE);
ExpectIntEQ(X509_pubkey_digest(x509ext, NULL, digest, &digestSz),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_pubkey_digest(x509ext, wolfSSL_EVP_sha1(), NULL,
&digestSz), WOLFSSL_FAILURE);
ExpectIntEQ(X509_pubkey_digest(x509ext, wolfSSL_EVP_sha1(), digest,
NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_pubkey_digest(x509ext, wolfSSL_EVP_sha1(), digest,
&digestSz), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_pubkey_digest(x509ext, wolfSSL_EVP_sha256(), digest,
&digestSz), WOLFSSL_SUCCESS);
ExpectNotNull(x509Empty = wolfSSL_X509_new());
ExpectIntEQ(X509_pubkey_digest(x509Empty, wolfSSL_EVP_sha256(), digest,
&digestSz), WOLFSSL_FAILURE);
wolfSSL_X509_free(x509Empty);
}
#endif /* !NO_SHA && !NO_SHA256 && !NO_PWDBASED */
/* test and checkout X509 extensions */
ExpectNotNull(bc = (BASIC_CONSTRAINTS*)X509_get_ext_d2i(x509ext,
NID_basic_constraints, NULL, NULL));
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
ExpectNotNull(bc = (BASIC_CONSTRAINTS*)X509_get_ext_d2i(x509ext,
NID_basic_constraints, &crit, NULL));
ExpectIntEQ(crit, 0);
#ifdef OPENSSL_ALL
ExpectNull(X509V3_EXT_i2d(NID_basic_constraints, crit, NULL));
{
int i;
int unsupportedNid[] = {
0,
NID_inhibit_any_policy,
NID_certificate_policies,
NID_policy_mappings,
NID_name_constraints,
NID_policy_constraints,
NID_crl_distribution_points
};
int unsupportedNidCnt = (int)(sizeof(unsupportedNid) /
sizeof(*unsupportedNid));
for (i = 0; i < unsupportedNidCnt; i++) {
ExpectNotNull(ext = X509V3_EXT_i2d(unsupportedNid[i], crit, bc));
X509_EXTENSION_free(ext);
ext = NULL;
}
}
ExpectNotNull(ext = X509V3_EXT_i2d(NID_basic_constraints, crit, bc));
X509_EXTENSION_free(ext);
ext = NULL;
ExpectNotNull(ext = X509_EXTENSION_new());
ExpectIntEQ(X509_EXTENSION_set_critical(NULL, 1), WOLFSSL_FAILURE);
ExpectIntEQ(X509_EXTENSION_set_critical(ext, 1), WOLFSSL_SUCCESS);
ExpectNotNull(obj = OBJ_nid2obj(NID_basic_constraints));
ExpectIntEQ(X509_EXTENSION_set_object(NULL, NULL), SSL_FAILURE);
ExpectIntEQ(X509_EXTENSION_set_object(NULL, obj), SSL_FAILURE);
ExpectIntEQ(X509_EXTENSION_set_object(ext, NULL), SSL_SUCCESS);
ExpectIntEQ(X509_EXTENSION_set_object(ext, obj), SSL_SUCCESS);
/* Check old object is being freed. */
ExpectIntEQ(X509_EXTENSION_set_object(ext, obj), SSL_SUCCESS);
ASN1_OBJECT_free(obj);
obj = NULL;
X509_EXTENSION_free(ext);
ext = NULL;
ExpectNotNull(ext = X509_EXTENSION_new());
ExpectIntEQ(X509_EXTENSION_set_critical(ext, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_EXTENSION_set_data(ext, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectNotNull(asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext,
NID_key_usage, NULL, NULL));
ASN1_STRING_free(asn1_str);
asn1_str = NULL;
ExpectNotNull(asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext,
NID_key_usage, &crit, NULL));
ExpectIntEQ(X509_EXTENSION_set_data(ext, asn1_str), SSL_SUCCESS);
ExpectIntEQ(X509_EXTENSION_set_data(ext, asn1_str), SSL_SUCCESS);
ASN1_STRING_free(asn1_str); /* X509_EXTENSION_set_data has made a copy
* and X509_get_ext_d2i has created new */
asn1_str = NULL;
X509_EXTENSION_free(ext);
ext = NULL;
#endif
BASIC_CONSTRAINTS_free(NULL);
BASIC_CONSTRAINTS_free(bc);
bc = NULL;
ExpectNotNull(asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext,
NID_key_usage, NULL, NULL));
ASN1_STRING_free(asn1_str);
asn1_str = NULL;
ExpectNotNull(asn1_str = (ASN1_STRING*)X509_get_ext_d2i(x509ext,
NID_key_usage, &crit, NULL));
ExpectIntEQ(crit, 1);
ExpectIntEQ(asn1_str->type, NID_key_usage);
#ifdef OPENSSL_ALL
ExpectNotNull(ext = X509V3_EXT_i2d(NID_key_usage, crit, asn1_str));
X509_EXTENSION_free(ext);
ext = NULL;
#endif
ASN1_STRING_free(asn1_str);
asn1_str = NULL;
#ifdef OPENSSL_ALL
ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
NID_ext_key_usage, NULL, NULL));
EXTENDED_KEY_USAGE_free(NULL);
EXTENDED_KEY_USAGE_free(sk);
sk = NULL;
ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
NID_ext_key_usage, &crit, NULL));
ExpectNotNull(ext = X509V3_EXT_i2d(NID_ext_key_usage, crit, sk));
X509_EXTENSION_free(ext);
ext = NULL;
EXTENDED_KEY_USAGE_free(sk);
sk = NULL;
#else
sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext, NID_ext_key_usage,
&crit, NULL);
ExpectNull(sk);
#endif
ExpectNotNull(akey = (AUTHORITY_KEYID*)X509_get_ext_d2i(x509ext,
NID_authority_key_identifier, NULL, NULL));
wolfSSL_AUTHORITY_KEYID_free(NULL);
wolfSSL_AUTHORITY_KEYID_free(akey);
akey = NULL;
ExpectNotNull(akey = (AUTHORITY_KEYID*)X509_get_ext_d2i(x509ext,
NID_authority_key_identifier, &crit, NULL));
#ifdef OPENSSL_ALL
ExpectNotNull(ext = X509V3_EXT_i2d(NID_authority_key_identifier, crit,
akey));
X509_EXTENSION_free(ext);
ext = NULL;
#endif
wolfSSL_AUTHORITY_KEYID_free(akey);
akey = NULL;
ExpectNotNull(skid = (WOLFSSL_STACK*)X509_get_ext_d2i(x509ext,
NID_subject_key_identifier, NULL, NULL));
wolfSSL_sk_ASN1_OBJECT_pop_free(skid, wolfSSL_ASN1_OBJECT_free);
skid = NULL;
ExpectNotNull(skid = (WOLFSSL_STACK*)X509_get_ext_d2i(x509ext,
NID_subject_key_identifier, &crit, NULL));
#ifdef OPENSSL_ALL
ExpectNotNull(ext = X509V3_EXT_i2d(NID_subject_key_identifier, crit,
skid));
X509_EXTENSION_free(ext);
ext = NULL;
#endif
wolfSSL_sk_ASN1_OBJECT_pop_free(skid, wolfSSL_ASN1_OBJECT_free);
skid = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_private_key_usage_period, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
ExpectNotNull(sk = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509ext,
NID_subject_alt_name, NULL, NULL));
sk_GENERAL_NAME_free(sk);
sk = NULL;
ExpectNotNull(sk = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509ext,
NID_subject_alt_name, &crit, NULL));
{
int i;
for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) {
GENERAL_NAME* gen = sk_GENERAL_NAME_value(sk, i);
ExpectIntEQ(gen->type, GEN_DNS);
ExpectIntEQ(gen->d.dNSName->type, V_ASN1_IA5STRING);
}
}
sk_GENERAL_NAME_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_issuer_alt_name, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_info_access, &crit, NULL));
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_sinfo_access, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_name_constraints, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* no cert policy set */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_certificate_policies, &crit, NULL));
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_policy_mappings, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_policy_constraints, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_inhibit_any_policy, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* NID not yet supported */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext,
NID_tlsfeature, &crit, NULL));
ExpectIntEQ(crit, -1);
sk_ASN1_OBJECT_free(sk);
sk = NULL;
/* test invalid cases */
crit = 0;
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509ext, -1, &crit,
NULL));
ExpectIntEQ(crit, -1);
/* NULL passed for criticality. */
ExpectNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(NULL,
NID_tlsfeature, NULL, NULL));
ExpectIntEQ(SSL_get_hit(ssl), 0);
#ifdef OPENSSL_ALL
X509_free(x509);
#endif
X509_free(x509ext);
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && !NO_CERTS */
return EXPECT_RESULT();
}
static int test_wolfSSL_private_keys(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
EVP_PKEY* pkey = NULL;
OpenSSL_add_all_digests();
OpenSSL_add_all_algorithms();
#ifndef NO_RSA
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
/* Have to load a cert before you can check the private key against that
* certificates public key! */
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
WOLFSSL_FILETYPE_PEM));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
#endif
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
/* Invalid parameters. */
ExpectIntEQ(SSL_use_PrivateKey_file(NULL, NULL, WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_use_PrivateKey_file(NULL, svrKeyFile, WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_use_PrivateKey_file(ssl, NULL, WOLFSSL_FILETYPE_PEM),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef USE_CERT_BUFFERS_2048
{
const unsigned char* server_key = (const unsigned char*)server_key_der_2048;
unsigned char buf[FOURK_BUF];
word32 bufSz;
/* Invalid parameters. */
ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(NULL,
(unsigned char*)client_key_der_2048, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, ssl, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, NULL, (unsigned char*)server_key, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, NULL, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx, NULL, 0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, NULL, (unsigned char*)server_key,
0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_RSAPrivateKey_ASN1(ssl,
(unsigned char*)client_key_der_2048,
sizeof_client_key_der_2048), WOLFSSL_SUCCESS);
#if !defined(NO_CHECK_PRIVATE_KEY)
/* Should mismatch now that a different private key loaded */
ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
ExpectIntEQ(SSL_use_PrivateKey_ASN1(0, ssl,
(unsigned char*)server_key,
sizeof_server_key_der_2048), WOLFSSL_SUCCESS);
#if !defined(NO_CHECK_PRIVATE_KEY)
/* After loading back in DER format of original key, should match */
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
/* test loading private key to the WOLFSSL_CTX */
ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx,
(unsigned char*)client_key_der_2048,
sizeof_client_key_der_2048), WOLFSSL_SUCCESS);
#if !defined(NO_CHECK_PRIVATE_KEY)
/* Should mismatch now that a different private key loaded */
ExpectIntNE(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
#endif
ExpectIntEQ(SSL_CTX_use_PrivateKey_ASN1(0, ctx,
(unsigned char*)server_key,
sizeof_server_key_der_2048), WOLFSSL_SUCCESS);
#if !defined(NO_CHECK_PRIVATE_KEY)
/* After loading back in DER format of original key, should match */
ExpectIntEQ(wolfSSL_CTX_check_private_key(ctx), WOLFSSL_SUCCESS);
#endif
/* Invalid parameters. */
ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new());
ExpectIntEQ(SSL_use_PrivateKey(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_PrivateKey(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_use_PrivateKey(NULL, pkey), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* pkey is empty - no key data to use. */
ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WC_NO_ERR_TRACE(ASN_PARSE_E));
wolfSSL_EVP_PKEY_free(pkey);
pkey = NULL;
/* set PKEY and test again */
ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey,
&server_key, (long)sizeof_server_key_der_2048));
ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WOLFSSL_SUCCESS);
/* reuse PKEY structure and test
* this should be checked with a memory management sanity checker */
ExpectFalse(server_key == (const unsigned char*)server_key_der_2048);
server_key = (const unsigned char*)server_key_der_2048;
ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey,
&server_key, (long)sizeof_server_key_der_2048));
ExpectIntEQ(SSL_use_PrivateKey(ssl, pkey), WOLFSSL_SUCCESS);
/* check striping PKCS8 header with wolfSSL_d2i_PrivateKey */
bufSz = FOURK_BUF;
ExpectIntGT((bufSz = (word32)wc_CreatePKCS8Key(buf, &bufSz,
(byte*)server_key_der_2048, sizeof_server_key_der_2048,
RSAk, NULL, 0)), 0);
server_key = (const unsigned char*)buf;
ExpectNotNull(wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, &pkey, &server_key,
(long)bufSz));
}
#endif
EVP_PKEY_free(pkey);
pkey = NULL;
SSL_free(ssl); /* frees x509 also since loaded into ssl */
ssl = NULL;
SSL_CTX_free(ctx);
ctx = NULL;
#endif /* end of RSA private key match tests */
#ifdef HAVE_ECC
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, eccCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
SSL_free(ssl);
ssl = NULL;
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEccKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
SSL_free(ssl);
ssl = NULL;
SSL_CTX_free(ctx);
ctx = NULL;
#endif /* end of ECC private key match tests */
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, edCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, edKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
SSL_free(ssl);
ssl = NULL;
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEdKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
#ifdef HAVE_ED25519_MAKE_KEY
ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
#endif
SSL_free(ssl);
ssl = NULL;
SSL_CTX_free(ctx);
ctx = NULL;
#endif /* end of Ed25519 private key match tests */
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, ed448CertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
SSL_free(ssl);
ssl = NULL;
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEd448KeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#if !defined(NO_CHECK_PRIVATE_KEY)
ExpectIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS);
#endif
SSL_free(ssl);
ssl = NULL;
SSL_CTX_free(ctx);
ctx = NULL;
#endif /* end of Ed448 private key match tests */
EVP_cleanup();
/* test existence of no-op macros in wolfssl/openssl/ssl.h */
CONF_modules_free();
ENGINE_cleanup();
CONF_modules_unload();
(void)ssl;
(void)ctx;
(void)pkey;
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) */
return EXPECT_RESULT();
}
static int test_wolfSSL_tmp_dh(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \
!defined(NO_RSA) && !defined(NO_DH) && !defined(NO_BIO) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
byte buff[6000];
static const unsigned char p[] = {
0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba,
0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5, 0x00,
0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6,
0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a,
0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84, 0xbf,
0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a,
0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91, 0xe6,
0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48,
0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d,
0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e, 0x19,
0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f,
0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d, 0x2a,
0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04,
0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93, 0x38,
0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5,
0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e,
0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e, 0x5a,
0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc,
0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62, 0xa7,
0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36,
0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90,
0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a, 0xc3,
0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48,
0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4, 0x9a,
0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b,
0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f, 0x08,
0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6,
0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b,
0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7, 0xfa,
0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
};
int pSz = (int)sizeof(p);
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
!defined(HAVE_SELFTEST)
static const unsigned char bad_p[] = {
0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba,
0x59, 0x06, 0x3c, 0xbc, 0x30, 0xd5, 0xf5, 0x00,
0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6,
0x25, 0x27, 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a,
0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84, 0xbf,
0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a,
0xc5, 0xbe, 0x72, 0x5c, 0xa7, 0xe7, 0x91, 0xe6,
0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48,
0xc7, 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d,
0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46, 0x3e, 0x19,
0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f,
0x2b, 0x96, 0x17, 0x39, 0x6d, 0x30, 0x8d, 0x2a,
0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04,
0x83, 0x57, 0x30, 0xfb, 0xda, 0x76, 0x93, 0x38,
0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5,
0xb7, 0xc8, 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e,
0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e, 0x5a,
0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc,
0x16, 0x30, 0xdb, 0x0c, 0xfc, 0xc5, 0x62, 0xa7,
0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36,
0xf6, 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90,
0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3, 0x1a, 0xc3,
0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48,
0x4e, 0x22, 0x73, 0x6f, 0xc3, 0x5f, 0xd4, 0x9a,
0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b,
0xa6, 0xb9, 0xcd, 0x29, 0xbf, 0x68, 0x1f, 0x08,
0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6,
0x06, 0x65, 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b,
0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7, 0xfa,
0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x91
};
#endif
static const unsigned char g[] = { 0x02 };
int gSz = (int)sizeof(g);
#if !defined(NO_DSA)
char file[] = "./certs/dsaparams.pem";
DSA* dsa = NULL;
#else
char file[] = "./certs/dh2048.pem";
#endif
XFILE f = XBADFILE;
int bytes = 0;
DH* dh = NULL;
DH* dh2 = NULL;
BIO* bio = NULL;
SSL* ssl = NULL;
SSL_CTX* ctx = NULL;
#ifndef NO_WOLFSSL_CLIENT
SSL* ssl_c = NULL;
SSL_CTX* ctx_c = NULL;
#endif
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
#endif
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx_c = SSL_CTX_new(wolfSSLv23_client_method()));
ExpectTrue(SSL_CTX_use_certificate_file(ctx_c, svrCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx_c, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(ssl_c = SSL_new(ctx_c));
#ifdef NO_WOLFSSL_SERVER
ctx = ctx_c;
ssl = ssl_c;
#endif
#endif
XMEMSET(buff, 0, sizeof(buff));
ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
#if !defined(NO_DSA)
dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
ExpectNotNull(dsa);
dh = wolfSSL_DSA_dup_DH(dsa);
#else
dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
#endif
ExpectNotNull(dh);
#if defined(WOLFSSL_DH_EXTRA) && \
(defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
ExpectNotNull(dh2 = wolfSSL_DH_dup(dh));
DH_free(dh2);
dh2 = NULL;
#endif
/* Failure cases */
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, NULL, 0, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , NULL, 0, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, p , 0, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, NULL, 0, g , 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , p , 0, NULL, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , NULL, 0, g , 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(NULL, p , 0, g , 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , p , 1, g , 1),
WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx , buff, 6000, g , 1),
WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
!defined(HAVE_SELFTEST)
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx, bad_p, pSz, g, gSz),
WC_NO_ERR_TRACE(DH_CHECK_PUB_E));
#endif
ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, NULL, 0, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , NULL, 0, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, p , 0, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, NULL, 0, g , 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , p , 0, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , NULL, 0, g , 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(NULL, p , 0, g , 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , p , 1, g , 1),
WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl , buff, 6000, g , 1),
WC_NO_ERR_TRACE(DH_KEY_SIZE_E));
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
!defined(HAVE_SELFTEST)
#ifndef NO_WOLFSSL_SERVER
/* Parameters will be tested later so it passes now. */
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl, bad_p, pSz, g, gSz),
WOLFSSL_SUCCESS);
#endif
#endif
#ifndef NO_WOLFSSL_CLIENT
ExpectIntEQ((int)wolfSSL_SetTmpDH(ssl_c, p, pSz, g, gSz),
WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx , NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(NULL, dh ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)SSL_set_tmp_dh(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)SSL_set_tmp_dh(ssl , NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ((int)SSL_set_tmp_dh(NULL, dh ), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* No p/g to use. */
dh2 = wolfSSL_DH_new();
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx , dh2 ), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ((int)SSL_set_tmp_dh(ssl , dh2 ), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
DH_free(dh2);
dh2 = NULL;
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz),
WOLFSSL_SUCCESS);
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS);
#ifndef NO_WOLFSSL_SERVER
ExpectIntEQ((int)SSL_set_tmp_dh(ssl, dh), WOLFSSL_SUCCESS);
#else
ExpectIntEQ((int)SSL_set_tmp_dh(ssl, dh), WC_NO_ERR_TRACE(SIDE_ERROR));
#endif
BIO_free(bio);
#if !defined(NO_DSA)
DSA_free(dsa);
#endif
DH_free(dh);
dh = NULL;
#ifndef NO_WOLFSSL_CLIENT
if (ssl != ssl_c) {
SSL_free(ssl_c);
}
#endif
SSL_free(ssl);
#ifndef NO_WOLFSSL_CLIENT
if (ctx != ctx_c) {
SSL_CTX_free(ctx_c);
}
#endif
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_ctrl(void)
{
EXPECT_DECLS;
#if defined (OPENSSL_EXTRA) && !defined(NO_BIO)
byte buff[6000];
BIO* bio = NULL;
int bytes;
BUF_MEM* ptr = NULL;
XMEMSET(buff, 0, sizeof(buff));
bytes = sizeof(buff);
ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
ExpectNotNull(BIO_s_socket());
ExpectIntEQ((int)wolfSSL_BIO_get_mem_ptr(bio, &ptr), WOLFSSL_SUCCESS);
/* needs tested after stubs filled out @TODO
SSL_ctrl
SSL_CTX_ctrl
*/
BIO_free(bio);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_BIO) */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_extra_chain_cert(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_BIO)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
char caFile[] = "./certs/client-ca.pem";
char clientFile[] = "./certs/client-cert.pem";
SSL_CTX* ctx = NULL;
X509* x509 = NULL;
BIO *bio = NULL;
X509 *cert = NULL;
X509 *ca = NULL;
STACK_OF(X509) *chain = NULL;
STACK_OF(X509) *chain2 = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(caFile,
WOLFSSL_FILETYPE_PEM));
/* Negative tests. */
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(NULL, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WOLFSSL_SUCCESS);
ExpectNotNull(x509 = wolfSSL_X509_new());
/* Empty certificate. */
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_X509_free(x509);
x509 = NULL;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
WOLFSSL_FILETYPE_PEM));
/* additional test of getting EVP_PKEY key size from X509
* Do not run with user RSA because wolfSSL_RSA_size is not currently
* allowed with user RSA */
{
EVP_PKEY* pkey = NULL;
#if defined(HAVE_ECC)
X509* ecX509 = NULL;
#endif /* HAVE_ECC */
ExpectNotNull(pkey = X509_get_pubkey(x509));
/* current RSA key is 2048 bit (256 bytes) */
ExpectIntEQ(EVP_PKEY_size(pkey), 256);
EVP_PKEY_free(pkey);
pkey = NULL;
#if defined(HAVE_ECC)
#if defined(USE_CERT_BUFFERS_256)
ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_buffer(
cliecc_cert_der_256, sizeof_cliecc_cert_der_256,
SSL_FILETYPE_ASN1));
#else
ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_file(
cliEccCertFile, SSL_FILETYPE_PEM));
#endif
pkey = X509_get_pubkey(ecX509);
ExpectNotNull(pkey);
/* current ECC key is 256 bit (32 bytes) */
ExpectIntGE(EVP_PKEY_size(pkey), 72);
X509_free(ecX509);
ecX509 = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
#endif /* HAVE_ECC */
}
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), SSL_SUCCESS);
if (EXPECT_SUCCESS()) {
x509 = NULL;
}
#ifdef WOLFSSL_ENCRYPTED_KEYS
ExpectNull(SSL_CTX_get_default_passwd_cb(ctx));
ExpectNull(SSL_CTX_get_default_passwd_cb_userdata(ctx));
#endif
SSL_CTX_free(ctx);
ctx = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
/* Test haproxy use case */
ExpectNotNull(bio = BIO_new_file(svrCertFile, "r"));
/* Read Certificate */
ExpectNotNull(cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
ExpectNotNull(ca = PEM_read_bio_X509(bio, NULL, NULL, NULL));
ExpectNotNull(chain = sk_X509_new_null());
ExpectIntEQ(sk_X509_push(chain, ca), 1);
if (EXPECT_SUCCESS()) {
ca = NULL;
}
ExpectNotNull(chain2 = X509_chain_up_ref(chain));
ExpectNotNull(ca = sk_X509_shift(chain2));
ExpectIntEQ(SSL_CTX_use_certificate(ctx, cert), 1);
ExpectIntEQ(SSL_CTX_add_extra_chain_cert(ctx, ca), 1);
if (EXPECT_SUCCESS()) {
ca = NULL;
}
BIO_free(bio);
X509_free(cert);
X509_free(ca);
X509_free(x509);
sk_X509_pop_free(chain, X509_free);
sk_X509_pop_free(chain2, X509_free);
SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined (NO_BIO) */
return EXPECT_RESULT();
}
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
static int test_wolfSSL_ERR_peek_last_error_line(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL) && \
!defined(NO_OLD_TLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_ERROR_QUEUE)
callback_functions client_cb;
callback_functions server_cb;
int line = 0;
int flag = ERR_TXT_STRING;
const char* file = NULL;
const char* data = NULL;
/* create a failed connection and inspect the error */
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = wolfTLSv1_1_client_method;
server_cb.method = wolfTLSv1_2_server_method;
test_wolfSSL_client_server_nofail(&client_cb, &server_cb);
ExpectIntGT(ERR_get_error_line_data(NULL, NULL, &data, &flag), 0);
ExpectNotNull(data);
/* check clearing error state */
ERR_remove_state(0);
ExpectIntEQ((int)ERR_peek_last_error_line(NULL, NULL), 0);
ERR_peek_last_error_line(NULL, &line);
ExpectIntEQ(line, 0);
ERR_peek_last_error_line(&file, NULL);
ExpectNull(file);
/* retry connection to fill error queue */
XMEMSET(&client_cb, 0, sizeof(callback_functions));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
client_cb.method = wolfTLSv1_1_client_method;
server_cb.method = wolfTLSv1_2_server_method;
test_wolfSSL_client_server_nofail(&client_cb, &server_cb);
/* check that error code was stored */
ExpectIntNE((int)ERR_peek_last_error_line(NULL, NULL), 0);
ERR_peek_last_error_line(NULL, &line);
ExpectIntNE(line, 0);
ERR_peek_last_error_line(&file, NULL);
ExpectNotNull(file);
fprintf(stderr, "\nTesting error print out\n");
ERR_print_errors_fp(stderr);
fprintf(stderr, "Done testing print out\n\n");
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) &&
* !defined(NO_FILESYSTEM) && !defined(DEBUG_WOLFSSL) */
return EXPECT_RESULT();
}
#endif /* !NO_WOLFSSL_CLIENT && !NO_WOLFSSL_SERVER */
static int test_wolfSSL_CTX_get0_set1_param(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#if !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
SSL_CTX* ctx = NULL;
WOLFSSL_X509_VERIFY_PARAM* pParam = NULL;
WOLFSSL_X509_VERIFY_PARAM* pvpm = NULL;
char testIPv4[] = "127.0.0.1";
char testhostName[] = "foo.hoge.com";
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectNull(SSL_CTX_get0_param(NULL));
ExpectNotNull(pParam = SSL_CTX_get0_param(ctx));
ExpectNotNull(pvpm = (WOLFSSL_X509_VERIFY_PARAM *)XMALLOC(
sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL));
ExpectNotNull(XMEMSET(pvpm, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)));
ExpectIntEQ(wolfSSL_X509_VERIFY_PARAM_set1_host(pvpm, testhostName,
(int)XSTRLEN(testhostName)), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(pvpm, testIPv4),
WOLFSSL_SUCCESS);
wolfSSL_X509_VERIFY_PARAM_set_hostflags(pvpm, 0x01);
ExpectIntEQ(SSL_CTX_set1_param(ctx, pvpm), 1);
ExpectIntEQ(0, XSTRNCMP(pParam->hostName, testhostName,
(int)XSTRLEN(testhostName)));
ExpectIntEQ(0x01, pParam->hostFlags);
ExpectIntEQ(0, XSTRNCMP(pParam->ipasc, testIPv4, WOLFSSL_MAX_IPSTR));
/* test for incorrect parameter */
ExpectIntEQ(1,SSL_CTX_set1_param(ctx, NULL));
ExpectIntEQ(1,SSL_CTX_set1_param(NULL, pvpm));
ExpectIntEQ(1,SSL_CTX_set1_param(NULL, NULL));
SSL_CTX_free(ctx);
XFREE(pvpm, NULL, DYNAMIC_TYPE_OPENSSL);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* OPENSSL_EXTRA && !defined(NO_RSA)*/
return EXPECT_RESULT();
}
static int test_wolfSSL_get0_param(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_FILESYSTEM)
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectNotNull(SSL_get0_param(ssl));
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_set1_host(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_FILESYSTEM)
const char host[] = "www.test_wolfSSL_set1_host.com";
const char emptyStr[] = "";
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
WOLFSSL_X509_VERIFY_PARAM* pParam = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
pParam = SSL_get0_param(ssl);
/* we should get back host string */
ExpectIntEQ(SSL_set1_host(ssl, host), WOLFSSL_SUCCESS);
ExpectIntEQ(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);
/* we should get back empty string */
ExpectIntEQ(SSL_set1_host(ssl, emptyStr), WOLFSSL_SUCCESS);
ExpectIntEQ(XMEMCMP(pParam->hostName, emptyStr, sizeof(emptyStr)), 0);
/* we should get back host string */
ExpectIntEQ(SSL_set1_host(ssl, host), WOLFSSL_SUCCESS);
ExpectIntEQ(XMEMCMP(pParam->hostName, host, sizeof(host)), 0);
/* we should get back empty string */
ExpectIntEQ(SSL_set1_host(ssl, NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(XMEMCMP(pParam->hostName, emptyStr, sizeof(emptyStr)), 0);
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_ECC) && !defined(NO_TLS) && defined(HAVE_AESGCM)
static int test_wolfSSL_get_client_ciphers_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectTrue(wolfSSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-GCM-SHA256"));
return EXPECT_RESULT();
}
static int test_wolfSSL_get_client_ciphers_on_result(WOLFSSL* ssl) {
EXPECT_DECLS;
WOLF_STACK_OF(WOLFSSL_CIPHER)* ciphers;
ciphers = SSL_get_client_ciphers(ssl);
if (wolfSSL_is_server(ssl) == 0) {
ExpectNull(ciphers);
}
else {
WOLFSSL_CIPHER* current;
/* client should have only sent over one cipher suite */
ExpectNotNull(ciphers);
ExpectIntEQ(sk_SSL_CIPHER_num(ciphers), 1);
current = sk_SSL_CIPHER_value(ciphers, 0);
ExpectNotNull(current);
#if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
!defined(WOLFSSL_QT)
ExpectStrEQ("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
SSL_CIPHER_get_name(current));
#else
ExpectStrEQ("ECDHE-RSA-AES128-GCM-SHA256",
SSL_CIPHER_get_name(current));
#endif
}
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_get_client_ciphers(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_ECC) && !defined(NO_TLS) && defined(HAVE_AESGCM)
test_ssl_cbf server_cb;
test_ssl_cbf client_cb;
XMEMSET(&client_cb, 0, sizeof(test_ssl_cbf));
XMEMSET(&server_cb, 0, sizeof(test_ssl_cbf));
client_cb.method = wolfTLSv1_2_client_method;
server_cb.method = wolfTLSv1_2_server_method;
client_cb.devId = testDevId;
server_cb.devId = testDevId;
client_cb.ctx_ready = test_wolfSSL_get_client_ciphers_ctx_ready;
client_cb.on_result = test_wolfSSL_get_client_ciphers_on_result;
server_cb.on_result = test_wolfSSL_get_client_ciphers_on_result;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
&server_cb, NULL), TEST_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_client_CA_list(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
!defined(NO_BIO) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
X509_NAME* name = NULL;
STACK_OF(X509_NAME)* names = NULL;
STACK_OF(X509_NAME)* ca_list = NULL;
int names_len = 0;
int i;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
/* Send two X501 names in cert request */
names = SSL_load_client_CA_file(cliCertFile);
ExpectNotNull(names);
ca_list = SSL_load_client_CA_file(caCertFile);
ExpectNotNull(ca_list);
ExpectNotNull(name = sk_X509_NAME_value(ca_list, 0));
ExpectIntEQ(sk_X509_NAME_push(names, name), 2);
if (EXPECT_FAIL()) {
wolfSSL_X509_NAME_free(name);
name = NULL;
}
SSL_CTX_set_client_CA_list(ctx, names);
/* This should only free the stack structure */
sk_X509_NAME_free(ca_list);
ca_list = NULL;
ExpectNotNull(ca_list = SSL_CTX_get_client_CA_list(ctx));
ExpectIntEQ(sk_X509_NAME_num(ca_list), sk_X509_NAME_num(names));
ExpectIntEQ(sk_X509_NAME_find(NULL, name), BAD_FUNC_ARG);
ExpectIntEQ(sk_X509_NAME_find(names, NULL), WOLFSSL_FATAL_ERROR);
ExpectIntGT((names_len = sk_X509_NAME_num(names)), 0);
for (i = 0; i < names_len; i++) {
ExpectNotNull(name = sk_X509_NAME_value(names, i));
ExpectIntEQ(sk_X509_NAME_find(names, name), i);
}
/* Needed to be able to create ssl object */
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* load again as old names are responsibility of ctx to free*/
names = SSL_load_client_CA_file(cliCertFile);
ExpectNotNull(names);
SSL_set_client_CA_list(ssl, names);
ExpectNotNull(ca_list = SSL_get_client_CA_list(ssl));
ExpectIntEQ(sk_X509_NAME_num(ca_list), sk_X509_NAME_num(names));
ExpectIntGT((names_len = sk_X509_NAME_num(names)), 0);
for (i = 0; i < names_len; i++) {
ExpectNotNull(name = sk_X509_NAME_value(names, i));
ExpectIntEQ(sk_X509_NAME_find(names, name), i);
}
#if !defined(SINGLE_THREADED) && defined(SESSION_CERTS)
{
tcp_ready ready;
func_args server_args;
callback_functions server_cb;
THREAD_TYPE serverThread;
WOLFSSL* ssl_client = NULL;
WOLFSSL_CTX* ctx_client = NULL;
SOCKET_T sockfd = 0;
/* wolfSSL_get_client_CA_list() with handshake */
StartTCP();
InitTcpReady(&ready);
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cb, 0, sizeof(callback_functions));
server_args.signal = &ready;
server_args.callbacks = &server_cb;
/* we are responsible for free'ing WOLFSSL_CTX */
server_cb.ctx = ctx;
server_cb.isSharedCtx = 1;
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
cliCertFile, 0));
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);
ExpectNotNull(ctx_client =
wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(
ctx_client, caCertFile, 0));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(
ctx_client, cliCertFile, SSL_FILETYPE_PEM));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(
ctx_client, cliKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl_client = wolfSSL_new(ctx_client));
ExpectIntEQ(wolfSSL_set_fd(ssl_client, sockfd), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_connect(ssl_client), WOLFSSL_SUCCESS);
ExpectNotNull(ca_list = SSL_get_client_CA_list(ssl_client));
/* We are expecting two cert names to be sent */
ExpectIntEQ(sk_X509_NAME_num(ca_list), 2);
ExpectNotNull(names = SSL_CTX_get_client_CA_list(ctx));
for (i=0; i<sk_X509_NAME_num(ca_list); i++) {
ExpectNotNull(name = sk_X509_NAME_value(ca_list, i));
ExpectIntGE(sk_X509_NAME_find(names, name), 0);
}
wolfSSL_shutdown(ssl_client);
wolfSSL_free(ssl_client);
wolfSSL_CTX_free(ctx_client);
CloseSocket(sockfd);
join_thread(serverThread);
FreeTcpReady(&ready);
}
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && !NO_RSA && !NO_CERTS && !NO_WOLFSSL_CLIENT &&
* !NO_BIO */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_add_client_CA(void)
{
EXPECT_DECLS;
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA) && \
!defined(NO_RSA) && !defined(NO_CERTS) && \
!defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT) && !defined(NO_FILESYSTEM)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL_X509* x509 = NULL;
WOLFSSL_X509* x509_a = NULL;
STACK_OF(X509_NAME)* ca_list = NULL;
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
/* Add client cert */
ExpectNotNull(x509 = X509_load_certificate_file(cliCertFile,
SSL_FILETYPE_PEM));
ExpectIntEQ(SSL_CTX_add_client_CA(ctx, x509), SSL_SUCCESS);
ExpectNotNull(ca_list = SSL_CTX_get_client_CA_list(ctx));
/* Add another client cert */
ExpectNotNull(x509_a = X509_load_certificate_file(cliCertFile,
SSL_FILETYPE_PEM));
ExpectIntEQ(SSL_CTX_add_client_CA(ctx, x509_a), SSL_SUCCESS);
/* test for incorrect parameter */
ExpectIntEQ(SSL_CTX_add_client_CA(NULL, x509), 0);
ExpectIntEQ(SSL_CTX_add_client_CA(ctx, NULL), 0);
ExpectIntEQ(SSL_CTX_add_client_CA(NULL, NULL), 0);
X509_free(x509);
X509_free(x509_a);
SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && !NO_RSA && !NO_CERTS && !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
static THREAD_RETURN WOLFSSL_THREAD server_task_ech(void* args)
{
callback_functions* callbacks = ((func_args*)args)->callbacks;
WOLFSSL_CTX* ctx = callbacks->ctx;
WOLFSSL* ssl = NULL;
SOCKET_T sfd = 0;
SOCKET_T cfd = 0;
word16 port;
char input[1024];
int idx;
int ret, err = 0;
const char* privateName = "ech-private-name.com";
int privateNameLen = (int)XSTRLEN(privateName);
((func_args*)args)->return_code = TEST_FAIL;
port = ((func_args*)args)->signal->port;
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_load_verify_locations(ctx, cliCertFile, 0));
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
WOLFSSL_FILETYPE_PEM));
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
if (callbacks->ctx_ready)
callbacks->ctx_ready(ctx);
ssl = wolfSSL_new(ctx);
/* set the sni for the server */
wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, privateName, privateNameLen);
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, NULL, NULL);
CloseSocket(sfd);
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));
if (callbacks->ssl_ready)
callbacks->ssl_ready(ssl);
do {
err = 0; /* Reset error */
ret = wolfSSL_accept(ssl);
if (ret != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
}
} while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));
if (ret != WOLFSSL_SUCCESS) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buff));
}
else {
if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
input[idx] = 0;
fprintf(stderr, "Client message: %s\n", input);
}
AssertIntEQ(privateNameLen, wolfSSL_write(ssl, privateName,
privateNameLen));
((func_args*)args)->return_code = TEST_SUCCESS;
}
if (callbacks->on_result)
callbacks->on_result(ssl);
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(cfd);
#ifdef FP_ECC
wc_ecc_fp_free();
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* HAVE_ECH && WOLFSSL_TLS13 */
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
static void keyLog_callback(const WOLFSSL* ssl, const char* line)
{
XFILE fp;
const byte lf = '\n';
AssertNotNull(ssl);
AssertNotNull(line);
fp = XFOPEN("./MyKeyLog.txt", "a");
XFWRITE(line, 1, XSTRLEN(line), fp);
XFWRITE((void*)&lf, 1, 1, fp);
XFFLUSH(fp);
XFCLOSE(fp);
}
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
static int test_wolfSSL_CTX_set_keylog_callback(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK) && \
!defined(NO_WOLFSSL_CLIENT)
SSL_CTX* ctx = NULL;
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
SSL_CTX_set_keylog_callback(ctx, keyLog_callback );
SSL_CTX_free(ctx);
SSL_CTX_set_keylog_callback(NULL, NULL);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_get_keylog_callback(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK) && \
!defined(NO_WOLFSSL_CLIENT)
SSL_CTX* ctx = NULL;
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),NULL);
SSL_CTX_set_keylog_callback(ctx, keyLog_callback );
ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),keyLog_callback);
SSL_CTX_set_keylog_callback(ctx, NULL );
ExpectPtrEq(SSL_CTX_get_keylog_callback(ctx),NULL);
SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
static int test_wolfSSL_Tls12_Key_Logging_client_ctx_ready(WOLFSSL_CTX* ctx)
{
/* set keylog callback */
wolfSSL_CTX_set_keylog_callback(ctx, keyLog_callback);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_Tls12_Key_Logging_test(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
/* This test is intended for checking whether keylog callback is called
* in client during TLS handshake between the client and a server.
*/
test_ssl_cbf server_cbf;
test_ssl_cbf client_cbf;
XFILE fp = XBADFILE;
char buff[500];
int found = 0;
XMEMSET(&server_cbf, 0, sizeof(test_ssl_cbf));
XMEMSET(&client_cbf, 0, sizeof(test_ssl_cbf));
server_cbf.method = wolfTLSv1_2_server_method;
client_cbf.ctx_ready = &test_wolfSSL_Tls12_Key_Logging_client_ctx_ready;
/* clean up keylog file */
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "w")) != XBADFILE);
if (fp != XBADFILE) {
XFFLUSH(fp);
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
/* check if the keylog file exists */
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "rb")) != XBADFILE);
XFFLUSH(fp); /* Just to make sure any buffers get flushed */
XMEMSET(buff, 0, sizeof(buff));
while (EXPECT_SUCCESS() && XFGETS(buff, (int)sizeof(buff), fp) != NULL) {
if (0 == strncmp(buff,"CLIENT_RANDOM ", sizeof("CLIENT_RANDOM ")-1)) {
found = 1;
break;
}
}
if (fp != XBADFILE) {
XFCLOSE(fp);
}
/* a log starting with "CLIENT_RANDOM " should exit in the file */
ExpectIntEQ(found, 1);
/* clean up */
ExpectIntEQ(rem_file("./MyKeyLog.txt"), 0);
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
defined(HAVE_SECRET_CALLBACK)
static int test_wolfSSL_Tls13_Key_Logging_client_ctx_ready(WOLFSSL_CTX* ctx)
{
/* set keylog callback */
wolfSSL_CTX_set_keylog_callback(ctx, keyLog_callback);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_Tls13_Key_Logging_test(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
defined(HAVE_SECRET_CALLBACK)
/* This test is intended for checking whether keylog callback is called
* in client during TLS handshake between the client and a server.
*/
test_ssl_cbf server_cbf;
test_ssl_cbf client_cbf;
XFILE fp = XBADFILE;
XMEMSET(&server_cbf, 0, sizeof(test_ssl_cbf));
XMEMSET(&client_cbf, 0, sizeof(test_ssl_cbf));
server_cbf.method = wolfTLSv1_3_server_method; /* TLS1.3 */
client_cbf.ctx_ready = &test_wolfSSL_Tls13_Key_Logging_client_ctx_ready;
/* clean up keylog file */
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "w")) != XBADFILE);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
/* check if the keylog file exists */
{
char buff[300] = {0};
int found[4] = {0};
int numfnd = 0;
int i;
ExpectTrue((fp = XFOPEN("./MyKeyLog.txt", "rb")) != XBADFILE);
while (EXPECT_SUCCESS() &&
XFGETS(buff, (int)sizeof(buff), fp) != NULL) {
if (0 == strncmp(buff, "CLIENT_HANDSHAKE_TRAFFIC_SECRET ",
sizeof("CLIENT_HANDSHAKE_TRAFFIC_SECRET ")-1)) {
found[0] = 1;
continue;
}
else if (0 == strncmp(buff, "SERVER_HANDSHAKE_TRAFFIC_SECRET ",
sizeof("SERVER_HANDSHAKE_TRAFFIC_SECRET ")-1)) {
found[1] = 1;
continue;
}
else if (0 == strncmp(buff, "CLIENT_TRAFFIC_SECRET_0 ",
sizeof("CLIENT_TRAFFIC_SECRET_0 ")-1)) {
found[2] = 1;
continue;
}
else if (0 == strncmp(buff, "SERVER_TRAFFIC_SECRET_0 ",
sizeof("SERVER_TRAFFIC_SECRET_0 ")-1)) {
found[3] = 1;
continue;
}
}
if (fp != XBADFILE)
XFCLOSE(fp);
for (i = 0; i < 4; i++) {
if (found[i] != 0)
numfnd++;
}
ExpectIntEQ(numfnd, 4);
}
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK && WOLFSSL_TLS13 */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
static int test_wolfSSL_Tls13_ECH_params(void)
{
EXPECT_DECLS;
#if !defined(NO_WOLFSSL_CLIENT)
word32 outputLen = 0;
byte testBuf[72];
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
WOLFSSL *ssl = wolfSSL_new(ctx);
ExpectNotNull(ctx);
ExpectNotNull(ssl);
/* invalid ctx */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(NULL,
"ech-public-name.com", 0, 0, 0));
/* invalid public name */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(ctx, NULL, 0,
0, 0));
/* invalid algorithms */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(ctx,
"ech-public-name.com", 1000, 1000, 1000));
/* invalid ctx */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigsBase64(NULL,
(char*)testBuf, sizeof(testBuf)));
/* invalid base64 configs */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigsBase64(ctx,
NULL, sizeof(testBuf)));
/* invalid length */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigsBase64(ctx,
(char*)testBuf, 0));
/* invalid ctx */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigs(NULL,
testBuf, sizeof(testBuf)));
/* invalid configs */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigs(ctx,
NULL, sizeof(testBuf)));
/* invalid length */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_SetEchConfigs(ctx,
testBuf, 0));
/* invalid ctx */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GetEchConfigs(NULL, NULL,
&outputLen));
/* invalid output len */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_CTX_GetEchConfigs(ctx, NULL, NULL));
/* invalid ssl */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(NULL,
(char*)testBuf, sizeof(testBuf)));
/* invalid configs64 */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(ssl, NULL,
sizeof(testBuf)));
/* invalid size */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigsBase64(ssl,
(char*)testBuf, 0));
/* invalid ssl */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(NULL, testBuf,
sizeof(testBuf)));
/* invalid configs */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, NULL,
sizeof(testBuf)));
/* invalid size */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, testBuf, 0));
/* invalid ssl */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_GetEchConfigs(NULL, NULL, &outputLen));
/* invalid size */
ExpectIntNE(WOLFSSL_SUCCESS, wolfSSL_GetEchConfigs(ssl, NULL, NULL));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
static int test_wolfSSL_Tls13_ECH_ex(int hrr)
{
EXPECT_DECLS;
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
callback_functions server_cbf;
callback_functions client_cbf;
SOCKET_T sockfd = 0;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
const char* publicName = "ech-public-name.com";
const char* privateName = "ech-private-name.com";
int privateNameLen = 20;
char reply[1024];
int replyLen = 0;
byte rawEchConfig[128];
word32 rawEchConfigLen = sizeof(rawEchConfig);
InitTcpReady(&ready);
ready.port = 22222;
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
server_cbf.method = wolfTLSv1_3_server_method; /* TLS1.3 */
/* create the server context here so we can get the ech config */
ExpectNotNull(server_cbf.ctx =
wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
/* generate ech config */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_GenerateEchConfig(server_cbf.ctx,
publicName, 0, 0, 0));
/* get the config for the client to use */
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_GetEchConfigs(server_cbf.ctx, rawEchConfig,
&rawEchConfigLen));
server_args.callbacks = &server_cbf;
server_args.signal = &ready;
/* start server task */
start_thread(server_task_ech, &server_args, &serverThread);
wait_tcp_ready(&server_args);
/* run as a TLS1.3 client */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM));
tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL);
/* get connected the server task */
ExpectNotNull(ssl = wolfSSL_new(ctx));
/* set the ech configs for the client */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetEchConfigs(ssl, rawEchConfig,
rawEchConfigLen));
/* set the sni for the client */
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
privateName, privateNameLen));
/* force hello retry request */
if (hrr)
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_NoKeyShares(ssl));
/* connect like normal */
ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
ExpectIntEQ(ssl->options.echAccepted, 1);
ExpectIntEQ(wolfSSL_write(ssl, privateName, privateNameLen),
privateNameLen);
ExpectIntGT((replyLen = wolfSSL_read(ssl, reply, sizeof(reply))), 0);
/* add th null terminator for string compare */
reply[replyLen] = 0;
/* check that the server replied with the private name */
ExpectStrEQ(privateName, reply);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(sockfd);
join_thread(serverThread);
FreeTcpReady(&ready);
return EXPECT_RESULT();
}
static int test_wolfSSL_Tls13_ECH(void)
{
return test_wolfSSL_Tls13_ECH_ex(0);
}
static int test_wolfSSL_Tls13_ECH_HRR(void)
{
return test_wolfSSL_Tls13_ECH_ex(1);
}
#endif /* HAVE_ECH && WOLFSSL_TLS13 */
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
static int post_auth_version_cb(WOLFSSL* ssl)
{
EXPECT_DECLS;
/* do handshake and then test version error */
ExpectIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
ExpectStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
return EXPECT_RESULT();
}
static int post_auth_version_client_cb(WOLFSSL* ssl)
{
EXPECT_DECLS;
/* do handshake and then test version error */
ExpectIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
ExpectStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
ExpectIntEQ(wolfSSL_verify_client_post_handshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if defined(OPENSSL_ALL) && !defined(NO_ERROR_QUEUE)
/* check was added to error queue */
ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION));
/* check the string matches expected string */
#ifndef NO_ERROR_STRINGS
ExpectStrEQ(wolfSSL_ERR_error_string(-WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION), NULL),
"WRONG_SSL_VERSION");
#endif
#endif
return EXPECT_RESULT();
}
static int post_auth_cb(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_X509* x509 = NULL;
/* do handshake and then test version error */
ExpectIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
ExpectStrEQ("TLSv1.3", wolfSSL_get_version(ssl));
ExpectNull(x509 = wolfSSL_get_peer_certificate(ssl));
wolfSSL_X509_free(x509);
ExpectIntEQ(wolfSSL_verify_client_post_handshake(ssl), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int set_post_auth_cb(WOLFSSL* ssl)
{
if (!wolfSSL_is_server(ssl)) {
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_allow_post_handshake_auth(ssl), 0);
return EXPECT_RESULT();
}
wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_POST_HANDSHAKE, NULL);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_Tls13_postauth(void)
{
EXPECT_DECLS;
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
test_ssl_cbf server_cbf;
test_ssl_cbf client_cbf;
/* test version failure doing post auth with TLS 1.2 connection */
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
server_cbf.method = wolfTLSv1_2_server_method;
server_cbf.ssl_ready = set_post_auth_cb;
server_cbf.on_result = post_auth_version_cb;
client_cbf.ssl_ready = set_post_auth_cb;
client_cbf.on_result = post_auth_version_client_cb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
/* tests on post auth with TLS 1.3 */
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
server_cbf.method = wolfTLSv1_3_server_method;
server_cbf.ssl_ready = set_post_auth_cb;
client_cbf.ssl_ready = set_post_auth_cb;
server_cbf.on_result = post_auth_cb;
client_cbf.on_result = NULL;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_srp_username(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \
!defined(NO_SHA256) && !defined(WC_NO_RNG) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
const char *username = "TESTUSER";
const char *password = "TESTPASSWORD";
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
SSL_SUCCESS);
wolfSSL_CTX_free(ctx);
ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
SSL_SUCCESS);
ExpectNotNull(ssl = SSL_new(ctx));
ExpectNotNull(SSL_get_srp_username(ssl));
ExpectStrEQ(SSL_get_srp_username(ssl), username);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFCRYPT_HAVE_SRP */
/* && !NO_SHA256 && !WC_NO_RNG && !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_srp_password(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \
!defined(NO_SHA256) && !defined(WC_NO_RNG) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL_CTX* ctx = NULL;
const char *username = "TESTUSER";
const char *password = "TESTPASSWORD";
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
SSL_SUCCESS);
wolfSSL_CTX_free(ctx);
ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(wolfSSL_CTX_set_srp_username(ctx, (char *)username),
SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_srp_password(ctx, (char *)password),
SSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && WOLFCRYPT_HAVE_SRP */
/* && !NO_SHA256 && !WC_NO_RNG && !NO_WOLFSSL_CLIENT */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
#define TEST_ARG 0x1234
static void msg_cb(int write_p, int version, int content_type,
const void *buf, size_t len, SSL *ssl, void *arg)
{
(void)write_p;
(void)version;
(void)content_type;
(void)buf;
(void)len;
(void)ssl;
AssertTrue(arg == (void*)TEST_ARG);
}
#endif
#if defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
#if defined(SESSION_CERTS)
#include "wolfssl/internal.h"
#endif
static int msgSrvCb(SSL_CTX *ctx, SSL *ssl)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
STACK_OF(X509)* sk = NULL;
X509* x509 = NULL;
int i, num;
BIO* bio = NULL;
#endif
ExpectNotNull(ctx);
ExpectNotNull(ssl);
fprintf(stderr, "\n===== msgSrvCb called ====\n");
#if defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)
ExpectTrue(SSL_get_peer_cert_chain(ssl) != NULL);
ExpectIntEQ(((WOLFSSL_X509_CHAIN *)SSL_get_peer_cert_chain(ssl))->count, 2);
ExpectNotNull(SSL_get0_verified_chain(ssl));
#endif
#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
#ifdef KEEP_PEER_CERT
{
WOLFSSL_X509* peer = NULL;
ExpectNotNull(peer= wolfSSL_get_peer_certificate(ssl));
ExpectNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE));
fprintf(stderr, "Peer Certificate = :\n");
X509_print(bio, peer);
X509_free(peer);
}
#endif
ExpectNotNull(sk = SSL_get_peer_cert_chain(ssl));
if (sk == NULL) {
BIO_free(bio);
return TEST_FAIL;
}
num = sk_X509_num(sk);
ExpectTrue(num > 0);
for (i = 0; i < num; i++) {
ExpectNotNull(x509 = sk_X509_value(sk,i));
if (x509 == NULL)
break;
fprintf(stderr, "Certificate at index [%d] = :\n",i);
X509_print(bio,x509);
fprintf(stderr, "\n\n");
}
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
static int msgCb(SSL_CTX *ctx, SSL *ssl)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
STACK_OF(X509)* sk = NULL;
X509* x509 = NULL;
int i, num;
BIO* bio = NULL;
#endif
ExpectNotNull(ctx);
ExpectNotNull(ssl);
fprintf(stderr, "\n===== msgcb called ====\n");
#if defined(SESSION_CERTS) && defined(TEST_PEER_CERT_CHAIN)
ExpectTrue(SSL_get_peer_cert_chain(ssl) != NULL);
ExpectIntEQ(((WOLFSSL_X509_CHAIN *)SSL_get_peer_cert_chain(ssl))->count, 2);
ExpectNotNull(SSL_get0_verified_chain(ssl));
#endif
#if defined(OPENSSL_ALL) && defined(SESSION_CERTS) && !defined(NO_BIO)
ExpectNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE));
ExpectNotNull(sk = SSL_get_peer_cert_chain(ssl));
if (sk == NULL) {
BIO_free(bio);
return TEST_FAIL;
}
num = sk_X509_num(sk);
ExpectTrue(num > 0);
for (i = 0; i < num; i++) {
ExpectNotNull(x509 = sk_X509_value(sk,i));
if (x509 == NULL)
break;
fprintf(stderr, "Certificate at index [%d] = :\n",i);
X509_print(bio,x509);
fprintf(stderr, "\n\n");
}
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_msgCb(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cb;
test_ssl_cbf server_cb;
XMEMSET(&client_cb, 0, sizeof(client_cb));
XMEMSET(&server_cb, 0, sizeof(server_cb));
#ifndef WOLFSSL_NO_TLS12
client_cb.method = wolfTLSv1_2_client_method;
server_cb.method = wolfTLSv1_2_server_method;
#else
client_cb.method = wolfTLSv1_3_client_method;
server_cb.method = wolfTLSv1_3_server_method;
#endif
server_cb.caPemFile = caCertFile;
client_cb.certPemFile = "./certs/intermediate/client-chain.pem";
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio_ex(&client_cb,
&server_cb, msgCb, msgSrvCb), TEST_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_either_side(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf client_cb;
test_ssl_cbf server_cb;
XMEMSET(&client_cb, 0, sizeof(client_cb));
XMEMSET(&server_cb, 0, sizeof(server_cb));
/* Use different CTX for client and server */
client_cb.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
ExpectNotNull(client_cb.ctx);
server_cb.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
ExpectNotNull(server_cb.ctx);
/* we are responsible for free'ing WOLFSSL_CTX */
server_cb.isSharedCtx = client_cb.isSharedCtx = 1;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
&server_cb, NULL), TEST_SUCCESS);
wolfSSL_CTX_free(client_cb.ctx);
wolfSSL_CTX_free(server_cb.ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_DTLS_either_side(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS)
test_ssl_cbf client_cb;
test_ssl_cbf server_cb;
XMEMSET(&client_cb, 0, sizeof(client_cb));
XMEMSET(&server_cb, 0, sizeof(server_cb));
/* Use different CTX for client and server */
client_cb.ctx = wolfSSL_CTX_new(wolfDTLS_method());
ExpectNotNull(client_cb.ctx);
server_cb.ctx = wolfSSL_CTX_new(wolfDTLS_method());
ExpectNotNull(server_cb.ctx);
/* we are responsible for free'ing WOLFSSL_CTX */
server_cb.isSharedCtx = client_cb.isSharedCtx = 1;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cb,
&server_cb, NULL), TEST_SUCCESS);
wolfSSL_CTX_free(client_cb.ctx);
wolfSSL_CTX_free(server_cb.ctx);
#endif
return EXPECT_RESULT();
}
static int test_generate_cookie(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(OPENSSL_EXTRA) && defined(USE_WOLFSSL_IO)
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
byte buf[FOURK_BUF] = {0};
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLS_method()));
ExpectNotNull(ssl = SSL_new(ctx));
/* Test unconnected */
ExpectIntEQ(EmbedGenerateCookie(ssl, buf, FOURK_BUF, NULL), WC_NO_ERR_TRACE(GEN_COOKIE_E));
wolfSSL_CTX_SetGenCookie(ctx, EmbedGenerateCookie);
wolfSSL_SetCookieCtx(ssl, ctx);
ExpectNotNull(wolfSSL_GetCookieCtx(ssl));
ExpectNull(wolfSSL_GetCookieCtx(NULL));
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_set_options(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_TLS) && !defined(NO_FILESYSTEM) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_RSA)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
char appData[] = "extra msg";
#endif
#ifdef OPENSSL_EXTRA
unsigned char protos[] = {
7, 't', 'l', 's', '/', '1', '.', '2',
8, 'h', 't', 't', 'p', '/', '1', '.', '1'
};
unsigned int len = sizeof(protos);
void *arg = (void *)TEST_ARG;
#endif
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1)
== WOLFSSL_OP_NO_TLSv1);
ExpectTrue(wolfSSL_CTX_get_options(ctx) == WOLFSSL_OP_NO_TLSv1);
ExpectIntGT((int)wolfSSL_CTX_set_options(ctx, (WOLFSSL_OP_COOKIE_EXCHANGE |
WOLFSSL_OP_NO_SSLv2)), 0);
ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_COOKIE_EXCHANGE) &
WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE);
ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2) &
WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2);
ExpectTrue((wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_COMPRESSION) &
WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION);
ExpectFalse((wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_COMPRESSION) &
WOLFSSL_OP_NO_COMPRESSION));
wolfSSL_CTX_free(ctx);
ctx = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
CERT_FILETYPE));
#ifdef OPENSSL_EXTRA
ExpectTrue(wolfSSL_CTX_set_msg_callback(ctx, msg_cb) == WOLFSSL_SUCCESS);
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx));
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#ifdef HAVE_EX_DATA
ExpectIntEQ(wolfSSL_set_app_data(ssl, (void*)appData), WOLFSSL_SUCCESS);
ExpectNotNull(wolfSSL_get_app_data((const WOLFSSL*)ssl));
if (ssl != NULL) {
ExpectIntEQ(XMEMCMP(wolfSSL_get_app_data((const WOLFSSL*)ssl),
appData, sizeof(appData)), 0);
}
#else
ExpectIntEQ(wolfSSL_set_app_data(ssl, (void*)appData), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectNull(wolfSSL_get_app_data((const WOLFSSL*)ssl));
#endif
#endif
ExpectTrue(wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1) ==
WOLFSSL_OP_NO_TLSv1);
ExpectTrue(wolfSSL_get_options(ssl) == WOLFSSL_OP_NO_TLSv1);
ExpectIntGT((int)wolfSSL_set_options(ssl, (WOLFSSL_OP_COOKIE_EXCHANGE |
WOLFSSL_OP_NO_SSLv2)), 0);
ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_COOKIE_EXCHANGE) &
WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE);
ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1_2) &
WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2);
ExpectTrue((wolfSSL_set_options(ssl, WOLFSSL_OP_NO_COMPRESSION) &
WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION);
#ifdef OPENSSL_EXTRA
ExpectFalse((wolfSSL_clear_options(ssl, WOLFSSL_OP_NO_COMPRESSION) &
WOLFSSL_OP_NO_COMPRESSION));
#endif
#ifdef OPENSSL_EXTRA
ExpectTrue(wolfSSL_set_msg_callback(ssl, msg_cb) == WOLFSSL_SUCCESS);
wolfSSL_set_msg_callback_arg(ssl, arg);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
ExpectTrue(wolfSSL_CTX_set_alpn_protos(ctx, protos, len) == 0);
#else
ExpectTrue(wolfSSL_CTX_set_alpn_protos(ctx, protos, len) == WOLFSSL_SUCCESS);
#endif
#endif
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_ALL) || \
defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL)
#if defined(HAVE_ALPN) && !defined(NO_BIO)
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
ExpectTrue(wolfSSL_set_alpn_protos(ssl, protos, len) == 0);
#else
ExpectTrue(wolfSSL_set_alpn_protos(ssl, protos, len) == WOLFSSL_SUCCESS);
#endif
#endif /* HAVE_ALPN && !NO_BIO */
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_sk_SSL_CIPHER(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA)
#if !defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)
SSL* ssl = NULL;
SSL_CTX* ctx = NULL;
STACK_OF(SSL_CIPHER) *sk = NULL;
STACK_OF(SSL_CIPHER) *dupSk = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectNotNull(sk = SSL_get_ciphers(ssl));
ExpectNotNull(dupSk = sk_SSL_CIPHER_dup(sk));
ExpectIntGT(sk_SSL_CIPHER_num(sk), 0);
ExpectIntEQ(sk_SSL_CIPHER_num(sk), sk_SSL_CIPHER_num(dupSk));
/* error case because connection has not been established yet */
ExpectIntEQ(sk_SSL_CIPHER_find(sk, SSL_get_current_cipher(ssl)), -1);
sk_SSL_CIPHER_free(dupSk);
/* sk is pointer to internal struct that should be free'd in SSL_free */
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif /* !NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER */
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) */
return EXPECT_RESULT();
}
static int test_wolfSSL_set1_curves_list(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_FILESYSTEM)
SSL* ssl = NULL;
SSL_CTX* ctx = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, eccCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, eccKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef HAVE_ECC
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "P-25X"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "P-256"), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_CURVE25519
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X25519"), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X25519"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_CURVE448
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X448"), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(SSL_CTX_set1_curves_list(ctx, "X448"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
ExpectIntEQ(SSL_set1_curves_list(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef HAVE_ECC
ExpectIntEQ(SSL_set1_curves_list(ssl, "P-25X"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_set1_curves_list(ssl, "P-256"), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_CURVE25519
ExpectIntEQ(SSL_set1_curves_list(ssl, "X25519"), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(SSL_set1_curves_list(ssl, "X25519"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_CURVE448
ExpectIntEQ(SSL_set1_curves_list(ssl, "X448"), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(SSL_set1_curves_list(ssl, "X448"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
(defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && defined(HAVE_ECC)
static int test_wolfSSL_curves_mismatch_ctx_ready(WOLFSSL_CTX* ctx)
{
static int counter = 0;
EXPECT_DECLS;
if (counter % 2) {
ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-256"),
WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(wolfSSL_CTX_set1_curves_list(ctx, "P-384"),
WOLFSSL_SUCCESS);
}
/* Ciphersuites that require curves */
wolfSSL_CTX_set_cipher_list(ctx, "TLS13-AES256-GCM-SHA384:"
"TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-GCM-SHA256:"
"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
"ECDHE-ECDSA-AES128-GCM-SHA256:"
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:"
"ECDHE-ECDSA-CHACHA20-POLY1305");
counter++;
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_curves_mismatch(void)
{
EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
(defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && defined(HAVE_ECC)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* desc;
int client_last_err;
int server_last_err;
} test_params[] = {
#ifdef WOLFSSL_TLS13
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3",
/* Client gets error because server will attempt HRR */
WC_NO_ERR_TRACE(BAD_KEY_SHARE_DATA),
WC_NO_ERR_TRACE(FATAL_ERROR)
},
#endif
#ifndef WOLFSSL_NO_TLS12
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2",
WC_NO_ERR_TRACE(FATAL_ERROR),
/* Server gets error because <=1.2 doesn't have a mechanism
* to negotiate curves. */
#ifdef OPENSSL_EXTRA
WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL)
#else
WC_NO_ERR_TRACE(MATCH_SUITE_ERROR)
#endif
},
#endif
#ifndef NO_OLD_TLS
{wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLS 1.1",
WC_NO_ERR_TRACE(FATAL_ERROR),
#ifdef OPENSSL_EXTRA
WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL)
#else
WC_NO_ERR_TRACE(MATCH_SUITE_ERROR)
#endif
},
#endif
};
for (i = 0; i < XELEM_CNT(test_params) && !EXPECT_FAIL(); i++) {
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
printf("\tTesting with %s...\n", test_params[i].desc);
func_cb_client.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;
func_cb_server.ctx_ready = &test_wolfSSL_curves_mismatch_ctx_ready;
func_cb_client.method = test_params[i].client_meth;
func_cb_server.method = test_params[i].server_meth;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);
ExpectIntEQ(func_cb_client.last_err, test_params[i].client_last_err);
ExpectIntEQ(func_cb_server.last_err, test_params[i].server_last_err);
if (!EXPECT_SUCCESS())
break;
printf("\t%s passed\n", test_params[i].desc);
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_set1_sigalgs_list(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_FILESYSTEM)
SSL* ssl = NULL;
SSL_CTX* ctx = NULL;
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, ""), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, ""), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_RSA
#ifndef NO_SHA256
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, "RSA+SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(NULL, "RSA+SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifdef WC_RSA_PSS
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-PSS+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-PSS+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "PSS+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "PSS+SHA256"),
WOLFSSL_SUCCESS);
#endif
#ifdef WOLFSSL_SHA512
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
"RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
"RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS);
#elif defined(WOLFSSL_SHA384)
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
"RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
"RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS);
#endif
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA:RSA+SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA:RSA+SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256+SHA256"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256+RSA"),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#endif
#ifdef HAVE_ECC
#ifndef NO_SHA256
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ECDSA+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ECDSA+SHA256"),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_SHA512
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
"ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
"ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS);
#elif defined(WOLFSSL_SHA384)
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
"ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
"ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS);
#endif
#endif
#endif
#ifdef HAVE_ED25519
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED25519"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED25519"), WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_ED448
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED448"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED448"), WOLFSSL_SUCCESS);
#endif
#ifndef NO_DSA
#ifndef NO_SHA256
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA256"),
WOLFSSL_SUCCESS);
#endif
#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \
defined(WOLFSSL_ALLOW_TLS_SHA1))
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA1"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA1"),
WOLFSSL_SUCCESS);
#endif
#endif
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
/* Testing wolfSSL_set_tlsext_status_type function.
* PRE: OPENSSL and HAVE_CERTIFICATE_STATUS_REQUEST defined.
*/
static int test_wolfSSL_set_tlsext_status_type(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
!defined(NO_RSA) && !defined(NO_WOLFSSL_SERVER)
SSL* ssl = NULL;
SSL_CTX* ctx = NULL;
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
ExpectTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_set_tlsext_status_type(ssl,TLSEXT_STATUSTYPE_ocsp),
SSL_SUCCESS);
ExpectIntEQ(SSL_get_tlsext_status_type(ssl), TLSEXT_STATUSTYPE_ocsp);
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif /* OPENSSL_EXTRA && HAVE_CERTIFICATE_STATUS_REQUEST && !NO_RSA */
return EXPECT_RESULT();
}
static int test_wolfSSL_a2i_IPADDRESS(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(WOLFSSL_USER_IO)
const unsigned char* data = NULL;
int dataSz = 0;
ASN1_OCTET_STRING *st = NULL;
const unsigned char ipv4_exp[] = {0x7F, 0, 0, 1};
const unsigned char ipv6_exp[] = {
0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77
};
const unsigned char ipv6_home[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
};
ExpectNull(st = a2i_IPADDRESS("127.0.0.1bad"));
ExpectNotNull(st = a2i_IPADDRESS("127.0.0.1"));
ExpectNotNull(data = ASN1_STRING_get0_data(st));
ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP4_ADDR_LEN);
ExpectIntEQ(XMEMCMP(data, ipv4_exp, dataSz), 0);
ASN1_STRING_free(st);
st = NULL;
ExpectNotNull(st = a2i_IPADDRESS("::1"));
ExpectNotNull(data = ASN1_STRING_get0_data(st));
ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP6_ADDR_LEN);
ExpectIntEQ(XMEMCMP(data, ipv6_home, dataSz), 0);
ASN1_STRING_free(st);
st = NULL;
ExpectNotNull(st = a2i_IPADDRESS("2021:db8::ff00:42:7777"));
ExpectNotNull(data = ASN1_STRING_get0_data(st));
ExpectIntEQ(dataSz = ASN1_STRING_length(st), WOLFSSL_IP6_ADDR_LEN);
ExpectIntEQ(XMEMCMP(data, ipv6_exp, dataSz), 0);
ASN1_STRING_free(st);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_ALGOR_get0(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
!defined(NO_SHA256) && !defined(NO_RSA)
X509* x509 = NULL;
const ASN1_OBJECT* obj = NULL;
const X509_ALGOR* alg = NULL;
X509_ALGOR* alg2 = NULL;
int pptype = 0;
const void *ppval = NULL;
byte* der = NULL;
const byte* tmp = NULL;
const byte badObj[] = { 0x06, 0x00 };
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile,
SSL_FILETYPE_PEM));
ExpectNotNull(alg = X509_get0_tbs_sigalg(x509));
/* Invalid case */
X509_ALGOR_get0(&obj, NULL, NULL, NULL);
ExpectNull(obj);
/* Valid case */
X509_ALGOR_get0(NULL, NULL, NULL, alg);
X509_ALGOR_get0(&obj, &pptype, &ppval, alg);
ExpectNotNull(obj);
ExpectNull(ppval);
ExpectIntNE(pptype, 0);
/* Make sure NID of X509_ALGOR is Sha256 with RSA */
ExpectIntEQ(OBJ_obj2nid(obj), NID_sha256WithRSAEncryption);
ExpectIntEQ(i2d_X509_ALGOR(NULL, NULL), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(i2d_X509_ALGOR(alg, &der), 15);
ExpectNull(d2i_X509_ALGOR(NULL, NULL, 0));
/* tmp is NULL. */
ExpectNull(d2i_X509_ALGOR(NULL, &tmp, 0));
tmp = badObj;
ExpectNull(d2i_X509_ALGOR(NULL, &tmp, (long)sizeof(badObj)));
tmp = der;
ExpectNull(d2i_X509_ALGOR(NULL, &tmp, 0));
ExpectNotNull(d2i_X509_ALGOR(&alg2, &tmp, 15));
tmp = der;
ExpectNotNull(d2i_X509_ALGOR(&alg2, &tmp, 15));
XFREE(der, NULL, DYNAMIC_TYPE_ASN1);
X509_free(x509);
X509_ALGOR_free(NULL);
X509_ALGOR_free(alg2);
alg2 = NULL;
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_HOSTNAME_VERIFY_ALT_NAME_ONLY)
static int test_wolfSSL_check_domain_verify_count = 0;
static WC_INLINE int test_wolfSSL_check_domain_verify_cb(int preverify,
WOLFSSL_X509_STORE_CTX* store)
{
EXPECT_DECLS;
ExpectIntEQ(X509_STORE_CTX_get_error(store), 0);
ExpectIntEQ(preverify, 1);
ExpectIntGT(++test_wolfSSL_check_domain_verify_count, 0);
return EXPECT_SUCCESS();
}
static int test_wolfSSL_check_domain_client_cb(WOLFSSL* ssl)
{
EXPECT_DECLS;
X509_VERIFY_PARAM *param = NULL;
ExpectNotNull(param = SSL_get0_param(ssl));
/* Domain check should only be done on the leaf cert */
X509_VERIFY_PARAM_set_hostflags(param,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
ExpectIntEQ(X509_VERIFY_PARAM_set1_host(param,
"wolfSSL Server Chain", 0), 1);
wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_PEER,
test_wolfSSL_check_domain_verify_cb);
return EXPECT_RESULT();
}
static int test_wolfSSL_check_domain_server_cb(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
/* Use a cert with different domains in chain */
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
"certs/intermediate/server-chain.pem"), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_wolfSSL_check_domain(void)
{
EXPECT_DECLS;
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.ssl_ready = &test_wolfSSL_check_domain_client_cb;
func_cb_server.ctx_ready = &test_wolfSSL_check_domain_server_cb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
/* Should have been called once for each cert in sent chain */
#ifdef WOLFSSL_VERIFY_CB_ALL_CERTS
ExpectIntEQ(test_wolfSSL_check_domain_verify_count, 3);
#else
ExpectIntEQ(test_wolfSSL_check_domain_verify_count, 1);
#endif
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_check_domain(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif /* OPENSSL_EXTRA && HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(OPENSSL_COMPATIBLE_DEFAULTS) && !defined(NO_SHA256)
static const char* dn = NULL;
static int test_wolfSSL_check_domain_basic_client_ssl(WOLFSSL* ssl)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_check_domain_name(ssl, dn), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_wolfSSL_check_domain_basic(void)
{
EXPECT_DECLS;
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
dn = "invalid.com";
func_cb_client.ssl_ready = &test_wolfSSL_check_domain_basic_client_ssl;
/* Expect to fail */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);
dn = "example.com";
/* Expect to succeed */
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_check_domain_basic(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif /* HAVE_SSL_MEMIO_TESTS_DEPENDENCIES */
static int test_wolfSSL_BUF(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
BUF_MEM* buf = NULL;
ExpectNotNull(buf = BUF_MEM_new());
ExpectIntEQ(BUF_MEM_grow(buf, 10), 10);
ExpectIntEQ(BUF_MEM_grow(buf, -1), 0);
BUF_MEM_free(buf);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_PKCS8_Compat(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC) && \
!defined(NO_BIO)
PKCS8_PRIV_KEY_INFO* pt = NULL;
PKCS8_PRIV_KEY_INFO* pt2 = NULL;
BIO* bio = NULL;
XFILE f = XBADFILE;
int bytes = 0;
char pkcs8_buffer[512];
#if defined(OPENSSL_ALL) || defined(WOLFSSL_WPAS_SMALL)
EVP_PKEY *pkey = NULL;
#endif
/* file from wolfssl/certs/ directory */
ExpectTrue((f = XFOPEN("./certs/ecc-keyPkcs8.pem", "rb")) != XBADFILE);
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer), f)),
0);
if (f != XBADFILE)
XFCLOSE(f);
ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
ExpectNotNull(pt = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL));
#if defined(OPENSSL_ALL) || defined(WOLFSSL_WPAS_SMALL)
ExpectNotNull(pkey = EVP_PKCS82PKEY(pt));
ExpectIntEQ(EVP_PKEY_type(pkey->type), EVP_PKEY_EC);
/* gets PKCS8 pointer to pkey */
ExpectNotNull(pt2 = EVP_PKEY2PKCS8(pkey));
EVP_PKEY_free(pkey);
#endif
BIO_free(bio);
PKCS8_PRIV_KEY_INFO_free(pt);
PKCS8_PRIV_KEY_INFO_free(pt2);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_BIO)
static int NoPasswordCallBack(char* passwd, int sz, int rw, void* userdata)
{
(void)passwd;
(void)sz;
(void)rw;
(void)userdata;
return -1;
}
#endif
static int test_wolfSSL_PKCS8_d2i(void)
{
EXPECT_DECLS;
#if !defined(HAVE_FIPS) && defined(OPENSSL_EXTRA)
/* This test ends up using HMAC as a part of PBKDF2, and HMAC
* requires a 12 byte password in FIPS mode. This test ends up
* trying to use an 8 byte password. */
#ifndef NO_FILESYSTEM
unsigned char pkcs8_buffer[2048];
const unsigned char* p = NULL;
int bytes = 0;
XFILE file = XBADFILE;
WOLFSSL_EVP_PKEY* pkey = NULL;
#ifndef NO_BIO
BIO* bio = NULL;
#if defined(OPENSSL_ALL) && \
((!defined(NO_RSA) && !defined(NO_DES3)) || \
defined(HAVE_ECC)) && \
!defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
WOLFSSL_EVP_PKEY* evpPkey = NULL;
#endif
#endif
#ifndef NO_RSA
const char rsaDerPkcs8File[] = "./certs/server-keyPkcs8.der";
const char rsaPemPkcs8File[] = "./certs/server-keyPkcs8.pem";
#ifndef NO_DES3
const char rsaDerPkcs8EncFile[] = "./certs/server-keyPkcs8Enc.der";
#endif
#endif /* NO_RSA */
#ifdef HAVE_ECC
const char ecDerPkcs8File[] = "certs/ecc-keyPkcs8.der";
const char ecPemPkcs8File[] = "certs/ecc-keyPkcs8.pem";
#ifndef NO_DES3
const char ecDerPkcs8EncFile[] = "certs/ecc-keyPkcs8Enc.der";
#endif
#endif /* HAVE_ECC */
#endif /* !NO_FILESYSTEM */
#if defined(OPENSSL_ALL) && (!defined(NO_RSA) || defined(HAVE_ECC))
#ifndef NO_RSA
#ifdef USE_CERT_BUFFERS_1024
const unsigned char* rsa = (unsigned char*)server_key_der_1024;
int rsaSz = sizeof_server_key_der_1024;
#else
const unsigned char* rsa = (unsigned char*)server_key_der_2048;
int rsaSz = sizeof_server_key_der_2048;
#endif
#endif
#ifdef HAVE_ECC
const unsigned char* ec = (unsigned char*)ecc_key_der_256;
int ecSz = sizeof_ecc_key_der_256;
#endif
#endif /* OPENSSL_ALL && (!NO_RSA || HAVE_ECC) */
#ifndef NO_FILESYSTEM
(void)pkcs8_buffer;
(void)p;
(void)bytes;
(void)file;
#ifndef NO_BIO
(void)bio;
#endif
#endif
#ifdef OPENSSL_ALL
#ifndef NO_RSA
/* Try to auto-detect normal RSA private key */
ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &rsa, rsaSz));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#ifdef HAVE_ECC
/* Try to auto-detect normal EC private key */
ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &ec, ecSz));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#endif /* OPENSSL_ALL */
#ifndef NO_FILESYSTEM
#if defined(OPENSSL_ALL) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
ExpectIntEQ(PEM_write_PKCS8PrivateKey(XBADFILE, pkey, NULL, NULL, 0, NULL,
NULL), 0);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, NULL, NULL, NULL, 0, NULL,
NULL), 0);
#endif
#ifndef NO_RSA
/* Get DER encoded RSA PKCS#8 data. */
ExpectTrue((file = XFOPEN(rsaDerPkcs8File, "rb")) != XBADFILE);
ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
p = pkcs8_buffer;
#ifdef OPENSSL_ALL
/* Try to decode - auto-detect key type. */
ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
#else
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, bytes));
#endif
/* Get PEM encoded RSA PKCS#8 data. */
ExpectTrue((file = XFOPEN(rsaPemPkcs8File, "rb")) != XBADFILE);
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
#if defined(OPENSSL_ALL) && \
!defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(NULL, pkey, NULL, NULL, 0, NULL,
NULL), 0);
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, NULL, NULL, NULL, 0, NULL,
NULL), 0);
/* Write PKCS#8 PEM to BIO. */
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
NULL), bytes);
/* Write PKCS#8 PEM to stderr. */
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, NULL, NULL, 0, NULL,
NULL), bytes);
/* Compare file and written data */
ExpectIntEQ(BIO_get_mem_data(bio, &p), bytes);
ExpectIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
BIO_free(bio);
bio = NULL;
#if !defined(NO_AES) && defined(HAVE_AESGCM)
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_gcm(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), 0);
#endif
#if !defined(NO_DES3) && !defined(NO_SHA)
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
/* Write Encrypted PKCS#8 PEM to BIO. */
bytes = 1834;
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_des_ede3_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_des_ede3_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
(void*)"yassl123"));
EVP_PKEY_free(evpPkey);
evpPkey = NULL;
BIO_free(bio);
bio = NULL;
#endif /* !NO_DES3 && !NO_SHA */
#endif /* !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
EVP_PKEY_free(pkey);
pkey = NULL;
/* PKCS#8 encrypted RSA key */
#ifndef NO_DES3
ExpectTrue((file = XFOPEN(rsaDerPkcs8EncFile, "rb")) != XBADFILE);
ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
#if defined(OPENSSL_ALL) && \
!defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
ExpectNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
(void*)"yassl123"));
EVP_PKEY_free(pkey);
pkey = NULL;
BIO_free(bio);
bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
#endif /* !NO_DES3 */
#endif /* NO_RSA */
#ifdef HAVE_ECC
/* PKCS#8 encode EC key */
ExpectTrue((file = XFOPEN(ecDerPkcs8File, "rb")) != XBADFILE);
ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
p = pkcs8_buffer;
#ifdef OPENSSL_ALL
/* Try to decode - auto-detect key type. */
ExpectNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
#else
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &p, bytes));
#endif
/* Get PEM encoded RSA PKCS#8 data. */
ExpectTrue((file = XFOPEN(ecPemPkcs8File, "rb")) != XBADFILE);
ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
#if defined(OPENSSL_ALL) && \
!defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8) && \
defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
/* Write PKCS#8 PEM to BIO. */
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
NULL), bytes);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, NULL, NULL, 0, NULL,
NULL), bytes);
/* Compare file and written data */
ExpectIntEQ(BIO_get_mem_data(bio, &p), bytes);
ExpectIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
BIO_free(bio);
bio = NULL;
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
/* Write Encrypted PKCS#8 PEM to BIO (test write 0 then 379) */
bytes = 379;
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
NULL, 0, NoPasswordCallBack, (void*)"yassl123"), 0);
ExpectIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
/* invalid cases to stderr */
#ifdef WOLFSSL_AES_128
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_128_cbc(),
(char*)"yassl123", 8, PasswordCallBack, NULL), bytes);
#endif
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_256_cbc(),
NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, pkey, EVP_aes_256_cbc(),
(char*)"yassl123", 8, PasswordCallBack, NULL), bytes);
/* read/decode private key with password */
ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
(void*)"yassl123"));
EVP_PKEY_free(evpPkey);
evpPkey = NULL;
BIO_free(bio);
bio = NULL;
/* https://github.com/wolfSSL/wolfssl/issues/8610 */
bytes = (int)XSTRLEN((char *)pkcs8_buffer);
ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
ExpectIntEQ(BIO_get_mem_data(bio, &p), bytes);
ExpectIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
ExpectNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, NULL,
(void*)"yassl123"));
ExpectIntEQ(PEM_write_PKCS8PrivateKey(stderr, evpPkey, NULL,
NULL, 0, NULL, NULL), bytes);
EVP_PKEY_free(evpPkey);
evpPkey = NULL;
BIO_free(bio);
bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 && HAVE_AES_CBC */
EVP_PKEY_free(pkey);
pkey = NULL;
/* PKCS#8 encrypted EC key */
#ifndef NO_DES3
ExpectTrue((file = XFOPEN(ecDerPkcs8EncFile, "rb")) != XBADFILE);
ExpectNotNull(XMEMSET(pkcs8_buffer, 0, sizeof(pkcs8_buffer)));
ExpectIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
file)), 0);
if (file != XBADFILE) {
XFCLOSE(file);
file = XBADFILE;
}
#if defined(OPENSSL_ALL) && \
!defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
ExpectNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
ExpectNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
(void*)"yassl123"));
EVP_PKEY_free(pkey);
pkey = NULL;
BIO_free(bio);
bio = NULL;
#endif /* OPENSSL_ALL && !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
#endif /* !NO_DES3 */
#endif /* HAVE_ECC */
#endif /* !NO_FILESYSTEM */
#endif /* HAVE_FIPS && OPENSSL_EXTRA */
return EXPECT_RESULT();
}
#if !defined(SINGLE_THREADED) && defined(ERROR_QUEUE_PER_THREAD) && \
!defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL)
#define LOGGING_THREADS 5
#define ERROR_COUNT 10
/* copied from logging.c since this is not exposed otherwise */
#ifndef ERROR_QUEUE_MAX
#ifdef ERROR_QUEUE_PER_THREAD
#define ERROR_QUEUE_MAX 16
#else
/* this breaks from compat of unlimited error queue size */
#define ERROR_QUEUE_MAX 100
#endif
#endif
static volatile int loggingThreadsReady;
static THREAD_RETURN WOLFSSL_THREAD test_logging(void* args)
{
const char* file;
int line;
unsigned long err;
int errorCount = 0;
int i;
(void)args;
while (!loggingThreadsReady);
for (i = 0; i < ERROR_COUNT; i++)
ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__);
while ((err = ERR_get_error_line(&file, &line))) {
AssertIntEQ(err, 990 + errorCount);
errorCount++;
}
AssertIntEQ(errorCount, ERROR_COUNT);
/* test max queue behavior, trying to add an arbitrary 3 errors over */
ERR_clear_error(); /* ERR_get_error_line() does not remove */
errorCount = 0;
for (i = 0; i < ERROR_QUEUE_MAX + 3; i++)
ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__);
while ((err = ERR_get_error_line(&file, &line))) {
AssertIntEQ(err, 990 + errorCount);
errorCount++;
}
/* test that the 3 errors over the max were dropped */
AssertIntEQ(errorCount, ERROR_QUEUE_MAX);
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif
static int test_error_queue_per_thread(void)
{
int res = TEST_SKIPPED;
#if !defined(SINGLE_THREADED) && defined(ERROR_QUEUE_PER_THREAD) && \
!defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL)
THREAD_TYPE loggingThreads[LOGGING_THREADS];
int i;
ERR_clear_error(); /* clear out any error nodes */
loggingThreadsReady = 0;
for (i = 0; i < LOGGING_THREADS; i++)
start_thread(test_logging, NULL, &loggingThreads[i]);
loggingThreadsReady = 1;
for (i = 0; i < LOGGING_THREADS; i++)
join_thread(loggingThreads[i]);
res = TEST_SUCCESS;
#endif
return res;
}
static int test_wolfSSL_ERR_put_error(void)
{
EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL)
const char* file;
int line;
ERR_clear_error(); /* clear out any error nodes */
ERR_put_error(0,SYS_F_ACCEPT, 0, "this file", 0);
ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
ERR_put_error(0,SYS_F_BIND, 1, "this file", 1);
ExpectIntEQ(ERR_get_error_line(&file, &line), 1);
ERR_put_error(0,SYS_F_CONNECT, 2, "this file", 2);
ExpectIntEQ(ERR_get_error_line(&file, &line), 2);
ERR_put_error(0,SYS_F_FOPEN, 3, "this file", 3);
ExpectIntEQ(ERR_get_error_line(&file, &line), 3);
ERR_put_error(0,SYS_F_FREAD, 4, "this file", 4);
ExpectIntEQ(ERR_get_error_line(&file, &line), 4);
ERR_put_error(0,SYS_F_GETADDRINFO, 5, "this file", 5);
ExpectIntEQ(ERR_get_error_line(&file, &line), 5);
ERR_put_error(0,SYS_F_GETSOCKOPT, 6, "this file", 6);
ExpectIntEQ(ERR_get_error_line(&file, &line), 6);
ERR_put_error(0,SYS_F_GETSOCKNAME, 7, "this file", 7);
ExpectIntEQ(ERR_get_error_line(&file, &line), 7);
ERR_put_error(0,SYS_F_GETHOSTBYNAME, 8, "this file", 8);
ExpectIntEQ(ERR_get_error_line(&file, &line), 8);
ERR_put_error(0,SYS_F_GETNAMEINFO, 9, "this file", 9);
ExpectIntEQ(ERR_get_error_line(&file, &line), 9);
ERR_put_error(0,SYS_F_GETSERVBYNAME, 10, "this file", 10);
ExpectIntEQ(ERR_get_error_line(&file, &line), 10);
ERR_put_error(0,SYS_F_IOCTLSOCKET, 11, "this file", 11);
ExpectIntEQ(ERR_get_error_line(&file, &line), 11);
ERR_put_error(0,SYS_F_LISTEN, 12, "this file", 12);
ExpectIntEQ(ERR_get_error_line(&file, &line), 12);
ERR_put_error(0,SYS_F_OPENDIR, 13, "this file", 13);
ExpectIntEQ(ERR_get_error_line(&file, &line), 13);
ERR_put_error(0,SYS_F_SETSOCKOPT, 14, "this file", 14);
ExpectIntEQ(ERR_get_error_line(&file, &line), 14);
ERR_put_error(0,SYS_F_SOCKET, 15, "this file", 15);
ExpectIntEQ(ERR_get_error_line(&file, &line), 15);
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
ERR_put_error(ERR_LIB_ASN1, SYS_F_ACCEPT, ASN1_R_HEADER_TOO_LONG,
"this file", 100);
ExpectIntEQ(wolfSSL_ERR_peek_last_error_line(&file, &line),
(ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG);
ExpectIntEQ(line, 100);
ExpectIntEQ(wolfSSL_ERR_peek_error(),
(ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG);
ExpectIntEQ(ERR_get_error_line(&file, &line), ASN1_R_HEADER_TOO_LONG);
#endif
/* try reading past end of error queue */
file = NULL;
ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
ExpectNull(file);
ExpectIntEQ(ERR_get_error_line_data(&file, &line, NULL, NULL), 0);
PEMerr(4,4);
ExpectIntEQ(ERR_get_error(), 4);
/* Empty and free up all error nodes */
ERR_clear_error();
/* Verify all nodes are cleared */
ERR_put_error(0,SYS_F_ACCEPT, 0, "this file", 0);
ERR_clear_error();
ExpectIntEQ(ERR_get_error_line(&file, &line), 0);
#endif
return EXPECT_RESULT();
}
/*
* This is a regression test for a bug where the peek/get error functions were
* drawing from the end of the queue rather than the front.
*/
static int test_wolfSSL_ERR_get_error_order(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_HAVE_ERROR_QUEUE) && defined(OPENSSL_EXTRA)
/* Empty the queue. */
wolfSSL_ERR_clear_error();
wolfSSL_ERR_put_error(0, 0, WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), "test", 0);
wolfSSL_ERR_put_error(0, 0, WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E), "test", 0);
ExpectIntEQ(wolfSSL_ERR_peek_error(), -WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(ASN_NO_SIGNER_E));
ExpectIntEQ(wolfSSL_ERR_peek_error(), -WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E));
ExpectIntEQ(wolfSSL_ERR_get_error(), -WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E));
#endif /* WOLFSSL_HAVE_ERROR_QUEUE && OPENSSL_EXTRA */
return EXPECT_RESULT();
}
#ifndef NO_BIO
static int test_wolfSSL_ERR_print_errors(void)
{
EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL) && !defined(NO_ERROR_STRINGS)
BIO* bio = NULL;
char buf[1024];
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ERR_clear_error(); /* clear out any error nodes */
ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0);
/* Choosing -600 as an unused errno. */
ERR_put_error(0,SYS_F_BIND, -600, "asn.c", 100);
ERR_print_errors(bio);
ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 56);
ExpectIntEQ(XSTRNCMP(
"error:173:wolfSSL library:Bad function argument:ssl.c:0",
buf, 55), 0);
ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57);
ExpectIntEQ(XSTRNCMP(
"error:600:wolfSSL library:unknown error number:asn.c:100",
buf, 56), 0);
ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1);
ExpectIntEQ(buf[0], '\0');
ExpectIntEQ(ERR_get_error_line(NULL, NULL), 0);
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL)
static int test_wolfSSL_error_cb(const char *str, size_t len, void *u)
{
if (u != NULL) {
wolfSSL_BIO_write((BIO*)u, str, (int)len);
}
return 0;
}
#endif
static int test_wolfSSL_ERR_print_errors_cb(void)
{
EXPECT_DECLS;
#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \
defined(DEBUG_WOLFSSL)
BIO* bio = NULL;
char buf[1024];
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ERR_clear_error(); /* clear out any error nodes */
ERR_put_error(0,SYS_F_ACCEPT, -173, "ssl.c", 0);
ERR_put_error(0,SYS_F_BIND, -275, "asn.c", 100);
ERR_print_errors_cb(test_wolfSSL_error_cb, bio);
ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 108);
ExpectIntEQ(XSTRNCMP(
"wolfSSL error occurred, error = 173 line:0 file:ssl.c",
buf, 53), 0);
ExpectIntEQ(XSTRNCMP(
"wolfSSL error occurred, error = 275 line:100 file:asn.c",
buf + 53, 55), 0);
ExpectIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0);
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
/*
* Testing WOLFSSL_ERROR_MSG
*/
static int test_WOLFSSL_ERROR_MSG(void)
{
int res = TEST_SKIPPED;
#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\
defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
const char* msg = TEST_STRING;
WOLFSSL_ERROR_MSG(msg);
res = TEST_SUCCESS;
#endif
return res;
} /* End test_WOLFSSL_ERROR_MSG */
/*
* Testing wc_ERR_remove_state
*/
static int test_wc_ERR_remove_state(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
wc_ERR_remove_state();
res = TEST_SUCCESS;
#endif
return res;
} /* End test_wc_ERR_remove_state */
/*
* Testing wc_ERR_print_errors_fp
*/
static int test_wc_ERR_print_errors_fp(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)) && \
(!defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM))
long sz;
XFILE fp = XBADFILE;
WOLFSSL_ERROR(WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectTrue((fp = XFOPEN("./tests/test-log-dump-to-file.txt", "a+")) !=
XBADFILE);
wc_ERR_print_errors_fp(fp);
#if defined(DEBUG_WOLFSSL)
ExpectTrue(XFSEEK(fp, 0, XSEEK_END) == 0);
#ifdef NO_ERROR_QUEUE
ExpectIntEQ(sz = XFTELL(fp), 0);
#else
ExpectIntNE(sz = XFTELL(fp), 0);
#endif
#endif
if (fp != XBADFILE)
XFCLOSE(fp);
(void)sz;
#endif
return EXPECT_RESULT();
} /* End test_wc_ERR_print_errors_fp */
#ifdef DEBUG_WOLFSSL
static void Logging_cb(const int logLevel, const char *const logMessage)
{
(void)logLevel;
(void)logMessage;
}
#endif
/*
* Testing wolfSSL_GetLoggingCb
*/
static int test_wolfSSL_GetLoggingCb(void)
{
EXPECT_DECLS;
#ifdef DEBUG_WOLFSSL
/* Testing without wolfSSL_SetLoggingCb() */
ExpectNull(wolfSSL_GetLoggingCb());
/* Testing with wolfSSL_SetLoggingCb() */
ExpectIntEQ(wolfSSL_SetLoggingCb(Logging_cb), 0);
ExpectNotNull(wolfSSL_GetLoggingCb());
ExpectIntEQ(wolfSSL_SetLoggingCb(NULL), 0);
#endif
ExpectNull(wolfSSL_GetLoggingCb());
return EXPECT_RESULT();
} /* End test_wolfSSL_GetLoggingCb */
#endif /* !NO_BIO */
/* Note the lack of wolfSSL_ prefix...this is a compatibility layer test. */
static int test_GENERAL_NAME_set0_othername(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM) && \
defined(WOLFSSL_FPKI) && !defined(NO_RSA)
/* ./configure --enable-opensslall --enable-certgen --enable-certreq
* --enable-certext --enable-debug 'CPPFLAGS=-DWOLFSSL_CUSTOM_OID
* -DWOLFSSL_ALT_NAMES -DWOLFSSL_FPKI' */
const char * cert_fname = "./certs/server-cert.der";
const char * key_fname = "./certs/server-key.der";
X509* x509 = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAMES* gns = NULL;
ASN1_OBJECT* upn_oid = NULL;
ASN1_UTF8STRING *utf8str = NULL;
ASN1_TYPE *value = NULL;
X509_EXTENSION * ext = NULL;
byte* pt = NULL;
byte der[4096];
int derSz = 0;
EVP_PKEY* priv = NULL;
XFILE f = XBADFILE;
ExpectTrue((f = XFOPEN(cert_fname, "rb")) != XBADFILE);
ExpectNotNull(x509 = d2i_X509_fp(f, NULL));
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectNotNull(gn = GENERAL_NAME_new());
ExpectNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
ExpectNotNull(utf8str = ASN1_UTF8STRING_new());
ExpectIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
ExpectNotNull(value = ASN1_TYPE_new());
ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
if ((value == NULL) || (value->value.ptr != (char*)utf8str)) {
wolfSSL_ASN1_STRING_free(utf8str);
}
ExpectIntEQ(GENERAL_NAME_set0_othername(NULL, NULL , NULL ),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(gn , NULL , NULL ),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(NULL, upn_oid, NULL ),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(NULL, NULL , value),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(gn , upn_oid, NULL ),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(gn , NULL , value),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(NULL, upn_oid, value ),
WOLFSSL_FAILURE);
ExpectIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
if (EXPECT_FAIL()) {
ASN1_TYPE_free(value);
}
ExpectNotNull(gns = sk_GENERAL_NAME_new(NULL));
ExpectIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
if (EXPECT_FAIL()) {
GENERAL_NAME_free(gn);
gn = NULL;
}
ExpectNotNull(ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
ExpectIntEQ(X509_add_ext(x509, ext, -1), 1);
ExpectTrue((f = XFOPEN(key_fname, "rb")) != XBADFILE);
ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
pt = der;
ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
(const unsigned char**)&pt, derSz));
ExpectIntGT(X509_sign(x509, priv, EVP_sha256()), 0);
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
gns = NULL;
ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509,
NID_subject_alt_name, NULL, NULL));
ExpectIntEQ(sk_GENERAL_NAME_num(NULL), 0);
ExpectIntEQ(sk_GENERAL_NAME_num(gns), 3);
ExpectNull(sk_GENERAL_NAME_value(NULL, 0));
ExpectNull(sk_GENERAL_NAME_value(gns, 20));
ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, 2));
ExpectIntEQ(gn->type, 0);
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
ASN1_OBJECT_free(upn_oid);
X509_EXTENSION_free(ext);
X509_free(x509);
EVP_PKEY_free(priv);
#endif
return EXPECT_RESULT();
}
/* Test RID (Registered ID) GENERAL_NAME creation and freeing */
static int test_RID_GENERAL_NAME_free(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(WOLFSSL_RID_ALT_NAME)
/* RID OID: 1.2.3.4.5 in DER */
const unsigned char ridData[] = { 0x06, 0x04, 0x2a, 0x03, 0x04, 0x05 };
const unsigned char* p = ridData;
GENERAL_NAME* gn = NULL;
GENERAL_NAMES* gns = NULL;
ASN1_OBJECT* ridObj = NULL;
/* Create RID ASN1_OBJECT from DER */
ExpectNotNull(ridObj = wolfSSL_d2i_ASN1_OBJECT(NULL, &p, sizeof(ridData)));
/* Create GENERAL_NAME and set up as RID */
ExpectNotNull(gn = GENERAL_NAME_new());
if (gn != NULL) {
/* GENERAL_NAME_new allocates ia5, must free before using as RID */
gn->type = GEN_RID;
wolfSSL_ASN1_STRING_free(gn->d.ia5);
gn->d.ia5 = NULL;
gn->d.registeredID = ridObj;
ridObj = NULL; /* gn owns */
}
if (EXPECT_FAIL()) {
wolfSSL_ASN1_OBJECT_free(ridObj);
}
/* Add to stack */
ExpectNotNull(gns = sk_GENERAL_NAME_new(NULL));
ExpectIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
if (EXPECT_FAIL()) {
GENERAL_NAME_free(gn);
gn = NULL;
}
/* Verify RID is set up correctly */
ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, 0));
ExpectIntEQ(gn->type, GEN_RID);
ExpectNotNull(gn->d.registeredID);
/* Free via sk_GENERAL_NAME_pop_free, exercises type_free for RID */
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
#endif
return EXPECT_RESULT();
}
/* Test RID (Registered ID) SAN parsing via X509_get_ext_d2i().
* Uses rid-cert.der which contains a RID SAN with OID 1.2.3.4.5. This tests
* that ASN_RID_TYPE case in wolfSSL_X509_get_ext_d2i() frees ia5 before
* allocating registeredID. */
static int test_RID_X509_get_ext_d2i(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(WOLFSSL_RID_ALT_NAME) && \
!defined(NO_RSA) && !defined(NO_FILESYSTEM)
int i;
int numNames;
int foundRID = 0;
const char* ridCert = "./certs/rid-cert.der";
X509* x509 = NULL;
GENERAL_NAMES* gns = NULL;
GENERAL_NAME* gn = NULL;
XFILE f = XBADFILE;
ExpectTrue((f = XFOPEN(ridCert, "rb")) != XBADFILE);
ExpectNotNull(x509 = d2i_X509_fp(f, NULL));
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
/* Get SANs, will exercise ASN_RID_TYPE case */
ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509,
NID_subject_alt_name, NULL, NULL));
/* rid-cert.der contains: UPN, RID (1.2.3.4.5), DNS, URI, othername */
numNames = sk_GENERAL_NAME_num(gns);
ExpectIntGE(numNames, 2);
for (i = 0; i < numNames; i++) {
gn = sk_GENERAL_NAME_value(gns, i);
if (gn != NULL && gn->type == GEN_RID) {
ExpectNotNull(gn->d.registeredID);
foundRID = 1;
break;
}
}
ExpectIntEQ(foundRID, 1);
/* Free via sk_GENERAL_NAME_pop_free, exercises type_free for RID */
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
X509_free(x509);
#endif
return EXPECT_RESULT();
}
/* Note the lack of wolfSSL_ prefix...this is a compatibility layer test. */
static int test_othername_and_SID_ext(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CUSTOM_OID) && defined(WOLFSSL_ALT_NAMES) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_FILESYSTEM) && \
defined(WOLFSSL_FPKI) && defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_RSA)
/* ./configure --enable-opensslall --enable-certgen --enable-certreq
* --enable-certext --enable-debug 'CPPFLAGS=-DWOLFSSL_CUSTOM_OID
* -DWOLFSSL_ALT_NAMES -DWOLFSSL_FPKI' */
const char* csr_fname = "./certs/csr.signed.der";
const char* key_fname = "./certs/server-key.der";
byte der[4096];
int derSz = 0;
byte badDer[2] = { 0x30, 0x00 };
X509_REQ* x509 = NULL;
STACK_OF(X509_EXTENSION) *exts = NULL;
X509_EXTENSION * san_ext = NULL;
X509_EXTENSION * ext = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAMES* gns = NULL;
ASN1_OBJECT* upn_oid = NULL;
ASN1_UTF8STRING *utf8str = NULL;
ASN1_TYPE *value = NULL;
ASN1_STRING *extval = NULL;
/* SID extension. SID data format explained here:
* https://blog.qdsecurity.se/2022/05/27/manually-injecting-a-sid-in-a-certificate/
*/
byte SidExtension[] = {
48, 64, 160, 62, 6, 10, 43, 6, 1, 4, 1, 130, 55, 25, 2, 1, 160,
48, 4, 46, 83, 45, 49, 45, 53, 45, 50, 49, 45, 50, 56, 52, 51, 57,
48, 55, 52, 49, 56, 45, 51, 57, 50, 54, 50, 55, 55, 52, 50, 49, 45,
51, 56, 49, 53, 57, 57, 51, 57, 55, 50, 45, 52, 54, 48, 49};
byte expectedAltName[] = {
0x30, 0x27, 0xA0, 0x25, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82,
0x37, 0x14, 0x02, 0x03, 0xA0, 0x17, 0x0C, 0x15, 0x6F, 0x74, 0x68, 0x65,
0x72, 0x6E, 0x61, 0x6D, 0x65, 0x40, 0x77, 0x6F, 0x6C, 0x66, 0x73, 0x73,
0x6C, 0x2E, 0x63, 0x6F, 0x6D};
X509_EXTENSION *sid_ext = NULL;
ASN1_OBJECT* sid_oid = NULL;
ASN1_OCTET_STRING *sid_data = NULL;
ASN1_OBJECT* alt_names_oid = NULL;
EVP_PKEY* priv = NULL;
XFILE f = XBADFILE;
byte* pt = NULL;
BIO* bio = NULL;
ExpectTrue((f = XFOPEN(csr_fname, "rb")) != XBADFILE);
ExpectNotNull(x509 = d2i_X509_REQ_fp(f, NULL));
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectIntEQ(X509_REQ_set_version(x509, 2), 1);
ExpectNotNull(gn = GENERAL_NAME_new());
ExpectNotNull(upn_oid = OBJ_txt2obj("1.3.6.1.4.1.311.20.2.3", 1));
ExpectNotNull(utf8str = ASN1_UTF8STRING_new());
ExpectIntEQ(ASN1_STRING_set(utf8str, "othername@wolfssl.com", -1), 1);
ExpectNotNull(value = ASN1_TYPE_new());
ASN1_TYPE_set(value, V_ASN1_UTF8STRING, utf8str);
if (EXPECT_FAIL()) {
ASN1_UTF8STRING_free(utf8str);
}
ExpectIntEQ(GENERAL_NAME_set0_othername(gn, upn_oid, value), 1);
if (EXPECT_FAIL()) {
ASN1_TYPE_free(value);
GENERAL_NAME_free(gn);
gn = NULL;
}
ExpectNotNull(gns = sk_GENERAL_NAME_new(NULL));
ExpectIntEQ(sk_GENERAL_NAME_push(gns, gn), 1);
if (EXPECT_FAIL()) {
GENERAL_NAME_free(gn);
}
ExpectNotNull(san_ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gns));
ExpectNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1));
ExpectNotNull(sid_data = ASN1_OCTET_STRING_new());
ASN1_OCTET_STRING_set(sid_data, SidExtension, sizeof(SidExtension));
ExpectNotNull(sid_ext = X509_EXTENSION_create_by_OBJ(NULL, sid_oid, 0,
sid_data));
ExpectNotNull(exts = sk_X509_EXTENSION_new_null());
wolfSSL_sk_X509_EXTENSION_free(exts);
exts = NULL;
ExpectNotNull(exts = sk_X509_EXTENSION_new_null());
/* Ensure an empty stack doesn't raise an error. */
ExpectIntEQ(X509_REQ_add_extensions(NULL, NULL), 0);
ExpectIntEQ(X509_REQ_add_extensions(x509, NULL), 0);
ExpectIntEQ(X509_REQ_add_extensions(NULL, exts), 0);
ExpectIntEQ(X509_REQ_add_extensions(x509, exts), 1);
ExpectIntEQ(sk_X509_EXTENSION_push(exts, san_ext), 1);
if (EXPECT_FAIL()) {
X509_EXTENSION_free(san_ext);
}
ExpectIntEQ(sk_X509_EXTENSION_push(exts, sid_ext), 2);
if (EXPECT_FAIL()) {
X509_EXTENSION_free(sid_ext);
}
ExpectIntEQ(X509_REQ_add_extensions(x509, exts), 1);
ExpectTrue((f = XFOPEN(key_fname, "rb")) != XBADFILE);
ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
pt = der;
ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL,
(const unsigned char**)&pt, derSz));
ExpectIntGT(X509_REQ_sign(x509, priv, EVP_sha256()), 0);
pt = der;
ExpectIntGT(derSz = i2d_X509_REQ(x509, &pt), 0);
X509_REQ_free(x509);
x509 = NULL;
ExpectNull(d2i_X509_REQ_INFO(&x509, NULL, derSz));
pt = badDer;
ExpectNull(d2i_X509_REQ_INFO(&x509, (const unsigned char**)&pt,
sizeof(badDer)));
pt = der;
ExpectNotNull(d2i_X509_REQ_INFO(&x509, (const unsigned char**)&pt, derSz));
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
gns = NULL;
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
exts = NULL;
ASN1_OBJECT_free(upn_oid);
ASN1_OBJECT_free(sid_oid);
sid_oid = NULL;
ASN1_OCTET_STRING_free(sid_data);
X509_REQ_free(x509);
EVP_PKEY_free(priv);
/* At this point everything used to generate what is in der is cleaned up.
* We now read back from der to confirm the extensions were inserted
* correctly. */
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
ExpectNotNull(bio);
ExpectIntEQ(BIO_write(bio, der, derSz), derSz); /* d2i consumes BIO */
ExpectNotNull(d2i_X509_REQ_bio(bio, &x509));
ExpectNotNull(x509);
BIO_free(bio);
ExpectNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(
x509));
ExpectIntEQ(sk_X509_EXTENSION_num(NULL), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(sk_X509_EXTENSION_num(exts), 2);
/* Check the SID extension. */
ExpectNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1));
ExpectNotNull(ext = sk_X509_EXTENSION_value(exts,
X509_get_ext_by_OBJ(x509, sid_oid, -1)));
ExpectNotNull(extval = X509_EXTENSION_get_data(ext));
ExpectIntEQ(extval->length, sizeof(SidExtension));
ExpectIntEQ(XMEMCMP(SidExtension, extval->data, sizeof(SidExtension)), 0);
ASN1_OBJECT_free(sid_oid);
/* Check the AltNames extension. */
ExpectNotNull(alt_names_oid = OBJ_txt2obj("subjectAltName", 0));
ExpectNotNull(ext = sk_X509_EXTENSION_value(exts,
X509_get_ext_by_OBJ(x509, alt_names_oid, -1)));
ExpectNotNull(extval = X509_EXTENSION_get_data(ext));
ExpectIntEQ(extval->length, sizeof(expectedAltName));
ExpectIntEQ(XMEMCMP(expectedAltName, extval->data, sizeof(expectedAltName)),
0);
ASN1_OBJECT_free(alt_names_oid);
/* Cleanup */
ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509,
NID_subject_alt_name, NULL, NULL));
ExpectIntEQ(sk_GENERAL_NAME_num(gns), 1);
ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, 0));
ExpectIntEQ(gn->type, 0);
sk_GENERAL_NAME_pop_free(gns, GENERAL_NAME_free);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
X509_REQ_free(x509);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
/* test that the callback arg is correct */
static int certCbArg = 0;
static int certCb(WOLFSSL* ssl, void* arg)
{
if (ssl == NULL || arg != &certCbArg)
return 0;
if (wolfSSL_is_server(ssl)) {
if (wolfSSL_use_certificate_file(ssl, svrCertFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
return 0;
if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
return 0;
}
else {
if (wolfSSL_use_certificate_file(ssl, cliCertFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
return 0;
if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile,
WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
return 0;
}
return 1;
}
static int certSetupCb(WOLFSSL_CTX* ctx)
{
SSL_CTX_set_cert_cb(ctx, certCb, &certCbArg);
return TEST_SUCCESS;
}
/**
* This is only done because test_wolfSSL_client_server_nofail_memio has no way
* to stop certificate and key loading
*/
static int certClearCb(WOLFSSL* ssl)
{
/* Clear the loaded certs to force the callbacks to set them up */
SSL_certs_clear(ssl);
return TEST_SUCCESS;
}
#endif
static int test_wolfSSL_cert_cb(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* desc;
} test_params[] = {
#ifdef WOLFSSL_TLS13
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3"},
#endif
#ifndef WOLFSSL_NO_TLS12
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2"},
#endif
#ifndef NO_OLD_TLS
{wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLS 1.1"},
#ifdef WOLFSSL_ALLOW_TLSV10
{wolfTLSv1_client_method, wolfTLSv1_server_method, "TLS 1.0"},
#endif
#endif
};
for (i = 0; i < XELEM_CNT(test_params) && !EXPECT_FAIL(); i++) {
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
printf("\tTesting with %s...\n", test_params[i].desc);
func_cb_client.method = test_params[i].client_meth;
func_cb_server.method = test_params[i].server_meth;
func_cb_client.ctx_ready = certSetupCb;
func_cb_client.ssl_ready = certClearCb;
func_cb_server.ctx_ready = certSetupCb;
func_cb_server.ssl_ready = certClearCb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
}
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_cipher = NULL;
static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs = NULL;
static int test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx,
test_wolfSSL_cert_cb_dyn_ciphers_client_cipher), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx,
test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg)
{
const byte* suites = NULL;
word16 suiteSz = 0;
const byte* hashSigAlgo = NULL;
word16 hashSigAlgoSz = 0;
word16 idx = 0;
int haveRSA = 0;
int haveECC = 0;
(void)arg;
if (wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo,
&hashSigAlgoSz) != WOLFSSL_SUCCESS)
return 0;
if (suites == NULL || suiteSz == 0 || hashSigAlgo == NULL ||
hashSigAlgoSz == 0)
return 0;
for (idx = 0; idx < suiteSz; idx += 2) {
WOLFSSL_CIPHERSUITE_INFO info =
wolfSSL_get_ciphersuite_info(suites[idx], suites[idx+1]);
if (info.rsaAuth)
haveRSA = 1;
else if (info.eccAuth)
haveECC = 1;
}
if (hashSigAlgoSz > 0) {
/* sigalgs extension takes precedence over ciphersuites */
haveRSA = 0;
haveECC = 0;
}
for (idx = 0; idx < hashSigAlgoSz; idx += 2) {
int hashAlgo = 0;
int sigAlgo = 0;
if (wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1],
&hashAlgo, &sigAlgo) != 0)
return 0;
if (sigAlgo == RSAk || sigAlgo == RSAPSSk)
haveRSA = 1;
else if (sigAlgo == ECDSAk)
haveECC = 1;
}
if (haveRSA) {
if (wolfSSL_use_certificate_file(ssl, svrCertFile, WOLFSSL_FILETYPE_PEM)
!= WOLFSSL_SUCCESS)
return 0;
if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile, WOLFSSL_FILETYPE_PEM)
!= WOLFSSL_SUCCESS)
return 0;
}
else if (haveECC) {
if (wolfSSL_use_certificate_file(ssl, eccCertFile, WOLFSSL_FILETYPE_PEM)
!= WOLFSSL_SUCCESS)
return 0;
if (wolfSSL_use_PrivateKey_file(ssl, eccKeyFile, WOLFSSL_FILETYPE_PEM)
!= WOLFSSL_SUCCESS)
return 0;
}
return 1;
}
static int test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready(WOLFSSL_CTX* ctx)
{
SSL_CTX_set_cert_cb(ctx, test_wolfSSL_cert_cb_dyn_ciphers_certCB, NULL);
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
return TEST_SUCCESS;
}
#endif
/* Testing dynamic ciphers offered by client */
static int test_wolfSSL_cert_cb_dyn_ciphers(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
struct {
method_provider client_meth;
const char* client_ciphers;
const char* client_sigalgs;
const char* client_ca;
method_provider server_meth;
} test_params[] = {
#if !defined(NO_SHA256) && defined(HAVE_AESGCM)
#ifdef WOLFSSL_TLS13
#if !defined(NO_RSA) && defined(WC_RSA_PSS)
{wolfTLSv1_3_client_method,
"TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256",
"RSA-PSS+SHA256", caCertFile, wolfTLSv1_3_server_method},
#endif
#ifdef HAVE_ECC
{wolfTLSv1_3_client_method,
"TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256",
"ECDSA+SHA256", caEccCertFile, wolfTLSv1_3_server_method},
#endif
#endif
#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_HARDEN_TLS)
#if !defined(NO_RSA) && defined(WC_RSA_PSS) && !defined(NO_DH)
{wolfTLSv1_2_client_method,
"DHE-RSA-AES128-GCM-SHA256",
"RSA-PSS+SHA256", caCertFile, wolfTLSv1_2_server_method},
#endif
#ifdef HAVE_ECC
{wolfTLSv1_2_client_method,
"ECDHE-ECDSA-AES128-GCM-SHA256",
"ECDSA+SHA256", caEccCertFile, wolfTLSv1_2_server_method},
#endif
#endif
#endif
};
size_t i;
size_t testCount = sizeof(test_params)/sizeof(*test_params);
if (testCount > 0) {
for (i = 0; i < testCount; i++) {
printf("\tTesting %s ciphers with %s sigalgs\n",
test_params[i].client_ciphers,
test_params[i].client_sigalgs);
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
test_wolfSSL_cert_cb_dyn_ciphers_client_cipher =
test_params[i].client_ciphers;
test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs =
test_params[i].client_sigalgs;
func_cb_client.method = test_params[i].client_meth;
func_cb_client.caPemFile = test_params[i].client_ca;
func_cb_client.ctx_ready =
test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready;
func_cb_server.ctx_ready =
test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready;
func_cb_server.ssl_ready = certClearCb; /* Reuse from prev test */
func_cb_server.method = test_params[i].server_meth;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
}
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_ciphersuite_auth(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
WOLFSSL_CIPHERSUITE_INFO info;
(void)info;
#ifndef WOLFSSL_NO_TLS12
#ifdef HAVE_CHACHA
info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
ExpectIntEQ(info.rsaAuth, 1);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 1);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE,
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 1);
#endif
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
#ifndef NO_RSA
info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
ExpectIntEQ(info.rsaAuth, 1);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA);
ExpectIntEQ(info.rsaAuth, 1);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 1);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA);
ExpectIntEQ(info.rsaAuth, 1);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 1);
ExpectIntEQ(info.psk, 0);
#endif
info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 1);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(ECC_BYTE,
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 1);
ExpectIntEQ(info.eccStatic, 1);
ExpectIntEQ(info.psk, 0);
info = wolfSSL_get_ciphersuite_info(ECDHE_PSK_BYTE,
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 1);
#endif
#endif
#ifdef WOLFSSL_TLS13
info = wolfSSL_get_ciphersuite_info(TLS13_BYTE,
TLS_AES_128_GCM_SHA256);
ExpectIntEQ(info.rsaAuth, 0);
ExpectIntEQ(info.eccAuth, 0);
ExpectIntEQ(info.eccStatic, 0);
ExpectIntEQ(info.psk, 0);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_sigalg_info(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
byte hashSigAlgo[WOLFSSL_MAX_SIGALGO];
word16 len = 0;
word16 idx = 0;
int allSigAlgs = SIG_ECDSA | SIG_RSA | SIG_SM2 | SIG_FALCON | SIG_DILITHIUM;
InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs, 1, 0xFFFFFFFF, &len);
for (idx = 0; idx < len; idx += 2) {
int hashAlgo = 0;
int sigAlgo = 0;
ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0],
hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0);
ExpectIntNE(hashAlgo, 0);
ExpectIntNE(sigAlgo, 0);
}
InitSuitesHashSigAlgo(hashSigAlgo, allSigAlgs | SIG_ANON, 1,
0xFFFFFFFF, &len);
for (idx = 0; idx < len; idx += 2) {
int hashAlgo = 0;
int sigAlgo = 0;
ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0],
hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0);
ExpectIntNE(hashAlgo, 0);
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_SESSION(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA) && !defined(NO_SHA256) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(NO_SESSION_CACHE)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL_SESSION* sess = NULL;
WOLFSSL_SESSION* sess_copy = NULL;
#ifdef OPENSSL_EXTRA
#ifdef HAVE_EXT_CACHE
unsigned char* sessDer = NULL;
unsigned char* ptr = NULL;
int sz = 0;
#endif
const unsigned char context[] = "user app context";
unsigned int contextSz = (unsigned int)sizeof(context);
#endif
int ret = 0, err = 0;
SOCKET_T sockfd;
tcp_ready ready;
func_args server_args;
THREAD_TYPE serverThread;
char msg[80];
const char* sendGET = "GET";
/* TLS v1.3 requires session tickets */
/* CHACHA and POLY1305 required for myTicketEncCb */
#if !defined(WOLFSSL_NO_TLS12) && (!defined(WOLFSSL_TLS13) || \
!(defined(HAVE_SESSION_TICKET) && ((defined(HAVE_CHACHA) && \
defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))))
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#endif
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, cliCertFile,
CERT_FILETYPE));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile,
CERT_FILETYPE));
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ENCRYPTED_KEYS
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
#ifdef HAVE_SESSION_TICKET
/* Use session tickets, for ticket tests below */
ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
#endif
XMEMSET(&server_args, 0, sizeof(func_args));
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
server_args.signal = &ready;
start_thread(test_server_nofail, &server_args, &serverThread);
wait_tcp_ready(&server_args);
/* client connection */
ExpectNotNull(ssl = wolfSSL_new(ctx));
tcp_connect(&sockfd, wolfSSLIP, ready.port, 0, 0, ssl);
ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS);
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_connect(ssl),
ret != WOLFSSL_SUCCESS);
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
WOLFSSL_ASYNC_WHILE_PENDING(
ret = wolfSSL_write(ssl, sendGET, (int)XSTRLEN(sendGET)),
ret <= 0);
ExpectIntEQ(ret, (int)XSTRLEN(sendGET));
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_read(ssl, msg, sizeof(msg)),
ret != 23);
ExpectIntEQ(ret, 23);
ExpectPtrNE((sess = wolfSSL_get1_session(ssl)), NULL); /* ref count 1 */
ExpectPtrNE((sess_copy = wolfSSL_get1_session(ssl)), NULL); /* ref count 2 */
ExpectIntEQ(wolfSSL_SessionIsSetup(sess), 1);
#ifdef HAVE_EXT_CACHE
ExpectPtrEq(sess, sess_copy); /* they should be the same pointer but without
* HAVE_EXT_CACHE we get new objects each time */
#endif
wolfSSL_SESSION_free(sess_copy); sess_copy = NULL;
wolfSSL_SESSION_free(sess); sess = NULL; /* free session ref */
sess = wolfSSL_get_session(ssl);
#ifdef OPENSSL_EXTRA
ExpectIntEQ(SSL_SESSION_is_resumable(NULL), 0);
ExpectIntEQ(SSL_SESSION_is_resumable(sess), 1);
ExpectIntEQ(wolfSSL_SESSION_has_ticket(NULL), 0);
ExpectIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(NULL), 0);
#ifdef HAVE_SESSION_TICKET
ExpectIntEQ(wolfSSL_SESSION_has_ticket(sess), 1);
ExpectIntEQ(wolfSSL_SESSION_get_ticket_lifetime_hint(sess),
SESSION_TICKET_HINT_DEFAULT);
#else
ExpectIntEQ(wolfSSL_SESSION_has_ticket(sess), 0);
#endif
#else
(void)sess;
#endif /* OPENSSL_EXTRA */
/* Retain copy of the session for later testing */
ExpectNotNull(sess = wolfSSL_get1_session(ssl));
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl); ssl = NULL;
CloseSocket(sockfd);
join_thread(serverThread);
FreeTcpReady(&ready);
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
{
X509 *x509 = NULL;
char buf[30];
int bufSz = 0;
ExpectNotNull(x509 = SSL_SESSION_get0_peer(sess));
ExpectIntGT((bufSz = X509_NAME_get_text_by_NID(
X509_get_subject_name(x509), NID_organizationalUnitName, buf,
sizeof(buf))), 0);
ExpectIntNE((bufSz == 7 || bufSz == 16), 0); /* should be one of these*/
if (bufSz == 7) {
ExpectIntEQ(XMEMCMP(buf, "Support", bufSz), 0);
}
if (bufSz == 16) {
ExpectIntEQ(XMEMCMP(buf, "Programming-2048", bufSz), 0);
}
}
#endif
#ifdef HAVE_EXT_CACHE
ExpectNotNull(sess_copy = wolfSSL_SESSION_dup(sess));
wolfSSL_SESSION_free(sess_copy); sess_copy = NULL;
sess_copy = NULL;
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE)
/* get session from DER and update the timeout */
ExpectIntEQ(wolfSSL_i2d_SSL_SESSION(NULL, &sessDer), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntGT((sz = wolfSSL_i2d_SSL_SESSION(sess, &sessDer)), 0);
wolfSSL_SESSION_free(sess); sess = NULL;
sess = NULL;
ptr = sessDer;
ExpectNull(sess = wolfSSL_d2i_SSL_SESSION(NULL, NULL, sz));
ExpectNotNull(sess = wolfSSL_d2i_SSL_SESSION(NULL,
(const unsigned char**)&ptr, sz));
XFREE(sessDer, NULL, DYNAMIC_TYPE_OPENSSL);
sessDer = NULL;
ExpectIntGT(wolfSSL_SESSION_get_time(sess), 0);
ExpectIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);
#endif
/* successful set session test */
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_set_session(ssl, sess), WOLFSSL_SUCCESS);
#ifdef HAVE_SESSION_TICKET
/* Test set/get session ticket */
{
const char* ticket = "This is a session ticket";
char buf[64] = {0};
word32 bufSz = (word32)sizeof(buf);
word32 retSz = 0;
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_set_SessionTicket(ssl, (byte *)ticket,
(word32)XSTRLEN(ticket)));
ExpectIntEQ(WOLFSSL_SUCCESS,
wolfSSL_get_SessionTicket(ssl, (byte *)buf, &bufSz));
ExpectStrEQ(ticket, buf);
/* return ticket length if buffer parameter is null */
wolfSSL_get_SessionTicket(ssl, NULL, &retSz);
ExpectIntEQ(bufSz, retSz);
}
#endif
#ifdef OPENSSL_EXTRA
/* session timeout case */
/* make the session to be expired */
ExpectIntEQ(SSL_SESSION_set_timeout(sess,1), SSL_SUCCESS);
XSLEEP_MS(1200);
/* SSL_set_session should reject specified session but return success
* if WOLFSSL_ERROR_CODE_OPENSSL macro is defined for OpenSSL compatibility.
*/
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
ExpectIntEQ(wolfSSL_set_session(ssl,sess), SSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_set_session(ssl,sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
ExpectIntEQ(wolfSSL_SSL_SESSION_set_timeout(sess, 500), SSL_SUCCESS);
#ifdef WOLFSSL_SESSION_ID_CTX
/* fail case with miss match session context IDs (use compatibility API) */
ExpectIntEQ(SSL_set_session_id_context(ssl, context, contextSz),
SSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_session(ssl, sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_free(ssl); ssl = NULL;
ExpectIntEQ(SSL_CTX_set_session_id_context(NULL, context, contextSz),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CTX_set_session_id_context(ctx, context, contextSz),
SSL_SUCCESS);
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_set_session(ssl, sess), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#endif /* OPENSSL_EXTRA */
wolfSSL_free(ssl);
wolfSSL_SESSION_free(sess);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
!defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
!defined(WOLFSSL_NO_TLS12)
static WOLFSSL_SESSION* test_wolfSSL_SESSION_expire_sess = NULL;
static void test_wolfSSL_SESSION_expire_downgrade_ctx_ready(WOLFSSL_CTX* ctx)
{
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
/* returns previous timeout value */
AssertIntEQ(wolfSSL_CTX_set_timeout(ctx, 1), 500);
#else
AssertIntEQ(wolfSSL_CTX_set_timeout(ctx, 1), WOLFSSL_SUCCESS);
#endif
}
/* set the session to timeout in a second */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready(WOLFSSL* ssl)
{
AssertIntEQ(wolfSSL_set_timeout(ssl, 2), 1);
}
/* store the client side session from the first successful connection */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_result(WOLFSSL* ssl)
{
AssertPtrNE((test_wolfSSL_SESSION_expire_sess = wolfSSL_get1_session(ssl)),
NULL); /* ref count 1 */
}
/* wait till session is expired then set it in the WOLFSSL struct for use */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready_wait(WOLFSSL* ssl)
{
AssertIntEQ(wolfSSL_set_timeout(ssl, 1), 1);
AssertIntEQ(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
WOLFSSL_SUCCESS);
XSLEEP_MS(2000); /* wait 2 seconds for session to expire */
}
/* set expired session in the WOLFSSL struct for use */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_ready_set(WOLFSSL* ssl)
{
XSLEEP_MS(1200); /* wait a second for session to expire */
/* set the expired session, call to set session fails but continuing on
after failure should be handled here */
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
AssertIntEQ(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
WOLFSSL_SUCCESS);
#else
AssertIntNE(wolfSSL_set_session(ssl, test_wolfSSL_SESSION_expire_sess),
WOLFSSL_SUCCESS);
#endif
}
/* check that the expired session was not reused */
static void test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse(WOLFSSL* ssl)
{
/* since the session has expired it should not have been reused */
AssertIntEQ(wolfSSL_session_reused(ssl), 0);
}
#endif
static int test_wolfSSL_SESSION_expire_downgrade(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
!defined(NO_SESSION_CACHE) && defined(OPENSSL_EXTRA) && \
!defined(WOLFSSL_NO_TLS12)
callback_functions server_cbf, client_cbf;
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
/* force server side to use TLS 1.2 */
server_cbf.method = wolfTLSv1_2_server_method;
client_cbf.method = wolfSSLv23_client_method;
server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready;
client_cbf.on_result = test_wolfSSL_SESSION_expire_downgrade_ssl_result;
test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
client_cbf.method = wolfSSLv23_client_method;
server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready_wait;
client_cbf.on_result =
test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse;
test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
client_cbf.method = wolfSSLv23_client_method;
server_cbf.ctx_ready = test_wolfSSL_SESSION_expire_downgrade_ctx_ready;
client_cbf.ssl_ready = test_wolfSSL_SESSION_expire_downgrade_ssl_ready_set;
client_cbf.on_result =
test_wolfSSL_SESSION_expire_downgrade_ssl_result_reuse;
test_wolfSSL_client_server_nofail(&client_cbf, &server_cbf);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
wolfSSL_SESSION_free(test_wolfSSL_SESSION_expire_sess);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
#ifdef WOLFSSL_ATOMIC_OPS
typedef wolfSSL_Atomic_Int SessRemCounter_t;
#else
typedef int SessRemCounter_t;
#endif
static SessRemCounter_t clientSessRemCountMalloc;
static SessRemCounter_t serverSessRemCountMalloc;
static SessRemCounter_t clientSessRemCountFree;
static SessRemCounter_t serverSessRemCountFree;
static WOLFSSL_CTX* serverSessCtx = NULL;
static WOLFSSL_SESSION* serverSess = NULL;
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
!defined(NO_SESSION_CACHE_REF)
static WOLFSSL_CTX* clientSessCtx = NULL;
static WOLFSSL_SESSION* clientSess = NULL;
#endif
static int serverSessRemIdx = 3;
static int sessRemCtx_Server = WOLFSSL_SERVER_END;
static int sessRemCtx_Client = WOLFSSL_CLIENT_END;
static void SessRemCtxCb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
{
int* side;
(void)ctx;
side = (int*)SSL_SESSION_get_ex_data(sess, serverSessRemIdx);
if (side != NULL) {
if (*side == WOLFSSL_CLIENT_END)
(void)wolfSSL_Atomic_Int_FetchAdd(&clientSessRemCountFree, 1);
else
(void)wolfSSL_Atomic_Int_FetchAdd(&serverSessRemCountFree, 1);
SSL_SESSION_set_ex_data(sess, serverSessRemIdx, NULL);
}
}
static int SessRemCtxSetupCb(WOLFSSL_CTX* ctx)
{
SSL_CTX_sess_set_remove_cb(ctx, SessRemCtxCb);
#if defined(WOLFSSL_TLS13) && !defined(HAVE_SESSION_TICKET) && \
!defined(NO_SESSION_CACHE_REF)
{
EXPECT_DECLS;
/* Allow downgrade, set min version, and disable TLS 1.3.
* Do this because without NO_SESSION_CACHE_REF we will want to return a
* reference to the session cache. But with WOLFSSL_TLS13 and without
* HAVE_SESSION_TICKET we won't have a session ID to be able to place
* the session in the cache. In this case we need to downgrade to
* previous versions to just use the legacy session ID field. */
ExpectIntEQ(SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION),
SSL_SUCCESS);
ExpectIntEQ(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION),
SSL_SUCCESS);
return EXPECT_RESULT();
}
#else
return TEST_SUCCESS;
#endif
}
static int SessRemSslSetupCb(WOLFSSL* ssl)
{
EXPECT_DECLS;
int* side;
if (SSL_is_server(ssl)) {
side = &sessRemCtx_Server;
(void)wolfSSL_Atomic_Int_FetchAdd(&serverSessRemCountMalloc, 1);
ExpectNotNull(serverSess = SSL_get1_session(ssl));
ExpectIntEQ(SSL_CTX_up_ref(serverSessCtx = SSL_get_SSL_CTX(ssl)),
SSL_SUCCESS);
}
else {
side = &sessRemCtx_Client;
(void)wolfSSL_Atomic_Int_FetchAdd(&clientSessRemCountMalloc, 1);
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
!defined(NO_SESSION_CACHE_REF)
ExpectNotNull(clientSess = SSL_get1_session(ssl));
ExpectIntEQ(SSL_CTX_up_ref(clientSessCtx = SSL_get_SSL_CTX(ssl)),
SSL_SUCCESS);
#endif
}
ExpectIntEQ(SSL_SESSION_set_ex_data(SSL_get_session(ssl),
serverSessRemIdx, side), SSL_SUCCESS);
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_CTX_sess_set_remove_cb(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
/* Check that the remove callback gets called for external data in a
* session object */
test_ssl_cbf func_cb;
wolfSSL_Atomic_Int_Init(&clientSessRemCountMalloc, 0);
wolfSSL_Atomic_Int_Init(&serverSessRemCountMalloc, 0);
wolfSSL_Atomic_Int_Init(&clientSessRemCountFree, 0);
wolfSSL_Atomic_Int_Init(&serverSessRemCountFree, 0);
XMEMSET(&func_cb, 0, sizeof(func_cb));
func_cb.ctx_ready = SessRemCtxSetupCb;
func_cb.on_result = SessRemSslSetupCb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb, &func_cb,
NULL), TEST_SUCCESS);
/* Both should have been allocated */
ExpectIntEQ(clientSessRemCountMalloc, 1);
ExpectIntEQ(serverSessRemCountMalloc, 1);
/* This should not be called yet. Session wasn't evicted from cache yet. */
ExpectIntEQ(clientSessRemCountFree, 0);
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
!defined(NO_SESSION_CACHE_REF)
/* Force a cache lookup */
ExpectNotNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
/* Force a cache update */
ExpectNotNull(SSL_SESSION_set_ex_data(clientSess, serverSessRemIdx - 1, 0));
/* This should set the timeout to 0 and call the remove callback from within
* the session cache. */
ExpectIntEQ(SSL_CTX_remove_session(clientSessCtx, clientSess), 0);
ExpectNull(SSL_SESSION_get_ex_data(clientSess, serverSessRemIdx));
ExpectIntEQ(clientSessRemCountFree, 1);
#endif
/* Server session is in the cache so ex_data isn't free'd with the SSL
* object */
ExpectIntEQ(serverSessRemCountFree, 0);
/* Force a cache lookup */
ExpectNotNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
/* Force a cache update */
ExpectNotNull(SSL_SESSION_set_ex_data(serverSess, serverSessRemIdx - 1, 0));
/* This should set the timeout to 0 and call the remove callback from within
* the session cache. */
ExpectIntEQ(SSL_CTX_remove_session(serverSessCtx, serverSess), 0);
ExpectNull(SSL_SESSION_get_ex_data(serverSess, serverSessRemIdx));
ExpectIntEQ(serverSessRemCountFree, 1);
/* Need to free the references that we kept */
SSL_CTX_free(serverSessCtx);
SSL_SESSION_free(serverSess);
#if (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)) || \
!defined(NO_SESSION_CACHE_REF)
SSL_CTX_free(clientSessCtx);
SSL_SESSION_free(clientSess);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_ticket_keys(void)
{
EXPECT_DECLS;
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
!defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
byte keys[WOLFSSL_TICKET_KEYS_SZ];
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, 0),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, NULL, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, NULL, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(NULL, keys, sizeof(keys)),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_CTX_get_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_tlsext_ticket_keys(ctx, keys, sizeof(keys)),
WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#ifndef NO_BIO
static int test_wolfSSL_d2i_PUBKEY(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
BIO* bio = NULL;
EVP_PKEY* pkey = NULL;
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectNull(d2i_PUBKEY_bio(NULL, NULL));
#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
/* RSA PUBKEY test */
ExpectIntGT(BIO_write(bio, client_keypub_der_2048,
sizeof_client_keypub_der_2048), 0);
ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#if defined(USE_CERT_BUFFERS_256) && defined(HAVE_ECC)
/* ECC PUBKEY test */
ExpectIntGT(BIO_write(bio, ecc_clikeypub_der_256,
sizeof_ecc_clikeypub_der_256), 0);
ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DSA)
/* DSA PUBKEY test */
ExpectIntGT(BIO_write(bio, dsa_pub_key_der_2048,
sizeof_dsa_pub_key_der_2048), 0);
ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif
#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DH) && \
defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
(HAVE_FIPS_VERSION > 2))
/* DH PUBKEY test */
ExpectIntGT(BIO_write(bio, dh_pub_key_der_2048,
sizeof_dh_pub_key_der_2048), 0);
ExpectNotNull(pkey = d2i_PUBKEY_bio(bio, NULL));
EVP_PKEY_free(pkey);
pkey = NULL;
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* USE_CERT_BUFFERS_2048 && !NO_DH && && OPENSSL_EXTRA */
BIO_free(bio);
(void)pkey;
#endif
return EXPECT_RESULT();
}
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA) && \
!defined(NO_TLS)
static int test_wolfSSL_d2i_PrivateKeys_bio(void)
{
EXPECT_DECLS;
BIO* bio = NULL;
EVP_PKEY* pkey = NULL;
WOLFSSL_CTX* ctx = NULL;
#if defined(WOLFSSL_KEY_GEN)
unsigned char buff[4096];
unsigned char* bufPtr = buff;
#endif
/* test creating new EVP_PKEY with bad arg */
ExpectNull((pkey = d2i_PrivateKey_bio(NULL, NULL)));
/* test loading RSA key using BIO */
#if !defined(NO_RSA) && !defined(NO_FILESYSTEM)
{
XFILE file = XBADFILE;
const char* fname = "./certs/server-key.der";
long lsz = 0;
size_t sz = 0;
byte* buf = NULL;
ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
ExpectTrue((lsz = XFTELL(file)) > 0);
sz = (size_t)lsz;
ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
ExpectNotNull(buf = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_FILE));
ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
if (file != XBADFILE) {
XFCLOSE(file);
}
/* Test using BIO new mem and loading DER private key */
ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
ExpectNotNull((pkey = d2i_PrivateKey_bio(bio, NULL)));
XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_FILE);
BIO_free(bio);
bio = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
}
#endif
/* test loading ECC key using BIO */
#if defined(HAVE_ECC) && !defined(NO_FILESYSTEM)
{
XFILE file = XBADFILE;
const char* fname = "./certs/ecc-key.der";
long lsz = 0;
size_t sz = 0;
byte* buf = NULL;
ExpectTrue((file = XFOPEN(fname, "rb")) != XBADFILE);
ExpectTrue(XFSEEK(file, 0, XSEEK_END) == 0);
ExpectTrue((lsz = XFTELL(file)) > 0);
sz = (size_t)lsz;
ExpectTrue(XFSEEK(file, 0, XSEEK_SET) == 0);
ExpectNotNull(buf = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_FILE));
ExpectIntEQ(XFREAD(buf, 1, sz, file), sz);
if (file != XBADFILE)
XFCLOSE(file);
/* Test using BIO new mem and loading DER private key */
ExpectNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
ExpectNotNull((pkey = d2i_PrivateKey_bio(bio, NULL)));
XFREE(buf, HEAP_HINT, DYNAMIC_TYPE_FILE);
BIO_free(bio);
bio = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
}
#endif
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
#ifndef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
#else
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method()));
#endif
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
{
const unsigned char seqOnly[] = { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 };
RSA* rsa = NULL;
/* Tests bad parameters */
ExpectNull(d2i_RSAPrivateKey_bio(NULL, NULL));
/* Test using bad data. */
ExpectIntGT(BIO_write(bio, seqOnly, sizeof(seqOnly)), 0);
ExpectNull(d2i_RSAPrivateKey_bio(bio, NULL));
/* RSA not set yet, expecting to fail*/
rsa = wolfSSL_RSA_new();
ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_RSA_free(rsa);
rsa = NULL;
#if defined(USE_CERT_BUFFERS_2048) && defined(WOLFSSL_KEY_GEN)
/* set RSA using bio*/
ExpectIntGT(BIO_write(bio, client_key_der_2048,
sizeof_client_key_der_2048), 0);
ExpectNotNull(d2i_RSAPrivateKey_bio(bio, &rsa));
ExpectNotNull(rsa);
/* Tests bad parameters */
ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(NULL, rsa), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WOLFSSL_SUCCESS);
/* i2d RSAprivate key tests */
ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(NULL, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 1192);
ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr),
sizeof_client_key_der_2048);
bufPtr -= sizeof_client_key_der_2048;
ExpectIntEQ(XMEMCMP(bufPtr, client_key_der_2048,
sizeof_client_key_der_2048), 0);
bufPtr = NULL;
ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr),
sizeof_client_key_der_2048);
ExpectNotNull(bufPtr);
ExpectIntEQ(XMEMCMP(bufPtr, client_key_der_2048,
sizeof_client_key_der_2048), 0);
XFREE(bufPtr, NULL, DYNAMIC_TYPE_OPENSSL);
RSA_free(rsa);
rsa = NULL;
ExpectIntGT(BIO_write(bio, client_key_der_2048,
sizeof_client_key_der_2048), 0);
ExpectNotNull(d2i_RSA_PUBKEY_bio(bio, &rsa));
(void)BIO_reset(bio);
RSA_free(rsa);
rsa = RSA_new();
ExpectIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 0);
#endif /* USE_CERT_BUFFERS_2048 WOLFSSL_KEY_GEN */
RSA_free(rsa);
}
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
SSL_CTX_free(ctx);
ctx = NULL;
BIO_free(bio);
bio = NULL;
return EXPECT_RESULT();
}
#endif /* OPENSSL_ALL || (WOLFSSL_ASIO && !NO_RSA) */
#endif /* !NO_BIO */
static int test_wolfSSL_sk_GENERAL_NAME(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA)
X509* x509 = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAME* dup_gn = NULL;
unsigned char buf[4096];
const unsigned char* bufPt = NULL;
int bytes = 0;
int i;
int j;
XFILE f = XBADFILE;
STACK_OF(GENERAL_NAME)* sk = NULL;
ExpectTrue((f = XFOPEN(cliCertDerFileExt, "rb")) != XBADFILE);
ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
if (f != XBADFILE)
XFCLOSE(f);
for (j = 0; j < 2; ++j) {
bufPt = buf;
ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));
ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
NID_subject_alt_name, NULL, NULL));
ExpectIntEQ(sk_GENERAL_NAME_num(sk), 1);
for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) {
ExpectNotNull(gn = sk_GENERAL_NAME_value(sk, i));
if (gn != NULL) {
switch (gn->type) {
case GEN_DNS:
fprintf(stderr, "found type GEN_DNS\n");
break;
case GEN_EMAIL:
fprintf(stderr, "found type GEN_EMAIL\n");
break;
case GEN_URI:
fprintf(stderr, "found type GEN_URI\n");
break;
}
}
ExpectNotNull(dup_gn = wolfSSL_GENERAL_NAME_dup(gn));
wolfSSL_GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
}
X509_free(x509);
x509 = NULL;
if (j == 0) {
sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free);
}
else {
/*
* We had a bug where GENERAL_NAMES_free didn't free all the memory
* it was supposed to. This is a regression test for that bug.
*/
GENERAL_NAMES_free(sk);
}
sk = NULL;
}
ExpectNull(wolfSSL_GENERAL_NAME_dup(NULL));
ExpectIntEQ(wolfSSL_GENERAL_NAME_set_type(NULL, WOLFSSL_GEN_IA5),
BAD_FUNC_ARG);
wolfSSL_GENERAL_NAMES_free(NULL);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_GENERAL_NAME_print(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_BIO) && !defined(NO_RSA)
X509* x509 = NULL;
GENERAL_NAME* gn = NULL;
GENERAL_NAME* dup_gn = NULL;
unsigned char buf[4096];
const unsigned char* bufPt = NULL;
int bytes = 0;
XFILE f = XBADFILE;
STACK_OF(GENERAL_NAME)* sk = NULL;
BIO* out = NULL;
unsigned char outbuf[128];
X509_EXTENSION* ext = NULL;
AUTHORITY_INFO_ACCESS* aia = NULL;
ACCESS_DESCRIPTION* ad = NULL;
ASN1_IA5STRING *dnsname = NULL;
ASN1_OBJECT* ridObj = NULL;
const unsigned char v4Addr[] = {192,168,53,1};
const unsigned char v6Addr[] =
{0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77};
const unsigned char email[] =
{'i', 'n', 'f', 'o', '@', 'w', 'o', 'l',
'f', 's', 's', 'l', '.', 'c', 'o', 'm'};
const unsigned char ridData[] = { 0x06, 0x04, 0x2a, 0x03, 0x04, 0x05 };
const unsigned char* p;
unsigned long len;
const char* dnsStr = "DNS:example.com";
const char* uriStr = "URI:http://127.0.0.1:22220";
const char* v4addStr = "IP Address:192.168.53.1";
const char* v6addStr = "IP Address:2021:DB8:0:0:0:FF00:42:7777";
const char* emailStr = "email:info@wolfssl.com";
const char* othrStr = "othername:<unsupported>";
const char* x400Str = "X400Name:<unsupported>";
const char* ediStr = "EdiPartyName:<unsupported>";
const char* dirNameStr = "DirName:";
const char* ridStr = "Registered ID:1.2.3.4.5";
/* BIO to output */
ExpectNotNull(out = BIO_new(BIO_s_mem()));
/* test for NULL param */
gn = NULL;
ExpectIntEQ(GENERAL_NAME_print(NULL, NULL), 0);
ExpectIntEQ(GENERAL_NAME_print(NULL, gn), 0);
ExpectIntEQ(GENERAL_NAME_print(out, NULL), 0);
/* test for GEN_DNS */
ExpectTrue((f = XFOPEN(cliCertDerFileExt, "rb")) != XBADFILE);
ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
bufPt = buf;
ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));
ExpectNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509,
NID_subject_alt_name, NULL, NULL));
ExpectNotNull(gn = sk_GENERAL_NAME_value(sk, 0));
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf, 0, sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, dnsStr, XSTRLEN(dnsStr)), 0);
sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free);
gn = NULL;
sk = NULL;
X509_free(x509);
x509 = NULL;
/* Lets test for setting as well. */
ExpectNotNull(gn = GENERAL_NAME_new());
ExpectNotNull(dnsname = ASN1_IA5STRING_new());
ExpectIntEQ(ASN1_STRING_set(dnsname, "example.com", -1), 1);
GENERAL_NAME_set0_value(gn, GEN_DNS, dnsname);
dnsname = NULL;
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf, 0, sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, dnsStr, XSTRLEN(dnsStr)), 0);
ExpectNotNull(dup_gn = GENERAL_NAME_dup(gn));
wolfSSL_GENERAL_NAME_set0_value(NULL, WOLFSSL_GEN_IA5, NULL);
wolfSSL_GENERAL_NAME_set0_value(dup_gn, WOLFSSL_GEN_IA5, NULL);
wolfSSL_GENERAL_NAME_set0_value(NULL, WOLFSSL_GEN_DNS, NULL);
wolfSSL_GENERAL_NAME_set0_value(NULL, WOLFSSL_GEN_IA5, outbuf);
wolfSSL_GENERAL_NAME_set0_value(dup_gn, WOLFSSL_GEN_DNS, NULL);
wolfSSL_GENERAL_NAME_set0_value(dup_gn, WOLFSSL_GEN_IA5, outbuf);
wolfSSL_GENERAL_NAME_set0_value(NULL, WOLFSSL_GEN_DNS, outbuf);
GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
GENERAL_NAME_free(gn);
/* test for GEN_URI */
ExpectTrue((f = XFOPEN("./certs/ocsp/root-ca-cert.pem", "rb")) != XBADFILE);
ExpectNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL));
if (f != XBADFILE) {
XFCLOSE(f);
f = XBADFILE;
}
ExpectNotNull(ext = wolfSSL_X509_get_ext(x509, 4));
ExpectNotNull(aia = (WOLFSSL_AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(
ext));
ExpectNotNull(ad = (WOLFSSL_ACCESS_DESCRIPTION *)wolfSSL_sk_value(aia, 0));
if (ad != NULL) {
gn = ad->location;
}
ExpectNotNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
gn = NULL;
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, uriStr, XSTRLEN(uriStr)), 0);
wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL);
aia = NULL;
aia = (AUTHORITY_INFO_ACCESS*)wolfSSL_X509V3_EXT_d2i(ext);
ExpectNotNull(aia);
AUTHORITY_INFO_ACCESS_pop_free(aia, NULL);
aia = NULL;
X509_free(x509);
x509 = NULL;
/* test for GEN_IPADD */
/* ip v4 address */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_IPADD;
if (gn->d.iPAddress != NULL) {
gn->d.iPAddress->length = sizeof(v4Addr);
}
}
ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v4Addr,
sizeof(v4Addr)), 1);
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, v4addStr, XSTRLEN(v4addStr)), 0);
ExpectNotNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
GENERAL_NAME_free(gn);
gn = NULL;
/* ip v6 address */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_IPADD;
if (gn->d.iPAddress != NULL) {
gn->d.iPAddress->length = sizeof(v6Addr);
}
}
ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.iPAddress, v6Addr,
sizeof(v6Addr)), 1);
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, v6addStr, XSTRLEN(v6addStr)), 0);
ExpectNotNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_EMAIL */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_EMAIL;
if (gn->d.rfc822Name != NULL) {
gn->d.rfc822Name->length = sizeof(email);
}
}
ExpectIntEQ(wolfSSL_ASN1_STRING_set(gn->d.rfc822Name, email, sizeof(email)),
1);
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, emailStr, XSTRLEN(emailStr)), 0);
ExpectNotNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(dup_gn);
dup_gn = NULL;
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_OTHERNAME */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_OTHERNAME;
}
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, othrStr, XSTRLEN(othrStr)), 0);
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_X400 */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_X400;
}
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, x400Str, XSTRLEN(x400Str)), 0);
/* Restore to GEN_IA5 (default) to avoid memory leak. */
if (gn != NULL) {
gn->type = GEN_IA5;
}
/* Duplicating GEN_X400 not supported. */
ExpectNull(GENERAL_NAME_dup(gn));
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_EDIPARTY */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_EDIPARTY;
}
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, ediStr, XSTRLEN(ediStr)), 0);
/* Restore to GEN_IA5 (default) to avoid memory leak. */
if (gn != NULL) {
gn->type = GEN_IA5;
}
/* Duplicating GEN_EDIPARTY not supported. */
ExpectNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_DIRNAME */
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_DIRNAME;
}
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, dirNameStr, XSTRLEN(dirNameStr)),
0);
/* Duplicating GEN_DIRNAME not supported. */
ExpectNull(dup_gn = GENERAL_NAME_dup(gn));
/* Restore to GEN_IA5 (default) to avoid memory leak. */
if (gn != NULL) {
gn->type = GEN_IA5;
}
GENERAL_NAME_free(gn);
gn = NULL;
/* test for GEN_RID */
p = ridData;
len = sizeof(ridData);
ExpectNotNull(ridObj = wolfSSL_d2i_ASN1_OBJECT(NULL, &p, len));
ExpectNotNull(gn = wolfSSL_GENERAL_NAME_new());
if (gn != NULL) {
gn->type = GEN_RID;
wolfSSL_ASN1_STRING_free(gn->d.ia5);
gn->d.registeredID = ridObj;
}
else {
wolfSSL_ASN1_OBJECT_free(ridObj);
}
ExpectIntEQ(GENERAL_NAME_print(out, gn), 1);
XMEMSET(outbuf,0,sizeof(outbuf));
ExpectIntGT(BIO_read(out, outbuf, sizeof(outbuf)), 0);
ExpectIntEQ(XSTRNCMP((const char*)outbuf, ridStr, XSTRLEN(ridStr)), 0);
/* Duplicating GEN_DIRNAME not supported. */
ExpectNull(dup_gn = GENERAL_NAME_dup(gn));
GENERAL_NAME_free(gn);
gn = NULL;
BIO_free(out);
#endif /* OPENSSL_ALL */
return EXPECT_RESULT();
}
static int test_wolfSSL_sk_DIST_POINT(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
!defined(NO_RSA)
X509* x509 = NULL;
unsigned char buf[4096];
const unsigned char* bufPt;
int bytes = 0;
int i = 0;
int j = 0;
XFILE f = XBADFILE;
DIST_POINT* dp = NULL;
DIST_POINT_NAME* dpn = NULL;
GENERAL_NAME* gn = NULL;
ASN1_IA5STRING* uri = NULL;
STACK_OF(DIST_POINT)* dps = NULL;
STACK_OF(GENERAL_NAME)* gns = NULL;
const char cliCertDerCrlDistPoint[] = "./certs/client-crl-dist.der";
ExpectTrue((f = XFOPEN(cliCertDerCrlDistPoint, "rb")) != XBADFILE);
ExpectIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0);
if (f != XBADFILE)
XFCLOSE(f);
bufPt = buf;
ExpectNotNull(x509 = d2i_X509(NULL, &bufPt, bytes));
ExpectNotNull(dps = (STACK_OF(DIST_POINT)*)X509_get_ext_d2i(x509,
NID_crl_distribution_points, NULL, NULL));
ExpectIntEQ(sk_DIST_POINT_num(dps), 1);
for (i = 0; i < sk_DIST_POINT_num(dps); i++) {
ExpectNotNull(dp = sk_DIST_POINT_value(dps, i));
ExpectNotNull(dpn = dp->distpoint);
/* this should be type 0, fullname */
ExpectIntEQ(dpn->type, 0);
ExpectNotNull(gns = dp->distpoint->name.fullname);
ExpectIntEQ(sk_GENERAL_NAME_num(gns), 1);
for (j = 0; j < sk_GENERAL_NAME_num(gns); j++) {
ExpectNotNull(gn = sk_GENERAL_NAME_value(gns, j));
ExpectIntEQ(gn->type, GEN_URI);
ExpectNotNull(uri = gn->d.uniformResourceIdentifier);
ExpectNotNull(uri->data);
ExpectIntGT(uri->length, 0);
}
}
ExpectNotNull(dp = wolfSSL_DIST_POINT_new());
wolfSSL_DIST_POINT_free(NULL);
wolfSSL_DIST_POINTS_free(NULL);
wolfSSL_sk_DIST_POINT_free(NULL);
ExpectIntEQ(wolfSSL_sk_DIST_POINT_push(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_DIST_POINT_push(dps, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_sk_DIST_POINT_push(NULL, dp), WOLFSSL_FAILURE);
ExpectNull(wolfSSL_sk_DIST_POINT_value(NULL, 0));
ExpectIntEQ(wolfSSL_sk_DIST_POINT_num(NULL), WOLFSSL_FATAL_ERROR);
wolfSSL_DIST_POINT_free(dp);
X509_free(x509);
CRL_DIST_POINTS_free(dps);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_verify_mode(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_TLS) && (defined(OPENSSL_ALL) || \
defined(HAVE_STUNNEL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY))
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
SSL_free(ssl);
ssl = NULL;
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_PEER);
wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, 0);
ExpectIntEQ(SSL_CTX_get_verify_mode(ctx), SSL_VERIFY_PEER);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_NONE);
SSL_free(ssl);
ssl = NULL;
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_CTX_get_verify_mode(ctx));
ExpectIntEQ(SSL_get_verify_mode(ssl),
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);
wolfSSL_set_verify(ssl, SSL_VERIFY_PEER, 0);
ExpectIntEQ(SSL_CTX_get_verify_mode(ctx),
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_PEER);
wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, 0);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_NONE);
wolfSSL_set_verify(ssl, SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
wolfSSL_set_verify(ssl, SSL_VERIFY_FAIL_EXCEPT_PSK, 0);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_FAIL_EXCEPT_PSK);
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
wolfSSL_set_verify(ssl, SSL_VERIFY_POST_HANDSHAKE, 0);
ExpectIntEQ(SSL_get_verify_mode(ssl), SSL_VERIFY_POST_HANDSHAKE);
#endif
ExpectIntEQ(SSL_CTX_get_verify_mode(ctx),
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT);
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_verify_depth(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
long depth = 0;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntGT((depth = SSL_CTX_get_verify_depth(ctx)), 0);
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_get_verify_depth(ssl), SSL_CTX_get_verify_depth(ctx));
SSL_free(ssl);
ssl = NULL;
SSL_CTX_set_verify_depth(ctx, -1);
ExpectIntEQ(depth, SSL_CTX_get_verify_depth(ctx));
SSL_CTX_set_verify_depth(ctx, 2);
ExpectIntEQ(2, SSL_CTX_get_verify_depth(ctx));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(2, SSL_get_verify_depth(ssl));
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_verify_result(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(OPENSSL_ALL)) && !defined(NO_TLS) && !defined(NO_WOLFSSL_CLIENT)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
long result = 0xDEADBEEF;
ExpectIntEQ(WC_NO_ERR_TRACE(WOLFSSL_FAILURE), wolfSSL_get_verify_result(ssl));
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = SSL_new(ctx));
wolfSSL_set_verify_result(ssl, result);
ExpectIntEQ(result, wolfSSL_get_verify_result(ssl));
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
static void sslMsgCb(int w, int version, int type, const void* buf,
size_t sz, SSL* ssl, void* arg)
{
int i;
unsigned char* pt = (unsigned char*)buf;
fprintf(stderr, "%s %d bytes of version %d , type %d : ",
(w)?"Writing":"Reading", (int)sz, version, type);
for (i = 0; i < (int)sz; i++) fprintf(stderr, "%02X", pt[i]);
fprintf(stderr, "\n");
(void)ssl;
(void)arg;
}
#endif /* OPENSSL_EXTRA */
static int test_wolfSSL_msg_callback(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_WOLFSSL_CLIENT)
WOLFSSL* ssl = NULL;
WOLFSSL_CTX* ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_set_msg_callback(ssl, NULL), SSL_SUCCESS);
ExpectIntEQ(SSL_set_msg_callback(ssl, &sslMsgCb), SSL_SUCCESS);
ExpectIntEQ(SSL_set_msg_callback(NULL, &sslMsgCb), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_SEP(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(WOLFSSL_SEP)
WOLFSSL_X509* x509 = NULL;
#if 0
byte* out;
#endif
int outSz;
ExpectNotNull(x509 = wolfSSL_X509_new());
outSz = 0;
ExpectNull(wolfSSL_X509_get_device_type(NULL, NULL, NULL));
ExpectNull(wolfSSL_X509_get_device_type(x509, NULL, NULL));
ExpectNull(wolfSSL_X509_get_device_type(NULL, NULL, &outSz));
ExpectNull(wolfSSL_X509_get_device_type(x509, NULL, &outSz));
outSz = 0;
ExpectNull(wolfSSL_X509_get_hw_type(NULL, NULL, NULL));
ExpectNull(wolfSSL_X509_get_hw_type(x509, NULL, NULL));
ExpectNull(wolfSSL_X509_get_hw_type(NULL, NULL, &outSz));
ExpectNull(wolfSSL_X509_get_hw_type(x509, NULL, &outSz));
outSz = 0;
ExpectNull(wolfSSL_X509_get_hw_serial_number(NULL, NULL, NULL));
ExpectNull(wolfSSL_X509_get_hw_serial_number(x509, NULL, NULL));
ExpectNull(wolfSSL_X509_get_hw_serial_number(NULL, NULL, &outSz));
ExpectNull(wolfSSL_X509_get_hw_serial_number(x509, NULL, &outSz));
ExpectIntEQ(wolfSSL_X509_ext_isSet_by_NID(x509,
WC_NID_certificate_policies), 0);
wolfSSL_X509_free(x509);
x509 = NULL;
#if 0
/* Use certificate with the extension here. */
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
SSL_FILETYPE_PEM));
outSz = 0;
ExpectNotNull(out = wolfSSL_X509_get_device_type(x509, NULL, &outSz));
ExpectIntGT(outSz, 0);
XFREE(out, NULL, DYNAMIC_TYPE_OPENSSL);
outSz = 0;
ExpectNotNull(out = wolfSSL_X509_get_hw_type(x509, NULL, &outSz));
ExpectIntGT(outSz, 0);
XFREE(out, NULL, DYNAMIC_TYPE_OPENSSL);
outSz = 0;
ExpectNotNull(out = wolfSSL_X509_get_hw_serial_number(x509, NULL, &outSz));
ExpectIntGT(outSz, 0);
XFREE(out, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL_X509_free(x509);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OpenSSL_add_all_algorithms(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
ExpectIntEQ(wolfSSL_add_all_algorithms(), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_OpenSSL_add_all_algorithms_noconf(), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_OpenSSL_add_all_algorithms_conf(), WOLFSSL_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OPENSSL_hexstr2buf(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#define MAX_HEXSTR_BUFSZ 9
#define NUM_CASES 5
struct Output {
const unsigned char buffer[MAX_HEXSTR_BUFSZ];
long ret;
};
int i;
int j;
const char* inputs[NUM_CASES] = {
"aabcd1357e",
"01:12:23:34:a5:b6:c7:d8:e9",
":01:02",
"012",
":ab:ac:d"
};
struct Output expectedOutputs[NUM_CASES] = {
{{0xaa, 0xbc, 0xd1, 0x35, 0x7e}, 5},
{{0x01, 0x12, 0x23, 0x34, 0xa5, 0xb6, 0xc7, 0xd8, 0xe9}, 9},
{{0x01, 0x02}, 2},
{{0x00}, 0},
{{0x00}, 0}
};
long len = 0;
unsigned char* returnedBuf = NULL;
for (i = 0; i < NUM_CASES && !EXPECT_FAIL(); ++i) {
returnedBuf = wolfSSL_OPENSSL_hexstr2buf(inputs[i], &len);
if (returnedBuf == NULL) {
ExpectIntEQ(expectedOutputs[i].ret, 0);
continue;
}
ExpectIntEQ(expectedOutputs[i].ret, len);
for (j = 0; j < len; ++j) {
ExpectIntEQ(expectedOutputs[i].buffer[j], returnedBuf[j]);
}
OPENSSL_free(returnedBuf);
}
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_ALL)
static int test_wolfSSL_sk_CIPHER_description(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_TLS)
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION;
int i;
int numCiphers = 0;
const SSL_METHOD *method = NULL;
const SSL_CIPHER *cipher = NULL;
STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
char buf[256];
char test_str[9] = "0000000";
const char badStr[] = "unknown";
const char certPath[] = "./certs/client-cert.pem";
XMEMSET(buf, 0, sizeof(buf));
ExpectNotNull(method = TLSv1_2_client_method());
ExpectNotNull(ctx = SSL_CTX_new(method));
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
SSL_CTX_set_verify_depth(ctx, 4);
SSL_CTX_set_options(ctx, flags);
ExpectIntEQ(SSL_CTX_load_verify_locations(ctx, certPath, NULL),
WOLFSSL_SUCCESS);
ExpectNotNull(ssl = SSL_new(ctx));
/* SSL_get_ciphers returns a stack of all configured ciphers
* A flag, getCipherAtOffset, is set to later have SSL_CIPHER_description
*/
ExpectNotNull(supportedCiphers = SSL_get_ciphers(ssl));
/* loop through the amount of supportedCiphers */
numCiphers = sk_num(supportedCiphers);
for (i = 0; i < numCiphers; ++i) {
int j;
/* sk_value increments "sk->data.cipher->cipherOffset".
* wolfSSL_sk_CIPHER_description sets the description for
* the cipher based on the provided offset.
*/
if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
SSL_CIPHER_description(cipher, buf, sizeof(buf));
}
/* Search cipher description string for "unknown" descriptor */
for (j = 0; j < (int)XSTRLEN(buf); j++) {
int k = 0;
while ((k < (int)XSTRLEN(badStr)) && (buf[j] == badStr[k])) {
test_str[k] = badStr[k];
j++;
k++;
}
}
/* Fail if test_str == badStr == "unknown" */
ExpectStrNE(test_str,badStr);
}
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_get_ciphers_compat(void)
{
EXPECT_DECLS;
#if !defined(NO_RSA) && !defined(NO_TLS)
const SSL_METHOD *method = NULL;
const char certPath[] = "./certs/client-cert.pem";
STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
SSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION;
ExpectNotNull(method = SSLv23_client_method());
ExpectNotNull(ctx = SSL_CTX_new(method));
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
SSL_CTX_set_verify_depth(ctx, 4);
SSL_CTX_set_options(ctx, flags);
ExpectIntEQ(SSL_CTX_load_verify_locations(ctx, certPath, NULL),
WOLFSSL_SUCCESS);
ExpectNotNull(ssl = SSL_new(ctx));
/* Test Bad NULL input */
ExpectNull(supportedCiphers = SSL_get_ciphers(NULL));
/* Test for Good input */
ExpectNotNull(supportedCiphers = SSL_get_ciphers(ssl));
/* Further usage of SSL_get_ciphers/wolfSSL_get_ciphers_compat is
* tested in test_wolfSSL_sk_CIPHER_description according to Qt usage */
SSL_free(ssl);
SSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_ctrl(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_TLS) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_WOLFSSL_SERVER)
char caFile[] = "./certs/client-ca.pem";
char clientFile[] = "./certs/client-cert.pem";
SSL_CTX* ctx = NULL;
X509* x509 = NULL;
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
byte buf[6000];
char file[] = "./certs/dsaparams.pem";
XFILE f = XBADFILE;
int bytes = 0;
BIO* bio = NULL;
DSA* dsa = NULL;
DH* dh = NULL;
#endif
#ifdef HAVE_ECC
WOLFSSL_EC_KEY* ecKey = NULL;
#endif
ExpectNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method()));
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(caFile,
WOLFSSL_FILETYPE_PEM));
ExpectIntEQ((int)SSL_CTX_add_extra_chain_cert(ctx, x509), WOLFSSL_SUCCESS);
if (EXPECT_FAIL()) {
wolfSSL_X509_free(x509);
}
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
WOLFSSL_FILETYPE_PEM));
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
/* Initialize DH */
ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
if (f != XBADFILE)
XFCLOSE(f);
ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
ExpectNotNull(dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL));
ExpectNotNull(dh = wolfSSL_DSA_dup_DH(dsa));
#endif
#ifdef HAVE_ECC
/* Initialize WOLFSSL_EC_KEY */
ExpectNotNull(ecKey = wolfSSL_EC_KEY_new());
ExpectIntEQ(wolfSSL_EC_KEY_generate_key(ecKey), 1);
#endif
/* additional test of getting EVP_PKEY key size from X509
* Do not run with user RSA because wolfSSL_RSA_size is not currently
* allowed with user RSA */
{
EVP_PKEY* pkey = NULL;
#if defined(HAVE_ECC)
X509* ecX509 = NULL;
#endif /* HAVE_ECC */
ExpectNotNull(pkey = X509_get_pubkey(x509));
/* current RSA key is 2048 bit (256 bytes) */
ExpectIntEQ(EVP_PKEY_size(pkey), 256);
EVP_PKEY_free(pkey);
pkey = NULL;
#if defined(HAVE_ECC)
#if defined(USE_CERT_BUFFERS_256)
ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_buffer(
cliecc_cert_der_256, sizeof_cliecc_cert_der_256,
SSL_FILETYPE_ASN1));
#else
ExpectNotNull(ecX509 = wolfSSL_X509_load_certificate_file(
cliEccCertFile, SSL_FILETYPE_PEM));
#endif
ExpectNotNull(pkey = X509_get_pubkey(ecX509));
/* current ECC key is 256 bit (32 bytes) */
ExpectIntGE(EVP_PKEY_size(pkey), 72);
X509_free(ecX509);
EVP_PKEY_free(pkey);
#endif /* HAVE_ECC */
}
/* Tests should fail with passed in NULL pointer */
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if !defined(NO_DH) && !defined(NO_DSA)
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#ifdef HAVE_ECC
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
/* Test with SSL_CTRL_EXTRA_CHAIN_CERT
* wolfSSL_CTX_ctrl should succesffuly call SSL_CTX_add_extra_chain_cert
*/
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509),
SSL_SUCCESS);
if (EXPECT_FAIL()) {
wolfSSL_X509_free(x509);
}
/* Test with SSL_CTRL_OPTIONS
* wolfSSL_CTX_ctrl should succesffuly call SSL_CTX_set_options
*/
ExpectTrue(wolfSSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, SSL_OP_NO_TLSv1,
NULL) == SSL_OP_NO_TLSv1);
ExpectTrue(SSL_CTX_get_options(ctx) == SSL_OP_NO_TLSv1);
/* Test with SSL_CTRL_SET_TMP_DH
* wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_dh
*/
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh),
SSL_SUCCESS);
#endif
/* Test with SSL_CTRL_SET_TMP_ECDH
* wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_ecdh
*/
#ifdef HAVE_ECC
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, ecKey),
SSL_SUCCESS);
#endif
#ifdef WOLFSSL_ENCRYPTED_KEYS
ExpectNull(SSL_CTX_get_default_passwd_cb(ctx));
ExpectNull(SSL_CTX_get_default_passwd_cb_userdata(ctx));
#endif
/* Test for min/max proto */
#ifndef WOLFSSL_NO_TLS12
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION,
0, NULL), SSL_SUCCESS);
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION,
TLS1_2_VERSION, NULL), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_2_VERSION);
#endif
#ifdef WOLFSSL_TLS13
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
0, NULL), SSL_SUCCESS);
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
TLS1_3_VERSION, NULL), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_3_VERSION);
#ifndef WOLFSSL_NO_TLS12
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION,
TLS1_2_VERSION, NULL), SSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx), TLS1_2_VERSION);
#endif
#endif
/* Cleanup and Pass */
#if !defined(NO_DH) && !defined(NO_DSA)
#ifndef NO_BIO
BIO_free(bio);
DSA_free(dsa);
DH_free(dh);
dh = NULL;
#endif
#endif
#ifdef HAVE_ECC
wolfSSL_EC_KEY_free(ecKey);
#endif
SSL_CTX_free(ctx);
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
* !defined(NO_FILESYSTEM) && !defined(NO_RSA) */
return EXPECT_RESULT();
}
#if !defined(NO_BIO)
static word32 TXT_DB_hash(const WOLFSSL_STRING *s)
{
return (word32)lh_strhash(s[3]);
}
static int TXT_DB_cmp(const WOLFSSL_STRING *a, const WOLFSSL_STRING *b)
{
return XSTRCMP(a[3], b[3]);
}
#endif
static int test_wolfSSL_TXT_DB(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_BIO)
BIO *bio = NULL;
TXT_DB *db = NULL;
const int columns = 6;
const char *fields[6] = {
"V",
"320926161116Z",
"",
"12BD",
"unknown",
"/CN=rsa doe",
};
char** fields_copy = NULL;
/* Test read */
ExpectNotNull(bio = BIO_new(BIO_s_file()));
ExpectIntGT(BIO_read_filename(bio, "./tests/TXT_DB.txt"), 0);
ExpectNotNull(db = TXT_DB_read(bio, columns));
ExpectNotNull(fields_copy = (char**)XMALLOC(sizeof(fields), NULL,
DYNAMIC_TYPE_OPENSSL));
if (fields_copy != NULL) {
XMEMCPY(fields_copy, fields, sizeof(fields));
}
ExpectIntEQ(TXT_DB_insert(db, fields_copy), 1);
if (EXPECT_FAIL()) {
XFREE(fields_copy, NULL, DYNAMIC_TYPE_OPENSSL);
}
BIO_free(bio);
bio = NULL;
/* Test write */
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(TXT_DB_write(bio, db), 1484);
BIO_free(bio);
/* Test index */
ExpectIntEQ(TXT_DB_create_index(db, 3, NULL,
(wolf_sk_hash_cb)(wc_ptr_t)TXT_DB_hash,
(wolf_lh_compare_cb)TXT_DB_cmp), 1);
ExpectNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
fields[3] = "12DA";
ExpectNotNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
fields[3] = "FFFF";
ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
fields[3] = "";
ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
TXT_DB_free(db);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_NCONF(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_BIO)
const char* confFile = "./tests/NCONF_test.cnf";
CONF* conf = NULL;
long eline = 0;
long num = 0;
ExpectNotNull(conf = NCONF_new(NULL));
ExpectIntEQ(NCONF_load(conf, confFile, &eline), 1);
ExpectIntEQ(NCONF_get_number(conf, NULL, "port", &num), 1);
ExpectIntEQ(num, 1234);
ExpectIntEQ(NCONF_get_number(conf, "section2", "port", &num), 1);
ExpectIntEQ(num, 4321);
ExpectStrEQ(NCONF_get_string(conf, NULL, "dir"), "./test-dir");
ExpectStrEQ(NCONF_get_string(conf, "section1", "file1_copy"),
"./test-dir/file1");
ExpectStrEQ(NCONF_get_string(conf, "section2", "file_list"),
"./test-dir/file1:./test-dir/file2:./section1:file2");
NCONF_free(conf);
#endif
return EXPECT_RESULT();
}
#endif /* OPENSSL_ALL */
static int test_wolfSSL_d2i_and_i2d_PublicKey(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA)
EVP_PKEY* pkey = NULL;
const unsigned char* p = NULL;
unsigned char *der = NULL;
unsigned char *tmp = NULL;
int derLen = 0;
p = client_keypub_der_2048;
/* Check that key can be successfully decoded. */
ExpectNotNull(pkey = wolfSSL_d2i_PublicKey(EVP_PKEY_RSA, NULL, &p,
sizeof_client_keypub_der_2048));
/* Check that key can be successfully encoded. */
ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0);
/* Ensure that the encoded version matches the original. */
ExpectIntEQ(derLen, sizeof_client_keypub_der_2048);
ExpectIntEQ(XMEMCMP(der, client_keypub_der_2048, derLen), 0);
/* Do same test except with pre-allocated buffer to ensure the der pointer
* is advanced. */
tmp = der;
ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &tmp)), 0);
ExpectIntEQ(derLen, sizeof_client_keypub_der_2048);
ExpectIntEQ(XMEMCMP(der, client_keypub_der_2048, derLen), 0);
ExpectTrue(der + derLen == tmp);
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
EVP_PKEY_free(pkey);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_d2i_and_i2d_PublicKey_ecc(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && !defined(NO_CERTS) && \
!defined(NO_ASN) && !defined(NO_PWDBASED)
EVP_PKEY* pkey = NULL;
const unsigned char* p;
unsigned char *der = NULL;
unsigned char *tmp = NULL;
int derLen;
unsigned char pub_buf[65];
unsigned char pub_spki_buf[91];
const int pub_len = 65;
const int pub_spki_len = 91;
BN_CTX* ctx = NULL;
EC_GROUP* curve = NULL;
EC_KEY* ephemeral_key = NULL;
const EC_POINT* h = NULL;
ecc_key *eccKey = NULL;
/* Generate an x963 key pair and get public part into pub_buf */
ExpectNotNull(ctx = BN_CTX_new());
ExpectNotNull(curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
ExpectNotNull(ephemeral_key = EC_KEY_new_by_curve_name(
NID_X9_62_prime256v1));
ExpectIntEQ(EC_KEY_generate_key(ephemeral_key), 1);
ExpectNotNull(h = EC_KEY_get0_public_key(ephemeral_key));
ExpectIntEQ(pub_len, EC_POINT_point2oct(curve, h,
POINT_CONVERSION_UNCOMPRESSED, pub_buf, pub_len, ctx));
/* Create an ecc key struct from the point.
Use it to create a DER with the appropriate
SubjectPublicKeyInfo format. */
ExpectNotNull(eccKey = (ecc_key *)XMALLOC(sizeof(*eccKey), NULL,
DYNAMIC_TYPE_ECC));
ExpectIntEQ(wc_ecc_init(eccKey), 0);
ExpectIntEQ(wc_ecc_import_x963(pub_buf, pub_len, eccKey), 0);
ExpectIntEQ(derLen = wc_EccPublicKeyDerSize(eccKey, 1),
pub_spki_len);
ExpectIntEQ(derLen = wc_EccPublicKeyToDer(eccKey, pub_spki_buf,
pub_spki_len, 1), pub_spki_len);
/* Prepare the EVP_PKEY */
ExpectNotNull(pkey = EVP_PKEY_new());
p = pub_buf;
/* Check that key can be successfully decoded. */
ExpectNotNull(wolfSSL_d2i_PublicKey(EVP_PKEY_EC, &pkey, &p,
pub_len));
/* Check that key can be successfully encoded. */
ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &der)), 0);
/* Ensure that the encoded version matches the original. */
ExpectIntEQ(derLen, pub_spki_len);
ExpectIntEQ(XMEMCMP(der, pub_spki_buf, derLen), 0);
/* Do same test except with pre-allocated buffer to ensure the der pointer
* is advanced. */
tmp = der;
ExpectIntGE((derLen = wolfSSL_i2d_PublicKey(pkey, &tmp)), 0);
ExpectIntEQ(derLen, pub_spki_len);
ExpectIntEQ(XMEMCMP(der, pub_spki_buf, derLen), 0);
ExpectTrue(der + derLen == tmp);
wc_ecc_free(eccKey);
XFREE(eccKey, NULL, DYNAMIC_TYPE_ECC);
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
EVP_PKEY_free(pkey);
EC_KEY_free(ephemeral_key);
EC_GROUP_free(curve);
BN_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_d2i_and_i2d_DSAparams(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_DSA)
DSA* dsa = NULL;
byte derIn[] = {
0x30, 0x82, 0x01, 0x1f, 0x02, 0x81, 0x81, 0x00,
0xcd, 0xde, 0x25, 0x68, 0x80, 0x53, 0x0d, 0xe5,
0x77, 0xd6, 0xd2, 0x90, 0x39, 0x3f, 0x90, 0xa2,
0x3f, 0x33, 0x94, 0x6e, 0xe8, 0x4f, 0x2b, 0x63,
0xab, 0x30, 0xab, 0x15, 0xba, 0x11, 0xea, 0x8a,
0x5d, 0x8d, 0xcc, 0xb8, 0xd4, 0xa1, 0xd5, 0xc1,
0x47, 0x9d, 0x5a, 0x73, 0x6a, 0x62, 0x49, 0xd1,
0x06, 0x07, 0x67, 0xf6, 0x2f, 0xa3, 0x39, 0xbd,
0x4e, 0x0d, 0xb4, 0xd3, 0x22, 0x23, 0x84, 0xec,
0x93, 0x26, 0x5a, 0x49, 0xee, 0x7c, 0x89, 0x48,
0x66, 0x4d, 0xe8, 0xe8, 0xd8, 0x50, 0xfb, 0xa5,
0x71, 0x9f, 0x22, 0x18, 0xe5, 0xe6, 0x0b, 0x46,
0x87, 0x66, 0xee, 0x52, 0x8f, 0x46, 0x4f, 0xb5,
0x03, 0xce, 0xed, 0xe3, 0xbe, 0xe5, 0xb5, 0x81,
0xd2, 0x59, 0xe9, 0xc0, 0xad, 0x4d, 0xd0, 0x4d,
0x26, 0xf7, 0xba, 0x50, 0xe8, 0xc9, 0x8f, 0xfe,
0x24, 0x19, 0x3d, 0x2e, 0xa7, 0x52, 0x3c, 0x6d,
0x02, 0x15, 0x00, 0xfb, 0x47, 0xfb, 0xec, 0x81,
0x20, 0xc8, 0x1c, 0xe9, 0x4a, 0xba, 0x04, 0x6f,
0x19, 0x9b, 0x94, 0xee, 0x82, 0x67, 0xd3, 0x02,
0x81, 0x81, 0x00, 0x9b, 0x95, 0xbb, 0x85, 0xc5,
0x58, 0x4a, 0x32, 0x9c, 0xaa, 0x44, 0x85, 0xd6,
0x68, 0xdc, 0x3e, 0x14, 0xf4, 0xce, 0x6d, 0xa3,
0x49, 0x38, 0xea, 0xd6, 0x61, 0x48, 0x92, 0x5a,
0x40, 0x95, 0x49, 0x38, 0xaa, 0xe1, 0x39, 0x29,
0x68, 0x58, 0x47, 0x8a, 0x4b, 0x01, 0xe1, 0x2e,
0x8e, 0x6c, 0x63, 0x6f, 0x40, 0xca, 0x50, 0x3f,
0x8c, 0x0b, 0x99, 0xe4, 0x72, 0x42, 0xb8, 0xb1,
0xc2, 0x26, 0x48, 0xf1, 0x9c, 0x83, 0xc6, 0x37,
0x2e, 0x5a, 0xae, 0x11, 0x09, 0xd9, 0xf3, 0xad,
0x1f, 0x6f, 0xad, 0xad, 0x50, 0xe3, 0x78, 0x32,
0xe6, 0xde, 0x8e, 0xaa, 0xbf, 0xd1, 0x00, 0x9f,
0xb3, 0x02, 0x12, 0x19, 0xa2, 0x15, 0xec, 0x14,
0x18, 0x5c, 0x0e, 0x26, 0xce, 0xf9, 0xae, 0xcc,
0x7b, 0xb5, 0xd1, 0x26, 0xfc, 0x85, 0xfe, 0x14,
0x93, 0xb6, 0x9d, 0x7d, 0x76, 0xe3, 0x35, 0x97,
0x1e, 0xde, 0xc4
};
int derInLen = sizeof(derIn);
byte* derOut = NULL;
int derOutLen;
byte* p = derIn;
/* Check that params can be successfully decoded. */
ExpectNotNull(dsa = d2i_DSAparams(NULL, (const byte**)&p, derInLen));
/* Check that params can be successfully encoded. */
ExpectIntGE((derOutLen = i2d_DSAparams(dsa, &derOut)), 0);
/* Ensure that the encoded version matches the original. */
ExpectIntEQ(derInLen, derOutLen);
ExpectIntEQ(XMEMCMP(derIn, derOut, derInLen), 0);
XFREE(derOut, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
DSA_free(dsa);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_i2d_PrivateKey(void)
{
EXPECT_DECLS;
#if (!defined(NO_RSA) || defined(HAVE_ECC)) && defined(OPENSSL_EXTRA) && \
!defined(NO_ASN) && !defined(NO_PWDBASED)
#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048)
{
EVP_PKEY* pkey = NULL;
const unsigned char* server_key =
(const unsigned char*)server_key_der_2048;
unsigned char buf[FOURK_BUF];
unsigned char* pt = NULL;
int bufSz = 0;
ExpectNotNull(pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &server_key,
(long)sizeof_server_key_der_2048));
ExpectIntEQ(i2d_PrivateKey(pkey, NULL), 1193);
pt = buf;
ExpectIntEQ((bufSz = i2d_PrivateKey(pkey, &pt)), 1193);
ExpectIntNE((pt - buf), 0);
ExpectIntEQ(XMEMCMP(buf, server_key_der_2048, bufSz), 0);
EVP_PKEY_free(pkey);
}
#endif
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
{
EVP_PKEY* pkey = NULL;
const unsigned char* client_key =
(const unsigned char*)ecc_clikey_der_256;
unsigned char buf[FOURK_BUF];
unsigned char* pt = NULL;
int bufSz = 0;
ExpectNotNull((pkey = d2i_PrivateKey(EVP_PKEY_EC, NULL, &client_key,
(long)sizeof_ecc_clikey_der_256)));
ExpectIntEQ(i2d_PrivateKey(pkey, NULL), 121);
pt = buf;
ExpectIntEQ((bufSz = i2d_PrivateKey(pkey, &pt)), 121);
ExpectIntNE((pt - buf), 0);
ExpectIntEQ(XMEMCMP(buf, ecc_clikey_der_256, bufSz), 0);
EVP_PKEY_free(pkey);
}
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_id_get0_info(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && \
defined(HAVE_OCSP) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
!defined(WOLFSSL_SM2) && !defined(WOLFSSL_SM3)
X509* cert = NULL;
X509* issuer = NULL;
OCSP_CERTID* id = NULL;
OCSP_CERTID* id2 = NULL;
ASN1_STRING* name = NULL;
ASN1_OBJECT* pmd = NULL;
ASN1_STRING* keyHash = NULL;
ASN1_INTEGER* serial = NULL;
ASN1_INTEGER* x509Int = NULL;
ExpectNotNull(cert = wolfSSL_X509_load_certificate_file(svrCertFile,
SSL_FILETYPE_PEM));
ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(caCertFile,
SSL_FILETYPE_PEM));
ExpectNotNull(id = OCSP_cert_to_id(NULL, cert, issuer));
ExpectNotNull(id2 = OCSP_cert_to_id(NULL, cert, issuer));
ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, NULL), 0);
ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, NULL, id), 1);
/* name, pmd, keyHash not supported yet, expect failure if not NULL */
ExpectIntEQ(OCSP_id_get0_info(&name, NULL, NULL, NULL, id), 0);
ExpectIntEQ(OCSP_id_get0_info(NULL, &pmd, NULL, NULL, id), 0);
ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, &keyHash, NULL, id), 0);
ExpectIntEQ(OCSP_id_get0_info(NULL, NULL, NULL, &serial, id), 1);
ExpectNotNull(serial);
/* compare serial number to one in cert, should be equal */
ExpectNotNull(x509Int = X509_get_serialNumber(cert));
ExpectIntEQ(x509Int->length, serial->length);
ExpectIntEQ(XMEMCMP(x509Int->data, serial->data, serial->length), 0);
ExpectNotNull(x509Int = X509_get_serialNumber(cert));
/* test OCSP_id_cmp */
ExpectIntNE(OCSP_id_cmp(NULL, NULL), 0);
ExpectIntNE(OCSP_id_cmp(id, NULL), 0);
ExpectIntNE(OCSP_id_cmp(NULL, id2), 0);
ExpectIntEQ(OCSP_id_cmp(id, id2), 0);
if (id != NULL) {
id->issuerHash[0] = ~id->issuerHash[0];
}
ExpectIntNE(OCSP_id_cmp(id, id2), 0);
OCSP_CERTID_free(id);
OCSP_CERTID_free(id2);
X509_free(cert); /* free's x509Int */
X509_free(issuer);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_i2d_OCSP_CERTID(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP)
WOLFSSL_OCSP_CERTID certId;
byte* targetBuffer = NULL;
byte* p;
/* OCSP CertID bytes taken from PCAP */
byte rawCertId[] = {
0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
0x00, 0x04, 0x14, 0x80, 0x51, 0x06, 0x01, 0x32, 0xad, 0x9a, 0xc2, 0x7d,
0x51, 0x87, 0xa0, 0xe8, 0x87, 0xfb, 0x01, 0x62, 0x01, 0x55, 0xee, 0x04,
0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3,
0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x02, 0x10, 0x01,
0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, 0x43, 0x8b, 0x72, 0x4b,
0xcf, 0xbc, 0x91
};
int ret = 0;
int i;
XMEMSET(&certId, 0, sizeof(WOLFSSL_OCSP_CERTID));
certId.rawCertId = rawCertId;
certId.rawCertIdSize = sizeof(rawCertId);
ExpectNotNull(targetBuffer = (byte*)XMALLOC(sizeof(rawCertId), NULL,
DYNAMIC_TYPE_TMP_BUFFER));
p = targetBuffer;
/* Function returns the size of the encoded data. */
ExpectIntEQ(ret = wolfSSL_i2d_OCSP_CERTID(&certId, &p), sizeof(rawCertId));
/* If target buffer is not null, function increments targetBuffer to point
* just past the end of the encoded data. */
ExpectPtrEq(p, (targetBuffer + sizeof(rawCertId)));
for (i = 0; EXPECT_SUCCESS() && i < ret; ++i) {
ExpectIntEQ(targetBuffer[i], rawCertId[i]);
}
XFREE(targetBuffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
targetBuffer = NULL;
/* If target buffer is null, function allocates memory for a buffer and
* copies the encoded data into it. targetBuffer then points to the start of
* this newly allocate buffer. */
ExpectIntEQ(ret = wolfSSL_i2d_OCSP_CERTID(&certId, &targetBuffer),
sizeof(rawCertId));
for (i = 0; EXPECT_SUCCESS() && i < ret; ++i) {
ExpectIntEQ(targetBuffer[i], rawCertId[i]);
}
XFREE(targetBuffer, NULL, DYNAMIC_TYPE_OPENSSL);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_d2i_OCSP_CERTID(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)) && defined(HAVE_OCSP)
WOLFSSL_OCSP_CERTID* certIdGood = NULL;
WOLFSSL_OCSP_CERTID* certIdBad = NULL;
const unsigned char* rawCertIdPtr = NULL;
const unsigned char rawCertId[] = {
0x30, 0x49, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
0x00, 0x04, 0x14, 0x80, 0x51, 0x06, 0x01, 0x32, 0xad, 0x9a, 0xc2, 0x7d,
0x51, 0x87, 0xa0, 0xe8, 0x87, 0xfb, 0x01, 0x62, 0x01, 0x55, 0xee, 0x04,
0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3,
0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x02, 0x10, 0x01,
0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, 0x43, 0x8b, 0x72, 0x4b,
0xcf, 0xbc, 0x91
};
rawCertIdPtr = &rawCertId[0];
/* If the cert ID is NULL the function should allocate it and copy the
* data to it. */
{
WOLFSSL_OCSP_CERTID* certId = NULL;
ExpectNotNull(certId = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
sizeof(rawCertId)));
if (certId != NULL) {
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL_OCSP_CERTID_free(certId);
}
}
/* If the cert ID is not NULL the function will just copy the data to it. */
{
WOLFSSL_OCSP_CERTID* certId = NULL;
ExpectNotNull(certId = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*certId), NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectNotNull(certId);
if (certId != NULL)
XMEMSET(certId, 0, sizeof(*certId));
/* Reset rawCertIdPtr since it was push forward in the previous call. */
rawCertIdPtr = &rawCertId[0];
ExpectNotNull(certIdGood = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr,
sizeof(rawCertId)));
ExpectPtrEq(certIdGood, certId);
if (certId != NULL) {
XFREE(certId->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL);
wolfSSL_OCSP_CERTID_free(certId);
certId = NULL;
}
}
/* The below tests should fail when passed bad parameters. NULL should
* always be returned. */
{
WOLFSSL_OCSP_CERTID* certId = NULL;
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, NULL,
sizeof(rawCertId)));
ExpectNull(certIdBad = wolfSSL_d2i_OCSP_CERTID(&certId, &rawCertIdPtr, 0));
}
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_id_cmp(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_OCSP)
OCSP_CERTID id1;
OCSP_CERTID id2;
XMEMSET(&id1, 0, sizeof(id1));
XMEMSET(&id2, 0, sizeof(id2));
ExpectIntEQ(OCSP_id_cmp(&id1, &id2), 0);
ExpectIntNE(OCSP_id_cmp(NULL, NULL), 0);
ExpectIntNE(OCSP_id_cmp(&id1, NULL), 0);
ExpectIntNE(OCSP_id_cmp(NULL, &id2), 0);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_SINGLERESP_get0_id(void)
{
EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
WOLFSSL_OCSP_SINGLERESP single;
const WOLFSSL_OCSP_CERTID* certId;
XMEMSET(&single, 0, sizeof(single));
certId = wolfSSL_OCSP_SINGLERESP_get0_id(&single);
ExpectPtrEq(&single, certId);
ExpectNull(wolfSSL_OCSP_SINGLERESP_get0_id(NULL));
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_single_get0_status(void)
{
EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_OCSP_PARSE_STATUS)
WOLFSSL_OCSP_SINGLERESP single;
CertStatus certStatus;
WOLFSSL_ASN1_TIME* thisDate;
WOLFSSL_ASN1_TIME* nextDate;
int ret, i;
XMEMSET(&single, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
XMEMSET(&certStatus, 0, sizeof(CertStatus));
/* Fill the date fields with some dummy data. */
for (i = 0; i < CTC_DATE_SIZE; ++i) {
certStatus.thisDateParsed.data[i] = i;
certStatus.nextDateParsed.data[i] = i;
}
certStatus.status = CERT_GOOD;
single.status = &certStatus;
ret = wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, &thisDate,
&nextDate);
ExpectIntEQ(ret, CERT_GOOD);
ExpectPtrEq(thisDate, &certStatus.thisDateParsed);
ExpectPtrEq(nextDate, &certStatus.nextDateParsed);
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(NULL, NULL, NULL, NULL, NULL),
CERT_GOOD);
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, NULL,
NULL), CERT_GOOD);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_resp_count(void)
{
EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
WOLFSSL_OCSP_BASICRESP basicResp;
WOLFSSL_OCSP_SINGLERESP singleRespOne;
WOLFSSL_OCSP_SINGLERESP singleRespTwo;
XMEMSET(&basicResp, 0, sizeof(WOLFSSL_OCSP_BASICRESP));
XMEMSET(&singleRespOne, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
XMEMSET(&singleRespTwo, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 0);
basicResp.single = &singleRespOne;
ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 1);
singleRespOne.next = &singleRespTwo;
ExpectIntEQ(wolfSSL_OCSP_resp_count(&basicResp), 2);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_resp_get0(void)
{
EXPECT_DECLS;
#if defined(HAVE_OCSP) && defined(OPENSSL_EXTRA)
WOLFSSL_OCSP_BASICRESP basicResp;
WOLFSSL_OCSP_SINGLERESP singleRespOne;
WOLFSSL_OCSP_SINGLERESP singleRespTwo;
XMEMSET(&basicResp, 0, sizeof(WOLFSSL_OCSP_BASICRESP));
XMEMSET(&singleRespOne, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
XMEMSET(&singleRespTwo, 0, sizeof(WOLFSSL_OCSP_SINGLERESP));
basicResp.single = &singleRespOne;
singleRespOne.next = &singleRespTwo;
ExpectPtrEq(wolfSSL_OCSP_resp_get0(&basicResp, 0), &singleRespOne);
ExpectPtrEq(wolfSSL_OCSP_resp_get0(&basicResp, 1), &singleRespTwo);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OCSP_parse_url(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_OCSP)
#define CK_OPU_OK(u, h, po, pa, s) do { \
char* host = NULL; \
char* port = NULL; \
char* path = NULL; \
int isSsl = 0; \
ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 1); \
ExpectStrEQ(host, h); \
ExpectStrEQ(port, po); \
ExpectStrEQ(path, pa); \
ExpectIntEQ(isSsl, s); \
XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \
XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \
XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \
} while(0)
#define CK_OPU_FAIL(u) do { \
char* host = NULL; \
char* port = NULL; \
char* path = NULL; \
int isSsl = 0; \
ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 0); \
XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \
XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \
XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \
} while(0)
CK_OPU_OK("http://localhost", "localhost", "80", "/", 0);
CK_OPU_OK("https://wolfssl.com", "wolfssl.com", "443", "/", 1);
CK_OPU_OK("https://www.wolfssl.com/fips-140-3-announcement-to-the-world/",
"www.wolfssl.com", "443", "/fips-140-3-announcement-to-the-world/", 1);
CK_OPU_OK("http://localhost:1234", "localhost", "1234", "/", 0);
CK_OPU_OK("https://localhost:1234", "localhost", "1234", "/", 1);
CK_OPU_FAIL("ftp://localhost");
/* two strings to cppcheck doesn't mark it as a c++ style comment */
CK_OPU_FAIL("http/""/localhost");
CK_OPU_FAIL("http:/localhost");
CK_OPU_FAIL("https://localhost/path:1234");
#undef CK_OPU_OK
#undef CK_OPU_FAIL
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \
defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) && \
!defined(NO_ASN_TIME) && \
!defined(WOLFSSL_SM2) && !defined(WOLFSSL_SM3)
static time_t test_wolfSSL_OCSP_REQ_CTX_time_cb(time_t* t)
{
if (t != NULL) {
*t = 1722006780;
}
return 1722006780;
}
#endif
static int test_wolfSSL_OCSP_REQ_CTX(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \
defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSSL_SM2) && !defined(WOLFSSL_SM3)
/* This buffer was taken from the ocsp-stapling.test test case 1. The ocsp
* response was captured in wireshark. It contains both the http and binary
* parts. The time test_wolfSSL_OCSP_REQ_CTX_time_cb is set exactly so that
* the time check passes. */
unsigned char ocspRespBin[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30,
0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68,
0x3a, 0x20, 0x31, 0x38, 0x32, 0x31, 0x0d, 0x0a, 0x0d, 0x0a, 0x30, 0x82,
0x07, 0x19, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x12, 0x30, 0x82, 0x07,
0x0e, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01,
0x04, 0x82, 0x06, 0xff, 0x30, 0x82, 0x06, 0xfb, 0x30, 0x82, 0x01, 0x19,
0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06,
0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e,
0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c,
0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04,
0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69,
0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53,
0x50, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31,
0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c,
0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, 0x32, 0x30,
0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35,
0x5a, 0x30, 0x62, 0x30, 0x60, 0x30, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b,
0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x71, 0x4d, 0x82, 0x23, 0x40, 0x59,
0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18,
0xda, 0x04, 0x04, 0x14, 0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02,
0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e,
0x02, 0x01, 0x05, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30,
0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35, 0x5a, 0xa0, 0x11,
0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35,
0x31, 0x33, 0x30, 0x35, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
0x00, 0x89, 0x7a, 0xe9, 0x6b, 0x66, 0x47, 0x8e, 0x52, 0x16, 0xf9, 0x8a,
0x5a, 0x1e, 0x7a, 0x35, 0xbb, 0x1d, 0x6c, 0xd8, 0x31, 0xbb, 0x24, 0xd2,
0xd7, 0xa4, 0x30, 0x27, 0x06, 0x17, 0x66, 0xd1, 0xf9, 0x8d, 0x24, 0xb0,
0x49, 0x37, 0x62, 0x13, 0x78, 0x5e, 0xa6, 0x6d, 0xea, 0xe3, 0xd0, 0x30,
0x82, 0x7d, 0xb6, 0xf6, 0x55, 0x82, 0x11, 0xdc, 0xe7, 0x0f, 0xd6, 0x24,
0xb4, 0x80, 0x23, 0x4f, 0xfd, 0xa7, 0x9a, 0x4b, 0xac, 0xf2, 0xd3, 0xde,
0x42, 0x10, 0xfb, 0x4b, 0x29, 0x06, 0x02, 0x7b, 0x47, 0x36, 0x70, 0x75,
0x45, 0x38, 0x8d, 0x3e, 0x55, 0x9c, 0xce, 0x78, 0xd8, 0x18, 0x45, 0x47,
0x2d, 0x2a, 0x46, 0x65, 0x13, 0x93, 0x1a, 0x98, 0x90, 0xc6, 0x2d, 0xd5,
0x05, 0x2a, 0xfc, 0xcb, 0xac, 0x53, 0x73, 0x93, 0x42, 0x4e, 0xdb, 0x17,
0x91, 0xcb, 0xe1, 0x08, 0x03, 0xd1, 0x33, 0x57, 0x4b, 0x1d, 0xb8, 0x71,
0x84, 0x01, 0x04, 0x47, 0x6f, 0x06, 0xfa, 0x76, 0x7d, 0xd9, 0x37, 0x64,
0x57, 0x37, 0x3a, 0x8f, 0x4d, 0x88, 0x11, 0xa5, 0xd4, 0xaa, 0xcb, 0x49,
0x47, 0x86, 0xdd, 0xcf, 0x46, 0xa6, 0xfa, 0x8e, 0xf2, 0x62, 0x0f, 0xc9,
0x25, 0xf2, 0x39, 0x62, 0x3e, 0x2d, 0x35, 0xc4, 0x76, 0x7b, 0xae, 0xd5,
0xe8, 0x85, 0xa1, 0xa6, 0x2d, 0x41, 0xd6, 0x8e, 0x3c, 0xfa, 0xdc, 0x6c,
0x66, 0xe2, 0x61, 0xe7, 0xe5, 0x90, 0xa1, 0xfd, 0x7f, 0xdb, 0x18, 0xd0,
0xeb, 0x6d, 0x73, 0x08, 0x5f, 0x6a, 0x65, 0x44, 0x50, 0xad, 0x38, 0x9d,
0xb6, 0xfb, 0xbf, 0x28, 0x55, 0x84, 0x65, 0xfa, 0x0e, 0x34, 0xfc, 0x43,
0x19, 0x80, 0x5c, 0x7d, 0x2d, 0x5b, 0xd8, 0x60, 0xec, 0x0e, 0xf9, 0x1e,
0x6e, 0x32, 0x3f, 0x35, 0xf7, 0xec, 0x7e, 0x47, 0xba, 0xb5, 0xd2, 0xaa,
0x5a, 0x9d, 0x07, 0x2c, 0xc5, 0xa0, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04,
0xc2, 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02,
0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x97, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57,
0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74,
0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a,
0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30,
0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69,
0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06,
0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53,
0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30,
0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01,
0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73,
0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34,
0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x5a, 0x17,
0x0d, 0x32, 0x37, 0x30, 0x34, 0x32, 0x32, 0x31, 0x35, 0x31, 0x32, 0x30,
0x34, 0x5a, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07,
0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30,
0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66,
0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e,
0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16,
0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, 0x50,
0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f,
0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66,
0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
0x82, 0x01, 0x01, 0x00, 0xb8, 0xba, 0x23, 0xb4, 0xf6, 0xc3, 0x7b, 0x14,
0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, 0x1e, 0x63, 0xb9, 0x85, 0x23,
0x34, 0x50, 0x6d, 0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, 0x5c,
0x2d, 0xf7, 0x63, 0x88, 0xd1, 0x07, 0x7a, 0xea, 0x0b, 0x45, 0x35, 0x2b,
0xeb, 0x1f, 0xb1, 0x22, 0xb4, 0x94, 0x41, 0x38, 0xe2, 0x9d, 0x74, 0xd6,
0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, 0xca, 0x3f, 0x46, 0x2b, 0xfe,
0xe5, 0x5a, 0x3f, 0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, 0xc3,
0xee, 0x42, 0xf8, 0x8d, 0xeb, 0x92, 0x95, 0xe1, 0xd9, 0x65, 0xb7, 0x43,
0xc4, 0x18, 0xde, 0x16, 0x80, 0x90, 0xce, 0x24, 0x35, 0x21, 0xc4, 0x55,
0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, 0x0a, 0x5a, 0x4f, 0x4a, 0x73,
0x31, 0x50, 0xee, 0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, 0x87,
0xb1, 0x99, 0xe2, 0x10, 0xa7, 0x06, 0x72, 0x67, 0xca, 0x5c, 0xd1, 0x97,
0xbd, 0xc8, 0xf1, 0x76, 0xf8, 0xe0, 0x4a, 0xec, 0xbc, 0x93, 0xf4, 0x66,
0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, 0xb4, 0x90, 0x30, 0xbb, 0x17,
0xb0, 0xfe, 0x97, 0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, 0x19,
0x12, 0x3c, 0xab, 0x82, 0x71, 0x78, 0xff, 0xae, 0x3f, 0x32, 0xb2, 0x08,
0x71, 0xb2, 0x1b, 0x8c, 0x27, 0xac, 0x11, 0xb8, 0xd8, 0x43, 0x49, 0xcf,
0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, 0x24, 0x87, 0x17, 0x3b, 0xd8,
0x04, 0x65, 0x6c, 0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, 0x73,
0x68, 0x26, 0x14, 0x87, 0x95, 0xc3, 0x5f, 0x6e, 0x61, 0xb8, 0x87, 0x84,
0xfa, 0x80, 0x1a, 0x0a, 0x8b, 0x98, 0xf3, 0xe3, 0xff, 0x4e, 0x44, 0x1c,
0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, 0x39, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, 0x06,
0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03,
0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x32, 0x67, 0xe1, 0xb1, 0x79,
0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, 0x40, 0x50, 0xb5, 0x46, 0x56,
0xb8, 0x30, 0x36, 0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
0x81, 0xbc, 0x30, 0x81, 0xb9, 0x80, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f,
0x82, 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, 0x7e,
0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, 0x81, 0x97,
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10,
0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61,
0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04,
0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14,
0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67,
0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53,
0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f,
0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66,
0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, 0x13,
0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
0x01, 0x01, 0x00, 0x37, 0xb9, 0x66, 0xd3, 0xa1, 0x08, 0xfc, 0x37, 0x58,
0x4e, 0xe0, 0x8c, 0xd3, 0x7f, 0xa6, 0x0f, 0x59, 0xd3, 0x14, 0xf7, 0x4b,
0x36, 0xf7, 0x2e, 0x98, 0xeb, 0x7c, 0x03, 0x3f, 0x3a, 0xd6, 0x9c, 0xcd,
0xb4, 0x9e, 0x8d, 0x5f, 0x92, 0xa6, 0x6f, 0x63, 0x87, 0x34, 0xe8, 0x83,
0xfd, 0x6d, 0x34, 0x64, 0xb5, 0xf0, 0x9c, 0x71, 0x02, 0xb8, 0xf6, 0x2f,
0x10, 0xa0, 0x92, 0x8f, 0x3f, 0x86, 0x3e, 0xe2, 0x01, 0x5a, 0x56, 0x39,
0x0a, 0x8d, 0xb1, 0xbe, 0x03, 0xf7, 0xf8, 0xa7, 0x88, 0x46, 0xef, 0x81,
0xa0, 0xad, 0x86, 0xc9, 0xe6, 0x23, 0x89, 0x1d, 0xa6, 0x24, 0x45, 0xf2,
0x6a, 0x83, 0x2d, 0x8e, 0x92, 0x17, 0x1e, 0x44, 0x19, 0xfa, 0x0f, 0x47,
0x6b, 0x8f, 0x4a, 0xa2, 0xda, 0xab, 0xd5, 0x2b, 0xcd, 0xcb, 0x14, 0xf0,
0xb5, 0xcf, 0x7c, 0x76, 0x42, 0x32, 0x90, 0x21, 0xdc, 0xdd, 0x52, 0xfc,
0x53, 0x7e, 0xff, 0x7f, 0xd9, 0x58, 0x6b, 0x1f, 0x73, 0xee, 0x83, 0xf4,
0x67, 0xfa, 0x4a, 0x4f, 0x24, 0xe4, 0x2b, 0x10, 0x74, 0x89, 0x52, 0x9a,
0xf7, 0xa4, 0xe0, 0xaf, 0xf5, 0x63, 0xd7, 0xfa, 0x0b, 0x2c, 0xc9, 0x39,
0x5d, 0xbd, 0x44, 0x93, 0x69, 0xa4, 0x1d, 0x01, 0xe2, 0x66, 0xe7, 0xc1,
0x11, 0x44, 0x7d, 0x0a, 0x7e, 0x5d, 0x1d, 0x26, 0xc5, 0x4a, 0x26, 0x2e,
0xa3, 0x58, 0xc4, 0xf7, 0x10, 0xcb, 0xba, 0xe6, 0x27, 0xfc, 0xdb, 0x54,
0xe2, 0x60, 0x08, 0xc2, 0x0e, 0x4b, 0xd4, 0xaa, 0x22, 0x23, 0x93, 0x9f,
0xe1, 0xcb, 0x85, 0xa4, 0x41, 0x6f, 0x26, 0xa7, 0x77, 0x8a, 0xef, 0x66,
0xd0, 0xf8, 0x33, 0xf6, 0xfd, 0x6d, 0x37, 0x7a, 0x89, 0xcc, 0x88, 0x3b,
0x82, 0xd0, 0xa9, 0xdf, 0xf1, 0x3d, 0xdc, 0xb0, 0x06, 0x1c, 0xe4, 0x4b,
0x57, 0xb4, 0x0c, 0x65, 0xb9, 0xb4, 0x6c
};
OCSP_REQ_CTX *ctx = NULL;
OCSP_REQUEST *req = NULL;
OCSP_CERTID *cid = NULL;
OCSP_RESPONSE *rsp = NULL;
BIO* bio1 = NULL;
BIO* bio2 = NULL;
X509* cert = NULL;
X509* empty = NULL;
X509 *issuer = NULL;
X509_LOOKUP *lookup = NULL;
X509_STORE *store = NULL;
STACK_OF(X509_OBJECT) *str_objs = NULL;
X509_OBJECT *x509_obj = NULL;
STACK_OF(WOLFSSL_STRING) *skStr = NULL;
ExpectNotNull(bio1 = BIO_new(BIO_s_bio()));
ExpectNotNull(bio2 = BIO_new(BIO_s_bio()));
ExpectIntEQ(BIO_make_bio_pair(bio1, bio2), WOLFSSL_SUCCESS);
/* Load the leaf cert */
ExpectNotNull(cert = wolfSSL_X509_load_certificate_file(
"certs/ocsp/server1-cert.pem", WOLFSSL_FILETYPE_PEM));
ExpectNull(wolfSSL_X509_get1_ocsp(NULL));
ExpectNotNull(skStr = wolfSSL_X509_get1_ocsp(cert));
wolfSSL_X509_email_free(NULL);
wolfSSL_X509_email_free(skStr);
ExpectNotNull(empty = wolfSSL_X509_new());
ExpectNull(wolfSSL_X509_get1_ocsp(empty));
wolfSSL_X509_free(empty);
ExpectNotNull(store = X509_STORE_new());
ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()));
ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/ocsp/server1-cert.pem",
X509_FILETYPE_PEM), 1);
ExpectNotNull(str_objs = X509_STORE_get0_objects(store));
ExpectNull(X509_OBJECT_retrieve_by_subject(NULL, X509_LU_X509, NULL));
ExpectNull(X509_OBJECT_retrieve_by_subject(str_objs, X509_LU_X509, NULL));
ExpectNull(X509_OBJECT_retrieve_by_subject(NULL, X509_LU_X509,
X509_get_issuer_name(cert)));
ExpectNull(X509_OBJECT_retrieve_by_subject(str_objs,
X509_LU_CRL, X509_get_issuer_name(cert)));
ExpectNotNull(x509_obj = X509_OBJECT_retrieve_by_subject(str_objs,
X509_LU_X509, X509_get_issuer_name(cert)));
ExpectNotNull(issuer = X509_OBJECT_get0_X509(x509_obj));
ExpectTrue(wolfSSL_X509_OBJECT_get_type(NULL) == WOLFSSL_X509_LU_NONE);
#ifndef NO_WOLFSSL_STUB
/* Not implemented and not in OpenSSL 1.1.0+ */
wolfSSL_X509_OBJECT_free_contents(x509_obj);
#endif
wolfSSL_X509_OBJECT_free(NULL);
ExpectNotNull(req = OCSP_REQUEST_new());
ExpectNotNull(cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer));
ExpectNotNull(OCSP_request_add0_id(req, cid));
ExpectIntEQ(OCSP_request_add1_nonce(req, NULL, -1), 1);
ExpectNotNull(ctx = OCSP_sendreq_new(bio1, "/", NULL, -1));
ExpectIntEQ(OCSP_REQ_CTX_add1_header(ctx, "Host", "127.0.0.1"), 1);
ExpectIntEQ(OCSP_REQ_CTX_set1_req(ctx, req), 1);
ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), -1);
ExpectIntEQ(BIO_write(bio2, ocspRespBin, sizeof(ocspRespBin)),
sizeof(ocspRespBin));
#ifndef NO_ASN_TIME
ExpectIntEQ(wc_SetTimeCb(test_wolfSSL_OCSP_REQ_CTX_time_cb), 0);
ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), 1);
ExpectIntEQ(wc_SetTimeCb(NULL), 0);
ExpectNotNull(rsp);
#endif
OCSP_REQ_CTX_free(ctx);
OCSP_REQUEST_free(req);
OCSP_RESPONSE_free(rsp);
BIO_free(bio1);
BIO_free(bio2);
X509_free(cert);
X509_STORE_free(store);
#endif
return EXPECT_RESULT();
}
static int test_no_op_functions(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
/* this makes sure wolfSSL can compile and run these no-op functions */
SSL_load_error_strings();
ENGINE_load_builtin_engines();
OpenSSL_add_all_ciphers();
ExpectIntEQ(CRYPTO_malloc_init(), 0);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CRYPTO_memcmp(void)
{
EXPECT_DECLS;
#ifdef OPENSSL_EXTRA
char a[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
"implementation of TLS/SSL for embedded devices to the cloud.";
char b[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
"implementation of TLS/SSL for embedded devices to the cloud.";
char c[] = "wolfSSL (formerly CyaSSL) is a small, fast, portable "
"implementation of TLS/SSL for embedded devices to the cloud!";
ExpectIntEQ(CRYPTO_memcmp(a, b, sizeof(a)), 0);
ExpectIntNE(CRYPTO_memcmp(a, c, sizeof(a)), 0);
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| wolfCrypt ASN
*----------------------------------------------------------------------------*/
static int test_wc_CreateEncryptedPKCS8Key(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && defined(WOLFSSL_AES_256) \
&& !defined(NO_AES_CBC) && !defined(NO_RSA) && !defined(NO_SHA) && \
!defined(NO_ASN_CRYPT)
WC_RNG rng;
byte* encKey = NULL;
word32 encKeySz = 0;
word32 decKeySz = 0;
const char password[] = "Lorem ipsum dolor sit amet";
word32 passwordSz = (word32)XSTRLEN(password);
word32 tradIdx = 0;
XMEMSET(&rng, 0, sizeof(WC_RNG));
ExpectIntEQ(wc_InitRng(&rng), 0);
PRIVATE_KEY_UNLOCK();
/* Call with NULL for out buffer to get necessary length. */
ExpectIntEQ(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
sizeof_server_key_der_2048, NULL, &encKeySz, password, (int)passwordSz,
PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
WC_NO_ERR_TRACE(LENGTH_ONLY_E));
ExpectNotNull(encKey = (byte*)XMALLOC(encKeySz, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER));
/* Call with the allocated out buffer. */
ExpectIntGT(wc_CreateEncryptedPKCS8Key((byte*)server_key_der_2048,
sizeof_server_key_der_2048, encKey, &encKeySz, password, (int)passwordSz,
PKCS5, PBES2, AES256CBCb, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL),
0);
/* Decrypt the encrypted PKCS8 key we just made. */
ExpectIntGT((decKeySz = (word32)wc_DecryptPKCS8Key(encKey, encKeySz, password,
(int)passwordSz)), 0);
/* encKey now holds the decrypted key (decrypted in place). */
ExpectIntGT(wc_GetPkcs8TraditionalOffset(encKey, &tradIdx, decKeySz), 0);
/* Check that the decrypted key matches the key prior to encryption. */
ExpectIntEQ(XMEMCMP(encKey + tradIdx, server_key_der_2048,
sizeof_server_key_der_2048), 0);
PRIVATE_KEY_LOCK();
XFREE(encKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRng(&rng);
#endif
return EXPECT_RESULT();
}
static int test_wc_DecryptedPKCS8Key(void)
{
EXPECT_DECLS;
#if defined(HAVE_PKCS8) && !defined(NO_PWDBASED) && defined(WOLFSSL_AES_256) \
&& !defined(NO_AES_CBC) && !defined(NO_RSA) && !defined(NO_SHA) && \
!defined(NO_ASN_CRYPT)
static byte badPkcs5RsaEnc[] = {
0x30, 0x82, 0x05, 0x2d, 0x30, 0x57, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
0x30, 0x1c, 0x04, 0x09, 0xad, 0x8f, 0xb7, 0x90,
0x43, 0xd9, 0x3f, 0xe5, 0x02, 0x02, 0x04, 0x02,
0x02, 0x04, 0x80, 0x30, 0x0c, 0x06, 0x08, 0x2a,
0xbc, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05,
0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48,
0x01, 0x65, 0x03, 0x04, 0x01, 0x2a, 0x04, 0x10,
0x90, 0xf9, 0xa4, 0xd7, 0xf2, 0xae, 0x58, 0xd6,
0xe1, 0x7c, 0x60, 0x7b, 0x84, 0xc0, 0x8c, 0x44,
0x04, 0x50, 0xc8, 0xd0, 0x03, 0xa7, 0x79, 0xa9,
0x11, 0x8b, 0xbd, 0xd6, 0xcb, 0xd9, 0x9e, 0xd7,
0x2d, 0xac, 0x2c, 0xb8, 0xc9, 0x5f, 0xe7, 0x8b,
0x36, 0x26, 0x26, 0x23, 0x2a, 0x21, 0x25, 0x6f,
0xd0, 0x52, 0xd3, 0xeb, 0xff, 0x1f, 0x06, 0xb0,
0x40, 0xd1, 0x4b, 0x9e, 0x73, 0xbf, 0x17, 0x24,
0x0b, 0x2d, 0xf6, 0x4f, 0xce, 0xb4, 0x47, 0x82,
0x7c, 0x23, 0x21, 0xdc, 0x71, 0xc7, 0x1c, 0x71,
0xc7, 0x1c, 0x71, 0xc7, 0x1c, 0x71, 0xc7, 0x1c,
0x71, 0xc7, 0x1c, 0x71, 0xc7, 0x1c, 0x71, 0xc7,
0x1c, 0x71, 0xc7, 0x1c, 0x71, 0xc7, 0x1c, 0x71,
0xc7, 0x1c, 0x71, 0xc7, 0x1c, 0x71, 0xc7, 0x07,
0x27, 0x82, 0xcd, 0x36, 0xd7, 0xf4, 0xa1, 0xb5,
0xc5, 0x17, 0x5f, 0xe6, 0xd0, 0xf3, 0x97, 0x3e,
0x1a, 0xcd, 0x39, 0x9d, 0x41, 0xce, 0xed, 0x14,
0xdb, 0x3d, 0xa5, 0x7b, 0xd3, 0xcb, 0x93, 0x1a,
0x4c, 0x32, 0x0e, 0x8b, 0xa3, 0x41, 0xbe, 0xcb,
0xa3, 0xd5, 0xfb, 0x8d, 0xb6, 0x8a, 0x4e, 0x0b,
0x0b, 0xbd, 0x74, 0x33, 0xd2, 0xb6, 0x43, 0x20,
0x96, 0xf9, 0x46, 0x57, 0x66, 0x54, 0x94, 0xfa,
0x1c, 0x3a, 0xe4, 0xf7, 0x0a, 0x59, 0x37, 0x5f,
0x6a, 0xc2, 0xba, 0xea, 0xfd, 0xd4, 0xd7, 0x64,
0xee, 0x53, 0x40, 0xe9, 0x3c, 0x71, 0xbf, 0x93,
0x87, 0xf3, 0x53, 0x0c, 0x92, 0x0b, 0xbe, 0x4c,
0xde, 0x35, 0xd7, 0xb0, 0x60, 0xc6, 0x37, 0x1c,
0x4c, 0x08, 0x8f, 0xe1, 0x95, 0xba, 0xde, 0x42,
0x68, 0x6a, 0x76, 0x0b, 0x84, 0x14, 0xc6, 0x5e,
0xb1, 0xa1, 0x45, 0xa7, 0x31, 0x72, 0xfe, 0xaa,
0x43, 0x86, 0xa3, 0x31, 0x41, 0x68, 0x66, 0x41,
0x31, 0xe0, 0xa4, 0x63, 0x1d, 0x62, 0x57, 0x2c,
0x49, 0x9b, 0x9c, 0x32, 0x4a, 0x4f, 0x3c, 0xf3,
0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c,
0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf,
0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3,
0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c,
0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf,
0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3,
0xcf, 0x3c, 0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3c,
0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3d, 0x4c, 0x72,
0x7d, 0xc7, 0xa8, 0x07, 0x4f, 0xa4, 0x52, 0x1f,
0xb8, 0xa9, 0x89, 0x4c, 0x65, 0xd1, 0x8f, 0x3c,
0xf3, 0xcf, 0x3c, 0xf3, 0xcf, 0x3f, 0x1e, 0x31,
0x53, 0x77, 0x37, 0xaf, 0xe4, 0x43, 0x23, 0x34,
0xfc, 0x8e, 0xc2, 0xba, 0x32, 0x40, 0xb3, 0xe7,
0xab, 0x6d, 0xc3, 0xa0, 0x9e, 0xc7, 0x6c, 0x13,
0xe7, 0x77, 0xd5, 0x0a, 0x1a, 0x04, 0xb7, 0xd4,
0x13, 0xcd, 0x04, 0x39, 0x22, 0x67, 0xc4, 0x00,
0xe4, 0xd0, 0x1f, 0xf7, 0x9d, 0x2b, 0x73, 0xda,
0xee, 0x00, 0x1b, 0x9a, 0x5c, 0xb0, 0x4c, 0x90,
0x9b, 0x38, 0x41, 0xd3, 0x13, 0xd0, 0xfa, 0xec,
0x0f, 0x65, 0xe9, 0x02, 0x90, 0x39, 0xa8, 0xe4,
0xd4, 0x52, 0xa6, 0x1f, 0x7a, 0x54, 0x00, 0x19,
0x13, 0x94, 0xae, 0x7a, 0xf2, 0xa7, 0xce, 0xf5,
0x29, 0x78, 0x66, 0x1c, 0x03, 0x26, 0x65, 0xe8,
0x03, 0x8e, 0x97, 0x67, 0x20, 0x61, 0x4c, 0xbd,
0xa0, 0xb3, 0x88, 0x10, 0x8b, 0x74, 0x40, 0x8d,
0xc6, 0xe6, 0x26, 0x32, 0x0f, 0x01, 0x47, 0x35,
0xb3, 0x86, 0x87, 0xa9, 0x6d, 0xf8, 0xf8, 0x9f,
0xca, 0x30, 0x69, 0xf7, 0x5d, 0x89, 0x3f, 0xf5,
0x1d, 0xd5, 0x26, 0xd7, 0xef, 0x43, 0x26, 0x06,
0x26, 0x7b, 0xf0, 0xdd, 0x86, 0xa6, 0x58, 0x71,
0xd6, 0xcb, 0x45, 0xb4, 0x4f, 0x52, 0xd7, 0xf1,
0xae, 0x06, 0xad, 0xc7, 0x94, 0x17, 0xe8, 0x44,
0x59, 0x02, 0xe1, 0x22, 0x9e, 0x59, 0xa6, 0xcc,
0x3b, 0x20, 0x5b, 0x95, 0xf1, 0x34, 0x31, 0x52,
0x7e, 0x6d, 0xff, 0x4b, 0x45, 0x9a, 0xff, 0xba,
0x1a, 0x41, 0x48, 0x20, 0x49, 0xb8, 0x62, 0xef,
0x82, 0xca, 0x14, 0x7e, 0x14, 0xfa, 0x49, 0x3f,
0xfb, 0x5e, 0xb1, 0x60, 0x30, 0x94, 0x4c, 0xee,
0x4b, 0x78, 0xa2, 0x79, 0xb2, 0xa1, 0xbd, 0xb1,
0x94, 0x24, 0xd6, 0x9c, 0xf0, 0x41, 0x3b, 0xc6,
0xf2, 0x30, 0x8c, 0x8a, 0xdd, 0x2e, 0x44, 0x41,
0x7e, 0x92, 0x3b, 0x09, 0x2e, 0x19, 0x9d, 0xb3,
0xb8, 0xa6, 0x9f, 0x86, 0x7e, 0x88, 0x5d, 0xe0,
0x13, 0x7c, 0x89, 0xf6, 0x96, 0xb1, 0x66, 0x3f,
0xc2, 0x8f, 0x71, 0x43, 0x6a, 0xd5, 0x8c, 0x6e,
0xae, 0xdf, 0x80, 0xd6, 0x01, 0x7a, 0x50, 0xf6,
0x2b, 0x25, 0x0f, 0x8d, 0x84, 0x3b, 0xd5, 0xb5,
0x61, 0xb1, 0x61, 0x58, 0xff, 0x4c, 0xe8, 0x6a,
0xa4, 0xae, 0x2b, 0xf5, 0xfe, 0xee, 0xeb, 0xa6,
0xf2, 0xf3, 0xc5, 0xa1, 0x63, 0x92, 0xde, 0x67,
0x2f, 0x40, 0xfc, 0x3b, 0x36, 0x64, 0xcc, 0x7b,
0xe9, 0xd8, 0xf7, 0x5d, 0x40, 0x56, 0x10, 0xaf,
0xd4, 0x52, 0xe2, 0xa6, 0x7c, 0xe9, 0xe4, 0x4b,
0x0b, 0xbd, 0x74, 0x33, 0xd2, 0xb6, 0x43, 0xd6,
0x0a, 0xe0, 0x12, 0x21, 0xa7, 0xab, 0x45, 0x19,
0x6e, 0xae, 0x71, 0x83, 0x22, 0x1a, 0x0d, 0xde,
0xd5, 0xb6, 0x82, 0xd2, 0xd7, 0xd8, 0x14, 0x6d,
0xfa, 0xb4, 0xae, 0xee, 0x55, 0x43, 0xd2, 0x1e,
0x59, 0xe2, 0x01, 0xe0, 0xfa, 0x53, 0x43, 0x3b,
0x40, 0x17, 0x06, 0x6a, 0x5e, 0x5f, 0x42, 0xc2,
0x6a, 0x4e, 0x7c, 0x5a, 0x69, 0x41, 0x8b, 0x62,
0x76, 0xd4, 0x1b, 0x00, 0xbc, 0x24, 0x27, 0x71,
0xf8, 0xf3, 0xca, 0x57, 0x10, 0xb9, 0x32, 0x14,
0x9b, 0x92, 0x35, 0xdd, 0xb7, 0xb8, 0x2e, 0xd8,
0xb3, 0xe9, 0x62, 0x8e, 0xe2, 0x5e, 0x16, 0xd4,
0xed, 0xf4, 0xd3, 0xc1, 0xba, 0x5d, 0x49, 0xce,
0x78, 0x5c, 0xf5, 0xbb, 0xad, 0x61, 0x1f, 0x64,
0x52, 0x22, 0xb4, 0xa3, 0x07, 0x18, 0x3d, 0xd3,
0x9d, 0xec, 0xe6, 0x9e, 0xb5, 0xad, 0x0c, 0xd3,
0x3b, 0xb6, 0xeb, 0xcd, 0x9c, 0x69, 0x45, 0xf2,
0x07, 0x24, 0xe9, 0xd7, 0xe0, 0xe7, 0x62, 0xe5,
0x01, 0x34, 0x24, 0x4e, 0xf6, 0x32, 0xe8, 0x42,
0x97, 0x3e, 0x14, 0xaf, 0xbc, 0x26, 0xbd, 0x73,
0xc5, 0xde, 0x5a, 0x8e, 0x65, 0x61, 0x97, 0x81,
0x31, 0x52, 0xa3, 0xbd, 0x9b, 0x9e, 0xda, 0xdd,
0x37, 0x15, 0x30, 0xfb, 0x3b, 0x59, 0x0c, 0x91,
0x8b, 0x54, 0x49, 0x68, 0xc6, 0x41, 0x38, 0x77,
0x1c, 0x00, 0xb2, 0xc3, 0x37, 0xe2, 0x50, 0x67,
0xeb, 0x49, 0xa4, 0xde, 0x04, 0x1e, 0xf5, 0xcc,
0x49, 0x24, 0x5a, 0x8d, 0x94, 0x33, 0xbf, 0x55,
0xf8, 0x70, 0x7d, 0x1e, 0x5b, 0xe3, 0x74, 0x6b,
0x34, 0xb3, 0xf6, 0x8a, 0x47, 0xf9, 0x2f, 0xc9,
0xcb, 0x6a, 0x80, 0x89, 0xf2, 0x19, 0x24, 0x5b,
0xdf, 0x04, 0x9a, 0x53, 0x1c, 0x9f, 0x71, 0xea,
0x01, 0xd3, 0xe9, 0x14, 0x87, 0xee, 0x2a, 0x62,
0x53, 0x19, 0x74, 0x64, 0x19, 0x03, 0x00, 0xd6,
0xa1, 0xcb, 0xdf, 0x59, 0x77, 0x6b, 0xa9, 0x25,
0x32, 0xff, 0xe9, 0xa9, 0x41, 0x06, 0x0c, 0x06,
0xd4, 0xae, 0xfb, 0x58, 0x20, 0x2e, 0xe3, 0xe0,
0xce, 0x53, 0xea, 0x03, 0xcb, 0x3f, 0x64, 0xe9,
0xd9, 0xc1, 0x0e, 0xf8, 0xec, 0x97, 0xee, 0x05,
0x42, 0x41, 0x61, 0xcc, 0x75, 0x13, 0x8d, 0x88,
0x62, 0x84, 0xa1, 0x3c, 0xa3, 0x30, 0xce, 0x12,
0xf1, 0x84, 0xee, 0x26, 0x08, 0x04, 0xae, 0x67,
0x56, 0xa0, 0x84, 0x91, 0x8a, 0xbd, 0xc4, 0xba,
0x07, 0xb3, 0x06, 0xe7, 0xc8, 0x12, 0xae, 0x56,
0x46, 0xcd, 0x8d, 0x5c, 0x91, 0x05, 0x90, 0x11,
0x37, 0xef, 0xe0, 0x3e, 0xf3, 0xc6, 0x95, 0x13,
0xeb, 0x2f, 0xe4, 0x3e, 0xfc, 0xe4, 0xc0, 0x61,
0xfb, 0x1b, 0x74, 0x78, 0xe9, 0x6b, 0x7d, 0xe4,
0xa2, 0xc4, 0x6d, 0x26, 0x6d, 0xc0, 0x06, 0xba,
0x9f, 0x7e, 0x7d, 0x5e, 0x7f, 0xfa, 0x66, 0x08,
0xd9, 0x70, 0x39, 0x05, 0xfa, 0x10, 0xfd, 0x5f,
0xaa, 0xc4, 0x9d, 0x02, 0xd4, 0xf8, 0x0f, 0x3f,
0xd3, 0xbe, 0xaa, 0x86, 0x4a, 0x0f, 0x8e, 0x23,
0x02, 0xbf, 0x48, 0x26, 0x93, 0x5f, 0xc2, 0xc5,
0x05, 0xca, 0xa1, 0x6d, 0x96, 0xd1, 0x3a, 0x30,
0x66, 0xe1, 0x97, 0x1d, 0x4c, 0xb0, 0x93, 0xd7,
0x8d, 0x3c, 0xc0, 0xf9, 0x2b, 0x81, 0x0d, 0xd7,
0x68, 0x49, 0x18, 0xab, 0xdc, 0x4b, 0xa0, 0x7b,
0x30, 0x6e, 0x7c, 0x81, 0x2a, 0xe5, 0x64, 0x6c,
0xd8, 0xd5, 0xc9, 0x10, 0x59, 0x01, 0x13, 0x7e,
0xfe, 0x03, 0xef, 0x3c, 0x69, 0x51, 0x3e, 0xb2,
0xfe, 0x43, 0xef, 0xce, 0x4c, 0x06, 0x1f, 0xb1,
0xb7, 0x47, 0x8e, 0x96, 0xb7, 0xde, 0x4a, 0x2c,
0x46, 0xd2, 0x66, 0xdc, 0x00, 0x6b, 0xa9, 0xf7,
0xe7, 0xd5, 0xe7, 0xff, 0xa6, 0x60, 0x8d, 0x97,
0x03, 0x90, 0x5f, 0xa1, 0x0f, 0xd5, 0xfa, 0xac,
0x49, 0xd0, 0x2d, 0x4f, 0x80, 0xf3, 0xfd, 0x3b,
0xea, 0xa8, 0x64, 0xa0, 0xf8, 0xe2, 0x30, 0x2b,
0xf4, 0x80, 0x2c, 0x50, 0x5c, 0xaa, 0x16, 0xd9,
0x6d, 0x13, 0xa3, 0x06, 0x6e, 0x19, 0x71, 0xd4,
0xcb, 0x09, 0x3d, 0x78, 0xd3, 0xcc, 0x0f, 0x92,
0xb8, 0x10, 0xdd, 0x76, 0x88, 0x97, 0x1b, 0x7f,
0xf0, 0x5c, 0xfb, 0x97, 0x66, 0x3e, 0x7f, 0x66,
0xf9, 0xa4, 0xd5, 0x29, 0xb5, 0x54, 0x8a, 0xaa,
0xfc, 0xe2, 0xdb, 0xb7,
};
const char password[] = "password";
word32 passwordSz = (word32)XSTRLEN(password);
/* Decrypt the encrypted PKCS8 key we just made. */
ExpectIntEQ(wc_DecryptPKCS8Key(badPkcs5RsaEnc, sizeof(badPkcs5RsaEnc),
password, (int)passwordSz), ASN_PARSE_E);
#endif
return EXPECT_RESULT();
}
static int test_wc_GetPkcs8TraditionalOffset(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(HAVE_PKCS8)
int length;
int derSz = 0;
word32 inOutIdx;
const char* path = "./certs/server-keyPkcs8.der";
const char* pathAttributes = "./certs/ca-key-pkcs8-attribute.der";
XFILE file = XBADFILE;
byte der[2048];
ExpectTrue((file = XFOPEN(path, "rb")) != XBADFILE);
ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), file), 0);
if (file != XBADFILE)
XFCLOSE(file);
file = XBADFILE; /* reset file to avoid warning of use after close */
/* valid case */
inOutIdx = 0;
ExpectIntGT(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
0);
/* inOutIdx > sz */
inOutIdx = 4000;
ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* null input */
inOutIdx = 0;
ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(NULL, &inOutIdx, 0),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* invalid input, fill buffer with 1's */
XMEMSET(der, 1, sizeof(der));
inOutIdx = 0;
ExpectIntEQ(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx, (word32)derSz),
WC_NO_ERR_TRACE(ASN_PARSE_E));
/* test parsing with attributes */
ExpectTrue((file = XFOPEN(pathAttributes, "rb")) != XBADFILE);
ExpectIntGT(derSz = (int)XFREAD(der, 1, sizeof(der), file), 0);
if (file != XBADFILE)
XFCLOSE(file);
inOutIdx = 0;
ExpectIntGT(length = wc_GetPkcs8TraditionalOffset(der, &inOutIdx,
(word32)derSz), 0);
#endif /* NO_ASN */
return EXPECT_RESULT();
}
static int test_wc_SetSubjectRaw(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
const char* joiCertFile = "./certs/test/cert-ext-joi.der";
WOLFSSL_X509* x509 = NULL;
int peerCertSz;
const byte* peerCertBuf = NULL;
Cert forgedCert;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
WOLFSSL_FILETYPE_ASN1));
ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));
ExpectIntEQ(0, wc_InitCert(&forgedCert));
ExpectIntEQ(0, wc_SetSubjectRaw(&forgedCert, peerCertBuf, peerCertSz));
wolfSSL_FreeX509(x509);
#endif
return EXPECT_RESULT();
}
static int test_wc_GetSubjectRaw(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT)
Cert cert;
byte *subjectRaw;
ExpectIntEQ(0, wc_InitCert(&cert));
ExpectIntEQ(0, wc_GetSubjectRaw(&subjectRaw, &cert));
#endif
return EXPECT_RESULT();
}
static int test_wc_SetIssuerRaw(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
const char* joiCertFile = "./certs/test/cert-ext-joi.der";
WOLFSSL_X509* x509 = NULL;
int peerCertSz;
const byte* peerCertBuf = NULL;
Cert forgedCert;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
WOLFSSL_FILETYPE_ASN1));
ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));
ExpectIntEQ(0, wc_InitCert(&forgedCert));
ExpectIntEQ(0, wc_SetIssuerRaw(&forgedCert, peerCertBuf, peerCertSz));
wolfSSL_FreeX509(x509);
#endif
return EXPECT_RESULT();
}
static int test_wc_SetIssueBuffer(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && !defined(NO_RSA)
const char* joiCertFile = "./certs/test/cert-ext-joi.der";
WOLFSSL_X509* x509 = NULL;
int peerCertSz;
const byte* peerCertBuf = NULL;
Cert forgedCert;
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile,
WOLFSSL_FILETYPE_ASN1));
ExpectNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));
ExpectIntEQ(0, wc_InitCert(&forgedCert));
ExpectIntEQ(0, wc_SetIssuerBuffer(&forgedCert, peerCertBuf, peerCertSz));
wolfSSL_FreeX509(x509);
#endif
return EXPECT_RESULT();
}
/*
* Testing wc_SetSubjectKeyId
*/
static int test_wc_SetSubjectKeyId(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC)
Cert cert;
const char* file = "certs/ecc-client-keyPub.pem";
ExpectIntEQ(0, wc_InitCert(&cert));
ExpectIntEQ(0, wc_SetSubjectKeyId(&cert, file));
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_SetSubjectKeyId(NULL, file));
ExpectIntGT(0, wc_SetSubjectKeyId(&cert, "badfile.name"));
#endif
return EXPECT_RESULT();
} /* END test_wc_SetSubjectKeyId */
/*
* Testing wc_SetSubject
*/
static int test_wc_SetSubject(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC)
Cert cert;
const char* file = "./certs/ca-ecc-cert.pem";
ExpectIntEQ(0, wc_InitCert(&cert));
ExpectIntEQ(0, wc_SetSubject(&cert, file));
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_SetSubject(NULL, file));
ExpectIntGT(0, wc_SetSubject(&cert, "badfile.name"));
#endif
return EXPECT_RESULT();
} /* END test_wc_SetSubject */
static int test_CheckCertSignature(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(WOLFSSL_SMALL_CERT_VERIFY)
WOLFSSL_CERT_MANAGER* cm = NULL;
#if !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
XFILE fp = XBADFILE;
byte cert[4096];
int certSz;
#endif
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_CheckCertSignature(NULL, 0, NULL, NULL));
ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
ExpectIntEQ(WC_NO_ERR_TRACE(BAD_FUNC_ARG), wc_CheckCertSignature(NULL, 0, NULL, cm));
#ifndef NO_RSA
#ifdef USE_CERT_BUFFERS_1024
ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(server_cert_der_1024,
sizeof_server_cert_der_1024, NULL, cm));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
ca_cert_der_1024, sizeof_ca_cert_der_1024,
WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(0, wc_CheckCertSignature(server_cert_der_1024,
sizeof_server_cert_der_1024, NULL, cm));
#elif defined(USE_CERT_BUFFERS_2048)
ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(server_cert_der_2048,
sizeof_server_cert_der_2048, NULL, cm));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
ca_cert_der_2048, sizeof_ca_cert_der_2048,
WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(0, wc_CheckCertSignature(server_cert_der_2048,
sizeof_server_cert_der_2048, NULL, cm));
#endif
#endif
#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)
ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(serv_ecc_der_256,
sizeof_serv_ecc_der_256, NULL, cm));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCABuffer(cm,
ca_ecc_cert_der_256, sizeof_ca_ecc_cert_der_256,
WOLFSSL_FILETYPE_ASN1));
ExpectIntEQ(0, wc_CheckCertSignature(serv_ecc_der_256, sizeof_serv_ecc_der_256,
NULL, cm));
#endif
#if !defined(NO_FILESYSTEM)
wolfSSL_CertManagerFree(cm);
cm = NULL;
ExpectNotNull(cm = wolfSSL_CertManagerNew_ex(NULL));
#ifndef NO_RSA
ExpectTrue((fp = XFOPEN("./certs/server-cert.der", "rb")) != XBADFILE);
ExpectIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(cert, certSz, NULL, cm));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
"./certs/ca-cert.pem", NULL));
ExpectIntEQ(0, wc_CheckCertSignature(cert, certSz, NULL, cm));
#endif
#ifdef HAVE_ECC
ExpectTrue((fp = XFOPEN("./certs/server-ecc.der", "rb")) != XBADFILE);
ExpectIntGT((certSz = (int)XFREAD(cert, 1, sizeof(cert), fp)), 0);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectIntEQ(WC_NO_ERR_TRACE(ASN_NO_SIGNER_E), wc_CheckCertSignature(cert, certSz, NULL, cm));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CertManagerLoadCA(cm,
"./certs/ca-ecc-cert.pem", NULL));
ExpectIntEQ(0, wc_CheckCertSignature(cert, certSz, NULL, cm));
#endif
#endif
#if !defined(NO_FILESYSTEM) && (!defined(NO_RSA) || defined(HAVE_ECC))
(void)fp;
(void)cert;
(void)certSz;
#endif
wolfSSL_CertManagerFree(cm);
#endif
return EXPECT_RESULT();
}
static int test_wc_ParseCert(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA)
DecodedCert decodedCert;
const byte* rawCert = client_cert_der_2048;
const int rawCertSize = sizeof_client_cert_der_2048;
wc_InitDecodedCert(&decodedCert, rawCert, rawCertSize, NULL);
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
#ifndef IGNORE_NAME_CONSTRAINTS
/* check that the subjects emailAddress was not put in the alt name list */
ExpectNotNull(decodedCert.subjectEmail);
ExpectNull(decodedCert.altEmailNames);
#endif
wc_FreeDecodedCert(&decodedCert);
#endif
return EXPECT_RESULT();
}
/* Test wc_ParseCert decoding of various encodings and scenarios ensuring that
* the API safely errors out on badly-formed ASN input.
* NOTE: Test not compatible with released FIPS implementations!
*/
static int test_wc_ParseCert_Error(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_RSA) && !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
DecodedCert decodedCert;
int i;
/* Certificate data */
const byte c0[] = { 0x30, 0x04, 0x30, 0x02, 0x02, 0x80, 0x00, 0x00};
const byte c1[] = { 0x30, 0x04, 0x30, 0x04, 0x02, 0x80, 0x00, 0x00};
const byte c2[] = { 0x30, 0x06, 0x30, 0x04, 0x02, 0x80, 0x00, 0x00};
const byte c3[] = { 0x30, 0x07, 0x30, 0x05, 0x02, 0x80, 0x10, 0x00, 0x00};
const byte c4[] = { 0x02, 0x80, 0x10, 0x00, 0x00};
/* Test data */
struct testStruct {
const byte* c;
word32 cSz;
int expRet;
} t[5];
const int tSz = (int)(sizeof(t) / sizeof(struct testStruct));
#define INIT_TEST_DATA(i,x,y) \
t[i].c = x; t[i].cSz = sizeof(x); t[i].expRet = y
INIT_TEST_DATA(0, c0, WC_NO_ERR_TRACE(ASN_PARSE_E) );
INIT_TEST_DATA(1, c1, WC_NO_ERR_TRACE(ASN_PARSE_E) );
INIT_TEST_DATA(2, c2, WC_NO_ERR_TRACE(ASN_PARSE_E) );
INIT_TEST_DATA(3, c3, WC_NO_ERR_TRACE(ASN_PARSE_E) );
INIT_TEST_DATA(4, c4, WC_NO_ERR_TRACE(ASN_PARSE_E) );
#undef INIT_TEST_DATA
for (i = 0; i < tSz; i++) {
WOLFSSL_MSG_EX("i == %d", i);
wc_InitDecodedCert(&decodedCert, t[i].c, t[i].cSz, NULL);
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), t[i].expRet);
wc_FreeDecodedCert(&decodedCert);
}
#endif
return EXPECT_RESULT();
}
static int test_MakeCertWithPathLen(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) && \
defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
const byte expectedPathLen = 7;
Cert cert;
DecodedCert decodedCert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
int ret;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = 1;
cert.pathLen = expectedPathLen;
cert.pathLenSet = 1;
cert.sigType = CTC_SHA256wECDSA;
#ifdef WOLFSSL_CERT_EXT
cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
FOURK_BUF, NULL, &key, &rng), 0);
wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
ExpectIntEQ(decodedCert.pathLength, expectedPathLen);
wc_FreeDecodedCert(&decodedCert);
ret = wc_ecc_free(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
#endif
return EXPECT_RESULT();
}
static int test_MakeCertWith0Ser(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) && \
defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC) && \
defined(WOLFSSL_ASN_TEMPLATE)
Cert cert;
DecodedCert decodedCert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
int ret;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = 1;
cert.sigType = CTC_SHA256wECDSA;
#ifdef WOLFSSL_CERT_EXT
cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif
/* set serial number to 0 */
cert.serialSz = 1;
cert.serial[0] = 0;
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
FOURK_BUF, NULL, &key, &rng), 0);
wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
!defined(WOLFSSL_ASN_ALLOW_0_SERIAL)
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL),
WC_NO_ERR_TRACE(ASN_PARSE_E));
#else
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
#endif
wc_FreeDecodedCert(&decodedCert);
ret = wc_ecc_free(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
#endif
return EXPECT_RESULT();
}
static int test_MakeCertWithCaFalse(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE) && defined(WOLFSSL_CERT_REQ) && \
!defined(NO_ASN_TIME) && defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
const byte expectedIsCa = 0;
Cert cert;
DecodedCert decodedCert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
int ret;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = expectedIsCa;
cert.isCaSet = 1;
cert.sigType = CTC_SHA256wECDSA;
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
FOURK_BUF, NULL, &key, &rng), 0);
wc_InitDecodedCert(&decodedCert, der, derSize, NULL);
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
ExpectIntEQ(decodedCert.isCA, expectedIsCa);
wc_FreeDecodedCert(&decodedCert);
ret = wc_ecc_free(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
#endif
return EXPECT_RESULT();
}
static int test_ERR_load_crypto_strings(void)
{
#if defined(OPENSSL_ALL)
ERR_load_crypto_strings();
return TEST_SUCCESS;
#else
return TEST_SKIPPED;
#endif
}
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
static WOLFSSL_X509 x1;
static WOLFSSL_X509 x2;
static void free_x509(X509* x)
{
AssertIntEQ((x == &x1 || x == &x2), 1);
}
#endif
static int test_sk_X509(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
{
STACK_OF(X509)* s = NULL;
ExpectNotNull(s = wolfSSL_sk_X509_new(NULL));
ExpectIntEQ(sk_X509_num(s), 0);
sk_X509_pop_free(s, NULL);
ExpectNotNull(s = sk_X509_new_null());
ExpectIntEQ(sk_X509_num(s), 0);
sk_X509_pop_free(s, NULL);
ExpectNotNull(s = sk_X509_new_null());
/* Test invalid parameters. */
ExpectIntEQ(sk_X509_push(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(sk_X509_push(s, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(sk_X509_push(NULL, (X509*)1), WOLFSSL_FAILURE);
ExpectNull(sk_X509_pop(NULL));
ExpectNull(sk_X509_value(NULL, 0));
ExpectNull(sk_X509_value(NULL, 1));
sk_X509_push(s, &x1);
ExpectIntEQ(sk_X509_num(s), 1);
ExpectIntEQ((sk_X509_value(s, 0) == &x1), 1);
sk_X509_push(s, &x2);
ExpectIntEQ(sk_X509_num(s), 2);
ExpectNull(sk_X509_value(s, 2));
ExpectIntEQ((sk_X509_value(s, 0) == &x1), 1);
ExpectIntEQ((sk_X509_value(s, 1) == &x2), 1);
sk_X509_push(s, &x2);
sk_X509_pop_free(s, free_x509);
}
{
/* Push a list of 10 X509s onto stack, then verify that
* value(), push(), shift(), and pop() behave as expected. */
STACK_OF(X509)* s = NULL;
X509* xList[10];
int i = 0;
const int len = (sizeof(xList) / sizeof(xList[0]));
for (i = 0; i < len; ++i) {
xList[i] = NULL;
ExpectNotNull(xList[i] = X509_new());
}
/* test push, pop, and free */
ExpectNotNull(s = sk_X509_new_null());
for (i = 0; i < len; ++i) {
sk_X509_push(s, xList[i]);
ExpectIntEQ(sk_X509_num(s), i + 1);
ExpectIntEQ((sk_X509_value(s, 0) == xList[0]), 1);
ExpectIntEQ((sk_X509_value(s, i) == xList[i]), 1);
}
/* pop returns and removes last pushed on stack, which is the last index
* in sk_x509_value */
for (i = len-1; i >= 0; --i) {
X509 * x = sk_X509_value(s, i);
X509 * y = sk_X509_pop(s);
X509 * z = xList[i];
ExpectPtrEq(x, y);
ExpectPtrEq(x, z);
ExpectIntEQ(sk_X509_num(s), i);
}
sk_free(s);
s = NULL;
/* test push, shift, and free */
ExpectNotNull(s = sk_X509_new_null());
for (i = 0; i < len; ++i) {
sk_X509_push(s, xList[i]);
ExpectIntEQ(sk_X509_num(s), i + 1);
ExpectIntEQ((sk_X509_value(s, 0) == xList[0]), 1);
ExpectIntEQ((sk_X509_value(s, i) == xList[i]), 1);
}
/* shift returns and removes first pushed on stack, which is index i
* in sk_x509_value() */
for (i = 0; i < len; ++i) {
X509 * x = sk_X509_value(s, 0);
X509 * y = sk_X509_shift(s);
X509 * z = xList[i];
ExpectIntEQ((x == y), 1);
ExpectIntEQ((x == z), 1);
ExpectIntEQ(sk_X509_num(s), len - 1 - i);
}
ExpectNull(sk_X509_shift(NULL));
ExpectNull(sk_X509_shift(s));
sk_free(s);
for (i = 0; i < len; ++i)
X509_free(xList[i]);
}
#endif
return EXPECT_RESULT();
}
static int test_sk_X509_CRL(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
!defined(NO_RSA)
X509_CRL* crl = NULL;
XFILE fp = XBADFILE;
STACK_OF(X509_CRL)* s = NULL;
#ifndef NO_BIO
BIO* bio = NULL;
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
RevokedCert* rev = NULL;
byte buff[1024];
int len = 0;
#endif
#if (!defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)) || \
!defined(NO_BIO)
X509_CRL empty;
#endif
WOLFSSL_X509_REVOKED revoked;
WOLFSSL_ASN1_INTEGER* asnInt = NULL;
const WOLFSSL_ASN1_INTEGER* sn = NULL;
#if (!defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)) || \
!defined(NO_BIO)
XMEMSET(&empty, 0, sizeof(X509_CRL));
#endif
#ifndef NO_BIO
ExpectNotNull(bio = BIO_new_file("./certs/crl/crl.der", "rb"));
ExpectNull(wolfSSL_d2i_X509_CRL_bio(NULL, NULL));
ExpectNotNull(crl = wolfSSL_d2i_X509_CRL_bio(bio, NULL));
BIO_free(bio);
bio = NULL;
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(wolfSSL_X509_CRL_print(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_print(bio, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_print(NULL, crl), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_print(bio, &empty), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_print(bio, crl), WOLFSSL_SUCCESS);
#ifndef NO_ASN_TIME
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 1466);
#else
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 1324);
#endif
BIO_free(bio);
bio = NULL;
wolfSSL_X509_CRL_free(crl);
crl = NULL;
#ifndef NO_ASN_TIME
/* Test CRL with invalid GeneralizedTime */
ExpectNotNull(bio = BIO_new_file("./certs/crl/bad_time_fmt.pem", "rb"));
ExpectNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL));
BIO_free(bio);
bio = NULL;
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(wolfSSL_X509_CRL_print(bio, crl), WOLFSSL_FAILURE);
BIO_free(bio);
bio = NULL;
wolfSSL_X509_CRL_free(crl);
crl = NULL;
#endif /* !NO_ASN_TIME */
#endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
ExpectTrue((fp = XFOPEN("./certs/crl/crl.der", "rb")) != XBADFILE);
ExpectNotNull(crl = d2i_X509_CRL_fp(fp, (X509_CRL **)NULL));
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
wolfSSL_X509_CRL_free(crl);
crl = NULL;
ExpectTrue((fp = XFOPEN("./certs/crl/crl.der", "rb")) != XBADFILE);
ExpectIntEQ(len = (int)XFREAD(buff, 1, sizeof(buff), fp), 520);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectNull(crl = d2i_X509_CRL((X509_CRL **)NULL, NULL, len));
ExpectNotNull(crl = d2i_X509_CRL((X509_CRL **)NULL, buff, len));
ExpectNotNull(rev = crl->crlList->certs);
ExpectNull(wolfSSL_X509_CRL_get_issuer_name(NULL));
ExpectNull(wolfSSL_X509_CRL_get_issuer_name(&empty));
ExpectIntEQ(wolfSSL_X509_CRL_version(NULL), 0);
ExpectIntEQ(wolfSSL_X509_CRL_version(&empty), 0);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_type(NULL), 0);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_type(&empty), 0);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(NULL), 0);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(&empty), 0);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, NULL), BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl , NULL, NULL), BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, &len), BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(&empty, NULL, &len),
BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(NULL, NULL, NULL),
BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(rev , NULL, NULL),
BAD_FUNC_ARG);
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(NULL, NULL, &len),
BAD_FUNC_ARG);
ExpectNull(wolfSSL_X509_CRL_get_lastUpdate(NULL));
ExpectNull(wolfSSL_X509_CRL_get_lastUpdate(&empty));
ExpectNull(wolfSSL_X509_CRL_get_nextUpdate(NULL));
ExpectNull(wolfSSL_X509_CRL_get_nextUpdate(&empty));
ExpectNotNull(wolfSSL_X509_CRL_get_issuer_name(crl));
ExpectIntEQ(wolfSSL_X509_CRL_version(crl), 2);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_type(crl), CTC_SHA256wRSA);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(crl),
WC_NID_sha256WithRSAEncryption);
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, NULL, &len),
WOLFSSL_SUCCESS);
ExpectIntEQ(len, 256);
len--;
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, buff, &len), BUFFER_E);
len += 2;
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, buff, &len),
WOLFSSL_SUCCESS);
ExpectIntEQ(len, 256);
ExpectNotNull(wolfSSL_X509_CRL_get_lastUpdate(crl));
ExpectNotNull(wolfSSL_X509_CRL_get_nextUpdate(crl));
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(rev, NULL, &len),
WOLFSSL_SUCCESS);
ExpectIntEQ(len, 1);
len--;
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(rev, buff, &len),
BUFFER_E);
len += 2;
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(rev, buff, &len),
WOLFSSL_SUCCESS);
ExpectIntEQ(len, 1);
#ifndef NO_WOLFSSL_STUB
ExpectIntEQ(wolfSSL_sk_X509_REVOKED_num(NULL), 0);
ExpectIntEQ(wolfSSL_sk_X509_REVOKED_num(&revoked), 0);
ExpectNull(wolfSSL_X509_CRL_get_REVOKED(NULL));
ExpectNull(wolfSSL_X509_CRL_get_REVOKED(crl));
ExpectNull(wolfSSL_sk_X509_REVOKED_value(NULL, 0));
ExpectNull(wolfSSL_sk_X509_REVOKED_value(&revoked, 0));
ExpectIntEQ(wolfSSL_X509_CRL_verify(NULL, NULL), 0);
ExpectIntEQ(X509_OBJECT_set1_X509_CRL(NULL, NULL), 0);
ExpectIntEQ(X509_OBJECT_set1_X509(NULL, NULL), 0);
#endif
wolfSSL_X509_CRL_free(crl);
crl = NULL;
#endif
ExpectNotNull(asnInt = wolfSSL_ASN1_INTEGER_new());
ExpectIntEQ(wolfSSL_ASN1_INTEGER_set(asnInt, 1), 1);
revoked.serialNumber = asnInt;
ExpectNull(wolfSSL_X509_REVOKED_get0_serial_number(NULL));
ExpectNotNull(sn = wolfSSL_X509_REVOKED_get0_serial_number(&revoked));
ExpectPtrEq(sn, asnInt);
#ifndef NO_WOLFSSL_STUB
ExpectNull(wolfSSL_X509_REVOKED_get0_revocation_date(NULL));
ExpectNull(wolfSSL_X509_REVOKED_get0_revocation_date(&revoked));
#endif
wolfSSL_ASN1_INTEGER_free(asnInt);
ExpectTrue((fp = XFOPEN("./certs/crl/crl.pem", "rb")) != XBADFILE);
ExpectNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
NULL, NULL));
if (fp != XBADFILE)
XFCLOSE(fp);
ExpectNotNull(s = sk_X509_CRL_new());
ExpectIntEQ(sk_X509_CRL_push(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(sk_X509_CRL_push(NULL, crl), WOLFSSL_FAILURE);
ExpectIntEQ(sk_X509_CRL_push(s, NULL), WOLFSSL_FAILURE);
ExpectNull(sk_X509_CRL_value(NULL, 0));
ExpectIntEQ(sk_X509_CRL_num(NULL), 0);
ExpectIntEQ(sk_X509_CRL_num(s), 0);
ExpectIntEQ(sk_X509_CRL_push(s, crl), 1);
if (EXPECT_FAIL()) {
X509_CRL_free(crl);
}
ExpectIntEQ(sk_X509_CRL_num(s), 1);
ExpectPtrEq(sk_X509_CRL_value(s, 0), crl);
sk_X509_CRL_free(s);
#endif
return EXPECT_RESULT();
}
static int test_X509_REQ(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_BIO)
X509_NAME* name = NULL;
#ifndef NO_RSA
X509_NAME* subject = NULL;
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC)
X509_REQ* req = NULL;
EVP_PKEY* priv = NULL;
EVP_PKEY* pub = NULL;
unsigned char* der = NULL;
int len;
#endif
#ifndef NO_RSA
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pkctx = NULL;
#ifdef USE_CERT_BUFFERS_1024
const unsigned char* rsaPriv = (const unsigned char*)client_key_der_1024;
const unsigned char* rsaPub = (unsigned char*)client_keypub_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
const unsigned char* rsaPriv = (const unsigned char*)client_key_der_2048;
const unsigned char* rsaPub = (unsigned char*)client_keypub_der_2048;
#endif
#endif
#ifdef HAVE_ECC
const unsigned char* ecPriv = (const unsigned char*)ecc_clikey_der_256;
const unsigned char* ecPub = (unsigned char*)ecc_clikeypub_der_256;
BIO* bio = NULL;
#endif
unsigned char tooLongPassword[WC_CTC_NAME_SIZE + 1];
XMEMSET(tooLongPassword, 0, sizeof(tooLongPassword));
ExpectNotNull(name = X509_NAME_new());
ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
(byte*)"wolfssl.com", 11, 0, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
(byte*)"support@wolfssl.com", 19, -1, 1), WOLFSSL_SUCCESS);
#ifndef NO_RSA
ExpectNotNull(priv = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &rsaPriv,
(long)sizeof_client_key_der_2048));
ExpectNotNull(pub = d2i_PUBKEY(NULL, &rsaPub,
(long)sizeof_client_keypub_der_2048));
ExpectNotNull(req = X509_REQ_new());
ExpectIntEQ(X509_REQ_set_subject_name(NULL, name), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_set_subject_name(req, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_set_pubkey(NULL, pub), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_set_pubkey(req, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_sign(NULL, priv, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_sign(req, NULL, EVP_sha256()), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_sign(req, priv, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
ExpectIntEQ(i2d_X509_REQ(NULL, NULL), BAD_FUNC_ARG);
ExpectIntEQ(i2d_X509_REQ(req, NULL), BAD_FUNC_ARG);
ExpectIntEQ(i2d_X509_REQ(NULL, &der), BAD_FUNC_ARG);
len = i2d_X509_REQ(req, &der);
DEBUG_WRITE_DER(der, len, "req.der");
#ifdef USE_CERT_BUFFERS_1024
ExpectIntEQ(len, 381);
#else
ExpectIntEQ(len, 643);
#endif
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
der = NULL;
mctx = EVP_MD_CTX_new();
ExpectIntEQ(EVP_DigestSignInit(mctx, &pkctx, EVP_sha256(), NULL, priv),
WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_sign_ctx(NULL, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_sign_ctx(req, NULL), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_sign_ctx(NULL, mctx), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_sign_ctx(req, mctx), WOLFSSL_SUCCESS);
EVP_MD_CTX_free(mctx);
mctx = NULL;
X509_REQ_free(NULL);
X509_REQ_free(req);
req = NULL;
/* Test getting the subject from a newly created X509_REQ */
ExpectNotNull(req = X509_REQ_new());
ExpectNotNull(subject = X509_REQ_get_subject_name(req));
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_commonName,
MBSTRING_UTF8, (unsigned char*)"www.wolfssl.com", -1, -1, 0), 1);
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_countryName,
MBSTRING_UTF8, (unsigned char*)"US", -1, -1, 0), 1);
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_localityName,
MBSTRING_UTF8, (unsigned char*)"Bozeman", -1, -1, 0), 1);
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_stateOrProvinceName,
MBSTRING_UTF8, (unsigned char*)"Montana", -1, -1, 0), 1);
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_organizationName,
MBSTRING_UTF8, (unsigned char*)"wolfSSL", -1, -1, 0), 1);
ExpectIntEQ(X509_NAME_add_entry_by_NID(subject, NID_organizationalUnitName,
MBSTRING_UTF8, (unsigned char*)"Testing", -1, -1, 0), 1);
ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
len = i2d_X509_REQ(req, &der);
DEBUG_WRITE_DER(der, len, "req2.der");
#ifdef USE_CERT_BUFFERS_1024
ExpectIntEQ(len, 435);
#else
ExpectIntEQ(len, 696);
#endif
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
der = NULL;
EVP_PKEY_free(pub);
pub = NULL;
EVP_PKEY_free(priv);
priv = NULL;
X509_REQ_free(req);
req = NULL;
#endif
#ifdef HAVE_ECC
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &ecPriv,
sizeof_ecc_clikey_der_256));
ExpectNotNull(pub = wolfSSL_d2i_PUBKEY(NULL, &ecPub,
sizeof_ecc_clikeypub_der_256));
ExpectNotNull(req = X509_REQ_new());
ExpectIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
/* Signature is random and may be shorter or longer. */
ExpectIntGE((len = i2d_X509_REQ(req, &der)), 245);
ExpectIntLE(len, 253);
ExpectNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE));
ExpectIntEQ(X509_REQ_print(bio, req), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_print(bio, NULL), WOLFSSL_FAILURE);
BIO_free(bio);
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
X509_REQ_free(req);
req = NULL;
EVP_PKEY_free(pub);
EVP_PKEY_free(priv);
#ifdef FP_ECC
wc_ecc_fp_free();
#endif
#endif /* HAVE_ECC */
X509_NAME_free(name);
ExpectNull(wolfSSL_X509_REQ_get_extensions(NULL));
/* Stub function. */
ExpectNull(wolfSSL_X509_to_X509_REQ(NULL, NULL, NULL));
ExpectNotNull(req = X509_REQ_new());
#ifdef HAVE_LIBEST
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, NULL,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, NULL,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, "name",
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, NULL,
WOLFSSL_MBSTRING_ASC, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, NULL,
WOLFSSL_MBSTRING_UTF8, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, "name",
WOLFSSL_MBSTRING_ASC, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, NULL,
WOLFSSL_MBSTRING_ASC, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "name",
WOLFSSL_MBSTRING_UTF8, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "name",
WOLFSSL_MBSTRING_ASC, NULL, 0), WOLFSSL_FAILURE);
/* Unsupported bytes. */
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "name",
WOLFSSL_MBSTRING_ASC, (byte*)"1.3.6.1.1.1.1.23", 16), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "MAC Address",
WOLFSSL_MBSTRING_ASC, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "ecpublicKey",
WOLFSSL_MBSTRING_ASC, (byte*)"1.2.840.10045.2.1", -1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "ecdsa-with-SHA384",
WOLFSSL_MBSTRING_ASC, (byte*)"1.2.840.10045.4.3.3", -1),
WOLFSSL_SUCCESS);
#else
/* Stub function. */
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(NULL, NULL,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_REQ_add1_attr_by_txt(req, "MAC Address",
WOLFSSL_MBSTRING_ASC, (byte*)"1.3.6.1.1.1.1.22", 16), WOLFSSL_FAILURE);
#endif
ExpectIntEQ(X509_REQ_add1_attr_by_NID(NULL, WC_NID_subject_alt_name,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_subject_alt_name,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(NULL, WC_NID_subject_alt_name,
WOLFSSL_MBSTRING_ASC, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(NULL, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_UTF8, NULL, 0), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(NULL, WC_NID_subject_alt_name,
WOLFSSL_MBSTRING_UTF8, (byte*)"password", 8), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(NULL, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_ASC, (byte*)"password", 8), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_subject_alt_name,
WOLFSSL_MBSTRING_ASC, (byte*)"password", 8), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_UTF8, (byte*)"password", 8), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_ASC, NULL, -1), WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_ASC, (byte*)"password", -1), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_challengePassword,
WOLFSSL_MBSTRING_ASC, tooLongPassword, sizeof(tooLongPassword)),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_serialNumber,
WOLFSSL_MBSTRING_ASC, (byte*)"123456", -1), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_serialNumber,
WOLFSSL_MBSTRING_ASC, tooLongPassword, sizeof(tooLongPassword)),
WOLFSSL_FAILURE);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_unstructuredName,
WOLFSSL_MBSTRING_ASC, (byte*)"name", 4), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_pkcs9_contentType,
WOLFSSL_MBSTRING_ASC, (byte*)"type", 4), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_surname,
WOLFSSL_MBSTRING_ASC, (byte*)"surname", 7), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_initials,
WOLFSSL_MBSTRING_ASC, (byte*)"s.g", 3), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_givenName,
WOLFSSL_MBSTRING_ASC, (byte*)"givenname", 9), WOLFSSL_SUCCESS);
ExpectIntEQ(X509_REQ_add1_attr_by_NID(req, WC_NID_dnQualifier,
WOLFSSL_MBSTRING_ASC, (byte*)"dnQualifier", 11), WOLFSSL_SUCCESS);
wolfSSL_X509_REQ_free(req);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_REQ_print(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && !defined(NO_BIO)
WOLFSSL_X509* req = NULL;
XFILE fp = XBADFILE;
const char* csrFileName = "certs/csr.attr.der";
const char* csrExtFileName = "certs/csr.ext.der";
BIO* bio = NULL;
ExpectTrue((fp = XFOPEN(csrFileName, "rb")) != XBADFILE);
ExpectNotNull(req = d2i_X509_REQ_fp(fp, NULL));
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(wolfSSL_X509_REQ_print(bio, req), WOLFSSL_SUCCESS);
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 2681);
BIO_free(bio);
bio = NULL;
wolfSSL_X509_REQ_free(req);
req = NULL;
ExpectTrue((fp = XFOPEN(csrExtFileName, "rb")) != XBADFILE);
ExpectNotNull(req = d2i_X509_REQ_fp(fp, NULL));
if (fp != XBADFILE) {
XFCLOSE(fp);
}
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(wolfSSL_X509_REQ_print(bio, req), WOLFSSL_SUCCESS);
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 1889);
BIO_free(bio);
wolfSSL_X509_REQ_free(req);
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Certificate Failure Checks
*----------------------------------------------------------------------------*/
#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
!defined(WOLFSSL_NO_CLIENT_AUTH)) && !defined(NO_FILESYSTEM)
#if (!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_SHA256)
/* Use the Cert Manager(CM) API to generate the error ASN_SIG_CONFIRM_E */
#ifndef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
static int verify_sig_cm(const char* ca, byte* cert_buf, size_t cert_sz,
int type)
{
int ret;
WOLFSSL_CERT_MANAGER* cm = NULL;
switch (type) {
case TESTING_RSA:
#ifdef NO_RSA
fprintf(stderr, "RSA disabled, skipping test\n");
return ASN_SIG_CONFIRM_E;
#else
break;
#endif
case TESTING_ECC:
#ifndef HAVE_ECC
fprintf(stderr, "ECC disabled, skipping test\n");
return ASN_SIG_CONFIRM_E;
#else
break;
#endif
default:
fprintf(stderr, "Bad function argument\n");
return BAD_FUNC_ARG;
}
cm = wolfSSL_CertManagerNew();
if (cm == NULL) {
fprintf(stderr, "wolfSSL_CertManagerNew failed\n");
return -1;
}
#ifndef NO_FILESYSTEM
ret = wolfSSL_CertManagerLoadCA(cm, ca, 0);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_CertManagerLoadCA failed\n");
wolfSSL_CertManagerFree(cm);
return ret;
}
#else
(void)ca;
#endif
ret = wolfSSL_CertManagerVerifyBuffer(cm, cert_buf, (long int)cert_sz,
WOLFSSL_FILETYPE_ASN1);
/* Let ExpectIntEQ handle return code */
wolfSSL_CertManagerFree(cm);
return ret;
}
#if !defined(NO_FILESYSTEM)
static int test_RsaSigFailure_cm(void)
{
EXPECT_DECLS;
#ifndef NO_RSA
#ifdef WOLFSSL_PEM_TO_DER
const char* ca_cert = "./certs/ca-cert.pem";
#else
const char* ca_cert = "./certs/ca-cert.der";
#endif
const char* server_cert = "./certs/server-cert.der";
byte* cert_buf = NULL;
size_t cert_sz = 0;
ExpectIntEQ(load_file(server_cert, &cert_buf, &cert_sz), 0);
if ((cert_buf != NULL) && (cert_sz > 0)) {
/* corrupt DER - invert last byte, which is signature */
cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1];
/* test bad cert */
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_ASN_CRYPT)
/* RSA verify is not called when ASN crypt support is disabled */
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
WOLFSSL_SUCCESS);
#else
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_RSA),
WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E));
#endif
}
/* load_file() uses malloc. */
if (cert_buf != NULL) {
free(cert_buf);
}
#endif /* !NO_RSA */
return EXPECT_RESULT();
}
static int test_EccSigFailure_cm(void)
{
EXPECT_DECLS;
#ifdef HAVE_ECC
/* self-signed ECC cert, so use server cert as CA */
#ifdef WOLFSSL_PEM_TO_DER
const char* ca_cert = "./certs/ca-ecc-cert.pem";
#else
const char* ca_cert = "./certs/ca-ecc-cert.der";
#endif
const char* server_cert = "./certs/server-ecc.der";
byte* cert_buf = NULL;
size_t cert_sz = 0;
ExpectIntEQ(load_file(server_cert, &cert_buf, &cert_sz), 0);
if (cert_buf != NULL && cert_sz > 0) {
/* corrupt DER - invert last byte, which is signature */
cert_buf[cert_sz-1] = ~cert_buf[cert_sz-1];
/* test bad cert */
#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
#elif defined(NO_ASN_CRYPT)
/* ECC verify is not called when ASN crypt support is disabled */
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
WOLFSSL_SUCCESS);
#else
ExpectIntEQ(verify_sig_cm(ca_cert, cert_buf, cert_sz, TESTING_ECC),
WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E));
#endif
}
/* load_file() uses malloc. */
if (cert_buf != NULL) {
free(cert_buf);
}
#ifdef FP_ECC
wc_ecc_fp_free();
#endif
#endif /* HAVE_ECC */
return EXPECT_RESULT();
}
#endif /* !NO_FILESYSTEM */
#endif /* !WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION*/
#endif /* !NO_RSA || HAVE_ECC */
#endif /* NO_CERTS */
#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFSSL_NO_TLS12)
#if !defined(NO_FILESYSTEM) && !defined(NO_DH) && \
!defined(NO_AES) && defined(HAVE_AES_CBC) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int my_DhCallback(WOLFSSL* ssl, struct DhKey* key,
const unsigned char* priv, unsigned int privSz,
const unsigned char* pubKeyDer, unsigned int pubKeySz,
unsigned char* out, unsigned int* outlen,
void* ctx)
{
int result;
/* Test fail when context associated with WOLFSSL is NULL */
if (ctx == NULL) {
return -1;
}
(void)ssl;
/* return 0 on success */
PRIVATE_KEY_UNLOCK();
result = wc_DhAgree(key, out, outlen, priv, privSz, pubKeyDer, pubKeySz);
PRIVATE_KEY_LOCK();
return result;
}
static int test_dh_ctx_setup(WOLFSSL_CTX* ctx) {
EXPECT_DECLS;
wolfSSL_CTX_SetDhAgreeCb(ctx, my_DhCallback);
#if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, "DHE-RSA-AES128-SHA256"),
WOLFSSL_SUCCESS);
#endif
#if defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, "DHE-RSA-AES256-SHA256"),
WOLFSSL_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_dh_ssl_setup(WOLFSSL* ssl)
{
EXPECT_DECLS;
static int dh_test_ctx = 1;
int ret;
wolfSSL_SetDhAgreeCtx(ssl, &dh_test_ctx);
ExpectIntEQ(*((int*)wolfSSL_GetDhAgreeCtx(ssl)), dh_test_ctx);
ret = wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(SIDE_ERROR)) {
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
}
return EXPECT_RESULT();
}
static int test_dh_ssl_setup_fail(WOLFSSL* ssl)
{
EXPECT_DECLS;
int ret;
wolfSSL_SetDhAgreeCtx(ssl, NULL);
ExpectNull(wolfSSL_GetDhAgreeCtx(ssl));
ret = wolfSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
if (ret != WOLFSSL_SUCCESS && ret != WC_NO_ERR_TRACE(SIDE_ERROR)) {
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
}
return EXPECT_RESULT();
}
#endif
static int test_DhCallbacks(void)
{
EXPECT_DECLS;
#if !defined(NO_FILESYSTEM) && !defined(NO_DH) && \
!defined(NO_AES) && defined(HAVE_AES_CBC) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
int test;
test_ssl_cbf func_cb_client;
test_ssl_cbf func_cb_server;
/* Test that DH callback APIs work. */
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(wolfSSL_CTX_set_cipher_list(NULL, "NONE"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
wolfSSL_CTX_SetDhAgreeCb(ctx, &my_DhCallback);
/* load client ca cert */
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0),
WOLFSSL_SUCCESS);
/* test with NULL arguments */
wolfSSL_SetDhAgreeCtx(NULL, &test);
ExpectNull(wolfSSL_GetDhAgreeCtx(NULL));
/* test success case */
test = 1;
ExpectNotNull(ssl = wolfSSL_new(ctx));
wolfSSL_SetDhAgreeCtx(ssl, &test);
ExpectIntEQ(*((int*)wolfSSL_GetDhAgreeCtx(ssl)), test);
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
/* set callbacks to use DH functions */
func_cb_client.ctx_ready = &test_dh_ctx_setup;
func_cb_client.ssl_ready = &test_dh_ssl_setup;
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_server.ctx_ready = &test_dh_ctx_setup;
func_cb_server.ssl_ready = &test_dh_ssl_setup;
func_cb_server.method = wolfTLSv1_2_server_method;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), TEST_SUCCESS);
/* Test fail */
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
/* set callbacks to use DH functions */
func_cb_client.ctx_ready = &test_dh_ctx_setup;
func_cb_client.ssl_ready = &test_dh_ssl_setup_fail;
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_server.ctx_ready = &test_dh_ctx_setup;
func_cb_server.ssl_ready = &test_dh_ssl_setup_fail;
func_cb_server.method = wolfTLSv1_2_server_method;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client,
&func_cb_server, NULL), -1001);
#endif
return EXPECT_RESULT();
}
#endif /* HAVE_PK_CALLBACKS */
static int test_wolfSSL_X509_CRL(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL)
X509_CRL *crl = NULL;
char pem[][100] = {
"./certs/crl/crl.pem",
"./certs/crl/crl2.pem",
"./certs/crl/caEccCrl.pem",
"./certs/crl/eccCliCRL.pem",
"./certs/crl/eccSrvCRL.pem",
""
};
#ifndef NO_BIO
BIO *bio = NULL;
#endif
#ifdef HAVE_TEST_d2i_X509_CRL_fp
char der[][100] = {
"./certs/crl/crl.der",
"./certs/crl/crl2.der",
""};
#endif
XFILE fp = XBADFILE;
int i;
for (i = 0; pem[i][0] != '\0'; i++)
{
ExpectTrue((fp = XFOPEN(pem[i], "rb")) != XBADFILE);
ExpectNotNull(crl = (X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
NULL, NULL));
ExpectNotNull(crl);
X509_CRL_free(crl);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectTrue((fp = XFOPEN(pem[i], "rb")) != XBADFILE);
ExpectNotNull((X509_CRL *)PEM_read_X509_CRL(fp, (X509_CRL **)&crl, NULL,
NULL));
if (EXPECT_FAIL()) {
crl = NULL;
}
ExpectNotNull(crl);
X509_CRL_free(crl);
crl = NULL;
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
}
#ifndef NO_BIO
for (i = 0; pem[i][0] != '\0'; i++)
{
ExpectNotNull(bio = BIO_new_file(pem[i], "rb"));
ExpectNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL));
X509_CRL_free(crl);
crl = NULL;
BIO_free(bio);
bio = NULL;
}
#endif
#ifdef HAVE_TEST_d2i_X509_CRL_fp
for (i = 0; der[i][0] != '\0'; i++) {
ExpectTrue((fp = XFOPEN(der[i], "rb")) != XBADFILE);
ExpectTrue((fp != XBADFILE));
ExpectNotNull(crl = (X509_CRL *)d2i_X509_CRL_fp((fp, X509_CRL **)NULL));
ExpectNotNull(crl);
X509_CRL_free(crl);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
fp = XFOPEN(der[i], "rb");
ExpectTrue((fp != XBADFILE));
ExpectNotNull((X509_CRL *)d2i_X509_CRL_fp(fp, (X509_CRL **)&crl));
if (EXPECT_FAIL()) {
crl = NULL;
}
ExpectNotNull(crl);
X509_CRL_free(crl);
crl = NULL;
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
}
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_d2i_X509_REQ(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_RSA) && !defined(NO_BIO) && \
(defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
!defined(WOLFSSL_SP_MATH)
/* ./certs/csr.signed.der, ./certs/csr.ext.der, and ./certs/csr.attr.der
* were generated by libest
* ./certs/csr.attr.der contains sample attributes
* ./certs/csr.ext.der contains sample extensions */
const char* csrFile = "./certs/csr.signed.der";
const char* csrPopFile = "./certs/csr.attr.der";
const char* csrExtFile = "./certs/csr.ext.der";
/* ./certs/csr.dsa.pem is generated using
* openssl req -newkey dsa:certs/dsaparams.pem \
* -keyout certs/csr.dsa.key.pem -keyform PEM -out certs/csr.dsa.pem \
* -outform PEM
* with the passphrase "wolfSSL"
*/
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
const char* csrDsaFile = "./certs/csr.dsa.pem";
XFILE f = XBADFILE;
#endif
BIO* bio = NULL;
X509* req = NULL;
EVP_PKEY *pub_key = NULL;
{
ExpectNotNull(bio = BIO_new_file(csrFile, "rb"));
ExpectNotNull(d2i_X509_REQ_bio(bio, &req));
/*
* Extract the public key from the CSR
*/
ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));
/*
* Verify the signature in the CSR
*/
ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);
X509_free(req);
req = NULL;
BIO_free(bio);
bio = NULL;
EVP_PKEY_free(pub_key);
pub_key = NULL;
}
{
X509_REQ* empty = NULL;
#ifdef OPENSSL_ALL
X509_ATTRIBUTE* attr = NULL;
ASN1_TYPE *at = NULL;
#endif
ExpectNotNull(empty = wolfSSL_X509_REQ_new());
ExpectNotNull(bio = BIO_new_file(csrPopFile, "rb"));
ExpectNotNull(d2i_X509_REQ_bio(bio, &req));
/*
* Extract the public key from the CSR
*/
ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));
/*
* Verify the signature in the CSR
*/
ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);
ExpectIntEQ(wolfSSL_X509_REQ_get_attr_count(NULL), 0);
ExpectIntEQ(wolfSSL_X509_REQ_get_attr_count(empty), 0);
#ifdef OPENSSL_ALL
ExpectIntEQ(wolfSSL_X509_REQ_get_attr_count(req), 2);
#else
ExpectIntEQ(wolfSSL_X509_REQ_get_attr_count(req), 0);
#endif
#ifdef OPENSSL_ALL
/*
* Obtain the challenge password from the CSR
*/
ExpectIntEQ(X509_REQ_get_attr_by_NID(NULL, NID_pkcs9_challengePassword,
-1), -1);
ExpectIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword,
-1), 1);
ExpectNull(X509_REQ_get_attr(NULL, 3));
ExpectNull(X509_REQ_get_attr(req, 3));
ExpectNull(X509_REQ_get_attr(NULL, 0));
ExpectNull(X509_REQ_get_attr(empty, 0));
ExpectNotNull(attr = X509_REQ_get_attr(req, 1));
ExpectNull(X509_ATTRIBUTE_get0_type(NULL, 1));
ExpectNull(X509_ATTRIBUTE_get0_type(attr, 1));
ExpectNull(X509_ATTRIBUTE_get0_type(NULL, 0));
ExpectNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
ExpectNotNull(at->value.asn1_string);
ExpectStrEQ((char*)ASN1_STRING_data(at->value.asn1_string),
"2xIE+qqp/rhyTXP+");
ExpectIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1);
#endif
X509_free(req);
req = NULL;
BIO_free(bio);
bio = NULL;
EVP_PKEY_free(pub_key);
pub_key = NULL;
wolfSSL_X509_REQ_free(empty);
}
{
#ifdef OPENSSL_ALL
X509_ATTRIBUTE* attr = NULL;
ASN1_TYPE *at = NULL;
STACK_OF(X509_EXTENSION) *exts = NULL;
#endif
ExpectNotNull(bio = BIO_new_file(csrExtFile, "rb"));
/* This CSR contains an Extension Request attribute so
* we test extension parsing in a CSR attribute here. */
ExpectNotNull(d2i_X509_REQ_bio(bio, &req));
/*
* Extract the public key from the CSR
*/
ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));
/*
* Verify the signature in the CSR
*/
ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);
#ifdef OPENSSL_ALL
ExpectNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(
req));
ExpectIntEQ(sk_X509_EXTENSION_num(exts), 2);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
/*
* Obtain the challenge password from the CSR
*/
ExpectIntEQ(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword,
-1), 0);
ExpectNotNull(attr = X509_REQ_get_attr(req, 0));
ExpectNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
ExpectNotNull(at->value.asn1_string);
ExpectStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo");
ExpectIntGE(X509_get_ext_by_NID(req, NID_key_usage, -1), 0);
ExpectIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0);
#endif
X509_free(req);
req = NULL;
BIO_free(bio);
bio = NULL;
EVP_PKEY_free(pub_key);
pub_key = NULL;
}
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
{
ExpectNotNull(bio = BIO_new_file(csrDsaFile, "rb"));
ExpectNotNull(PEM_read_bio_X509_REQ(bio, &req, NULL, NULL));
/*
* Extract the public key from the CSR
*/
ExpectNotNull(pub_key = X509_REQ_get_pubkey(req));
/*
* Verify the signature in the CSR
*/
ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);
X509_free(req);
req = NULL;
BIO_free(bio);
/* Run the same test, but with a file pointer instead of a BIO.
* (PEM_read_X509_REQ)*/
ExpectTrue((f = XFOPEN(csrDsaFile, "rb")) != XBADFILE);
ExpectNull(PEM_read_X509_REQ(XBADFILE, &req, NULL, NULL));
if (EXPECT_SUCCESS())
ExpectNotNull(PEM_read_X509_REQ(f, &req, NULL, NULL));
else if (f != XBADFILE)
XFCLOSE(f);
ExpectIntEQ(X509_REQ_verify(req, pub_key), 1);
X509_free(req);
EVP_PKEY_free(pub_key);
}
#endif /* !NO_DSA && !HAVE_SELFTEST */
#endif /* WOLFSSL_CERT_REQ && (OPENSSL_ALL || OPENSSL_EXTRA) */
return EXPECT_RESULT();
}
static int test_wolfSSL_PEM_read(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_BIO)
const char* filename = "./certs/server-keyEnc.pem";
XFILE fp = XBADFILE;
char* name = NULL;
char* header = NULL;
byte* data = NULL;
long len;
EVP_CIPHER_INFO cipher;
WOLFSSL_BIO* bio = NULL;
byte* fileData = NULL;
size_t fileDataSz = 0;
byte* out;
ExpectNotNull(bio = BIO_new_file(filename, "rb"));
ExpectIntEQ(PEM_read_bio(bio, NULL, &header, &data, &len), 0);
ExpectIntEQ(PEM_read_bio(bio, &name, NULL, &data, &len), 0);
ExpectIntEQ(PEM_read_bio(bio, &name, &header, NULL, &len), 0);
ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, NULL), 0);
ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
ExpectIntGT(XSTRLEN(header), 0);
ExpectIntGT(len, 0);
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
name = NULL;
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
header = NULL;
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
data = NULL;
BIO_free(bio);
bio = NULL;
ExpectTrue((fp = XFOPEN(filename, "rb")) != XBADFILE);
/* Fail cases. */
ExpectIntEQ(PEM_read(fp, NULL, &header, &data, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_read(fp, &name, NULL, &data, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_read(fp, &name, &header, NULL, &len), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_read(fp, &name, &header, &data, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);
ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
ExpectIntGT(XSTRLEN(header), 0);
ExpectIntGT(len, 0);
ExpectIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
ExpectIntGT((fileDataSz = XFTELL(fp)), 0);
ExpectIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
ExpectNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
if (fp != XBADFILE) {
XFCLOSE(fp);
fp = XBADFILE;
}
ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
/* Fail cases. */
ExpectIntEQ(PEM_write_bio(NULL, name, header, data, len), 0);
ExpectIntEQ(PEM_write_bio(bio, NULL, header, data, len), 0);
ExpectIntEQ(PEM_write_bio(bio, name, NULL, data, len), 0);
ExpectIntEQ(PEM_write_bio(bio, name, header, NULL, len), 0);
ExpectIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
ExpectIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
ExpectIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);
/* Fail cases. */
ExpectIntEQ(PEM_write(XBADFILE, name, header, data, len), 0);
ExpectIntEQ(PEM_write(stderr, NULL, header, data, len), 0);
ExpectIntEQ(PEM_write(stderr, name, NULL, data, len), 0);
ExpectIntEQ(PEM_write(stderr, name, header, NULL, len), 0);
/* Pass case */
ExpectIntEQ(PEM_write(stderr, name, header, data, len), fileDataSz);
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
name = NULL;
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
header = NULL;
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
data = NULL;
/* Read out of a fixed buffer BIO - forces malloc in PEM_read_bio. */
ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
ExpectIntGT(XSTRLEN(header), 0);
ExpectIntGT(len, 0);
/* Fail cases. */
ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(NULL, &cipher), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(header, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_get_EVP_CIPHER_INFO((char*)"", &cipher), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#ifndef NO_DES3
ExpectIntEQ(PEM_get_EVP_CIPHER_INFO(header, &cipher), WOLFSSL_SUCCESS);
#endif
/* Fail cases. */
ExpectIntEQ(PEM_do_header(NULL, data, &len, PasswordCallBack,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_do_header(&cipher, NULL, &len, PasswordCallBack,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_do_header(&cipher, data, NULL, PasswordCallBack,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_do_header(&cipher, data, &len, NULL,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(PEM_do_header(&cipher, data, &len, NoPasswordCallBack,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if !defined(NO_DES3) && !defined(NO_MD5)
ExpectIntEQ(PEM_do_header(&cipher, data, &len, PasswordCallBack,
(void*)"yassl123"), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(PEM_do_header(&cipher, data, &len, PasswordCallBack,
(void*)"yassl123"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
BIO_free(bio);
bio = NULL;
XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
fileData = NULL;
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
name = NULL;
header = NULL;
data = NULL;
ExpectTrue((fp = XFOPEN(svrKeyFile, "rb")) != XBADFILE);
ExpectIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);
ExpectIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
ExpectIntEQ(XSTRLEN(header), 0);
ExpectIntGT(len, 0);
ExpectIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
ExpectIntGT((fileDataSz = XFTELL(fp)), 0);
ExpectIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
ExpectNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
ExpectIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
if (fp != XBADFILE)
XFCLOSE(fp);
ExpectNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
ExpectIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
ExpectIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
ExpectIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);
BIO_free(bio);
XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_dup_CA_list(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_ALL)
EXPECT_DECLS;
STACK_OF(X509_NAME) *originalStack = NULL;
STACK_OF(X509_NAME) *copyStack = NULL;
int originalCount = 0;
int copyCount = 0;
X509_NAME *name = NULL;
int i;
originalStack = sk_X509_NAME_new_null();
ExpectNotNull(originalStack);
for (i = 0; i < 3; i++) {
name = X509_NAME_new();
ExpectNotNull(name);
ExpectIntEQ(sk_X509_NAME_push(originalStack, name), i+1);
if (EXPECT_FAIL()) {
X509_NAME_free(name);
}
}
copyStack = SSL_dup_CA_list(originalStack);
ExpectNotNull(copyStack);
ExpectIntEQ(sk_X509_NAME_num(NULL), BAD_FUNC_ARG);
originalCount = sk_X509_NAME_num(originalStack);
copyCount = sk_X509_NAME_num(copyStack);
ExpectIntEQ(originalCount, copyCount);
sk_X509_NAME_pop_free(originalStack, X509_NAME_free);
sk_X509_NAME_pop_free(copyStack, X509_NAME_free);
originalStack = NULL;
copyStack = NULL;
originalStack = sk_X509_NAME_new_null();
ExpectNull(sk_X509_NAME_pop(NULL));
ExpectNull(sk_X509_NAME_pop(originalStack));
for (i = 0; i < 3; i++) {
name = X509_NAME_new();
ExpectNotNull(name);
ExpectIntEQ(sk_X509_NAME_push(originalStack, name), i+1);
if (EXPECT_FAIL()) {
X509_NAME_free(name);
}
name = NULL;
}
ExpectNotNull(name = sk_X509_NAME_pop(originalStack));
X509_NAME_free(name);
wolfSSL_sk_X509_NAME_set_cmp_func(NULL, NULL);
wolfSSL_sk_X509_NAME_set_cmp_func(originalStack, NULL);
wolfSSL_sk_X509_NAME_pop_free(originalStack, X509_NAME_free);
res = EXPECT_RESULT();
#endif /* OPENSSL_ALL */
return res;
}
static int test_ForceZero(void)
{
EXPECT_DECLS;
unsigned char data[32];
unsigned int i, j, len;
/* Test case with 0 length */
ForceZero(data, 0);
/* Test ForceZero */
for (i = 0; i < sizeof(data); i++) {
for (len = 1; len < sizeof(data) - i; len++) {
for (j = 0; j < sizeof(data); j++)
data[j] = ((unsigned char)j + 1);
ForceZero(data + i, len);
for (j = 0; j < sizeof(data); j++) {
if (j < i || j >= i + len) {
ExpectIntNE(data[j], 0x00);
}
else {
ExpectIntEQ(data[j], 0x00);
}
}
}
}
return EXPECT_RESULT();
}
#ifndef NO_BIO
static int test_wolfSSL_X509_print(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \
!defined(NO_RSA) && defined(XSNPRINTF)
X509 *x509 = NULL;
BIO *bio = NULL;
#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR)
const X509_ALGOR *cert_sig_alg = NULL;
#endif
ExpectNotNull(x509 = X509_load_certificate_file(svrCertFile,
WOLFSSL_FILETYPE_PEM));
/* print to memory */
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(X509_print(bio, x509), SSL_SUCCESS);
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
#if defined(WC_DISABLE_RADIX_ZERO_PAD)
/* Will print IP address subject alt name. */
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3349);
#elif defined(NO_ASN_TIME)
/* Will print IP address subject alt name but not Validity. */
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3235);
#else
/* Will print IP address subject alt name. */
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3350);
#endif
#elif defined(NO_ASN_TIME)
/* With NO_ASN_TIME defined, X509_print skips printing Validity. */
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3213);
#else
ExpectIntEQ(BIO_get_mem_data(bio, NULL), 3328);
#endif
BIO_free(bio);
bio = NULL;
ExpectNotNull(bio = BIO_new_fd(STDERR_FILENO, BIO_NOCLOSE));
#if defined(OPENSSL_ALL) && !defined(NO_WOLFSSL_DIR)
/* Print signature */
ExpectNotNull(cert_sig_alg = X509_get0_tbs_sigalg(x509));
ExpectIntEQ(X509_signature_print(bio, cert_sig_alg, NULL), SSL_SUCCESS);
#endif
/* print to stderr */
#if !defined(NO_WOLFSSL_DIR)
ExpectIntEQ(X509_print(bio, x509), SSL_SUCCESS);
#endif
/* print again */
ExpectIntEQ(X509_print_fp(stderr, x509), SSL_SUCCESS);
X509_free(x509);
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_CRL_print(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
!defined(NO_RSA) && !defined(NO_FILESYSTEM) && defined(XSNPRINTF)
X509_CRL* crl = NULL;
BIO *bio = NULL;
XFILE fp = XBADFILE;
ExpectTrue((fp = XFOPEN("./certs/crl/crl.pem", "rb")) != XBADFILE);
ExpectNotNull(crl = (X509_CRL*)PEM_read_X509_CRL(fp, (X509_CRL **)NULL,
NULL, NULL));
if (fp != XBADFILE)
XFCLOSE(fp);
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(X509_CRL_print(bio, crl), SSL_SUCCESS);
X509_CRL_free(crl);
BIO_free(bio);
#endif
return EXPECT_RESULT();
}
#endif /* !NO_BIO */
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
!defined(NO_ASN_TIME)
static int test_openssl_make_self_signed_certificate(EVP_PKEY* pkey,
int expectedDerSz)
{
EXPECT_DECLS;
X509* x509 = NULL;
BIGNUM* serial_number = NULL;
X509_NAME* name = NULL;
time_t epoch_off = 0;
ASN1_INTEGER* asn1_serial_number = NULL;
long not_before, not_after;
int derSz;
ExpectNotNull(x509 = X509_new());
ExpectIntNE(X509_set_pubkey(x509, pkey), 0);
ExpectNotNull(serial_number = BN_new());
ExpectIntNE(BN_pseudo_rand(serial_number, 64, 0, 0), 0);
ExpectNotNull(asn1_serial_number = X509_get_serialNumber(x509));
ExpectNotNull(BN_to_ASN1_INTEGER(serial_number, asn1_serial_number));
/* version 3 */
ExpectIntNE(X509_set_version(x509, 2L), 0);
ExpectNotNull(name = X509_NAME_new());
ExpectIntNE(X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
(unsigned char*)"www.wolfssl.com", -1, -1, 0), 0);
ExpectIntNE(X509_NAME_add_entry_by_NID(name, NID_pkcs9_contentType,
MBSTRING_UTF8,(unsigned char*)"Server", -1, -1, 0), 0);
ExpectIntNE(X509_set_subject_name(x509, name), 0);
ExpectIntNE(X509_set_issuer_name(x509, name), 0);
not_before = (long)wc_Time(NULL);
not_after = not_before + (365 * 24 * 60 * 60);
ExpectNotNull(X509_time_adj(X509_get_notBefore(x509), not_before,
&epoch_off));
ExpectNotNull(X509_time_adj(X509_get_notAfter(x509), not_after,
&epoch_off));
ExpectIntNE(X509_sign(x509, pkey, EVP_sha256()), 0);
ExpectNotNull(wolfSSL_X509_get_der(x509, &derSz));
ExpectIntGE(derSz, expectedDerSz);
BN_free(serial_number);
X509_NAME_free(name);
X509_free(x509);
return EXPECT_RESULT();
}
#endif
static int test_openssl_generate_key_and_cert(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
int expectedDerSz;
EVP_PKEY* pkey = NULL;
#ifdef HAVE_ECC
EC_KEY* ec_key = NULL;
#endif
#if !defined(NO_RSA)
int key_length = 2048;
BIGNUM* exponent = NULL;
RSA* rsa = NULL;
ExpectNotNull(pkey = EVP_PKEY_new());
ExpectNotNull(exponent = BN_new());
ExpectNotNull(rsa = RSA_new());
ExpectIntNE(BN_set_word(exponent, WC_RSA_EXPONENT), 0);
#ifndef WOLFSSL_KEY_GEN
ExpectIntEQ(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0);
#if defined(USE_CERT_BUFFERS_1024)
ExpectIntNE(wolfSSL_RSA_LoadDer_ex(rsa, server_key_der_1024,
sizeof_server_key_der_1024, WOLFSSL_RSA_LOAD_PRIVATE), 0);
key_length = 1024;
#elif defined(USE_CERT_BUFFERS_2048)
ExpectIntNE(wolfSSL_RSA_LoadDer_ex(rsa, server_key_der_2048,
sizeof_server_key_der_2048, WOLFSSL_RSA_LOAD_PRIVATE), 0);
#else
RSA_free(rsa);
rsa = NULL;
#endif
#else
ExpectIntEQ(RSA_generate_key_ex(NULL, key_length, exponent, NULL), 0);
ExpectIntEQ(RSA_generate_key_ex(rsa, 0, exponent, NULL), 0);
ExpectIntEQ(RSA_generate_key_ex(rsa, key_length, NULL, NULL), 0);
ExpectIntNE(RSA_generate_key_ex(rsa, key_length, exponent, NULL), 0);
#endif
if (rsa) {
ExpectIntNE(EVP_PKEY_assign_RSA(pkey, rsa), 0);
if (EXPECT_FAIL()) {
RSA_free(rsa);
}
#if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \
defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME)
expectedDerSz = 743;
ExpectIntEQ(test_openssl_make_self_signed_certificate(pkey,
expectedDerSz), TEST_SUCCESS);
#endif
}
EVP_PKEY_free(pkey);
pkey = NULL;
BN_free(exponent);
#endif /* !NO_RSA */
#ifdef HAVE_ECC
ExpectNotNull(pkey = EVP_PKEY_new());
ExpectNotNull(ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
#ifndef NO_WOLFSSL_STUB
EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
#endif
ExpectIntNE(EC_KEY_generate_key(ec_key), 0);
ExpectIntNE(EVP_PKEY_assign_EC_KEY(pkey, ec_key), 0);
if (EXPECT_FAIL()) {
EC_KEY_free(ec_key);
}
#if !defined(NO_CERTS) && defined(WOLFSSL_CERT_GEN) && \
defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME)
expectedDerSz = 344;
ExpectIntEQ(test_openssl_make_self_signed_certificate(pkey, expectedDerSz),
TEST_SUCCESS);
#endif
EVP_PKEY_free(pkey);
#endif /* HAVE_ECC */
(void)pkey;
(void)expectedDerSz;
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_stubs_are_stubs(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_WOLFSSL_STUB) && \
!defined(NO_TLS) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CTX* ctx = NULL;
WOLFSSL_CTX* ctxN = NULL;
#ifndef NO_WOLFSSL_CLIENT
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#elif !defined(NO_WOLFSSL_SERVER)
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
#define CHECKZERO_RET(x, y, z) ExpectIntEQ((int) x(y), 0); \
ExpectIntEQ((int) x(z), 0)
/* test logic, all stubs return same result regardless of ctx being NULL
* as there are no sanity checks, it's just a stub! If at some
* point a stub is not a stub it should begin to return BAD_FUNC_ARG
* if invalid inputs are supplied. Test calling both
* with and without valid inputs, if a stub functionality remains unchanged.
*/
CHECKZERO_RET(wolfSSL_CTX_sess_accept, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_connect, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_accept_good, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_connect_good, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_accept_renegotiate, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_connect_renegotiate, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_hits, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_cb_hits, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_cache_full, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_misses, ctx, ctxN);
CHECKZERO_RET(wolfSSL_CTX_sess_timeouts, ctx, ctxN);
/* when implemented this should take WOLFSSL object instead, right now
* always returns 0 */
ExpectPtrEq(SSL_get_current_expansion(NULL), NULL);
wolfSSL_CTX_free(ctx);
ctx = NULL;
ExpectStrEQ(SSL_COMP_get_name(NULL), "not supported");
ExpectPtrEq(SSL_get_current_expansion(NULL), NULL);
#endif /* OPENSSL_EXTRA && !NO_WOLFSSL_STUB && (!NO_WOLFSSL_CLIENT ||
* !NO_WOLFSSL_SERVER) */
return EXPECT_RESULT();
}
static int test_CONF_modules_xxx(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
CONF_modules_free();
CONF_modules_unload(0);
CONF_modules_unload(1);
CONF_modules_unload(-1);
res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
return res;
}
static int test_CRYPTO_set_dynlock_xxx(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
CRYPTO_set_dynlock_create_callback(
(struct CRYPTO_dynlock_value *(*)(const char*, int))NULL);
CRYPTO_set_dynlock_create_callback(
(struct CRYPTO_dynlock_value *(*)(const char*, int))1);
CRYPTO_set_dynlock_destroy_callback(
(void (*)(struct CRYPTO_dynlock_value*, const char*, int))NULL);
CRYPTO_set_dynlock_destroy_callback(
(void (*)(struct CRYPTO_dynlock_value*, const char*, int))1);
CRYPTO_set_dynlock_lock_callback(
(void (*)(int, struct CRYPTO_dynlock_value *, const char*, int))NULL);
CRYPTO_set_dynlock_lock_callback(
(void (*)(int, struct CRYPTO_dynlock_value *, const char*, int))1);
res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
return res;
}
static int test_CRYPTO_THREADID_xxx(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
CRYPTO_THREADID_current((CRYPTO_THREADID*)NULL);
CRYPTO_THREADID_current((CRYPTO_THREADID*)1);
ExpectIntEQ(CRYPTO_THREADID_hash((const CRYPTO_THREADID*)NULL), 0);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_ENGINE_cleanup(void)
{
int res = TEST_SKIPPED;
#if defined(OPENSSL_EXTRA)
ENGINE_cleanup();
res = TEST_SUCCESS;
#endif /* OPENSSL_EXTRA */
return res;
}
static int test_wolfSSL_CTX_LoadCRL(void)
{
EXPECT_DECLS;
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
WOLFSSL_CERT_MANAGER* cm = NULL;
const char* issuerCert = "./certs/client-cert.pem";
const char* validFilePath = "./certs/crl/cliCrl.pem";
int pemType = WOLFSSL_FILETYPE_PEM;
#ifndef NO_TLS
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
const char* badPath = "dummypath";
const char* validPath = "./certs/crl";
int derType = WOLFSSL_FILETYPE_ASN1;
#ifdef HAVE_CRL_MONITOR
int monitor = WOLFSSL_CRL_MONITOR;
#else
int monitor = 0;
#endif
#define FAIL_T1(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
WC_NO_ERR_TRACE(BAD_FUNC_ARG))
#define FAIL_T2(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
WC_NO_ERR_TRACE(NOT_COMPILED_IN))
#define SUCC_T(x, y, z, p, d) ExpectIntEQ((int) x(y, z, p, d), \
WOLFSSL_SUCCESS)
#ifndef NO_WOLFSSL_CLIENT
#define NEW_CTX(ctx) ExpectNotNull( \
(ctx) = wolfSSL_CTX_new(wolfSSLv23_client_method()))
#elif !defined(NO_WOLFSSL_SERVER)
#define NEW_CTX(ctx) ExpectNotNull( \
(ctx) = wolfSSL_CTX_new(wolfSSLv23_server_method()))
#else
#define NEW_CTX(ctx) return
#endif
FAIL_T1(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor);
NEW_CTX(ctx);
#ifndef HAVE_CRL_MONITOR
FAIL_T2(wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, WOLFSSL_CRL_MONITOR);
wolfSSL_CTX_free(ctx);
NEW_CTX(ctx);
#endif
SUCC_T (wolfSSL_CTX_LoadCRL, ctx, validPath, pemType, monitor);
SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, pemType, monitor);
SUCC_T (wolfSSL_CTX_LoadCRL, ctx, badPath, derType, monitor);
wolfSSL_CTX_free(ctx);
ctx = NULL;
NEW_CTX(ctx);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx, validFilePath, pemType), WOLFSSL_SUCCESS);
wolfSSL_CTX_free(ctx);
ctx = NULL;
NEW_CTX(ctx);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx, issuerCert, NULL),
WOLFSSL_SUCCESS);
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_LoadCRLFile(ssl, validFilePath, pemType), WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
ssl = NULL;
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif /* !NO_TLS */
ExpectNotNull(cm = wolfSSL_CertManagerNew());
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, issuerCert, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, validFilePath, pemType),
WOLFSSL_SUCCESS);
wolfSSL_CertManagerFree(cm);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_LoadCRL_largeCRLnum(void)
{
EXPECT_DECLS;
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
defined(HAVE_CRL_UPDATE_CB)
WOLFSSL_CERT_MANAGER* cm = NULL;
const char* caCert = "./certs/ca-cert.pem";
const char* crl_lrgcrlnum = "./certs/crl/extra-crls/large_crlnum.pem";
const char* crl_lrgcrlnum2 = "./certs/crl/extra-crls/large_crlnum2.pem";
const char* exp_crlnum = "D8AFADA7F08B38E6178BD0E5CD7B0DF80071BA74";
byte *crlLrgCrlNumBuff = NULL;
word32 crlLrgCrlNumSz;
CrlInfo crlInfo;
XFILE f;
word32 sz;
cm = wolfSSL_CertManagerNew();
ExpectNotNull(cm);
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caCert, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl_lrgcrlnum,
WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);
AssertTrue((f = XFOPEN(crl_lrgcrlnum, "rb")) != XBADFILE);
AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0);
AssertIntGE(sz = (word32) XFTELL(f), 1);
AssertTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
AssertTrue( \
(crlLrgCrlNumBuff =
(byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
AssertTrue(XFREAD(crlLrgCrlNumBuff, 1, sz, f) == sz);
XFCLOSE(f);
crlLrgCrlNumSz = sz;
AssertIntEQ(wolfSSL_CertManagerGetCRLInfo(
cm, &crlInfo, crlLrgCrlNumBuff, crlLrgCrlNumSz, WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);
AssertIntEQ(XMEMCMP(
crlInfo.crlNumber, exp_crlnum, XSTRLEN(exp_crlnum)), 0);
/* Expect to fail loading CRL because of >21 octets CRL number */
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl_lrgcrlnum2,
WOLFSSL_FILETYPE_PEM),
ASN_PARSE_E);
XFREE(crlLrgCrlNumBuff, NULL, DYNAMIC_TYPE_FILE);
wolfSSL_CertManagerFree(cm);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
defined(HAVE_CRL_UPDATE_CB)
int crlUpdateTestStatus = 0;
WOLFSSL_CERT_MANAGER* updateCrlTestCm = NULL;
static void updateCrlCb(CrlInfo* old, CrlInfo* cnew)
{
const char* crl1 = "./certs/crl/crl.pem";
const char* crlRevoked = "./certs/crl/crl.revoked";
byte *crl1Buff = NULL;
word32 crl1Sz;
byte *crlRevBuff = NULL;
word32 crlRevSz;
WOLFSSL_CERT_MANAGER* cm = updateCrlTestCm;
XFILE f;
word32 sz;
CrlInfo crl1Info;
CrlInfo crlRevInfo;
crlUpdateTestStatus = 0;
if (old == NULL || cnew == NULL) {
return;
}
AssertTrue((f = XFOPEN(crl1, "rb")) != XBADFILE);
AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0);
AssertIntGE(sz = (word32) XFTELL(f), 1);
AssertTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
AssertTrue( \
(crl1Buff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
AssertTrue(XFREAD(crl1Buff, 1, sz, f) == sz);
XFCLOSE(f);
crl1Sz = sz;
AssertTrue((f = XFOPEN(crlRevoked, "rb")) != XBADFILE);
AssertTrue(XFSEEK(f, 0, XSEEK_END) == 0);
AssertIntGE(sz = (word32) XFTELL(f), 1);
AssertTrue(XFSEEK(f, 0, XSEEK_SET) == 0);
AssertTrue( \
(crlRevBuff = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE)) != NULL);
AssertTrue(XFREAD(crlRevBuff, 1, sz, f) == sz);
XFCLOSE(f);
crlRevSz = sz;
AssertIntEQ(wolfSSL_CertManagerGetCRLInfo(
cm, &crl1Info, crl1Buff, crl1Sz, WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_CertManagerGetCRLInfo(
cm, &crlRevInfo, crlRevBuff, crlRevSz, WOLFSSL_FILETYPE_PEM),
WOLFSSL_SUCCESS);
/* Old entry being replaced should match crl1 */
AssertIntEQ(crl1Info.issuerHashLen, old->issuerHashLen);
AssertIntEQ(crl1Info.lastDateMaxLen, old->lastDateMaxLen);
AssertIntEQ(crl1Info.lastDateFormat, old->lastDateFormat);
AssertIntEQ(crl1Info.nextDateMaxLen, old->nextDateMaxLen);
AssertIntEQ(crl1Info.nextDateFormat, old->nextDateFormat);
AssertIntEQ(XMEMCMP(
crl1Info.crlNumber, old->crlNumber, sizeof(old->crlNumber)), 0);
AssertIntEQ(XMEMCMP(
crl1Info.issuerHash, old->issuerHash, old->issuerHashLen), 0);
AssertIntEQ(XMEMCMP(
crl1Info.lastDate, old->lastDate, old->lastDateMaxLen), 0);
AssertIntEQ(XMEMCMP(
crl1Info.nextDate, old->nextDate, old->nextDateMaxLen), 0);
/* Newer entry should match crl revoked */
AssertIntEQ(crlRevInfo.issuerHashLen, cnew->issuerHashLen);
AssertIntEQ(crlRevInfo.lastDateMaxLen, cnew->lastDateMaxLen);
AssertIntEQ(crlRevInfo.lastDateFormat, cnew->lastDateFormat);
AssertIntEQ(crlRevInfo.nextDateMaxLen, cnew->nextDateMaxLen);
AssertIntEQ(crlRevInfo.nextDateFormat, cnew->nextDateFormat);
AssertIntEQ(XMEMCMP(
crlRevInfo.crlNumber, cnew->crlNumber, sizeof(cnew->crlNumber)), 0);
AssertIntEQ(XMEMCMP(
crlRevInfo.issuerHash, cnew->issuerHash, cnew->issuerHashLen), 0);
AssertIntEQ(XMEMCMP(
crlRevInfo.lastDate, cnew->lastDate, cnew->lastDateMaxLen), 0);
AssertIntEQ(XMEMCMP(
crlRevInfo.nextDate, cnew->nextDate, cnew->nextDateMaxLen), 0);
XFREE(crl1Buff, NULL, DYNAMIC_TYPE_FILE);
XFREE(crlRevBuff, NULL, DYNAMIC_TYPE_FILE);
crlUpdateTestStatus = 1;
}
#endif
static int test_wolfSSL_crl_update_cb(void)
{
EXPECT_DECLS;
#if defined(HAVE_CRL) && !defined(NO_RSA) && !defined(NO_FILESYSTEM) && \
defined(HAVE_CRL_UPDATE_CB)
const char* crl1 = "./certs/crl/crl.pem";
const char* crlRevoked = "./certs/crl/crl.revoked";
const char* issuerCert = "./certs/client-cert.pem";
const char* caCert = "./certs/ca-cert.pem";
const char* goodCert = "./certs/server-cert.pem";
const char* revokedCert = "./certs/server-revoked-cert.pem";
int pemType = WOLFSSL_FILETYPE_PEM;
WOLFSSL_CERT_MANAGER* cm = NULL;
updateCrlTestCm = wolfSSL_CertManagerNew();
ExpectNotNull(updateCrlTestCm);
cm = updateCrlTestCm;
ExpectIntEQ(wolfSSL_CertManagerSetCRLUpdate_Cb(cm, updateCrlCb),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, caCert, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, issuerCert, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crl1, pemType),
WOLFSSL_SUCCESS);
/* CRL1 does not have good cert revoked */
ExpectIntEQ(wolfSSL_CertManagerVerify(cm, goodCert, pemType),
WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_CertManagerVerify(cm, revokedCert, pemType),
WOLFSSL_SUCCESS);
/* Load newer CRL from same issuer, callback verifies CRL entry details */
ExpectIntEQ(wolfSSL_CertManagerLoadCRLFile(cm, crlRevoked, pemType),
WOLFSSL_SUCCESS);
/* CRL callback verified entry info was as expected */
ExpectIntEQ(crlUpdateTestStatus, 1);
/* Ensure that both certs fail with newer CRL */
ExpectIntNE(wolfSSL_CertManagerVerify(cm, goodCert, pemType),
WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_CertManagerVerify(cm, revokedCert, pemType),
WOLFSSL_SUCCESS);
#endif
return EXPECT_RESULT();
}
static int test_SetTmpEC_DHE_Sz(void)
{
EXPECT_DECLS;
#if defined(HAVE_ECC) && !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
WOLFSSL_CTX *ctx = NULL;
WOLFSSL *ssl = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpEC_DHE_Sz(ctx, 32));
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpEC_DHE_Sz(ssl, 32));
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_get0_privatekey(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_TLS)
WOLFSSL_CTX* ctx = NULL;
(void)ctx;
#ifndef NO_RSA
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
ExpectNull(SSL_CTX_get0_privatekey(ctx));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectNull(SSL_CTX_get0_privatekey(ctx));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(SSL_CTX_get0_privatekey(ctx));
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif
#ifdef HAVE_ECC
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
ExpectNull(SSL_CTX_get0_privatekey(ctx));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectNull(SSL_CTX_get0_privatekey(ctx));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectNotNull(SSL_CTX_get0_privatekey(ctx));
wolfSSL_CTX_free(ctx);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_dtls_set_mtu(void)
{
EXPECT_DECLS;
#if (defined(WOLFSSL_DTLS_MTU) || defined(WOLFSSL_SCTP)) && \
!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_DTLS) && \
!defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
const char* testCertFile;
const char* testKeyFile;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#endif
if (testCertFile != NULL && testKeyFile != NULL) {
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx, testCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
WOLFSSL_FILETYPE_PEM));
}
ExpectNotNull(ssl = wolfSSL_new(ctx));
ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(NULL, 1488), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_dtls_set_mtu(NULL, 1488), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(ctx, 20000), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl, 20000), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_get_error(ssl, WC_NO_ERR_TRACE(WOLFSSL_FAILURE)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_dtls_set_mtu(ctx, 1488), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl, 1488), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
ExpectIntEQ(SSL_set_mtu(ssl, 1488), WOLFSSL_SUCCESS);
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
static WC_INLINE void generateDTLSMsg(byte* out, int outSz, word32 seq,
enum HandShakeType hsType, word16 length)
{
size_t idx = 0;
byte* l;
/* record layer */
/* handshake type */
out[idx++] = handshake;
/* protocol version */
out[idx++] = 0xfe;
out[idx++] = 0xfd; /* DTLS 1.2 */
/* epoch 0 */
XMEMSET(out + idx, 0, 2);
idx += 2;
/* sequence number */
XMEMSET(out + idx, 0, 6);
c32toa(seq, out + idx + 2);
idx += 6;
/* length in BE */
if (length)
c16toa(length, out + idx);
else
c16toa(outSz - idx - 2, out + idx);
idx += 2;
/* handshake layer */
/* handshake type */
out[idx++] = (byte)hsType;
/* length */
l = out + idx;
idx += 3;
/* message seq */
c16toa(0, out + idx);
idx += 2;
/* frag offset */
c32to24(0, out + idx);
idx += 3;
/* frag length */
c32to24((word32)outSz - (word32)idx - 3, l);
c32to24((word32)outSz - (word32)idx - 3, out + idx);
idx += 3;
XMEMSET(out + idx, 0, outSz - idx);
}
static void test_wolfSSL_dtls_plaintext_server(WOLFSSL* ssl)
{
byte msg[] = "This is a msg for the client";
byte reply[40];
AssertIntGT(wolfSSL_read(ssl, reply, sizeof(reply)),0);
reply[sizeof(reply) - 1] = '\0';
fprintf(stderr, "Client message: %s\n", reply);
AssertIntEQ(wolfSSL_write(ssl, msg, sizeof(msg)), sizeof(msg));
}
static void test_wolfSSL_dtls_plaintext_client(WOLFSSL* ssl)
{
byte ch[50];
int fd = wolfSSL_get_wfd(ssl);
byte msg[] = "This is a msg for the server";
byte reply[40];
AssertIntGE(fd, 0);
generateDTLSMsg(ch, sizeof(ch), 20, client_hello, 0);
/* Server should ignore this datagram */
AssertIntEQ(send(fd, (MESSAGE_TYPE_CAST)ch, sizeof(ch), 0), sizeof(ch));
generateDTLSMsg(ch, sizeof(ch), 20, client_hello, 10000);
/* Server should ignore this datagram */
AssertIntEQ(send(fd, (MESSAGE_TYPE_CAST)ch, sizeof(ch), 0), sizeof(ch));
AssertIntEQ(wolfSSL_write(ssl, msg, sizeof(msg)), sizeof(msg));
AssertIntGT(wolfSSL_read(ssl, reply, sizeof(reply)),0);
reply[sizeof(reply) - 1] = '\0';
fprintf(stderr, "Server response: %s\n", reply);
}
static int test_wolfSSL_dtls_plaintext(void)
{
callback_functions func_cb_client;
callback_functions func_cb_server;
size_t i;
struct test_params {
method_provider client_meth;
method_provider server_meth;
ssl_callback on_result_server;
ssl_callback on_result_client;
} params[] = {
{wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
test_wolfSSL_dtls_plaintext_server,
test_wolfSSL_dtls_plaintext_client},
};
for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_server.method = params[i].server_meth;
func_cb_client.method = params[i].client_meth;
func_cb_client.on_result = params[i].on_result_client;
func_cb_server.on_result = params[i].on_result_server;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
if (!func_cb_client.return_code)
return TEST_FAIL;
if (!func_cb_server.return_code)
return TEST_FAIL;
}
return TEST_RES_CHECK(1);
}
#else
static int test_wolfSSL_dtls_plaintext(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
static void test_wolfSSL_dtls12_fragments_spammer(WOLFSSL* ssl)
{
byte b[1100]; /* buffer for the messages to send */
size_t idx = 0;
size_t seq_offset = 0;
size_t msg_offset = 0;
int i;
int fd = wolfSSL_get_wfd(ssl);
int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
word32 seq_number = 100; /* start high so server definitely reads this */
word16 msg_number = 50; /* start high so server has to buffer this */
AssertIntEQ(ret, 1);
/* Now let's start spamming the peer with fragments it needs to store */
XMEMSET(b, -1, sizeof(b));
/* record layer */
/* handshake type */
b[idx++] = 22;
/* protocol version */
b[idx++] = 0xfe;
b[idx++] = 0xfd; /* DTLS 1.2 */
/* epoch 0 */
XMEMSET(b + idx, 0, 2);
idx += 2;
/* sequence number */
XMEMSET(b + idx, 0, 6);
seq_offset = idx + 2; /* increment only the low 32 bits */
idx += 6;
/* static length in BE */
c16toa(42, b + idx);
idx += 2;
/* handshake layer */
/* cert type */
b[idx++] = 11;
/* length */
c32to24(1000, b + idx);
idx += 3;
/* message seq */
c16toa(0, b + idx);
msg_offset = idx;
idx += 2;
/* frag offset */
c32to24(500, b + idx);
idx += 3;
/* frag length */
c32to24(30, b + idx);
idx += 3;
(void)idx; /* inhibit clang-analyzer-deadcode.DeadStores */
for (i = 0; i < DTLS_POOL_SZ * 2 && ret > 0;
seq_number++, msg_number++, i++) {
struct timespec delay;
XMEMSET(&delay, 0, sizeof(delay));
delay.tv_nsec = 10000000; /* wait 0.01 seconds */
c32toa(seq_number, b + seq_offset);
c16toa(msg_number, b + msg_offset);
ret = (int)send(fd, (MESSAGE_TYPE_CAST)b, 55, 0);
nanosleep(&delay, NULL);
}
}
#ifdef WOLFSSL_DTLS13
static void test_wolfSSL_dtls13_fragments_spammer(WOLFSSL* ssl)
{
const word16 sendCountMax = 100;
byte b[150]; /* buffer for the messages to send */
size_t idx = 0;
size_t msg_offset = 0;
int fd = wolfSSL_get_wfd(ssl);
word16 msg_number = 10; /* start high so server has to buffer this */
int ret = wolfSSL_connect_cert(ssl); /* This gets us past the cookie */
AssertIntEQ(ret, 1);
/* Now let's start spamming the peer with fragments it needs to store */
XMEMSET(b, -1, sizeof(b));
/* handshake type */
b[idx++] = 11;
/* length */
c32to24(10000, b + idx);
idx += 3;
/* message_seq */
msg_offset = idx;
idx += 2;
/* fragment_offset */
c32to24(5000, b + idx);
idx += 3;
/* fragment_length */
c32to24(100, b + idx);
idx += 3;
/* fragment contents */
idx += 100;
for (; ret > 0 && msg_number < sendCountMax; msg_number++) {
byte sendBuf[150];
int sendSz = sizeof(sendBuf);
struct timespec delay;
XMEMSET(&delay, 0, sizeof(delay));
delay.tv_nsec = 10000000; /* wait 0.01 seconds */
c16toa(msg_number, b + msg_offset);
ret = sendSz = BuildTls13Message(ssl, sendBuf, sendSz, b,
(int)idx, handshake, 0, 0, 0);
if (sendSz > 0)
ret = (int)send(fd, (MESSAGE_TYPE_CAST)sendBuf, (size_t)sendSz, 0);
nanosleep(&delay, NULL);
}
}
#endif
static int test_wolfSSL_dtls_fragments(void)
{
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
size_t i;
struct test_params {
method_provider client_meth;
method_provider server_meth;
ssl_callback spammer;
} params[] = {
#if !defined(WOLFSSL_NO_TLS12)
{wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
test_wolfSSL_dtls12_fragments_spammer},
#endif
#ifdef WOLFSSL_DTLS13
{wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
test_wolfSSL_dtls13_fragments_spammer},
#endif
};
for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_server.method = params[i].server_meth;
func_cb_client.method = params[i].client_meth;
func_cb_client.ssl_ready = params[i].spammer;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectFalse(func_cb_client.return_code);
ExpectFalse(func_cb_server.return_code);
/* The socket should be closed by the server resulting in a
* socket error, fatal error or reading a close notify alert */
if (func_cb_client.last_err != WC_NO_ERR_TRACE(SOCKET_ERROR_E) &&
func_cb_client.last_err != WOLFSSL_ERROR_ZERO_RETURN &&
func_cb_client.last_err != WC_NO_ERR_TRACE(FATAL_ERROR)) {
ExpectIntEQ(func_cb_client.last_err, WC_NO_ERR_TRACE(SOCKET_ERROR_E));
}
/* Check the server returned an error indicating the msg buffer
* was full */
ExpectIntEQ(func_cb_server.last_err, WC_NO_ERR_TRACE(DTLS_TOO_MANY_FRAGMENTS_E));
if (EXPECT_FAIL())
break;
}
return EXPECT_RESULT();
}
static void test_wolfSSL_dtls_send_alert(WOLFSSL* ssl)
{
int fd, ret;
byte alert_msg[] = {
0x15, /* alert type */
0xfe, 0xfd, /* version */
0x00, 0x00, /* epoch */
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* seq number */
0x00, 0x02, /* length */
0x02, /* level: fatal */
0x46 /* protocol version */
};
fd = wolfSSL_get_wfd(ssl);
AssertIntGE(fd, 0);
ret = (int)send(fd, (MESSAGE_TYPE_CAST)alert_msg, sizeof(alert_msg), 0);
AssertIntGT(ret, 0);
}
static int _test_wolfSSL_ignore_alert_before_cookie(byte version12)
{
callback_functions client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.doUdp = server_cbs.doUdp = 1;
if (version12) {
#if !defined(WOLFSSL_NO_TLS12)
client_cbs.method = wolfDTLSv1_2_client_method;
server_cbs.method = wolfDTLSv1_2_server_method;
#else
return TEST_SKIPPED;
#endif
}
else
{
#ifdef WOLFSSL_DTLS13
client_cbs.method = wolfDTLSv1_3_client_method;
server_cbs.method = wolfDTLSv1_3_server_method;
#else
return TEST_SKIPPED;
#endif /* WOLFSSL_DTLS13 */
}
client_cbs.ssl_ready = test_wolfSSL_dtls_send_alert;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
if (!client_cbs.return_code)
return TEST_FAIL;
if (!server_cbs.return_code)
return TEST_FAIL;
return TEST_SUCCESS;
}
static int test_wolfSSL_ignore_alert_before_cookie(void)
{
int ret;
ret =_test_wolfSSL_ignore_alert_before_cookie(0);
if (ret != 0)
return ret;
ret =_test_wolfSSL_ignore_alert_before_cookie(1);
if (ret != 0)
return ret;
return 0;
}
static void test_wolfSSL_send_bad_record(WOLFSSL* ssl)
{
int ret;
int fd;
byte bad_msg[] = {
0x17, /* app data */
0xaa, 0xfd, /* bad version */
0x00, 0x01, /* epoch 1 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x55, /* not seen seq number */
0x00, 0x26, /* length: 38 bytes */
0xae, 0x30, 0x31, 0xb1, 0xf1, 0xb9, 0x6f, 0xda, 0x17, 0x19, 0xd9, 0x57,
0xa9, 0x9d, 0x5c, 0x51, 0x9b, 0x53, 0x63, 0xa5, 0x24, 0x70, 0xa1,
0xae, 0xdf, 0x1c, 0xb9, 0xfc, 0xe3, 0xd7, 0x77, 0x6d, 0xb6, 0x89, 0x0f,
0x03, 0x18, 0x72
};
fd = wolfSSL_get_wfd(ssl);
AssertIntGE(fd, 0);
ret = (int)send(fd, (MESSAGE_TYPE_CAST)bad_msg, sizeof(bad_msg), 0);
AssertIntEQ(ret, sizeof(bad_msg));
ret = wolfSSL_write(ssl, "badrecordtest", sizeof("badrecordtest"));
AssertIntEQ(ret, sizeof("badrecordtest"));
}
static void test_wolfSSL_read_string(WOLFSSL* ssl)
{
byte buf[100];
int ret;
ret = wolfSSL_read(ssl, buf, sizeof(buf));
AssertIntGT(ret, 0);
AssertIntEQ(strcmp((char*)buf, "badrecordtest"), 0);
}
static int _test_wolfSSL_dtls_bad_record(
method_provider client_method, method_provider server_method)
{
callback_functions client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.doUdp = server_cbs.doUdp = 1;
client_cbs.method = client_method;
server_cbs.method = server_method;
client_cbs.on_result = test_wolfSSL_send_bad_record;
server_cbs.on_result = test_wolfSSL_read_string;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
if (!client_cbs.return_code)
return TEST_FAIL;
if (!server_cbs.return_code)
return TEST_FAIL;
return TEST_SUCCESS;
}
static int test_wolfSSL_dtls_bad_record(void)
{
int ret = TEST_SUCCESS;
#if !defined(WOLFSSL_NO_TLS12)
ret = _test_wolfSSL_dtls_bad_record(wolfDTLSv1_2_client_method,
wolfDTLSv1_2_server_method);
#endif
#ifdef WOLFSSL_DTLS13
if (ret == TEST_SUCCESS) {
ret = _test_wolfSSL_dtls_bad_record(wolfDTLSv1_3_client_method,
wolfDTLSv1_3_server_method);
}
#endif /* WOLFSSL_DTLS13 */
return ret;
}
#else
static int test_wolfSSL_dtls_fragments(void)
{
return TEST_SKIPPED;
}
static int test_wolfSSL_ignore_alert_before_cookie(void)
{
return TEST_SKIPPED;
}
static int test_wolfSSL_dtls_bad_record(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_DTLS13) && !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
static volatile int test_AEAD_seq_num = 0;
#ifdef WOLFSSL_NO_ATOMICS
static volatile int test_AEAD_done = 0;
#else
wolfSSL_Atomic_Int test_AEAD_done = WOLFSSL_ATOMIC_INITIALIZER(0);
#endif
#ifdef WOLFSSL_MUTEX_INITIALIZER
static wolfSSL_Mutex test_AEAD_mutex = WOLFSSL_MUTEX_INITIALIZER(test_AEAD_mutex);
#endif
static int test_AEAD_fail_decryption = 0;
static int test_AEAD_cbiorecv(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
int fd = wolfSSL_get_fd(ssl);
int ret = -1;
if (fd >= 0 && (ret = (int)recv(fd, buf, sz, 0)) > 0) {
if (test_AEAD_fail_decryption) {
/* Modify the packet to trigger a decryption failure */
buf[ret/2] ^= 0xFF;
if (test_AEAD_fail_decryption == 1)
test_AEAD_fail_decryption = 0;
}
}
(void)ctx;
return ret;
}
static void test_AEAD_get_limits(WOLFSSL* ssl, w64wrapper* hardLimit,
w64wrapper* keyUpdateLimit, w64wrapper* sendLimit)
{
if (sendLimit)
w64Zero(sendLimit);
switch (ssl->specs.bulk_cipher_algorithm) {
case wolfssl_aes_gcm:
if (sendLimit)
*sendLimit = AEAD_AES_LIMIT;
FALL_THROUGH;
case wolfssl_chacha:
if (hardLimit)
*hardLimit = DTLS_AEAD_AES_GCM_CHACHA_FAIL_LIMIT;
if (keyUpdateLimit)
*keyUpdateLimit = DTLS_AEAD_AES_GCM_CHACHA_FAIL_KU_LIMIT;
break;
case wolfssl_aes_ccm:
if (sendLimit)
*sendLimit = DTLS_AEAD_AES_CCM_LIMIT;
if (ssl->specs.aead_mac_size == AES_CCM_8_AUTH_SZ) {
if (hardLimit)
*hardLimit = DTLS_AEAD_AES_CCM_8_FAIL_LIMIT;
if (keyUpdateLimit)
*keyUpdateLimit = DTLS_AEAD_AES_CCM_8_FAIL_KU_LIMIT;
}
else {
if (hardLimit)
*hardLimit = DTLS_AEAD_AES_CCM_FAIL_LIMIT;
if (keyUpdateLimit)
*keyUpdateLimit = DTLS_AEAD_AES_CCM_FAIL_KU_LIMIT;
}
break;
default:
fprintf(stderr, "Unrecognized bulk cipher");
AssertFalse(1);
break;
}
}
static void test_AEAD_limit_client(WOLFSSL* ssl)
{
int ret;
int i;
int didReKey = 0;
char msgBuf[20];
w64wrapper hardLimit;
w64wrapper keyUpdateLimit;
w64wrapper counter;
w64wrapper sendLimit;
test_AEAD_get_limits(ssl, &hardLimit, &keyUpdateLimit, &sendLimit);
w64Zero(&counter);
AssertTrue(w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->dropCount, counter));
wolfSSL_SSLSetIORecv(ssl, test_AEAD_cbiorecv);
for (i = 0; i < 10; i++) {
/* Test some failed decryptions */
test_AEAD_fail_decryption = 1;
w64Increment(&counter);
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
/* Should succeed since decryption failures are dropped */
AssertIntGT(ret, 0);
AssertTrue(w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount, counter));
}
test_AEAD_fail_decryption = 1;
Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount = keyUpdateLimit;
w64Increment(&Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount);
/* 100 read calls should be enough to complete the key update */
w64Zero(&counter);
for (i = 0; i < 100; i++) {
/* Key update should be sent and negotiated */
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
AssertIntGT(ret, 0);
/* Epoch after one key update is 4 */
if (w64Equal(ssl->dtls13PeerEpoch, w64From32(0, 4)) &&
w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount, counter)) {
didReKey = 1;
break;
}
}
AssertTrue(didReKey);
if (!w64IsZero(sendLimit)) {
/* Test the sending limit for AEAD ciphers */
#ifdef WOLFSSL_MUTEX_INITIALIZER
(void)wc_LockMutex(&test_AEAD_mutex);
#endif
Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->nextSeqNumber = sendLimit;
test_AEAD_seq_num = 1;
XMEMSET(msgBuf, 0, sizeof(msgBuf));
ret = wolfSSL_write(ssl, msgBuf, sizeof(msgBuf));
AssertIntGT(ret, 0);
didReKey = 0;
w64Zero(&counter);
#ifdef WOLFSSL_MUTEX_INITIALIZER
wc_UnLockMutex(&test_AEAD_mutex);
#endif
/* 100 read calls should be enough to complete the key update */
for (i = 0; i < 100; i++) {
/* Key update should be sent and negotiated */
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
AssertIntGT(ret, 0);
/* Epoch after another key update is 5 */
if (w64Equal(ssl->dtls13Epoch, w64From32(0, 5)) &&
w64Equal(Dtls13GetEpoch(ssl, ssl->dtls13Epoch)->dropCount, counter)) {
didReKey = 1;
break;
}
}
AssertTrue(didReKey);
}
test_AEAD_fail_decryption = 2;
Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount = hardLimit;
w64Decrement(&Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch)->dropCount);
/* Connection should fail with a DECRYPT_ERROR */
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
AssertIntEQ(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
AssertIntEQ(wolfSSL_get_error(ssl, ret), WC_NO_ERR_TRACE(DECRYPT_ERROR));
#ifdef WOLFSSL_ATOMIC_INITIALIZER
WOLFSSL_ATOMIC_STORE(test_AEAD_done, 1);
#else
test_AEAD_done = 1;
#endif
}
int counter = 0;
static void test_AEAD_limit_server(WOLFSSL* ssl)
{
char msgBuf[] = "Sending data";
int ret = WOLFSSL_SUCCESS;
w64wrapper sendLimit;
SOCKET_T fd = wolfSSL_get_fd(ssl);
struct timespec delay;
XMEMSET(&delay, 0, sizeof(delay));
delay.tv_nsec = 100000000; /* wait 0.1 seconds */
tcp_set_nonblocking(&fd); /* So that read doesn't block */
wolfSSL_dtls_set_using_nonblock(ssl, 1);
test_AEAD_get_limits(ssl, NULL, NULL, &sendLimit);
while (!
#ifdef WOLFSSL_ATOMIC_INITIALIZER
WOLFSSL_ATOMIC_LOAD(test_AEAD_done)
#else
test_AEAD_done
#endif
&& ret > 0)
{
counter++;
#ifdef WOLFSSL_MUTEX_INITIALIZER
(void)wc_LockMutex(&test_AEAD_mutex);
#endif
if (test_AEAD_seq_num) {
/* We need to update the seq number so that we can understand the
* peer. Otherwise we will incorrectly interpret the seq number. */
Dtls13Epoch* e = Dtls13GetEpoch(ssl, ssl->dtls13PeerEpoch);
AssertNotNull(e);
e->nextPeerSeqNumber = sendLimit;
test_AEAD_seq_num = 0;
}
#ifdef WOLFSSL_MUTEX_INITIALIZER
wc_UnLockMutex(&test_AEAD_mutex);
#endif
(void)wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
ret = wolfSSL_write(ssl, msgBuf, sizeof(msgBuf));
nanosleep(&delay, NULL);
}
}
static int test_wolfSSL_dtls_AEAD_limit(void)
{
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_server.method = wolfDTLSv1_3_server_method;
func_cb_client.method = wolfDTLSv1_3_client_method;
func_cb_server.on_result = test_AEAD_limit_server;
func_cb_client.on_result = test_AEAD_limit_client;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
if (!func_cb_client.return_code)
return TEST_FAIL;
if (!func_cb_server.return_code)
return TEST_FAIL;
return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls_AEAD_limit(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_DTLS) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(SINGLE_THREADED) && \
!defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING)
static void test_wolfSSL_dtls_send_ch(WOLFSSL* ssl)
{
int fd, ret;
byte ch_msg[] = {
0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xfa, 0x01, 0x00, 0x01, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0xee, 0xfe, 0xfd, 0xc0, 0xca, 0xb5, 0x6f, 0x3d, 0x23, 0xcc, 0x53, 0x9a,
0x67, 0x17, 0x70, 0xd3, 0xfb, 0x23, 0x16, 0x9e, 0x4e, 0xd6, 0x7e, 0x29,
0xab, 0xfa, 0x4c, 0xa5, 0x84, 0x95, 0xc3, 0xdb, 0x21, 0x9a, 0x52, 0x00,
0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x01,
0x8e, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00, 0x0c,
0x00, 0x0a, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00,
0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x01, 0x4b, 0x01, 0x49, 0x00, 0x17,
0x00, 0x41, 0x04, 0x96, 0xcb, 0x2e, 0x4e, 0xd9, 0x88, 0x71, 0xc7, 0xf3,
0x1a, 0x16, 0xdd, 0x7a, 0x7c, 0xf7, 0x67, 0x8a, 0x5d, 0x9a, 0x55, 0xa6,
0x4a, 0x90, 0xd9, 0xfb, 0xc7, 0xfb, 0xbe, 0x09, 0xa9, 0x8a, 0xb5, 0x7a,
0xd1, 0xde, 0x83, 0x74, 0x27, 0x31, 0x1c, 0xaa, 0xae, 0xef, 0x58, 0x43,
0x13, 0x7d, 0x15, 0x4d, 0x7f, 0x68, 0xf6, 0x8a, 0x38, 0xef, 0x0e, 0xb3,
0xcf, 0xb8, 0x4a, 0xa9, 0xb4, 0xd7, 0xcb, 0x01, 0x00, 0x01, 0x00, 0x1d,
0x0a, 0x22, 0x8a, 0xd1, 0x78, 0x85, 0x1e, 0x5a, 0xe1, 0x1d, 0x1e, 0xb7,
0x2d, 0xbc, 0x5f, 0x52, 0xbc, 0x97, 0x5d, 0x8b, 0x6a, 0x8b, 0x9d, 0x1e,
0xb1, 0xfc, 0x8a, 0xb2, 0x56, 0xcd, 0xed, 0x4b, 0xfb, 0x66, 0x3f, 0x59,
0x3f, 0x15, 0x5d, 0x09, 0x9e, 0x2f, 0x60, 0x5b, 0x31, 0x81, 0x27, 0xf0,
0x1c, 0xda, 0xcd, 0x48, 0x66, 0xc6, 0xbb, 0x25, 0xf0, 0x5f, 0xda, 0x4c,
0xcf, 0x1d, 0x88, 0xc8, 0xda, 0x1b, 0x53, 0xea, 0xbd, 0xce, 0x6d, 0xf6,
0x4a, 0x76, 0xdb, 0x75, 0x99, 0xaf, 0xcf, 0x76, 0x4a, 0xfb, 0xe3, 0xef,
0xb2, 0xcb, 0xae, 0x4a, 0xc0, 0xe8, 0x63, 0x1f, 0xd6, 0xe8, 0xe6, 0x45,
0xf9, 0xea, 0x0d, 0x06, 0x19, 0xfc, 0xb1, 0xfd, 0x5d, 0x92, 0x89, 0x7b,
0xc7, 0x9f, 0x1a, 0xb3, 0x2b, 0xc7, 0xad, 0x0e, 0xfb, 0x13, 0x41, 0x83,
0x84, 0x58, 0x3a, 0x25, 0xb9, 0x49, 0x35, 0x1c, 0x23, 0xcb, 0xd6, 0xe7,
0xc2, 0x8c, 0x4b, 0x2a, 0x73, 0xa1, 0xdf, 0x4f, 0x73, 0x9b, 0xb3, 0xd2,
0xb2, 0x95, 0x00, 0x3c, 0x26, 0x09, 0x89, 0x71, 0x05, 0x39, 0xc8, 0x98,
0x8f, 0xed, 0x32, 0x15, 0x78, 0xcd, 0xd3, 0x7e, 0xfb, 0x5a, 0x78, 0x2a,
0xdc, 0xca, 0x20, 0x09, 0xb5, 0x14, 0xf9, 0xd4, 0x58, 0xf6, 0x69, 0xf8,
0x65, 0x9f, 0xb7, 0xe4, 0x93, 0xf1, 0xa3, 0x84, 0x7e, 0x1b, 0x23, 0x5d,
0xea, 0x59, 0x3e, 0x4d, 0xca, 0xfd, 0xa5, 0x55, 0xdd, 0x99, 0xb5, 0x02,
0xf8, 0x0d, 0xe5, 0xf4, 0x06, 0xb0, 0x43, 0x9e, 0x2e, 0xbf, 0x05, 0x33,
0x65, 0x7b, 0x13, 0x8c, 0xf9, 0x16, 0x4d, 0xc5, 0x15, 0x0b, 0x40, 0x2f,
0x66, 0x94, 0xf2, 0x43, 0x95, 0xe7, 0xa9, 0xb6, 0x39, 0x99, 0x73, 0xb3,
0xb0, 0x06, 0xfe, 0x52, 0x9e, 0x57, 0xba, 0x75, 0xfd, 0x76, 0x7b, 0x20,
0x31, 0x68, 0x4c
};
fd = wolfSSL_get_wfd(ssl);
AssertIntGE(fd, 0);
ret = (int)send(fd, (MESSAGE_TYPE_CAST)ch_msg, sizeof(ch_msg), 0);
AssertIntGT(ret, 0);
/* consume the HRR otherwise handshake will fail */
ret = (int)recv(fd, (MESSAGE_TYPE_CAST)ch_msg, sizeof(ch_msg), 0);
AssertIntGT(ret, 0);
}
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
static void test_wolfSSL_dtls_send_ch_with_invalid_cookie(WOLFSSL* ssl)
{
int fd, ret;
byte ch_msh_invalid_cookie[] = {
0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
0x4e, 0x01, 0x00, 0x02, 0x42, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
0x42, 0xfe, 0xfd, 0x69, 0xca, 0x77, 0x60, 0x6f, 0xfc, 0xd1, 0x5b, 0x60,
0x5d, 0xf1, 0xa6, 0x5c, 0x44, 0x71, 0xae, 0xca, 0x62, 0x19, 0x0c, 0xb6,
0xf7, 0x2c, 0xa6, 0xd5, 0xd2, 0x99, 0x9d, 0x18, 0xae, 0xac, 0x11, 0x00,
0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x01,
0xe2, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x2c, 0x00, 0x45,
0x00, 0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x2d, 0x00,
0x03, 0x02, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x19,
0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00,
0x00, 0x33, 0x01, 0x4b, 0x01, 0x49, 0x00, 0x17, 0x00, 0x41, 0x04, 0x7c,
0x5a, 0xc2, 0x5a, 0xfd, 0xcd, 0x2b, 0x08, 0xb2, 0xeb, 0x8e, 0xc0, 0x02,
0x03, 0x9d, 0xb1, 0xc1, 0x0d, 0x7b, 0x7f, 0x46, 0x43, 0xdf, 0xf3, 0xee,
0x2b, 0x78, 0x0e, 0x29, 0x8c, 0x42, 0x11, 0x2c, 0xde, 0xd7, 0x41, 0x0f,
0x28, 0x94, 0x80, 0x41, 0x70, 0xc4, 0x17, 0xfd, 0x6d, 0xfa, 0xee, 0x9a,
0xf2, 0xc4, 0x15, 0x4c, 0x5f, 0x54, 0xb6, 0x78, 0x6e, 0xf9, 0x63, 0x27,
0x33, 0xb8, 0x7b, 0x01, 0x00, 0x01, 0x00, 0xd4, 0x46, 0x62, 0x9c, 0xbf,
0x8f, 0x1b, 0x65, 0x9b, 0xf0, 0x29, 0x64, 0xd8, 0x50, 0x0e, 0x74, 0xf1,
0x58, 0x10, 0xc9, 0xd9, 0x82, 0x5b, 0xd9, 0xbe, 0x14, 0xdf, 0xde, 0x86,
0xb4, 0x2e, 0x15, 0xee, 0x4f, 0xf6, 0x74, 0x9e, 0x59, 0x11, 0x36, 0x2d,
0xb9, 0x67, 0xaa, 0x5a, 0x09, 0x9b, 0x45, 0xf1, 0x01, 0x4c, 0x4e, 0xf6,
0xda, 0x6a, 0xae, 0xa7, 0x73, 0x7b, 0x2e, 0xb6, 0x24, 0x89, 0x99, 0xb7,
0x52, 0x16, 0x62, 0x0a, 0xab, 0x58, 0xf8, 0x3f, 0x10, 0x5b, 0x83, 0xfd,
0x7b, 0x81, 0x77, 0x81, 0x8d, 0xef, 0x24, 0x56, 0x6d, 0xba, 0x49, 0xd4,
0x8b, 0xb5, 0xa0, 0xb1, 0xc9, 0x8c, 0x32, 0x95, 0x1c, 0x5e, 0x0a, 0x4b,
0xf6, 0x00, 0x50, 0x0a, 0x87, 0x99, 0x59, 0xcf, 0x6f, 0x9d, 0x02, 0xd0,
0x1b, 0xa1, 0x96, 0x45, 0x28, 0x76, 0x40, 0x33, 0x28, 0xc9, 0xa1, 0xfd,
0x46, 0xab, 0x2c, 0x9e, 0x5e, 0xc6, 0x74, 0x19, 0x9a, 0xf5, 0x9b, 0x51,
0x11, 0x4f, 0xc8, 0xb9, 0x99, 0x6b, 0x4e, 0x3e, 0x31, 0x64, 0xb4, 0x92,
0xf4, 0x0d, 0x41, 0x4b, 0x2c, 0x65, 0x23, 0xf7, 0x47, 0xe3, 0xa5, 0x2e,
0xe4, 0x9c, 0x2b, 0xc9, 0x41, 0x22, 0x83, 0x8a, 0x23, 0xef, 0x29, 0x7e,
0x4f, 0x3f, 0xa3, 0xbf, 0x73, 0x2b, 0xd7, 0xcc, 0xc8, 0xc6, 0xe9, 0xbc,
0x01, 0xb7, 0x32, 0x63, 0xd4, 0x7e, 0x7f, 0x9a, 0xaf, 0x5f, 0x05, 0x31,
0x53, 0xd6, 0x1f, 0xa2, 0xd0, 0xdf, 0x67, 0x56, 0xf1, 0x9c, 0x4a, 0x9d,
0x83, 0xb4, 0xef, 0xb3, 0xf2, 0xcc, 0xf1, 0x91, 0x6c, 0x47, 0xc3, 0x8b,
0xd0, 0x92, 0x79, 0x3d, 0xa0, 0xc0, 0x3a, 0x57, 0x26, 0x6d, 0x0a, 0xad,
0x5f, 0xad, 0xb4, 0x74, 0x48, 0x4a, 0x51, 0xe1, 0xb5, 0x82, 0x0a, 0x4c,
0x4f, 0x9d, 0xaf, 0xee, 0x5a, 0xa2, 0x4d, 0x4d, 0x5f, 0xe0, 0x17, 0x00,
0x23, 0x00, 0x00
};
byte alert_reply[50];
byte expected_alert_reply[] = {
0x15, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x02, 0x02, 0x2f
};
fd = wolfSSL_get_wfd(ssl);
if (fd >= 0) {
ret = (int)send(fd, (MESSAGE_TYPE_CAST)ch_msh_invalid_cookie,
sizeof(ch_msh_invalid_cookie), 0);
AssertIntGT(ret, 0);
/* should reply with an illegal_parameter reply */
ret = (int)recv(fd, (MESSAGE_TYPE_CAST)alert_reply, sizeof(alert_reply), 0);
AssertIntEQ(ret, sizeof(expected_alert_reply));
AssertIntEQ(XMEMCMP(alert_reply, expected_alert_reply,
sizeof(expected_alert_reply)), 0);
}
}
#endif
static word32 test_wolfSSL_dtls_stateless_HashWOLFSSL(const WOLFSSL* ssl)
{
#ifndef NO_MD5
enum wc_HashType hashType = WC_HASH_TYPE_MD5;
#elif !defined(NO_SHA)
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#elif !defined(NO_SHA256)
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
#error "We need a digest to hash the WOLFSSL object"
#endif
byte hashBuf[WC_MAX_DIGEST_SIZE];
wc_HashAlg hash;
const TLSX* exts = ssl->extensions;
WOLFSSL sslCopy; /* Use a copy to omit certain fields */
#ifndef WOLFSSL_SMALL_STACK_CACHE
HS_Hashes* hsHashes = ssl->hsHashes; /* Is re-allocated in
* InitHandshakeHashes */
#endif
XMEMCPY(&sslCopy, ssl, sizeof(*ssl));
XMEMSET(hashBuf, 0, sizeof(hashBuf));
/* Following fields are not important to compare */
XMEMSET(sslCopy.buffers.inputBuffer.staticBuffer, 0, STATIC_BUFFER_LEN);
sslCopy.buffers.inputBuffer.buffer = NULL;
sslCopy.buffers.inputBuffer.bufferSize = 0;
sslCopy.buffers.inputBuffer.dynamicFlag = 0;
sslCopy.buffers.inputBuffer.offset = 0;
XMEMSET(sslCopy.buffers.outputBuffer.staticBuffer, 0, STATIC_BUFFER_LEN);
sslCopy.buffers.outputBuffer.buffer = NULL;
sslCopy.buffers.outputBuffer.bufferSize = 0;
sslCopy.buffers.outputBuffer.dynamicFlag = 0;
sslCopy.buffers.outputBuffer.offset = 0;
sslCopy.error = 0;
sslCopy.curSize = 0;
sslCopy.curStartIdx = 0;
sslCopy.keys.curSeq_lo = 0;
XMEMSET(&sslCopy.curRL, 0, sizeof(sslCopy.curRL));
#ifdef WOLFSSL_DTLS13
XMEMSET(&sslCopy.keys.curSeq, 0, sizeof(sslCopy.keys.curSeq));
sslCopy.dtls13FastTimeout = 0;
#endif
sslCopy.keys.dtls_peer_handshake_number = 0;
XMEMSET(&sslCopy.alert_history, 0, sizeof(sslCopy.alert_history));
sslCopy.hsHashes = NULL;
#ifdef WOLFSSL_ASYNC_IO
#ifdef WOLFSSL_ASYNC_CRYPT
sslCopy.asyncDev = NULL;
#endif
sslCopy.async = NULL;
#endif
AssertIntEQ(wc_HashInit(&hash, hashType), 0);
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)&sslCopy, sizeof(sslCopy)), 0);
/* hash extension list */
while (exts != NULL) {
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)exts, sizeof(*exts)), 0);
exts = exts->next;
}
/* Hash suites */
if (sslCopy.suites != NULL) {
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)sslCopy.suites,
sizeof(struct Suites)), 0);
}
#ifdef WOLFSSL_SMALL_STACK_CACHE
/* with WOLFSSL_SMALL_STACK_CACHE, the SHA-2 objects always differ after
* initialization because of cached W and (for SHA512) X buffers.
*/
#else
/* Hash hsHashes */
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)hsHashes,
sizeof(*hsHashes)), 0);
#endif
AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
AssertIntEQ(wc_HashFree(&hash, hashType), 0);
return MakeWordFromHash(hashBuf);
}
static CallbackIORecv test_wolfSSL_dtls_compare_stateless_cb;
static int test_wolfSSL_dtls_compare_stateless_cb_call_once;
static int test_wolfSSL_dtls_compare_stateless_read_cb_once(WOLFSSL *ssl,
char *buf, int sz, void *ctx)
{
if (test_wolfSSL_dtls_compare_stateless_cb_call_once) {
test_wolfSSL_dtls_compare_stateless_cb_call_once = 0;
return test_wolfSSL_dtls_compare_stateless_cb(ssl, buf, sz, ctx);
}
else {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
}
static void test_wolfSSL_dtls_compare_stateless(WOLFSSL* ssl)
{
/* Compare the ssl object before and after one ClientHello msg */
SOCKET_T fd = wolfSSL_get_fd(ssl);
int res;
int err;
word32 initHash;
test_wolfSSL_dtls_compare_stateless_cb = ssl->CBIORecv;
test_wolfSSL_dtls_compare_stateless_cb_call_once = 1;
wolfSSL_dtls_set_using_nonblock(ssl, 1);
ssl->CBIORecv = test_wolfSSL_dtls_compare_stateless_read_cb_once;
initHash = test_wolfSSL_dtls_stateless_HashWOLFSSL(ssl);
(void)initHash;
res = tcp_select(fd, 5);
/* We are expecting a msg. A timeout indicates failure. */
AssertIntEQ(res, TEST_RECV_READY);
res = wolfSSL_accept(ssl);
err = wolfSSL_get_error(ssl, res);
AssertIntEQ(res, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
AssertIntEQ(err, WOLFSSL_ERROR_WANT_READ);
AssertIntEQ(initHash, test_wolfSSL_dtls_stateless_HashWOLFSSL(ssl));
wolfSSL_dtls_set_using_nonblock(ssl, 0);
ssl->CBIORecv = test_wolfSSL_dtls_compare_stateless_cb;
}
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
static void test_wolfSSL_dtls_enable_hrrcookie(WOLFSSL* ssl)
{
int ret;
ret = wolfSSL_send_hrr_cookie(ssl, NULL, 0);
AssertIntEQ(ret, WOLFSSL_SUCCESS);
test_wolfSSL_dtls_compare_stateless(ssl);
}
#endif
static int test_wolfSSL_dtls_stateless(void)
{
callback_functions client_cbs, server_cbs;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
ssl_callback client_ssl_ready;
ssl_callback server_ssl_ready;
} test_params[] = {
#if !defined(WOLFSSL_NO_TLS12)
{wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method,
test_wolfSSL_dtls_send_ch, test_wolfSSL_dtls_compare_stateless},
#endif
#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
{wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
test_wolfSSL_dtls_send_ch, test_wolfSSL_dtls_enable_hrrcookie},
{wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method,
test_wolfSSL_dtls_send_ch_with_invalid_cookie, test_wolfSSL_dtls_enable_hrrcookie},
#endif
};
if (0 == sizeof(test_params)){
return TEST_SKIPPED;
}
for (i = 0; i < sizeof(test_params)/sizeof(*test_params); i++) {
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.doUdp = server_cbs.doUdp = 1;
client_cbs.method = test_params[i].client_meth;
server_cbs.method = test_params[i].server_meth;
client_cbs.ssl_ready = test_params[i].client_ssl_ready;
server_cbs.ssl_ready = test_params[i].server_ssl_ready;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
if (!client_cbs.return_code)
return TEST_FAIL;
if (!server_cbs.return_code)
return TEST_FAIL;
}
return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls_stateless(void)
{
return TEST_SKIPPED;
}
#endif /* WOLFSSL_DTLS13 && WOLFSSL_SEND_HRR_COOKIE &&
* HAVE_IO_TESTS_DEPENDENCIES && !SINGLE_THREADED */
#if defined(HAVE_KEYING_MATERIAL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_export_keying_material_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
{
EXPECT_DECLS;
byte ekm[100] = {0};
(void)ctx;
/* Success Cases */
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 0), 1);
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1), 1);
/* Use some random context */
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"Test label", XSTR_SIZEOF("Test label"), ekm, 10, 1), 1);
/* Failure cases */
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"client finished", XSTR_SIZEOF("client finished"), NULL, 0, 0), 0);
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"server finished", XSTR_SIZEOF("server finished"), NULL, 0, 0), 0);
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"master secret", XSTR_SIZEOF("master secret"), NULL, 0, 0), 0);
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"extended master secret", XSTR_SIZEOF("extended master secret"),
NULL, 0, 0), 0);
ExpectIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
"key expansion", XSTR_SIZEOF("key expansion"), NULL, 0, 0), 0);
return EXPECT_RESULT();
}
static int test_export_keying_material_ssl_cb(WOLFSSL* ssl)
{
wolfSSL_KeepArrays(ssl);
return TEST_SUCCESS;
}
static int test_export_keying_material(void)
{
EXPECT_DECLS;
test_ssl_cbf serverCb;
test_ssl_cbf clientCb;
XMEMSET(&serverCb, 0, sizeof(serverCb));
XMEMSET(&clientCb, 0, sizeof(clientCb));
clientCb.ssl_ready = test_export_keying_material_ssl_cb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&clientCb,
&serverCb, test_export_keying_material_cb), TEST_SUCCESS);
return EXPECT_RESULT();
}
#endif /* HAVE_KEYING_MATERIAL */
static int test_wolfSSL_THREADID_hash(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
CRYPTO_THREADID id;
CRYPTO_THREADID_current(NULL);
/* Hash result is word32. */
ExpectTrue(CRYPTO_THREADID_hash(NULL) == 0UL);
XMEMSET(&id, 0, sizeof(id));
ExpectTrue(CRYPTO_THREADID_hash(&id) == 0UL);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_wolfSSL_set_ecdh_auto(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
WOLFSSL* ssl = NULL;
ExpectIntEQ(SSL_set_ecdh_auto(NULL,0), 1);
ExpectIntEQ(SSL_set_ecdh_auto(NULL,1), 1);
ExpectIntEQ(SSL_set_ecdh_auto(ssl,0), 1);
ExpectIntEQ(SSL_set_ecdh_auto(ssl,1), 1);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_ecdh_auto(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
WOLFSSL_CTX* ctx = NULL;
ExpectIntEQ(SSL_CTX_set_ecdh_auto(NULL,0), 1);
ExpectIntEQ(SSL_CTX_set_ecdh_auto(NULL,1), 1);
ExpectIntEQ(SSL_CTX_set_ecdh_auto(ctx,0), 1);
ExpectIntEQ(SSL_CTX_set_ecdh_auto(ctx,1), 1);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_server_thread(void* args)
{
EXPECT_DECLS;
callback_functions* callbacks = NULL;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
SOCKET_T sfd = 0;
SOCKET_T cfd = 0;
word16 port;
char msg[] = "I hear you fa shizzle!";
int len = (int) XSTRLEN(msg);
char input[1024];
int ret = 0;
int err = 0;
if (!args)
WOLFSSL_RETURN_FROM_THREAD(0);
((func_args*)args)->return_code = TEST_FAIL;
callbacks = ((func_args*)args)->callbacks;
ctx = wolfSSL_CTX_new(callbacks->method());
#if defined(USE_WINDOWS_API)
port = ((func_args*)args)->signal->port;
#else
/* Let tcp_listen assign port */
port = 0;
#endif
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
caCertFile, 0));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(ctx,
svrCertFile, WOLFSSL_FILETYPE_PEM));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(ctx,
svrKeyFile, WOLFSSL_FILETYPE_PEM));
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
ExpectIntEQ(wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#elif !defined(NO_DH)
SetDHCtx(ctx); /* will repick suites with DHE, higher priority than PSK */
#endif
if (callbacks->ctx_ready)
callbacks->ctx_ready(ctx);
ssl = wolfSSL_new(ctx);
ExpectNotNull(ssl);
/* listen and accept */
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1, 0, 0);
CloseSocket(sfd);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));
if (callbacks->ssl_ready)
callbacks->ssl_ready(ssl);
if (EXPECT_SUCCESS()) {
do {
err = 0; /* Reset error */
ret = wolfSSL_accept(ssl);
if (ret != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
}
} while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));
}
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
/* read and write data */
XMEMSET(input, 0, sizeof(input));
while (EXPECT_SUCCESS()) {
ret = wolfSSL_read(ssl, input, sizeof(input));
if (ret > 0) {
break;
}
else {
err = wolfSSL_get_error(ssl,ret);
if (err == WOLFSSL_ERROR_WANT_READ) {
continue;
}
break;
}
}
if (EXPECT_SUCCESS() && (err == WOLFSSL_ERROR_ZERO_RETURN)) {
do {
ret = wolfSSL_write(ssl, msg, len);
if (ret > 0) {
break;
}
} while (ret < 0);
}
/* bidirectional shutdown */
while (EXPECT_SUCCESS()) {
ret = wolfSSL_shutdown(ssl);
ExpectIntNE(ret, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
if (ret == WOLFSSL_SUCCESS) {
break;
}
}
if (EXPECT_SUCCESS()) {
/* wait for the peer to disconnect the tcp connection */
do {
ret = wolfSSL_read(ssl, input, sizeof(input));
err = wolfSSL_get_error(ssl, ret);
} while (ret > 0 || err != WOLFSSL_ERROR_ZERO_RETURN);
}
/* detect TCP disconnect */
ExpectIntLE(ret,WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_get_error(ssl, ret), WOLFSSL_ERROR_ZERO_RETURN);
((func_args*)args)->return_code = EXPECT_RESULT();
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(cfd);
#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_client_thread(void* args)
{
EXPECT_DECLS;
callback_functions* callbacks = NULL;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
SOCKET_T sfd = 0;
char msg[] = "hello wolfssl server!";
int len = (int) XSTRLEN(msg);
char input[1024];
int idx = 0;
int ret = 0, err = 0;
if (!args)
WOLFSSL_RETURN_FROM_THREAD(0);
((func_args*)args)->return_code = TEST_FAIL;
callbacks = ((func_args*)args)->callbacks;
ctx = wolfSSL_CTX_new(callbacks->method());
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx,
caCertFile, 0));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_certificate_file(ctx,
cliCertFile, WOLFSSL_FILETYPE_PEM));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_use_PrivateKey_file(ctx,
cliKeyFile, WOLFSSL_FILETYPE_PEM));
ExpectNotNull((ssl = wolfSSL_new(ctx)));
tcp_connect(&sfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, 0, ssl);
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_set_fd(ssl, sfd));
if (EXPECT_SUCCESS()) {
do {
err = 0; /* Reset error */
ret = wolfSSL_connect(ssl);
if (ret != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
}
} while (ret != WOLFSSL_SUCCESS && err == WC_NO_ERR_TRACE(WC_PENDING_E));
}
ExpectIntGE(wolfSSL_write(ssl, msg, len), 0);
if (EXPECT_SUCCESS()) {
if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
input[idx] = 0;
}
}
if (EXPECT_SUCCESS()) {
ret = wolfSSL_shutdown(ssl);
if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
ret = wolfSSL_shutdown(ssl);
}
}
ExpectIntEQ(ret, WOLFSSL_SUCCESS);
((func_args*)args)->return_code = EXPECT_RESULT();
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
CloseSocket(sfd);
#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */
#endif
WOLFSSL_RETURN_FROM_THREAD(0);
}
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL &&
HAVE_IO_TESTS_DEPENDENCIES && !WOLFSSL_NO_TLS12 */
/* This test is to check wolfSSL_read behaves as same as
* openSSL when it is called after SSL_shutdown completes.
*/
static int test_wolfSSL_read_detect_TCP_disconnect(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
tcp_ready ready;
func_args client_args;
func_args server_args;
THREAD_TYPE serverThread;
THREAD_TYPE clientThread;
callback_functions server_cbf;
callback_functions client_cbf;
#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
#endif
StartTCP();
InitTcpReady(&ready);
#if defined(USE_WINDOWS_API)
/* use RNG to get random port if using windows */
ready.port = GetRandomPort();
#endif
XMEMSET(&client_args, 0, sizeof(func_args));
XMEMSET(&server_args, 0, sizeof(func_args));
XMEMSET(&server_cbf, 0, sizeof(callback_functions));
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
server_cbf.method = wolfTLSv1_2_server_method;
client_cbf.method = wolfTLSv1_2_client_method;
server_args.callbacks = &server_cbf;
client_args.callbacks = &client_cbf;
server_args.signal = &ready;
client_args.signal = &ready;
start_thread(SSL_read_test_server_thread, &server_args, &serverThread);
wait_tcp_ready(&server_args);
start_thread(SSL_read_test_client_thread, &client_args, &clientThread);
join_thread(clientThread);
join_thread(serverThread);
ExpectTrue(client_args.return_code);
ExpectTrue(server_args.return_code);
FreeTcpReady(&ready);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_get_min_proto_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_TLS)
WOLFSSL_CTX *ctx = NULL;
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, SSL3_VERSION),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ALLOW_SSLV3
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), SSL3_VERSION);
#else
ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), SSL3_VERSION);
#endif
wolfSSL_CTX_free(ctx);
ctx = NULL;
#ifndef NO_OLD_TLS
#ifdef WOLFSSL_ALLOW_TLSV10
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
#endif
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_VERSION),
WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ALLOW_TLSV10
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_VERSION);
#else
ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_VERSION);
#endif
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_method()));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION),
WOLFSSL_SUCCESS);
#ifndef NO_OLD_TLS
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_1_VERSION);
#else
ExpectIntGT(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_1_VERSION);
#endif
wolfSSL_CTX_free(ctx);
ctx = NULL;
#ifndef WOLFSSL_NO_TLS12
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_method()));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_2_VERSION);
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif
#ifdef WOLFSSL_TLS13
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_method()));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx), TLS1_3_VERSION);
wolfSSL_CTX_free(ctx);
ctx = NULL;
#endif
#endif
return EXPECT_RESULT();
}
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
static int test_wolfSSL_set_SSL_CTX(void)
{
EXPECT_DECLS;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) \
&& !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_TLS13) && \
!defined(NO_RSA) && !defined(NO_WOLFSSL_SERVER)
WOLFSSL_CTX *ctx1 = NULL;
WOLFSSL_CTX *ctx2 = NULL;
WOLFSSL *ssl = NULL;
const byte *session_id1 = (const byte *)"CTX1";
const byte *session_id2 = (const byte *)"CTX2";
ExpectNotNull(ctx1 = wolfSSL_CTX_new(wolfTLS_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx1, svrCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx1, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx1, TLS1_2_VERSION),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx1), TLS1_2_VERSION);
ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx1), TLS1_3_VERSION);
ExpectIntEQ(wolfSSL_CTX_set_session_id_context(ctx1, session_id1, 4),
WOLFSSL_SUCCESS);
ExpectNotNull(ctx2 = wolfSSL_CTX_new(wolfTLS_server_method()));
ExpectTrue(wolfSSL_CTX_use_certificate_file(ctx2, svrCertFile,
WOLFSSL_FILETYPE_PEM));
ExpectTrue(wolfSSL_CTX_use_PrivateKey_file(ctx2, svrKeyFile,
WOLFSSL_FILETYPE_PEM));
ExpectIntEQ(wolfSSL_CTX_set_min_proto_version(ctx2, TLS1_2_VERSION),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_max_proto_version(ctx2, TLS1_2_VERSION),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_get_min_proto_version(ctx2), TLS1_2_VERSION);
ExpectIntEQ(wolfSSL_CTX_get_max_proto_version(ctx2), TLS1_2_VERSION);
ExpectIntEQ(wolfSSL_CTX_set_session_id_context(ctx2, session_id2, 4),
WOLFSSL_SUCCESS);
#ifdef HAVE_SESSION_TICKET
ExpectIntEQ((wolfSSL_CTX_get_options(ctx1) & SSL_OP_NO_TICKET), 0);
wolfSSL_CTX_set_options(ctx2, SSL_OP_NO_TICKET);
ExpectIntNE((wolfSSL_CTX_get_options(ctx2) & SSL_OP_NO_TICKET), 0);
#endif
ExpectNotNull(ssl = wolfSSL_new(ctx2));
ExpectIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
#ifdef WOLFSSL_INT_H
#ifdef WOLFSSL_SESSION_ID_CTX
ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id2, 4), 0);
#endif
#ifdef WOLFSSL_COPY_CERT
if (ctx2 != NULL && ctx2->certificate != NULL) {
ExpectFalse(ssl->buffers.certificate == ctx2->certificate);
}
if (ctx2 != NULL && ctx2->certChain != NULL) {
ExpectFalse(ssl->buffers.certChain == ctx2->certChain);
}
#else
ExpectTrue(ssl->buffers.certificate == ctx2->certificate);
ExpectTrue(ssl->buffers.certChain == ctx2->certChain);
#endif
#endif
#ifdef HAVE_SESSION_TICKET
ExpectIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
#endif
/* Set the ctx1 that has TLSv1.3 as max proto version */
ExpectNotNull(wolfSSL_set_SSL_CTX(ssl, ctx1));
/* MUST not change proto versions of ssl */
ExpectIntNE((wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_3), 0);
#ifdef HAVE_SESSION_TICKET
/* MUST not change */
ExpectIntNE((wolfSSL_get_options(ssl) & SSL_OP_NO_TICKET), 0);
#endif
/* MUST change */
#ifdef WOLFSSL_INT_H
#ifdef WOLFSSL_COPY_CERT
if (ctx1 != NULL && ctx1->certificate != NULL) {
ExpectFalse(ssl->buffers.certificate == ctx1->certificate);
}
if (ctx1 != NULL && ctx1->certChain != NULL) {
ExpectFalse(ssl->buffers.certChain == ctx1->certChain);
}
#else
ExpectTrue(ssl->buffers.certificate == ctx1->certificate);
ExpectTrue(ssl->buffers.certChain == ctx1->certChain);
#endif
#ifdef WOLFSSL_SESSION_ID_CTX
ExpectIntEQ(XMEMCMP(ssl->sessionCtx, session_id1, 4), 0);
#endif
#endif
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx1);
wolfSSL_CTX_free(ctx2);
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */
return EXPECT_RESULT();
}
#endif /* defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))) */
static int test_wolfSSL_security_level(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
SSL_CTX *ctx = NULL;
#ifdef WOLFSSL_TLS13
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
SSL_CTX_set_security_level(NULL, 1);
SSL_CTX_set_security_level(ctx, 1);
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
ExpectIntEQ(SSL_CTX_get_security_level(NULL), BAD_FUNC_ARG);
#else
ExpectIntEQ(SSL_CTX_get_security_level(NULL), 0);
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
/* Stub so nothing happens. */
ExpectIntEQ(SSL_CTX_get_security_level(ctx), 0);
SSL_CTX_free(ctx);
#else
(void)ctx;
#endif
#endif
return EXPECT_RESULT();
}
/* System wide crypto-policy test.
*
* Loads three different policies (legacy, default, future),
* then tests crypt_policy api.
* */
static int test_wolfSSL_crypto_policy(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SYS_CRYPTO_POLICY) && !defined(NO_TLS)
int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
const char * policy_list[] = {
"examples/crypto_policies/legacy/wolfssl.txt",
"examples/crypto_policies/default/wolfssl.txt",
"examples/crypto_policies/future/wolfssl.txt",
};
const char * ciphers_list[] = {
"@SECLEVEL=1:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK"
":!eNULL:!aNULL",
"@SECLEVEL=2:EECDH:kRSA:EDH:PSK:DHEPSK:ECDHEPSK:RSAPSK"
":!RC4:!eNULL:!aNULL",
"@SECLEVEL=3:EECDH:EDH:PSK:DHEPSK:ECDHEPSK:!RSAPSK:!kRSA"
":!AES128:!RC4:!eNULL:!aNULL:!SHA1",
};
int seclevel_list[] = { 1, 2, 3 };
int i = 0;
for (i = 0; i < 3; ++i) {
const char * ciphers = NULL;
int n_diff = 0;
WOLFSSL_CTX * ctx = NULL;
WOLFSSL * ssl = NULL;
/* Enable crypto policy. */
rc = wolfSSL_crypto_policy_enable(policy_list[i]);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
rc = wolfSSL_crypto_policy_is_enabled();
ExpectIntEQ(rc, 1);
/* Trying to enable while already enabled should return
* forbidden. */
rc = wolfSSL_crypto_policy_enable(policy_list[i]);
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
/* Security level and ciphers should match what is expected. */
rc = wolfSSL_crypto_policy_get_level();
ExpectIntEQ(rc, seclevel_list[i]);
ciphers = wolfSSL_crypto_policy_get_ciphers();
ExpectNotNull(ciphers);
if (ciphers != NULL) {
n_diff = XSTRNCMP(ciphers, ciphers_list[i], strlen(ciphers));
#ifdef DEBUG_WOLFSSL
if (n_diff) {
printf("error: got \n%s, expected \n%s\n",
ciphers, ciphers_list[i]);
}
#endif /* DEBUG_WOLFSSL */
ExpectIntEQ(n_diff, 0);
}
/* TLSv1_2_method should work for all policies. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
ssl = wolfSSL_new(ctx);
ExpectNotNull(ssl);
/* These API should be rejected while enabled. */
rc = wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_TLSV1_3);
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
rc = wolfSSL_SetMinVersion(ssl, WOLFSSL_TLSV1_3);
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
if (ssl != NULL) {
wolfSSL_free(ssl);
ssl = NULL;
}
wolfSSL_crypto_policy_disable();
/* Do the same test by buffer. */
rc = wolfSSL_crypto_policy_enable_buffer(ciphers_list[i]);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
rc = wolfSSL_crypto_policy_is_enabled();
ExpectIntEQ(rc, 1);
/* Security level and ciphers should match what is expected. */
rc = wolfSSL_crypto_policy_get_level();
ExpectIntEQ(rc, seclevel_list[i]);
ciphers = wolfSSL_crypto_policy_get_ciphers();
ExpectNotNull(ciphers);
if (ciphers != NULL) {
n_diff = XSTRNCMP(ciphers, ciphers_list[i], strlen(ciphers));
#ifdef DEBUG_WOLFSSL
if (n_diff) {
printf("error: got \n%s, expected \n%s\n",
ciphers, ciphers_list[i]);
}
#endif /* DEBUG_WOLFSSL */
ExpectIntEQ(n_diff, 0);
}
wolfSSL_crypto_policy_disable();
}
wolfSSL_crypto_policy_disable();
#endif /* WOLFSSL_SYS_CRYPTO_POLICY && !NO_TLS */
return EXPECT_RESULT();
}
/* System wide crypto-policy test: certs and keys.
*
* Loads three different policies (legacy, default, future),
* then tests loading different certificates and keys of
* varying strength.
* */
static int test_wolfSSL_crypto_policy_certs_and_keys(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SYS_CRYPTO_POLICY) && !defined(NO_TLS)
int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
const char * policy_list[] = {
"examples/crypto_policies/legacy/wolfssl.txt",
"examples/crypto_policies/default/wolfssl.txt",
"examples/crypto_policies/future/wolfssl.txt",
};
int i = 0;
for (i = 0; i < 3; ++i) {
WOLFSSL_CTX * ctx = NULL;
WOLFSSL * ssl = NULL;
int is_legacy = 0;
int is_future = 0;
/* certs */
const char * cert1024 = "certs/1024/client-cert.pem";
const char * cert2048 = "certs/client-cert.pem";
const char * cert3072 = "certs/3072/client-cert.pem";
const char * cert256 = "certs/client-ecc-cert.pem";
const char * cert384 = "certs/client-ecc384-cert.pem";
/* keys */
const char * key1024 = "certs/1024/client-key.pem";
const char * key2048 = "certs/client-key.pem";
const char * key3072 = "certs/3072/client-key.pem";
const char * key256 = "certs/ecc-key.pem";
const char * key384 = "certs/client-ecc384-key.pem";
is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0;
is_future = (XSTRSTR(policy_list[i], "future") != NULL) ? 1 : 0;
/* Enable crypto policy. */
rc = wolfSSL_crypto_policy_enable(policy_list[i]);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
rc = wolfSSL_crypto_policy_is_enabled();
ExpectIntEQ(rc, 1);
/* TLSv1_2_method should work for all policies. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
/* Test certs of varying strength. */
if (ctx != NULL) {
/* VERIFY_PEER must be set for key/cert checks to be done. */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
/* Test loading a cert with 1024 RSA key size.
* This should fail for all but legacy. */
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert1024);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, WOLFSSL_FAILURE);
}
/* Test loading a cert with 2048 RSA key size.
* Future crypto-policy is min 3072 RSA and DH key size,
* and should fail. */
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert2048);
if (is_future) {
/* Future crypto-policy is min 3072 RSA and DH key size, this
* and should fail. */
ExpectIntEQ(rc, WOLFSSL_FAILURE);
/* Set to VERIFY_NONE. This will disable key size checks,
* it should now succeed. */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert2048);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* Set back to verify peer. */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
}
else {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
/* Test loading a CA cert with 3072 RSA key size.
* This should succeed for all policies. */
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert3072);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* Test loading an ecc cert with 256 key size.
* This should succeed for all policies. */
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert256);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* Test loading an ecc cert with 384 key size.
* This should succeed for all policies. */
rc = wolfSSL_CTX_use_certificate_chain_file(ctx, cert384);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* cleanup */
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
/* TLSv1_2_method should work for all policies. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
/* Repeat same tests for keys of varying strength. */
if (ctx != NULL) {
/* 1024 RSA */
rc = SSL_CTX_use_PrivateKey_file(ctx, key1024,
SSL_FILETYPE_PEM);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, WOLFSSL_FAILURE);
}
/* 2048 RSA */
rc = SSL_CTX_use_PrivateKey_file(ctx, key2048,
SSL_FILETYPE_PEM);
if (!is_future) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, WOLFSSL_FAILURE);
}
/* 3072 RSA */
rc = SSL_CTX_use_PrivateKey_file(ctx, key3072,
SSL_FILETYPE_PEM);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* 256 ecc */
rc = SSL_CTX_use_PrivateKey_file(ctx, key256,
SSL_FILETYPE_PEM);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* 384 ecc */
rc = SSL_CTX_use_PrivateKey_file(ctx, key384,
SSL_FILETYPE_PEM);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* cleanup */
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#ifdef HAVE_ECC
/* Test set ecc min key size. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
ssl = SSL_new(ctx);
ExpectNotNull(ssl);
/* Test setting ctx. */
rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 160);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 224);
if (!is_future) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_CTX_SetMinEccKey_Sz(ctx, 256);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* Test setting ssl. */
if (ssl != NULL) {
rc = wolfSSL_SetMinEccKey_Sz(ssl, 160);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_SetMinEccKey_Sz(ssl, 224);
if (!is_future) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_SetMinEccKey_Sz(ssl, 256);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
ssl = NULL;
}
/* cleanup */
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#endif /* HAVE_ECC */
#if !defined(NO_RSA)
/* Test set rsa min key size. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
ssl = SSL_new(ctx);
ExpectNotNull(ssl);
/* Test setting ctx. */
rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 1024);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 2048);
if (!is_future) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_CTX_SetMinRsaKey_Sz(ctx, 3072);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
/* Test setting ssl. */
if (ssl != NULL) {
rc = wolfSSL_SetMinRsaKey_Sz(ssl, 1024);
if (is_legacy) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_SetMinRsaKey_Sz(ssl, 2048);
if (!is_future) {
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
}
else {
ExpectIntEQ(rc, CRYPTO_POLICY_FORBIDDEN);
}
rc = wolfSSL_SetMinRsaKey_Sz(ssl, 3072);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
wolfSSL_free(ssl);
ssl = NULL;
}
/* cleanup */
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#endif /* !NO_RSA */
wolfSSL_crypto_policy_disable();
}
wolfSSL_crypto_policy_disable();
#endif /* WOLFSSL_SYS_CRYPTO_POLICY && !NO_TLS */
return EXPECT_RESULT();
}
/* System wide crypto-policy test: tls and dtls methods.
* */
static int test_wolfSSL_crypto_policy_tls_methods(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SYS_CRYPTO_POLICY) && !defined(NO_TLS)
int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
const char * policy_list[] = {
"examples/crypto_policies/legacy/wolfssl.txt",
"examples/crypto_policies/default/wolfssl.txt",
"examples/crypto_policies/future/wolfssl.txt",
};
int i = 0;
for (i = 0; i < 3; ++i) {
WOLFSSL_CTX * ctx = NULL;
int is_legacy = 0;
is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0;
/* Enable crypto policy. */
rc = wolfSSL_crypto_policy_enable(policy_list[i]);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
rc = wolfSSL_crypto_policy_is_enabled();
ExpectIntEQ(rc, 1);
/* Try to use old TLS methods. Only allowed with legacy. */
#if !defined(NO_OLD_TLS)
ctx = wolfSSL_CTX_new(wolfTLSv1_1_method());
if (is_legacy) {
ExpectNotNull(ctx);
}
else {
ExpectNull(ctx);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#if defined(WOLFSSL_ALLOW_TLSV10)
ctx = wolfSSL_CTX_new(wolfTLSv1_method());
if (is_legacy) {
ExpectNotNull(ctx);
}
else {
ExpectNull(ctx);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#endif /* WOLFSSL_ALLOW_TLSV10 */
#else
(void) is_legacy;
#endif /* !NO_OLD_TLS */
/* TLSv1_2_method should work for all policies. */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
ctx = wolfSSL_CTX_new(wolfTLSv1_3_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
ctx = wolfSSL_CTX_new(TLS_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#ifdef WOLFSSL_DTLS
ctx = wolfSSL_CTX_new(DTLS_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
ctx = wolfSSL_CTX_new(wolfDTLSv1_2_method());
ExpectNotNull(ctx);
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#ifndef NO_OLD_TLS
/* Only allowed with legacy. */
ctx = wolfSSL_CTX_new(wolfDTLSv1_method());
if (is_legacy) {
ExpectNotNull(ctx);
}
else {
ExpectNull(ctx);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
#endif /* !NO_OLD_TLS */
#endif /* WOLFSSL_DTLS */
wolfSSL_crypto_policy_disable();
}
wolfSSL_crypto_policy_disable();
#endif /* WOLFSSL_SYS_CRYPTO_POLICY && !NO_TLS */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_SYS_CRYPTO_POLICY) && !defined(NO_TLS)
/* Helper function for test_wolfSSL_crypto_policy_ciphers.
* Searches ssl suites for cipher string.
*
* Returns 1 if found.
* Returns 0 if not found.
* Returns < 0 if error.
* */
static int crypto_policy_cipher_found(const WOLFSSL * ssl,
const char * cipher,
int match)
{
WOLF_STACK_OF(WOLFSSL_CIPHER) * sk = NULL;
WOLFSSL_CIPHER * current = NULL;
const char * suite;
int found = 0;
int i = 0;
if (ssl == NULL || cipher == NULL || *cipher == '\0') {
return -1;
}
sk = wolfSSL_get_ciphers_compat(ssl);
if (sk == NULL) {
return -1;
}
do {
current = wolfSSL_sk_SSL_CIPHER_value(sk, i++);
if (current) {
suite = wolfSSL_CIPHER_get_name(current);
if (suite) {
if (match == 1) {
/* prefix match */
if (XSTRNCMP(suite, cipher, XSTRLEN(cipher)) == 0) {
found = 1;
break;
}
}
else if (match == -1) {
/* postfix match */
if (XSTRLEN(suite) > XSTRLEN(cipher)) {
const char * postfix = suite + XSTRLEN(suite)
- XSTRLEN(cipher);
if (XSTRNCMP(postfix, cipher, XSTRLEN(cipher)) == 0) {
found = 1;
break;
}
}
}
else {
/* needle in haystack match */
if (XSTRSTR(suite, cipher)) {
found = 1;
break;
}
}
}
}
} while (current);
return found == 1;
}
#endif /* WOLFSSL_SYS_CRYPTO_POLICY && !NO_TLS */
/* System wide crypto-policy test: ciphers.
* */
static int test_wolfSSL_crypto_policy_ciphers(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_SYS_CRYPTO_POLICY) && !defined(NO_TLS)
int rc = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
const char * policy_list[] = {
"examples/crypto_policies/legacy/wolfssl.txt",
"examples/crypto_policies/default/wolfssl.txt",
"examples/crypto_policies/future/wolfssl.txt",
};
int seclevel_list[] = { 1, 2, 3 };
int i = 0;
int is_legacy = 0;
int is_future = 0;
for (i = 0; i < 3; ++i) {
WOLFSSL_CTX * ctx = NULL;
WOLFSSL * ssl = NULL;
int found = 0;
is_legacy = (XSTRSTR(policy_list[i], "legacy") != NULL) ? 1 : 0;
is_future = (XSTRSTR(policy_list[i], "future") != NULL) ? 1 : 0;
(void) is_legacy;
/* Enable crypto policy. */
rc = wolfSSL_crypto_policy_enable(policy_list[i]);
ExpectIntEQ(rc, WOLFSSL_SUCCESS);
rc = wolfSSL_crypto_policy_is_enabled();
ExpectIntEQ(rc, 1);
ctx = wolfSSL_CTX_new(TLS_method());
ExpectNotNull(ctx);
ssl = SSL_new(ctx);
ExpectNotNull(ssl);
rc = wolfSSL_CTX_get_security_level(ctx);
ExpectIntEQ(rc, seclevel_list[i]);
rc = wolfSSL_get_security_level(ssl);
ExpectIntEQ(rc, seclevel_list[i]);
found = crypto_policy_cipher_found(ssl, "RC4", 0);
ExpectIntEQ(found, is_legacy);
/* We return a different cipher string depending on build settings. */
#if !defined(WOLFSSL_CIPHER_INTERNALNAME) && \
!defined(NO_ERROR_STRINGS) && !defined(WOLFSSL_QT)
found = crypto_policy_cipher_found(ssl, "AES_128", 0);
ExpectIntEQ(found, !is_future);
found = crypto_policy_cipher_found(ssl, "TLS_DHE_RSA_WITH_AES", 1);
ExpectIntEQ(found, !is_future);
found = crypto_policy_cipher_found(ssl, "_SHA", -1);
ExpectIntEQ(found, !is_future);
#else
found = crypto_policy_cipher_found(ssl, "AES128", 0);
ExpectIntEQ(found, !is_future);
found = crypto_policy_cipher_found(ssl, "DHE-RSA-AES", 1);
ExpectIntEQ(found, !is_future);
found = crypto_policy_cipher_found(ssl, "-SHA", -1);
ExpectIntEQ(found, !is_future);
#endif
if (ssl != NULL) {
SSL_free(ssl);
ssl = NULL;
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
ctx = NULL;
}
wolfSSL_crypto_policy_disable();
}
wolfSSL_crypto_policy_disable();
#endif /* WOLFSSL_SYS_CRYPTO_POLICY && !NO_TLS */
return EXPECT_RESULT();
}
static int test_wolfSSL_SSL_in_init(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_BIO) && !defined(NO_TLS)
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
const char* testCertFile;
const char* testKeyFile;
#ifdef WOLFSSL_TLS13
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
#else
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
#endif
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#else
testCertFile = NULL;
testKeyFile = NULL;
#endif
if ((testCertFile != NULL) && (testKeyFile != NULL)) {
ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
SSL_FILETYPE_PEM));
}
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_in_init(ssl), 1);
SSL_CTX_free(ctx);
SSL_free(ssl);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_timeout(void)
{
EXPECT_DECLS;
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS) && \
!defined(NO_SESSION_CACHE)
WOLFSSL_CTX* ctx = NULL;
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
int timeout;
#endif
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
/* in WOLFSSL_ERROR_CODE_OPENSSL macro guard,
* wolfSSL_CTX_set_timeout returns previous timeout value on success.
*/
ExpectIntEQ(wolfSSL_CTX_set_timeout(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* giving 0 as timeout value sets default timeout */
timeout = wolfSSL_CTX_set_timeout(ctx, 0);
ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 20), timeout);
ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 30), 20);
#else
ExpectIntEQ(wolfSSL_CTX_set_timeout(NULL, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 100), 1);
ExpectIntEQ(wolfSSL_CTX_set_timeout(ctx, 0), 1);
#endif
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_OpenSSL_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
const char* ver;
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
ExpectNotNull(ver = OpenSSL_version(0));
#else
ExpectNotNull(ver = OpenSSL_version());
#endif
ExpectIntEQ(XMEMCMP(ver, "wolfSSL " LIBWOLFSSL_VERSION_STRING,
XSTRLEN("wolfSSL " LIBWOLFSSL_VERSION_STRING)), 0);
#endif
return EXPECT_RESULT();
}
static int test_CONF_CTX_CMDLINE(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_TLS) && !defined(NO_WOLFSSL_SERVER)
SSL_CTX* ctx = NULL;
SSL_CONF_CTX* cctx = NULL;
ExpectNotNull(cctx = SSL_CONF_CTX_new());
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
/* set flags */
ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CMDLINE),
WOLFSSL_CONF_FLAG_CMDLINE);
ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CERTIFICATE),
WOLFSSL_CONF_FLAG_CMDLINE | WOLFSSL_CONF_FLAG_CERTIFICATE);
/* cmd invalid command */
ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", "foobar"), -2);
ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", NULL), -2);
ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CONF_cmd(NULL, "-curves", "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* cmd Certificate and Private Key*/
{
#if !defined(NO_CERTS) && !defined(NO_RSA)
const char* ourCert = svrCertFile;
const char* ourKey = svrKeyFile;
ExpectIntEQ(SSL_CONF_cmd(cctx, "-cert", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-cert", ourCert), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-key", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-key", ourKey), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
/* cmd curves */
{
#if defined(HAVE_ECC)
const char* curve = "secp256r1";
ExpectIntEQ(SSL_CONF_cmd(cctx, "-curves", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-curves", curve), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
/* cmd CipherString */
{
char* cipher = wolfSSL_get_cipher_list(0/*top priority*/);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-cipher", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-cipher", cipher), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
}
/* cmd DH parameter */
{
#if !defined(NO_DH) && !defined(NO_BIO)
const char* ourdhcert = "./certs/dh2048.pem";
ExpectIntEQ(SSL_CONF_cmd(cctx, "-dhparam", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "-dhparam", ourdhcert), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
SSL_CTX_free(ctx);
SSL_CONF_CTX_free(cctx);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_CONF_CTX_FILE(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_TLS) && !defined(NO_WOLFSSL_SERVER)
SSL_CTX* ctx = NULL;
SSL_CONF_CTX* cctx = NULL;
ExpectNotNull(cctx = SSL_CONF_CTX_new());
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
/* set flags */
ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_FILE),
WOLFSSL_CONF_FLAG_FILE);
ExpectIntEQ(SSL_CONF_CTX_set_flags(cctx, WOLFSSL_CONF_FLAG_CERTIFICATE),
WOLFSSL_CONF_FLAG_FILE | WOLFSSL_CONF_FLAG_CERTIFICATE);
/* sanity check */
ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", "foobar"), -2);
ExpectIntEQ(SSL_CONF_cmd(cctx, "foo", NULL), -2);
ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CONF_cmd(cctx, NULL, "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(SSL_CONF_cmd(NULL, "-curves", "foobar"), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
/* cmd Certificate and Private Key*/
{
#if !defined(NO_CERTS) && !defined(NO_RSA)
const char* ourCert = svrCertFile;
const char* ourKey = svrKeyFile;
ExpectIntEQ(SSL_CONF_cmd(cctx, "Certificate", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "PrivateKey", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "Certificate", ourCert),
WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_cmd(cctx, "PrivateKey", ourKey), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
/* cmd curves */
{
#if defined(HAVE_ECC)
const char* curve = "secp256r1";
ExpectIntEQ(SSL_CONF_cmd(cctx, "Curves", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "Curves", curve), WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
/* cmd CipherString */
{
char* cipher = wolfSSL_get_cipher_list(0/*top priority*/);
ExpectIntEQ(SSL_CONF_cmd(cctx, "CipherString", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "CipherString", cipher),
WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
}
/* cmd DH parameter */
{
#if !defined(NO_DH) && !defined(NO_BIO) && defined(HAVE_FFDHE_3072)
const char* ourdhcert = "./certs/dh3072.pem";
ExpectIntEQ(SSL_CONF_cmd(cctx, "DHParameters", NULL), -3);
ExpectIntEQ(SSL_CONF_cmd(cctx, "DHParameters", ourdhcert),
WOLFSSL_SUCCESS);
ExpectIntEQ(SSL_CONF_CTX_finish(cctx), WOLFSSL_SUCCESS);
#endif
}
SSL_CTX_free(ctx);
SSL_CONF_CTX_free(cctx);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
}
static int test_wolfSSL_CRYPTO_get_ex_new_index(void)
{
EXPECT_DECLS;
#ifdef HAVE_EX_DATA_CRYPTO
int idx1, idx2;
/* test for unsupported class index */
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509_STORE,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(
WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DH,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DSA,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_EC_KEY,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_RSA,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_ENGINE,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_UI,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_BIO,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_APP,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_UI_METHOD,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_DRBG,
0,NULL, NULL, NULL, NULL ), -1);
ExpectIntEQ(wolfSSL_CRYPTO_get_ex_new_index(20,
0,NULL, NULL, NULL, NULL ), -1);
/* test for supported class index */
idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL,
0,NULL, NULL, NULL, NULL );
idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL,
0,NULL, NULL, NULL, NULL );
ExpectIntNE(idx1, -1);
ExpectIntNE(idx2, -1);
ExpectIntNE(idx1, idx2);
idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX,
0,NULL, NULL, NULL, NULL );
idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX,
0,NULL, NULL, NULL, NULL );
ExpectIntNE(idx1, -1);
ExpectIntNE(idx2, -1);
ExpectIntNE(idx1, idx2);
idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509,
0,NULL, NULL, NULL, NULL );
idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_X509,
0,NULL, NULL, NULL, NULL );
ExpectIntNE(idx1, -1);
ExpectIntNE(idx2, -1);
ExpectIntNE(idx1, idx2);
idx1 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION,
0,NULL, NULL, NULL, NULL );
idx2 = wolfSSL_CRYPTO_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION,
0,NULL, NULL, NULL, NULL );
ExpectIntNE(idx1, -1);
ExpectIntNE(idx2, -1);
ExpectIntNE(idx1, idx2);
#endif /* HAVE_EX_DATA_CRYPTO */
return EXPECT_RESULT();
}
#if defined(HAVE_EX_DATA_CRYPTO) && defined(OPENSSL_EXTRA)
#define SESSION_NEW_IDX_LONG 0xDEADBEEF
#define SESSION_NEW_IDX_VAL ((void*)0xAEADAEAD)
#define SESSION_DUP_IDX_VAL ((void*)0xDEDEDEDE)
#define SESSION_NEW_IDX_PTR "Testing"
static void test_wolfSSL_SESSION_get_ex_new_index_new_cb(void* p, void* ptr,
CRYPTO_EX_DATA* a, int idx, long argValue, void* arg)
{
AssertNotNull(p);
AssertNull(ptr);
AssertIntEQ(CRYPTO_set_ex_data(a, idx, SESSION_NEW_IDX_VAL), SSL_SUCCESS);
AssertIntEQ(argValue, SESSION_NEW_IDX_LONG);
AssertStrEQ(arg, SESSION_NEW_IDX_PTR);
}
static int test_wolfSSL_SESSION_get_ex_new_index_dup_cb(CRYPTO_EX_DATA* out,
const CRYPTO_EX_DATA* in, void* inPtr, int idx, long argV,
void* arg)
{
EXPECT_DECLS;
ExpectNotNull(out);
ExpectNotNull(in);
ExpectPtrEq(*(void**)inPtr, SESSION_NEW_IDX_VAL);
ExpectPtrEq(CRYPTO_get_ex_data(in, idx), SESSION_NEW_IDX_VAL);
ExpectPtrEq(CRYPTO_get_ex_data(out, idx), SESSION_NEW_IDX_VAL);
ExpectIntEQ(argV, SESSION_NEW_IDX_LONG);
ExpectStrEQ(arg, SESSION_NEW_IDX_PTR);
*(void**)inPtr = SESSION_DUP_IDX_VAL;
if (EXPECT_SUCCESS()) {
return SSL_SUCCESS;
}
else {
return SSL_FAILURE;
}
}
static int test_wolfSSL_SESSION_get_ex_new_index_free_cb_called = 0;
static void test_wolfSSL_SESSION_get_ex_new_index_free_cb(void* p, void* ptr,
CRYPTO_EX_DATA* a, int idx, long argValue, void* arg)
{
EXPECT_DECLS;
ExpectNotNull(p);
ExpectNull(ptr);
ExpectPtrNE(CRYPTO_get_ex_data(a, idx), 0);
ExpectIntEQ(argValue, SESSION_NEW_IDX_LONG);
ExpectStrEQ(arg, SESSION_NEW_IDX_PTR);
if (EXPECT_SUCCESS()) {
test_wolfSSL_SESSION_get_ex_new_index_free_cb_called++;
}
}
static int test_wolfSSL_SESSION_get_ex_new_index(void)
{
EXPECT_DECLS;
int idx = SSL_SESSION_get_ex_new_index(SESSION_NEW_IDX_LONG,
(void*)SESSION_NEW_IDX_PTR,
test_wolfSSL_SESSION_get_ex_new_index_new_cb,
test_wolfSSL_SESSION_get_ex_new_index_dup_cb,
test_wolfSSL_SESSION_get_ex_new_index_free_cb);
SSL_SESSION* s = SSL_SESSION_new();
SSL_SESSION* d = NULL;
ExpectNotNull(s);
ExpectPtrEq(SSL_SESSION_get_ex_data(s, idx), SESSION_NEW_IDX_VAL);
ExpectNotNull(d = SSL_SESSION_dup(s));
ExpectPtrEq(SSL_SESSION_get_ex_data(d, idx), SESSION_DUP_IDX_VAL);
SSL_SESSION_free(s);
ExpectIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 1);
SSL_SESSION_free(d);
ExpectIntEQ(test_wolfSSL_SESSION_get_ex_new_index_free_cb_called, 2);
crypto_ex_cb_free(crypto_ex_cb_ctx_session);
crypto_ex_cb_ctx_session = NULL;
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_SESSION_get_ex_new_index(void)
{
return TEST_SKIPPED;
}
#endif
static int test_wolfSSL_set_psk_use_session_callback(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_PSK) && !defined(NO_TLS)
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
const char* testCertFile;
const char* testKeyFile;
#ifdef WOLFSSL_TLS13
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()));
#endif
#else
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
#endif
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#else
testCertFile = NULL;
testKeyFile = NULL;
#endif
if ((testCertFile != NULL) && (testKeyFile != NULL)) {
ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
SSL_FILETYPE_PEM));
}
ExpectNotNull(ssl = SSL_new(ctx));
SSL_set_psk_use_session_callback(ssl, my_psk_use_session_cb);
SSL_CTX_free(ctx);
SSL_free(ssl);
#endif
return EXPECT_RESULT();
}
/* similar to error_test() in wolfcrypt/test/test.c, but adding error codes from
* TLS layer.
*/
static int error_test(void)
{
EXPECT_DECLS;
const char* errStr;
const char* unknownStr = wc_GetErrorString(0);
#ifdef NO_ERROR_STRINGS
/* Ensure a valid error code's string matches an invalid code's.
* The string is that error strings are not available.
*/
errStr = wc_GetErrorString(OPEN_RAN_E);
ExpectIntEQ(XSTRCMP(errStr, unknownStr), 0);
if (EXPECT_FAIL())
return OPEN_RAN_E;
#else
int start_idx = 0;
int i;
int j = 0;
/* Values that are not or no longer error codes. */
static const struct {
int first;
int last;
} missing[] = {
#ifndef OPENSSL_EXTRA
{ 0, 0 },
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
{11, 11},
{17, 15},
{19, 19},
{27, 26 },
#endif
{ -9, WC_SPAN1_FIRST_E + 1 },
{ -124, -124 },
{ -167, -169 },
{ -300, -300 },
{ -334, -336 },
{ -346, -349 },
{ -356, -356 },
{ -358, -358 },
{ -384, -384 },
{ -466, -499 },
{ WOLFSSL_LAST_E - 1, WC_SPAN2_FIRST_E + 1 },
{ WC_SPAN2_LAST_E - 1, MIN_CODE_E }
};
/* Check that all errors have a string and it's the same through the two
* APIs. Check that the values that are not errors map to the unknown
* string.
*/
#if defined(OPENSSL_EXTRA)
start_idx = WC_OSSL_V509_V_ERR_MAX - 1;
#endif
for (i = start_idx; i >= MIN_CODE_E; i--) {
int this_missing = 0;
for (j = 0; j < (int)XELEM_CNT(missing); ++j) {
if ((i <= missing[j].first) && (i >= missing[j].last)) {
this_missing = 1;
break;
}
}
errStr = wolfSSL_ERR_reason_error_string((word32)i);
if (! this_missing) {
ExpectIntNE(XSTRCMP(errStr, unknownStr), 0);
if (EXPECT_FAIL()) {
return i;
}
ExpectTrue(XSTRLEN(errStr) < WOLFSSL_MAX_ERROR_SZ);
if (EXPECT_FAIL()) {
return i;
}
}
else {
j++;
ExpectIntEQ(XSTRCMP(errStr, unknownStr), 0);
if (EXPECT_FAIL()) {
return i;
}
}
}
#endif
return 1;
}
static int test_wolfSSL_ERR_strings(void)
{
EXPECT_DECLS;
#if !defined(NO_ERROR_STRINGS)
const char* err1 = "unsupported cipher suite";
const char* err2 = "wolfSSL PEM routines";
const char* err = NULL;
(void)err;
(void)err1;
(void)err2;
#if defined(OPENSSL_EXTRA)
ExpectNotNull(err = ERR_reason_error_string(WC_NO_ERR_TRACE(UNSUPPORTED_SUITE)));
ExpectIntEQ(XSTRNCMP(err, err1, XSTRLEN(err1)), 0);
ExpectNotNull(err = ERR_func_error_string(WC_NO_ERR_TRACE(UNSUPPORTED_SUITE)));
ExpectIntEQ((*err == '\0'), 1);
ExpectNotNull(err = ERR_lib_error_string(PEM_R_PROBLEMS_GETTING_PASSWORD));
ExpectIntEQ(XSTRNCMP(err, err2, XSTRLEN(err2)), 0);
#else
ExpectNotNull(err = wolfSSL_ERR_reason_error_string(WC_NO_ERR_TRACE((word32)UNSUPPORTED_SUITE)));
ExpectIntEQ(XSTRNCMP(err, err1, XSTRLEN(err1)), 0);
ExpectNotNull(err = wolfSSL_ERR_func_error_string(WC_NO_ERR_TRACE((word32)UNSUPPORTED_SUITE)));
ExpectIntEQ((*err == '\0'), 1);
ExpectNotNull(err = wolfSSL_ERR_lib_error_string(-WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E));
ExpectIntEQ((*err == '\0'), 1);
#endif
#endif
ExpectIntEQ(error_test(), 1);
return EXPECT_RESULT();
}
static int test_SSL_CIPHER_get_xxx(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && \
!defined(NO_FILESYSTEM) && !defined(NO_TLS)
const SSL_CIPHER* cipher = NULL;
STACK_OF(SSL_CIPHER) *supportedCiphers = NULL;
int i, numCiphers = 0;
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
const char* testCertFile;
const char* testKeyFile;
char buf[256] = {0};
const char* cipher_id = NULL;
int expect_nid1 = NID_undef;
int expect_nid2 = NID_undef;
int expect_nid3 = NID_undef;
int expect_nid4 = NID_undef;
int expect_nid5 = 0;
const char* cipher_id2 = NULL;
int expect_nid21 = NID_undef;
int expect_nid22 = NID_undef;
int expect_nid23 = NID_undef;
int expect_nid24 = NID_undef;
int expect_nid25 = 0;
(void)cipher;
(void)supportedCiphers;
(void)i;
(void)numCiphers;
(void)ctx;
(void)ssl;
(void)testCertFile;
(void)testKeyFile;
#if defined(WOLFSSL_TLS13)
cipher_id = "TLS13-AES128-GCM-SHA256";
expect_nid1 = NID_auth_rsa;
expect_nid2 = NID_aes_128_gcm;
expect_nid3 = NID_sha256;
expect_nid4 = NID_kx_any;
expect_nid5 = 1;
#if !defined(WOLFSSL_NO_TLS12)
cipher_id2 = "ECDHE-RSA-AES256-GCM-SHA384";
expect_nid21 = NID_auth_rsa;
expect_nid22 = NID_aes_256_gcm;
expect_nid23 = NID_sha384;
expect_nid24 = NID_kx_ecdhe;
expect_nid25 = 1;
#endif
#endif
#ifdef NO_WOLFSSL_SERVER
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
#else
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
#endif
if (cipher_id) {
#ifndef NO_RSA
testCertFile = svrCertFile;
testKeyFile = svrKeyFile;
#elif defined(HAVE_ECC)
testCertFile = eccCertFile;
testKeyFile = eccKeyFile;
#else
testCertFile = NULL;
testKeyFile = NULL;
#endif
if (testCertFile != NULL && testKeyFile != NULL) {
ExpectTrue(SSL_CTX_use_certificate_file(ctx, testCertFile,
SSL_FILETYPE_PEM));
ExpectTrue(SSL_CTX_use_PrivateKey_file(ctx, testKeyFile,
SSL_FILETYPE_PEM));
}
ExpectNotNull(ssl = SSL_new(ctx));
ExpectIntEQ(SSL_in_init(ssl), 1);
supportedCiphers = SSL_get_ciphers(ssl);
numCiphers = sk_num(supportedCiphers);
for (i = 0; i < numCiphers; ++i) {
if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
SSL_CIPHER_description(cipher, buf, sizeof(buf));
}
if (XMEMCMP(cipher_id, buf, XSTRLEN(cipher_id)) == 0) {
break;
}
}
/* test case for */
if (i != numCiphers) {
ExpectIntEQ(wolfSSL_CIPHER_get_auth_nid(cipher), expect_nid1);
ExpectIntEQ(wolfSSL_CIPHER_get_cipher_nid(cipher), expect_nid2);
ExpectIntEQ(wolfSSL_CIPHER_get_digest_nid(cipher), expect_nid3);
ExpectIntEQ(wolfSSL_CIPHER_get_kx_nid(cipher), expect_nid4);
ExpectIntEQ(wolfSSL_CIPHER_is_aead(cipher), expect_nid5);
}
if (cipher_id2) {
for (i = 0; i < numCiphers; ++i) {
if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) {
SSL_CIPHER_description(cipher, buf, sizeof(buf));
}
if (XMEMCMP(cipher_id2, buf, XSTRLEN(cipher_id2)) == 0) {
break;
}
}
/* test case for */
if (i != numCiphers) {
ExpectIntEQ(wolfSSL_CIPHER_get_auth_nid(cipher), expect_nid21);
ExpectIntEQ(wolfSSL_CIPHER_get_cipher_nid(cipher), expect_nid22);
ExpectIntEQ(wolfSSL_CIPHER_get_digest_nid(cipher), expect_nid23);
ExpectIntEQ(wolfSSL_CIPHER_get_kx_nid(cipher), expect_nid24);
ExpectIntEQ(wolfSSL_CIPHER_is_aead(cipher), expect_nid25);
}
}
}
SSL_CTX_free(ctx);
SSL_free(ssl);
#endif
return EXPECT_RESULT();
}
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_IO_TESTS_DEPENDENCIES)
static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
int* keyFormat)
{
int ret;
byte* key_buf = NULL;
size_t key_sz = 0;
EncryptedInfo encInfo;
XMEMSET(&encInfo, 0, sizeof(encInfo));
ret = load_file(privKeyFile, &key_buf, &key_sz);
if (ret == 0) {
ret = wc_PemToDer(key_buf, key_sz, PRIVATEKEY_TYPE, pDer,
NULL, &encInfo, keyFormat);
}
if (key_buf != NULL) {
free(key_buf); key_buf = NULL;
}
(void)encInfo; /* not used in this test */
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "%s (%d): Loading PEM %s (len %d) to DER (len %d)\n",
(ret == 0) ? "Success" : "Failure", ret, privKeyFile, (int)key_sz,
(*pDer)->length);
#endif
return ret;
}
static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
const char* privKeyFile = (const char*)ctx;
DerBuffer* pDer = NULL;
int keyFormat = 0;
if (info->algo_type == WC_ALGO_TYPE_PK) {
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: Pk Type %d\n", info->pk.type);
#endif
#ifndef NO_RSA
if (info->pk.type == WC_PK_TYPE_RSA) {
switch (info->pk.rsa.type) {
case RSA_PUBLIC_ENCRYPT:
case RSA_PUBLIC_DECRYPT:
/* perform software based RSA public op */
ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); /* fallback to software */
break;
case RSA_PRIVATE_ENCRYPT:
case RSA_PRIVATE_DECRYPT:
{
RsaKey key;
/* perform software based RSA private op */
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: RSA Priv\n");
#endif
ret = load_pem_key_file_as_der(privKeyFile, &pDer,
&keyFormat);
if (ret != 0) {
return ret;
}
ret = wc_InitRsaKey(&key, HEAP_HINT);
if (ret == 0) {
word32 keyIdx = 0;
/* load RSA private key and perform private transform */
ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
&key, pDer->length);
if (ret == 0) {
ret = wc_RsaFunction(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, info->pk.rsa.outLen,
info->pk.rsa.type, &key, info->pk.rsa.rng);
}
else {
/* if decode fails, then fall-back to software based crypto */
fprintf(stderr, "test_CryptoCb_Func: RSA private "
"key decode failed %d, falling back to "
"software\n", ret);
ret = CRYPTOCB_UNAVAILABLE;
}
wc_FreeRsaKey(&key);
}
wc_FreeDer(&pDer); pDer = NULL;
break;
}
}
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: RSA Type %d, Ret %d, Out %d\n",
info->pk.rsa.type, ret, *info->pk.rsa.outLen);
#endif
}
#ifdef WOLF_CRYPTO_CB_RSA_PAD
else if (info->pk.type == WC_PK_TYPE_RSA_PKCS ||
info->pk.type == WC_PK_TYPE_RSA_PSS ||
info->pk.type == WC_PK_TYPE_RSA_OAEP) {
RsaKey key;
if (info->pk.rsa.type == RSA_PUBLIC_ENCRYPT ||
info->pk.rsa.type == RSA_PUBLIC_DECRYPT) {
/* Have all public key ops fall back to SW */
return CRYPTOCB_UNAVAILABLE;
}
if (info->pk.rsa.padding == NULL) {
return BAD_FUNC_ARG;
}
/* Initialize key */
ret = load_pem_key_file_as_der(privKeyFile, &pDer,
&keyFormat);
if (ret != 0) {
return ret;
}
ret = wc_InitRsaKey(&key, HEAP_HINT);
if (ret == 0) {
word32 keyIdx = 0;
/* load RSA private key and perform private transform */
ret = wc_RsaPrivateKeyDecode(pDer->buffer, &keyIdx,
&key, pDer->length);
}
/* Perform RSA operation */
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PKCS)) {
#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
ret = wc_RsaSSL_Sign(info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen, &key,
info->pk.rsa.rng);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_PSS)) {
#ifdef WC_RSA_PSS
ret = wc_RsaPSS_Sign_ex(info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen,
info->pk.rsa.padding->hash, info->pk.rsa.padding->mgf,
info->pk.rsa.padding->saltLen, &key, info->pk.rsa.rng);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}
if ((ret == 0) && (info->pk.type == WC_PK_TYPE_RSA_OAEP)) {
#if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING)
ret = wc_RsaPrivateDecrypt_ex(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, *info->pk.rsa.outLen,
&key, WC_RSA_OAEP_PAD, info->pk.rsa.padding->hash,
info->pk.rsa.padding->mgf, info->pk.rsa.padding->label,
info->pk.rsa.padding->labelSz);
#else
ret = CRYPTOCB_UNAVAILABLE;
#endif
}
if (ret > 0) {
*info->pk.rsa.outLen = ret;
}
wc_FreeRsaKey(&key);
wc_FreeDer(&pDer); pDer = NULL;
}
#endif /* ifdef WOLF_CRYPTO_CB_RSA_PAD */
#endif /* !NO_RSA */
#ifdef HAVE_ECC
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
/* mark this key as ephemeral */
if (info->pk.eckg.key != NULL) {
XSTRNCPY(info->pk.eckg.key->label, "ephemeral",
sizeof(info->pk.eckg.key->label));
info->pk.eckg.key->labelLen = (int)XSTRLEN(info->pk.eckg.key->label);
}
}
else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
ecc_key key;
/* perform software based ECC sign */
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: ECC Sign\n");
#endif
if (info->pk.eccsign.key != NULL &&
XSTRCMP(info->pk.eccsign.key->label, "ephemeral") == 0) {
/* this is an empheral key */
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: skipping signing op on "
"ephemeral key\n");
#endif
return CRYPTOCB_UNAVAILABLE;
}
ret = load_pem_key_file_as_der(privKeyFile, &pDer, &keyFormat);
if (ret != 0) {
return ret;
}
ret = wc_ecc_init(&key);
if (ret == 0) {
word32 keyIdx = 0;
/* load ECC private key and perform private transform */
ret = wc_EccPrivateKeyDecode(pDer->buffer, &keyIdx,
&key, pDer->length);
if (ret == 0) {
ret = wc_ecc_sign_hash(
info->pk.eccsign.in, info->pk.eccsign.inlen,
info->pk.eccsign.out, info->pk.eccsign.outlen,
info->pk.eccsign.rng, &key);
}
else {
/* if decode fails, then fall-back to software based crypto */
fprintf(stderr, "test_CryptoCb_Func: ECC private key "
"decode failed %d, falling back to software\n", ret);
ret = CRYPTOCB_UNAVAILABLE;
}
wc_ecc_free(&key);
}
wc_FreeDer(&pDer); pDer = NULL;
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: ECC Ret %d, Out %d\n",
ret, *info->pk.eccsign.outlen);
#endif
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
ed25519_key key;
/* perform software based ED25519 sign */
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: ED25519 Sign\n");
#endif
ret = load_pem_key_file_as_der(privKeyFile, &pDer, &keyFormat);
if (ret != 0) {
return ret;
}
ret = wc_ed25519_init(&key);
if (ret == 0) {
word32 keyIdx = 0;
/* load ED25519 private key and perform private transform */
ret = wc_Ed25519PrivateKeyDecode(pDer->buffer, &keyIdx,
&key, pDer->length);
if (ret == 0) {
/* calculate public key */
ret = wc_ed25519_make_public(&key, key.p, ED25519_PUB_KEY_SIZE);
if (ret == 0) {
key.pubKeySet = 1;
ret = wc_ed25519_sign_msg_ex(
info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
&key, info->pk.ed25519sign.type,
info->pk.ed25519sign.context,
info->pk.ed25519sign.contextLen);
}
}
else {
/* if decode fails, then fall-back to software based crypto */
fprintf(stderr, "test_CryptoCb_Func: ED25519 private key "
"decode failed %d, falling back to software\n", ret);
ret = CRYPTOCB_UNAVAILABLE;
}
wc_ed25519_free(&key);
}
wc_FreeDer(&pDer); pDer = NULL;
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: ED25519 Ret %d, Out %d\n",
ret, *info->pk.ed25519sign.outLen);
#endif
}
#endif /* HAVE_ED25519 */
}
#ifdef WOLF_CRYPTO_CB_COPY
else if (info->algo_type == WC_ALGO_TYPE_COPY) {
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: Copy Algo=%d Type=%d\n",
info->copy.algo, info->copy.type);
#endif
if (info->copy.algo == WC_ALGO_TYPE_HASH) {
switch (info->copy.type) {
#ifndef NO_SHA
case WC_HASH_TYPE_SHA:
{
wc_Sha* src = (wc_Sha*)info->copy.src;
wc_Sha* dst = (wc_Sha*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_ShaCopy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#ifdef WOLFSSL_SHA224
case WC_HASH_TYPE_SHA224:
{
wc_Sha224* src = (wc_Sha224*)info->copy.src;
wc_Sha224* dst = (wc_Sha224*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha224Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#ifndef NO_SHA256
case WC_HASH_TYPE_SHA256:
{
wc_Sha256* src = (wc_Sha256*)info->copy.src;
wc_Sha256* dst = (wc_Sha256*)info->copy.dst;
/* set devId to invalid, so software is used */
src->devId = INVALID_DEVID;
ret = wc_Sha256Copy(src, dst);
/* reset devId */
src->devId = thisDevId;
if (ret == 0) {
/* Set the devId of the destination to the same */
/* since we used the software implementation of copy */
/* so dst would have been set to INVALID_DEVID */
dst->devId = thisDevId;
}
break;
}
#endif /* !NO_SHA256 */
#ifdef WOLFSSL_SHA384
case WC_HASH_TYPE_SHA384:
{
wc_Sha384* src = (wc_Sha384*)info->copy.src;
wc_Sha384* dst = (wc_Sha384*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha384Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#ifdef WOLFSSL_SHA512
case WC_HASH_TYPE_SHA512:
{
wc_Sha512* src = (wc_Sha512*)info->copy.src;
wc_Sha512* dst = (wc_Sha512*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha512Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
case WC_HASH_TYPE_SHA3_224:
{
wc_Sha3* src = (wc_Sha3*)info->copy.src;
wc_Sha3* dst = (wc_Sha3*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha3_224_Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
case WC_HASH_TYPE_SHA3_256:
{
wc_Sha3* src = (wc_Sha3*)info->copy.src;
wc_Sha3* dst = (wc_Sha3*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha3_256_Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
case WC_HASH_TYPE_SHA3_384:
{
wc_Sha3* src = (wc_Sha3*)info->copy.src;
wc_Sha3* dst = (wc_Sha3*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha3_384_Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
case WC_HASH_TYPE_SHA3_512:
{
wc_Sha3* src = (wc_Sha3*)info->copy.src;
wc_Sha3* dst = (wc_Sha3*)info->copy.dst;
src->devId = INVALID_DEVID;
ret = wc_Sha3_512_Copy(src, dst);
src->devId = thisDevId;
if (ret == 0) {
dst->devId = thisDevId;
}
break;
}
#endif
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
else {
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
}
}
#endif /* WOLF_CRYPTO_CB_COPY */
#ifdef WOLF_CRYPTO_CB_FREE
else if (info->algo_type == WC_ALGO_TYPE_FREE) {
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: Free Algo=%d Type=%d\n",
info->free.algo, info->free.type);
#endif
if (info->free.algo == WC_ALGO_TYPE_HASH) {
switch (info->free.type) {
#ifndef NO_SHA
case WC_HASH_TYPE_SHA:
{
wc_Sha* sha = (wc_Sha*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_ShaFree(sha);
ret = 0;
break;
}
#endif
#ifdef WOLFSSL_SHA224
case WC_HASH_TYPE_SHA224:
{
wc_Sha224* sha = (wc_Sha224*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha224Free(sha);
ret = 0;
break;
}
#endif
#ifndef NO_SHA256
case WC_HASH_TYPE_SHA256:
{
wc_Sha256* sha = (wc_Sha256*)info->free.obj;
/* set devId to invalid, so software is used */
sha->devId = INVALID_DEVID;
/* Call the actual free function */
wc_Sha256Free(sha);
/* Note: devId doesn't need to be restored as object is freed */
ret = 0;
break;
}
#endif
#ifdef WOLFSSL_SHA384
case WC_HASH_TYPE_SHA384:
{
wc_Sha384* sha = (wc_Sha384*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha384Free(sha);
ret = 0;
break;
}
#endif
#ifdef WOLFSSL_SHA512
case WC_HASH_TYPE_SHA512:
{
wc_Sha512* sha = (wc_Sha512*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha512Free(sha);
ret = 0;
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
case WC_HASH_TYPE_SHA3_224:
{
wc_Sha3* sha = (wc_Sha3*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha3_224_Free(sha);
ret = 0;
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
case WC_HASH_TYPE_SHA3_256:
{
wc_Sha3* sha = (wc_Sha3*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha3_256_Free(sha);
ret = 0;
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
case WC_HASH_TYPE_SHA3_384:
{
wc_Sha3* sha = (wc_Sha3*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha3_384_Free(sha);
ret = 0;
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
case WC_HASH_TYPE_SHA3_512:
{
wc_Sha3* sha = (wc_Sha3*)info->free.obj;
sha->devId = INVALID_DEVID;
wc_Sha3_512_Free(sha);
ret = 0;
break;
}
#endif
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
else if (info->free.algo == WC_ALGO_TYPE_CIPHER) {
switch (info->free.type) {
#ifndef NO_AES
case WC_CIPHER_AES:
{
Aes* aes = (Aes*)info->free.obj;
aes->devId = INVALID_DEVID;
wc_AesFree(aes);
ret = 0;
break;
}
#endif
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
else {
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
}
}
#endif /* WOLF_CRYPTO_CB_FREE */
(void)thisDevId;
(void)keyFormat;
return ret;
}
/* tlsVer: WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wc_CryptoCb_TLS(int tlsVer,
const char* cliCaPemFile, const char* cliCertPemFile,
const char* cliPrivKeyPemFile, const char* cliPubKeyPemFile,
const char* svrCaPemFile, const char* svrCertPemFile,
const char* svrPrivKeyPemFile, const char* svrPubKeyPemFile)
{
EXPECT_DECLS;
callback_functions client_cbf;
callback_functions server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
if (tlsVer == WOLFSSL_TLSV1_3) {
#ifdef WOLFSSL_TLS13
server_cbf.method = wolfTLSv1_3_server_method;
client_cbf.method = wolfTLSv1_3_client_method;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1_2) {
#ifndef WOLFSSL_NO_TLS12
server_cbf.method = wolfTLSv1_2_server_method;
client_cbf.method = wolfTLSv1_2_client_method;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1_1) {
#ifndef NO_OLD_TLS
server_cbf.method = wolfTLSv1_1_server_method;
client_cbf.method = wolfTLSv1_1_client_method;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1) {
#if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
server_cbf.method = wolfTLSv1_server_method;
client_cbf.method = wolfTLSv1_client_method;
#endif
}
else if (tlsVer == WOLFSSL_SSLV3) {
#if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \
defined(WOLFSSL_STATIC_RSA)
server_cbf.method = wolfSSLv3_server_method;
client_cbf.method = wolfSSLv3_client_method;
#endif
}
else if (tlsVer == WOLFSSL_DTLSV1_2) {
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
server_cbf.method = wolfDTLSv1_2_server_method;
client_cbf.method = wolfDTLSv1_2_client_method;
#endif
}
else if (tlsVer == WOLFSSL_DTLSV1) {
#if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS)
server_cbf.method = wolfDTLSv1_server_method;
client_cbf.method = wolfDTLSv1_client_method;
#endif
}
if (server_cbf.method == NULL) {
/* not enabled */
return TEST_SUCCESS;
}
/* Setup the keys for the TLS test */
client_cbf.certPemFile = cliCertPemFile;
client_cbf.keyPemFile = cliPubKeyPemFile;
client_cbf.caPemFile = cliCaPemFile;
server_cbf.certPemFile = svrCertPemFile;
server_cbf.keyPemFile = svrPubKeyPemFile;
server_cbf.caPemFile = svrCaPemFile;
/* Setup a crypto callback with pointer to private key file for testing */
client_cbf.devId = 1;
wc_CryptoCb_RegisterDevice(client_cbf.devId, test_CryptoCb_Func,
(void*)cliPrivKeyPemFile);
server_cbf.devId = 2;
wc_CryptoCb_RegisterDevice(server_cbf.devId, test_CryptoCb_Func,
(void*)svrPrivKeyPemFile);
/* Perform TLS server and client test */
/* First test is at WOLFSSL_CTX level */
test_wolfSSL_client_server(&client_cbf, &server_cbf);
/* Check for success */
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
if (EXPECT_SUCCESS()) {
/* Second test is a WOLFSSL object level */
client_cbf.loadToSSL = 1; server_cbf.loadToSSL = 1;
test_wolfSSL_client_server(&client_cbf, &server_cbf);
}
/* Check for success */
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
/* Un register the devId's */
wc_CryptoCb_UnRegisterDevice(client_cbf.devId);
client_cbf.devId = INVALID_DEVID;
wc_CryptoCb_UnRegisterDevice(server_cbf.devId);
server_cbf.devId = INVALID_DEVID;
return EXPECT_RESULT();
}
#endif /* WOLF_CRYPTO_CB && HAVE_IO_TESTS_DEPENDENCIES */
static int test_wc_CryptoCb(void)
{
EXPECT_DECLS;
#ifdef WOLF_CRYPTO_CB
/* TODO: Add crypto callback API tests */
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
int tlsVer;
#endif
#ifndef NO_RSA
for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
svrCertFile, cliCertFile, cliKeyFile, cliKeyPubFile,
cliCertFile, svrCertFile, svrKeyFile, svrKeyPubFile),
TEST_SUCCESS);
}
#endif
#ifdef HAVE_ECC
for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
caEccCertFile, cliEccCertFile, cliEccKeyFile, cliEccKeyPubFile,
cliEccCertFile, eccCertFile, eccKeyFile, eccKeyPubFile),
TEST_SUCCESS);
}
#endif
#ifdef HAVE_ED25519
for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) {
if (tlsVer == WOLFSSL_DTLSV1) continue;
ExpectIntEQ(test_wc_CryptoCb_TLS(tlsVer,
caEdCertFile, cliEdCertFile, cliEdKeyFile, cliEdKeyPubFile,
cliEdCertFile, edCertFile, edKeyFile, edKeyPubFile),
TEST_SUCCESS);
}
#endif
#endif /* HAVE_IO_TESTS_DEPENDENCIES */
#endif /* WOLF_CRYPTO_CB */
return EXPECT_RESULT();
}
#if defined(WOLFSSL_STATIC_MEMORY) && defined(HAVE_IO_TESTS_DEPENDENCIES)
/* tlsVer: Example: WOLFSSL_TLSV1_2 or WOLFSSL_TLSV1_3 */
static int test_wolfSSL_CTX_StaticMemory_TLS(int tlsVer,
const char* cliCaPemFile, const char* cliCertPemFile,
const char* cliPrivKeyPemFile,
const char* svrCaPemFile, const char* svrCertPemFile,
const char* svrPrivKeyPemFile,
byte* cliMem, word32 cliMemSz, byte* svrMem, word32 svrMemSz)
{
EXPECT_DECLS;
callback_functions client_cbf;
callback_functions server_cbf;
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
if (tlsVer == WOLFSSL_TLSV1_3) {
#ifdef WOLFSSL_TLS13
server_cbf.method_ex = wolfTLSv1_3_server_method_ex;
client_cbf.method_ex = wolfTLSv1_3_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1_2) {
#ifndef WOLFSSL_NO_TLS12
server_cbf.method_ex = wolfTLSv1_2_server_method_ex;
client_cbf.method_ex = wolfTLSv1_2_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1_1) {
#ifndef NO_OLD_TLS
server_cbf.method_ex = wolfTLSv1_1_server_method_ex;
client_cbf.method_ex = wolfTLSv1_1_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_TLSV1) {
#if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
server_cbf.method_ex = wolfTLSv1_server_method_ex;
client_cbf.method_ex = wolfTLSv1_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_SSLV3) {
#if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3) && \
defined(WOLFSSL_STATIC_RSA)
server_cbf.method_ex = wolfSSLv3_server_method_ex;
client_cbf.method_ex = wolfSSLv3_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_DTLSV1_2) {
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
server_cbf.method_ex = wolfDTLSv1_2_server_method_ex;
client_cbf.method_ex = wolfDTLSv1_2_client_method_ex;
#endif
}
else if (tlsVer == WOLFSSL_DTLSV1) {
#if defined(WOLFSSL_DTLS) && !defined(NO_OLD_TLS)
server_cbf.method_ex = wolfDTLSv1_server_method_ex;
client_cbf.method_ex = wolfDTLSv1_client_method_ex;
#endif
}
if (server_cbf.method_ex == NULL) {
/* not enabled */
return TEST_SUCCESS;
}
/* Setup the keys for the TLS test */
client_cbf.certPemFile = cliCertPemFile;
client_cbf.keyPemFile = cliPrivKeyPemFile;
client_cbf.caPemFile = cliCaPemFile;
server_cbf.certPemFile = svrCertPemFile;
server_cbf.keyPemFile = svrPrivKeyPemFile;
server_cbf.caPemFile = svrCaPemFile;
client_cbf.mem = cliMem;
client_cbf.memSz = cliMemSz;
server_cbf.mem = svrMem;
server_cbf.memSz = svrMemSz;
client_cbf.devId = INVALID_DEVID;
server_cbf.devId = INVALID_DEVID;
/* Perform TLS server and client test */
/* First test is at WOLFSSL_CTX level */
test_wolfSSL_client_server(&client_cbf, &server_cbf);
/* Check for success */
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
if (EXPECT_SUCCESS()) {
/* Second test is a WOLFSSL object level */
client_cbf.loadToSSL = 1; server_cbf.loadToSSL = 1;
test_wolfSSL_client_server(&client_cbf, &server_cbf);
}
/* Check for success */
ExpectIntEQ(server_cbf.return_code, TEST_SUCCESS);
ExpectIntEQ(client_cbf.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#endif /* WOLFSSL_STATIC_MEMORY && HAVE_IO_TESTS_DEPENDENCIES */
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
static int test_wolfSSL_CTX_StaticMemory_SSL(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
WOLFSSL *ssl1 = NULL, *ssl2 = NULL, *ssl3 = NULL;
WOLFSSL_MEM_STATS mem_stats;
WOLFSSL_MEM_CONN_STATS ssl_stats;
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)
ExpectIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
#endif
ExpectNotNull((ssl1 = wolfSSL_new(ctx)));
ExpectNotNull((ssl2 = wolfSSL_new(ctx)));
#ifndef WOLFSSL_STATIC_MEMORY_LEAN
/* this should fail because kMaxCtxClients == 2 */
ExpectNull((ssl3 = wolfSSL_new(ctx)));
#else
(void)ssl3;
#endif
if (wolfSSL_is_static_memory(ssl1, &ssl_stats) == 1) {
#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
wolfSSL_PrintStatsConn(&ssl_stats);
#endif
(void)ssl_stats;
}
/* display collected statistics */
if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) == 1) {
#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
wolfSSL_PrintStats(&mem_stats);
#endif
(void)mem_stats;
}
wolfSSL_free(ssl1);
wolfSSL_free(ssl2);
return EXPECT_RESULT();
}
#endif /* WOLFSSL_STATIC_MEMORY && !WOLFCRYPT_ONLY */
static int test_wolfSSL_CTX_StaticMemory(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFCRYPT_ONLY)
wolfSSL_method_func method_func;
WOLFSSL_CTX* ctx;
const int kMaxCtxClients = 2;
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
int tlsVer;
byte cliMem[TEST_TLS_STATIC_MEMSZ];
#endif
#endif
byte svrMem[TEST_TLS_STATIC_MEMSZ];
#ifndef NO_WOLFSSL_SERVER
#ifndef WOLFSSL_NO_TLS12
method_func = wolfTLSv1_2_server_method_ex;
#else
method_func = wolfTLSv1_3_server_method_ex;
#endif
#else
#ifndef WOLFSSL_NO_TLS12
method_func = wolfTLSv1_2_client_method_ex;
#else
method_func = wolfTLSv1_3_client_method_ex;
#endif
#endif
/* Test creating CTX directly from static memory pool */
ctx = NULL;
ExpectIntEQ(wolfSSL_CTX_load_static_memory(&ctx, method_func, svrMem,
sizeof(svrMem), 0, kMaxCtxClients), WOLFSSL_SUCCESS);
ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_SSL(ctx), TEST_SUCCESS);
wolfSSL_CTX_free(ctx);
ctx = NULL;
/* Test for heap allocated CTX, then assigning static pool to it */
ExpectNotNull(ctx = wolfSSL_CTX_new(method_func(NULL)));
ExpectIntEQ(wolfSSL_CTX_load_static_memory(&ctx, NULL, svrMem,
sizeof(svrMem), 0, kMaxCtxClients), WOLFSSL_SUCCESS);
ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_SSL(ctx), TEST_SUCCESS);
wolfSSL_CTX_free(ctx);
/* TLS Level Tests using static memory */
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#ifndef NO_RSA
for (tlsVer = WOLFSSL_SSLV3; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
svrCertFile, cliCertFile, cliKeyFile,
cliCertFile, svrCertFile, svrKeyFile,
cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
TEST_SUCCESS);
}
#endif
#ifdef HAVE_ECC
for (tlsVer = WOLFSSL_TLSV1; tlsVer <= WOLFSSL_DTLSV1; tlsVer++) {
ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
caEccCertFile, cliEccCertFile, cliEccKeyFile,
cliEccCertFile, eccCertFile, eccKeyFile,
cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
TEST_SUCCESS);
}
#endif
#ifdef HAVE_ED25519
for (tlsVer = WOLFSSL_TLSV1_2; tlsVer <= WOLFSSL_DTLSV1_2; tlsVer++) {
if (tlsVer == WOLFSSL_DTLSV1) continue;
ExpectIntEQ(test_wolfSSL_CTX_StaticMemory_TLS(tlsVer,
caEdCertFile, cliEdCertFile, cliEdKeyFile,
cliEdCertFile, edCertFile, edKeyFile,
cliMem, (word32)sizeof(cliMem), svrMem, (word32)sizeof(svrMem)),
TEST_SUCCESS);
}
#endif
#endif /* HAVE_IO_TESTS_DEPENDENCIES */
#endif /* WOLFSSL_STATIC_MEMORY && !WOLFCRYPT_ONLY */
return EXPECT_RESULT();
}
static int test_openssl_FIPS_drbg(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
DRBG_CTX* dctx = NULL;
byte data1[32], data2[32], zeroData[32];
byte testSeed[16];
size_t dlen = sizeof(data1);
int i;
XMEMSET(data1, 0, dlen);
XMEMSET(data2, 0, dlen);
XMEMSET(zeroData, 0, sizeof(zeroData));
for (i = 0; i < (int)sizeof(testSeed); i++) {
testSeed[i] = (byte)i;
}
ExpectNotNull(dctx = FIPS_get_default_drbg());
ExpectIntEQ(FIPS_drbg_init(dctx, 0, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(FIPS_drbg_set_callbacks(dctx, NULL, NULL, 20, NULL, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(FIPS_drbg_instantiate(dctx, NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(FIPS_drbg_generate(dctx, data1, dlen, 0, NULL, 0),
WOLFSSL_SUCCESS);
ExpectIntNE(XMEMCMP(data1, zeroData, dlen), 0);
ExpectIntEQ(FIPS_drbg_reseed(dctx, testSeed, sizeof(testSeed)),
WOLFSSL_SUCCESS);
ExpectIntEQ(FIPS_drbg_generate(dctx, data2, dlen, 0, NULL, 0),
WOLFSSL_SUCCESS);
ExpectIntNE(XMEMCMP(data1, zeroData, dlen), 0);
ExpectIntNE(XMEMCMP(data1, data2, dlen), 0);
ExpectIntEQ(FIPS_drbg_uninstantiate(dctx), WOLFSSL_SUCCESS);
#ifndef HAVE_GLOBAL_RNG
/* gets freed by wolfSSL_Cleanup() when HAVE_GLOBAL_RNG defined */
wolfSSL_FIPS_drbg_free(dctx);
#endif
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_FIPS_mode(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_ALL)
#ifdef HAVE_FIPS
ExpectIntEQ(wolfSSL_FIPS_mode(), 1);
ExpectIntEQ(wolfSSL_FIPS_mode_set(0), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectIntEQ(wolfSSL_FIPS_mode_set(1), WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_FIPS_mode(), 0);
ExpectIntEQ(wolfSSL_FIPS_mode_set(0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_FIPS_mode_set(1), WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
#endif
return EXPECT_RESULT();
}
#ifdef WOLFSSL_DTLS
/* Prints out the current window */
static void DUW_TEST_print_window_binary(word32 h, word32 l, word32* w) {
#ifdef WOLFSSL_DEBUG_DTLS_WINDOW
int i;
for (i = WOLFSSL_DTLS_WINDOW_WORDS - 1; i >= 0; i--) {
word32 b = w[i];
int j;
/* Prints out a 32 bit binary number in big endian order */
for (j = 0; j < 32; j++, b <<= 1) {
if (b & (((word32)1) << 31))
fprintf(stderr, "1");
else
fprintf(stderr, "0");
}
fprintf(stderr, " ");
}
fprintf(stderr, "cur_hi %u cur_lo %u\n", h, l);
#else
(void)h;
(void)l;
(void)w;
#endif
}
/* a - cur_hi
* b - cur_lo
* c - next_hi
* d - next_lo
* e - window
* f - expected next_hi
* g - expected next_lo
* h - expected window[1]
* i - expected window[0]
*/
#define DUW_TEST(a,b,c,d,e,f,g,h,i) do { \
ExpectIntEQ(wolfSSL_DtlsUpdateWindow((a), (b), &(c), &(d), (e)), 1); \
DUW_TEST_print_window_binary((a), (b), (e)); \
ExpectIntEQ((c), (f)); \
ExpectIntEQ((d), (g)); \
ExpectIntEQ((e)[1], (h)); \
ExpectIntEQ((e)[0], (i)); \
} while (0)
static int test_wolfSSL_DtlsUpdateWindow(void)
{
EXPECT_DECLS;
word32 window[WOLFSSL_DTLS_WINDOW_WORDS];
word32 next_lo = 0;
word16 next_hi = 0;
#ifdef WOLFSSL_DEBUG_DTLS_WINDOW
fprintf(stderr, "\n");
#endif
XMEMSET(window, 0, sizeof window);
DUW_TEST(0, 0, next_hi, next_lo, window, 0, 1, 0, 0x01);
DUW_TEST(0, 1, next_hi, next_lo, window, 0, 2, 0, 0x03);
DUW_TEST(0, 5, next_hi, next_lo, window, 0, 6, 0, 0x31);
DUW_TEST(0, 4, next_hi, next_lo, window, 0, 6, 0, 0x33);
DUW_TEST(0, 100, next_hi, next_lo, window, 0, 101, 0, 0x01);
DUW_TEST(0, 101, next_hi, next_lo, window, 0, 102, 0, 0x03);
DUW_TEST(0, 133, next_hi, next_lo, window, 0, 134, 0x03, 0x01);
DUW_TEST(0, 200, next_hi, next_lo, window, 0, 201, 0, 0x01);
DUW_TEST(0, 264, next_hi, next_lo, window, 0, 265, 0, 0x01);
DUW_TEST(0, 0xFFFFFFFF, next_hi, next_lo, window, 1, 0, 0, 0x01);
DUW_TEST(0, 0xFFFFFFFD, next_hi, next_lo, window, 1, 0, 0, 0x05);
DUW_TEST(0, 0xFFFFFFFE, next_hi, next_lo, window, 1, 0, 0, 0x07);
DUW_TEST(1, 3, next_hi, next_lo, window, 1, 4, 0, 0x71);
DUW_TEST(1, 0, next_hi, next_lo, window, 1, 4, 0, 0x79);
DUW_TEST(1, 0xFFFFFFFF, next_hi, next_lo, window, 2, 0, 0, 0x01);
DUW_TEST(2, 3, next_hi, next_lo, window, 2, 4, 0, 0x11);
DUW_TEST(2, 0, next_hi, next_lo, window, 2, 4, 0, 0x19);
DUW_TEST(2, 25, next_hi, next_lo, window, 2, 26, 0, 0x6400001);
DUW_TEST(2, 27, next_hi, next_lo, window, 2, 28, 0, 0x19000005);
DUW_TEST(2, 29, next_hi, next_lo, window, 2, 30, 0, 0x64000015);
DUW_TEST(2, 33, next_hi, next_lo, window, 2, 34, 6, 0x40000151);
DUW_TEST(2, 60, next_hi, next_lo, window, 2, 61, 0x3200000A, 0x88000001);
DUW_TEST(1, 0xFFFFFFF0, next_hi, next_lo, window, 2, 61, 0x3200000A, 0x88000001);
DUW_TEST(2, 0xFFFFFFFD, next_hi, next_lo, window, 2, 0xFFFFFFFE, 0, 0x01);
DUW_TEST(3, 1, next_hi, next_lo, window, 3, 2, 0, 0x11);
DUW_TEST(99, 66, next_hi, next_lo, window, 99, 67, 0, 0x01);
DUW_TEST(50, 66, next_hi, next_lo, window, 99, 67, 0, 0x01);
DUW_TEST(100, 68, next_hi, next_lo, window, 100, 69, 0, 0x01);
DUW_TEST(99, 50, next_hi, next_lo, window, 100, 69, 0, 0x01);
DUW_TEST(99, 0xFFFFFFFF, next_hi, next_lo, window, 100, 69, 0, 0x01);
DUW_TEST(150, 0xFFFFFFFF, next_hi, next_lo, window, 151, 0, 0, 0x01);
DUW_TEST(152, 0xFFFFFFFF, next_hi, next_lo, window, 153, 0, 0, 0x01);
return EXPECT_RESULT();
}
#endif /* WOLFSSL_DTLS */
#ifdef WOLFSSL_DTLS
static int DFB_TEST(WOLFSSL* ssl, word32 seq, word32 len, word32 f_offset,
word32 f_len, word32 f_count, byte ready, word32 bytesReceived)
{
DtlsMsg* cur;
static byte msg[100];
static byte msgInit = 0;
if (!msgInit) {
int i;
for (i = 0; i < 100; i++)
msg[i] = i + 1;
msgInit = 1;
}
/* Sanitize test parameters */
if (len > sizeof(msg))
return -1;
if (f_offset + f_len > sizeof(msg))
return -1;
DtlsMsgStore(ssl, 0, seq, msg + f_offset, len, certificate, f_offset, f_len, NULL);
if (ssl->dtls_rx_msg_list == NULL)
return -100;
if ((cur = DtlsMsgFind(ssl->dtls_rx_msg_list, 0, seq)) == NULL)
return -200;
if (cur->fragBucketListCount != f_count)
return -300;
if (cur->ready != ready)
return -400;
if (cur->bytesReceived != bytesReceived)
return -500;
if (ready) {
if (cur->fragBucketList != NULL)
return -600;
if (XMEMCMP(cur->fullMsg, msg, cur->sz) != 0)
return -700;
}
else {
DtlsFragBucket* fb;
if (cur->fragBucketList == NULL)
return -800;
for (fb = cur->fragBucketList; fb != NULL; fb = fb->m.m.next) {
if (XMEMCMP(fb->buf, msg + fb->m.m.offset, fb->m.m.sz) != 0)
return -900;
}
}
return 0;
}
static int test_wolfSSL_DTLS_fragment_buckets(void)
{
EXPECT_DECLS;
WOLFSSL ssl[1];
XMEMSET(ssl, 0, sizeof(*ssl));
ExpectIntEQ(DFB_TEST(ssl, 0, 100, 0, 100, 0, 1, 100), 0); /* 0-100 */
ExpectIntEQ(DFB_TEST(ssl, 1, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
ExpectIntEQ(DFB_TEST(ssl, 1, 100, 20, 20, 1, 0, 40), 0); /* 20-40 */
ExpectIntEQ(DFB_TEST(ssl, 1, 100, 40, 20, 1, 0, 60), 0); /* 40-60 */
ExpectIntEQ(DFB_TEST(ssl, 1, 100, 60, 20, 1, 0, 80), 0); /* 60-80 */
ExpectIntEQ(DFB_TEST(ssl, 1, 100, 80, 20, 0, 1, 100), 0); /* 80-100 */
/* Test all permutations of 3 regions */
/* 1 2 3 */
ExpectIntEQ(DFB_TEST(ssl, 2, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
ExpectIntEQ(DFB_TEST(ssl, 2, 100, 30, 30, 1, 0, 60), 0); /* 30-60 */
ExpectIntEQ(DFB_TEST(ssl, 2, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
/* 1 3 2 */
ExpectIntEQ(DFB_TEST(ssl, 3, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
ExpectIntEQ(DFB_TEST(ssl, 3, 100, 60, 40, 2, 0, 70), 0); /* 60-100 */
ExpectIntEQ(DFB_TEST(ssl, 3, 100, 30, 30, 0, 1, 100), 0); /* 30-60 */
/* 2 1 3 */
ExpectIntEQ(DFB_TEST(ssl, 4, 100, 30, 30, 1, 0, 30), 0); /* 30-60 */
ExpectIntEQ(DFB_TEST(ssl, 4, 100, 0, 30, 1, 0, 60), 0); /* 0-30 */
ExpectIntEQ(DFB_TEST(ssl, 4, 100, 60, 40, 0, 1, 100), 0); /* 60-100 */
/* 2 3 1 */
ExpectIntEQ(DFB_TEST(ssl, 5, 100, 30, 30, 1, 0, 30), 0); /* 30-60 */
ExpectIntEQ(DFB_TEST(ssl, 5, 100, 60, 40, 1, 0, 70), 0); /* 60-100 */
ExpectIntEQ(DFB_TEST(ssl, 5, 100, 0, 30, 0, 1, 100), 0); /* 0-30 */
/* 3 1 2 */
ExpectIntEQ(DFB_TEST(ssl, 6, 100, 60, 40, 1, 0, 40), 0); /* 60-100 */
ExpectIntEQ(DFB_TEST(ssl, 6, 100, 0, 30, 2, 0, 70), 0); /* 0-30 */
ExpectIntEQ(DFB_TEST(ssl, 6, 100, 30, 30, 0, 1, 100), 0); /* 30-60 */
/* 3 2 1 */
ExpectIntEQ(DFB_TEST(ssl, 7, 100, 60, 40, 1, 0, 40), 0); /* 60-100 */
ExpectIntEQ(DFB_TEST(ssl, 7, 100, 30, 30, 1, 0, 70), 0); /* 30-60 */
ExpectIntEQ(DFB_TEST(ssl, 7, 100, 0, 30, 0, 1, 100), 0); /* 0-30 */
/* Test overlapping regions */
ExpectIntEQ(DFB_TEST(ssl, 8, 100, 0, 30, 1, 0, 30), 0); /* 0-30 */
ExpectIntEQ(DFB_TEST(ssl, 8, 100, 20, 10, 1, 0, 30), 0); /* 20-30 */
ExpectIntEQ(DFB_TEST(ssl, 8, 100, 70, 10, 2, 0, 40), 0); /* 70-80 */
ExpectIntEQ(DFB_TEST(ssl, 8, 100, 20, 30, 2, 0, 60), 0); /* 20-50 */
ExpectIntEQ(DFB_TEST(ssl, 8, 100, 40, 60, 0, 1, 100), 0); /* 40-100 */
/* Test overlapping multiple regions */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 30, 5, 2, 0, 25), 0); /* 30-35 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 40, 5, 3, 0, 30), 0); /* 40-45 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 50, 5, 4, 0, 35), 0); /* 50-55 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 60, 5, 5, 0, 40), 0); /* 60-65 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 70, 5, 6, 0, 45), 0); /* 70-75 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 30, 25, 4, 0, 55), 0); /* 30-55 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 55, 15, 2, 0, 65), 0); /* 55-70 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 75, 25, 2, 0, 90), 0); /* 75-100 */
ExpectIntEQ(DFB_TEST(ssl, 9, 100, 10, 25, 0, 1, 100), 0); /* 10-35 */
ExpectIntEQ(DFB_TEST(ssl, 10, 100, 0, 20, 1, 0, 20), 0); /* 0-20 */
ExpectIntEQ(DFB_TEST(ssl, 10, 100, 30, 20, 2, 0, 40), 0); /* 30-50 */
ExpectIntEQ(DFB_TEST(ssl, 10, 100, 0, 40, 1, 0, 50), 0); /* 0-40 */
ExpectIntEQ(DFB_TEST(ssl, 10, 100, 50, 50, 0, 1, 100), 0); /* 10-35 */
DtlsMsgListDelete(ssl->dtls_rx_msg_list, ssl->heap);
ssl->dtls_rx_msg_list = NULL;
ssl->dtls_rx_msg_list_sz = 0;
return EXPECT_RESULT();
}
#endif
#if !defined(NO_FILESYSTEM) && \
defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_RSA)
static int test_wolfSSL_dtls_stateless2(void)
{
EXPECT_DECLS;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_c2 = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c2, NULL,
wolfDTLSv1_2_client_method, NULL), 0);
ExpectFalse(wolfSSL_is_stateful(ssl_s));
/* send CH */
ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_FAILURE);
ExpectFalse(wolfSSL_is_stateful(ssl_s));
ExpectIntNE(test_ctx.c_len, 0);
/* consume HRR */
test_memio_clear_buffer(&test_ctx, 1);
/* send CH1 */
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* send HRR */
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_FAILURE);
/* send CH2 */
ExpectIntEQ(wolfSSL_connect(ssl_c), WOLFSSL_FATAL_ERROR);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WOLFSSL_FATAL_ERROR),
WOLFSSL_ERROR_WANT_READ);
/* send HRR */
ExpectIntEQ(wolfDTLS_accept_stateless(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectTrue(wolfSSL_is_stateful(ssl_s));
wolfSSL_free(ssl_c2);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#ifdef HAVE_MAX_FRAGMENT
static int test_wolfSSL_dtls_stateless_maxfrag(void)
{
EXPECT_DECLS;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_c2 = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
word16 max_fragment = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
ExpectNotNull(ssl_s);
ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c));
ExpectIntEQ(wolfSSL_UseMaxFragment(ssl_c2, WOLFSSL_MFL_2_8),
WOLFSSL_SUCCESS);
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
if (EXPECT_SUCCESS()) {
max_fragment = ssl_s->max_fragment;
}
/* send CH */
ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
/* CH without cookie shouldn't change state */
ExpectIntEQ(ssl_s->max_fragment, max_fragment);
ExpectIntNE(test_ctx.c_len, 0);
/* consume HRR from buffer */
test_memio_clear_buffer(&test_ctx, 1);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c2);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#endif /* HAVE_MAX_FRAGMENT */
#if defined(WOLFSSL_DTLS_NO_HVR_ON_RESUME)
#define ROUNDS_WITH_HVR 4
#define ROUNDS_WITHOUT_HVR 2
#define HANDSHAKE_TYPE_OFFSET DTLS_RECORD_HEADER_SZ
static int buf_is_hvr(const byte *data, int len)
{
if (len < DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ)
return 0;
return data[HANDSHAKE_TYPE_OFFSET] == hello_verify_request;
}
static int _test_wolfSSL_dtls_stateless_resume(byte useticket, byte bad)
{
EXPECT_DECLS;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
WOLFSSL_SESSION *sess = NULL;
int round_trips;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
&ssl_s, wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
#ifdef HAVE_SESSION_TICKET
if (useticket) {
ExpectIntEQ(wolfSSL_UseSessionTicket(ssl_c), WOLFSSL_SUCCESS);
}
#endif
round_trips = ROUNDS_WITH_HVR;
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, round_trips,
&round_trips), 0);
ExpectIntEQ(round_trips, ROUNDS_WITH_HVR);
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
wolfSSL_shutdown(ssl_c);
wolfSSL_shutdown(ssl_s);
wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_free(ssl_s);
ssl_s = NULL;
test_memio_clear_buffer(&test_ctx, 1);
test_memio_clear_buffer(&test_ctx, 0);
/* make resumption invalid */
if (bad && (sess != NULL)) {
if (useticket) {
#ifdef HAVE_SESSION_TICKET
if (sess->ticket != NULL) {
sess->ticket[0] = !sess->ticket[0];
}
#endif /* HAVE_SESSION_TICKET */
}
else {
sess->sessionID[0] = !sess->sessionID[0];
}
}
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectFalse(bad && !buf_is_hvr(test_ctx.c_buff, test_ctx.c_len));
ExpectFalse(!bad && buf_is_hvr(test_ctx.c_buff, test_ctx.c_len));
if (!useticket) {
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, &round_trips), 0);
ExpectFalse(bad && round_trips != ROUNDS_WITH_HVR - 1);
ExpectFalse(!bad && round_trips != ROUNDS_WITHOUT_HVR - 1);
}
wolfSSL_SESSION_free(sess);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
static int test_wolfSSL_dtls_stateless_resume(void)
{
EXPECT_DECLS;
#ifdef HAVE_SESSION_TICKET
ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(1, 0), TEST_SUCCESS);
ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(1, 1), TEST_SUCCESS);
#endif /* HAVE_SESION_TICKET */
ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(0, 0), TEST_SUCCESS);
ExpectIntEQ(_test_wolfSSL_dtls_stateless_resume(0, 1), TEST_SUCCESS);
return EXPECT_RESULT();
}
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
#if !defined(NO_OLD_TLS)
static int test_wolfSSL_dtls_stateless_downgrade(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_c2 = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_c2 = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_CTX_SetMinVersion(ctx_s, WOLFSSL_DTLSV1),
WOLFSSL_SUCCESS);
ExpectNotNull(ctx_c2 = wolfSSL_CTX_new(wolfDTLSv1_client_method()));
wolfSSL_SetIORecv(ctx_c2, test_memio_read_cb);
wolfSSL_SetIOSend(ctx_c2, test_memio_write_cb);
ExpectNotNull(ssl_c2 = wolfSSL_new(ctx_c2));
wolfSSL_SetIOWriteCtx(ssl_c2, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_c2, &test_ctx);
/* send CH */
ExpectTrue((wolfSSL_connect(ssl_c2) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c2->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectIntNE(test_ctx.c_len, 0);
/* consume HRR */
test_memio_clear_buffer(&test_ctx, 1);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c2);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_c2);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#endif /* !defined(NO_OLD_TLS) */
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)*/
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
!defined(NO_OLD_TLS) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
static int test_WOLFSSL_dtls_version_alert(void)
{
EXPECT_DECLS;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_server_method), 0);
/* client hello */
ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
/* hrr */
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
/* client hello 1 */
ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
/* server hello */
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
/* should fail */
ExpectTrue((wolfSSL_connect(ssl_c) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c->error == WC_NO_ERR_TRACE(VERSION_ERROR)));
/* shuould fail */
ExpectTrue((wolfSSL_accept(ssl_s) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_s->error == WC_NO_ERR_TRACE(VERSION_ERROR) || ssl_s->error == WC_NO_ERR_TRACE(FATAL_ERROR)));
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_WOLFSSL_dtls_version_alert(void)
{
return TEST_SKIPPED;
}
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) &&
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) &&
* !defined(NO_OLD_TLS) && !defined(NO_RSA)
*/
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET) \
&& defined(WOLFSSL_TLS13) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))\
&& defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
static int send_new_session_ticket(WOLFSSL *ssl, byte nonceLength, byte filler)
{
struct test_memio_ctx *test_ctx;
byte buf[2048];
int idx, sz;
word32 tmp;
int ret;
idx = 5; /* space for record header */
buf[idx] = session_ticket; /* type */
idx++;
tmp = OPAQUE32_LEN +
OPAQUE32_LEN +
OPAQUE8_LEN + nonceLength +
OPAQUE16_LEN + OPAQUE8_LEN + OPAQUE16_LEN;
c32to24(tmp, buf + idx);
idx += OPAQUE24_LEN;
c32toa((word32)12345, buf+idx); /* lifetime */
idx += OPAQUE32_LEN;
c32toa((word32)12345, buf+idx); /* add */
idx += OPAQUE32_LEN;
buf[idx] = nonceLength; /* nonce length */
idx++;
XMEMSET(&buf[idx], filler, nonceLength); /* nonce */
idx += nonceLength;
tmp = 1; /* ticket len */
c16toa((word16)tmp, buf+idx);
idx += 2;
buf[idx] = 0xFF; /* ticket */
idx++;
tmp = 0; /* ext len */
c16toa((word16)tmp, buf+idx);
idx += 2;
sz = BuildTls13Message(ssl, buf, 2048, buf+5, idx - 5,
handshake, 0, 0, 0);
AssertIntGT(sz, 0);
test_ctx = (struct test_memio_ctx*)wolfSSL_GetIOWriteCtx(ssl);
AssertNotNull(test_ctx);
ret = test_memio_write_cb(ssl, (char*)buf, sz, test_ctx);
return !(ret == sz);
}
static int test_ticket_nonce_check(WOLFSSL_SESSION *sess, byte len)
{
int ret = 0;
if ((sess == NULL) || (sess->ticketNonce.len != len)) {
ret = -1;
}
else {
int i;
for (i = 0; i < len; i++) {
if (sess->ticketNonce.data[i] != len) {
ret = -1;
break;
}
}
}
return ret;
}
static int test_ticket_nonce_malloc_do(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
{
EXPECT_DECLS;
char *buf[1024];
ExpectIntEQ(send_new_session_ticket(ssl_s, len, len), 0);
ExpectTrue((wolfSSL_recv(ssl_c, buf, 1024, 0) == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) &&
(ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectIntEQ(test_ticket_nonce_check(ssl_c->session, len), 0);
return EXPECT_RESULT();
}
static int test_ticket_nonce_cache(WOLFSSL *ssl_s, WOLFSSL *ssl_c, byte len)
{
EXPECT_DECLS;
WOLFSSL_SESSION *sess = NULL;
WOLFSSL_SESSION *cached = NULL;
WOLFSSL_CTX *ctx = ssl_c->ctx;
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, len), TEST_SUCCESS);
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
ExpectIntEQ(AddSessionToCache(ctx, sess, sess->sessionID, sess->sessionIDSz,
NULL, ssl_c->options.side, 1,NULL), 0);
ExpectNotNull(cached = wolfSSL_SESSION_new());
ExpectIntEQ(wolfSSL_GetSessionFromCache(ssl_c, cached), WOLFSSL_SUCCESS);
ExpectIntEQ(test_ticket_nonce_check(cached, len), 0);
wolfSSL_SESSION_free(cached);
wolfSSL_SESSION_free(sess);
return EXPECT_RESULT();
}
static int test_ticket_nonce_malloc(void)
{
EXPECT_DECLS;
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
byte small;
byte medium;
byte big;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
/* will send ticket manually */
ExpectIntEQ(wolfSSL_no_ticket_TLSv13(ssl_s), 0);
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, 0);
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, 0);
while (EXPECT_SUCCESS() && (ssl_c->options.handShakeDone == 0) &&
(ssl_s->options.handShakeDone == 0)) {
ExpectTrue((wolfSSL_connect(ssl_c) == WOLFSSL_SUCCESS) ||
(ssl_c->error == WC_NO_ERR_TRACE(WANT_READ)));
ExpectTrue((wolfSSL_accept(ssl_s) == WOLFSSL_SUCCESS) ||
(ssl_s->error == WC_NO_ERR_TRACE(WANT_READ)));
}
small = TLS13_TICKET_NONCE_STATIC_SZ;
#if TLS13_TICKET_NONCE_STATIC_SZ + 20 <= 255
medium = small + 20;
#else
medium = 255;
#endif
#if TLS13_TICKET_NONCE_STATIC_SZ + 20 + 20 <= 255
big = small + 20;
#else
big = 255;
#endif
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, small), TEST_SUCCESS);
ExpectPtrEq(ssl_c->session->ticketNonce.data,
ssl_c->session->ticketNonce.dataStatic);
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium),
TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, big), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, medium),
TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_malloc_do(ssl_s, ssl_c, small), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, small), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, medium), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, big), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, medium), TEST_SUCCESS);
ExpectIntEQ(test_ticket_nonce_cache(ssl_s, ssl_c, small), TEST_SUCCESS);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#endif /* WOLFSSL_TICKET_NONCE_MALLOC */
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_TLS12) && \
!defined(WOLFSSL_TICKET_DECRYPT_NO_CREATE) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
!defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(NO_RSA) && \
defined(HAVE_ECC) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
static int test_ticket_ret_create(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
byte ticket[SESSION_TICKET_LEN];
struct test_memio_ctx test_ctx;
WOLFSSL_SESSION *sess = NULL;
word16 ticketLen = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_NONE, 0);
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_NONE, 0);
ExpectIntEQ(wolfSSL_CTX_UseSessionTicket(ctx_c), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
ExpectIntLE(sess->ticketLen, SESSION_TICKET_LEN);
if (sess != NULL) {
ticketLen = sess->ticketLen;
XMEMCPY(ticket, sess->ticket, sess->ticketLen);
}
wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_free(ssl_s);
ssl_s = NULL;
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
wolfSSL_SetIOWriteCtx(ssl_s, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_s, &test_ctx);
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
wolfSSL_SetIOWriteCtx(ssl_c, &test_ctx);
wolfSSL_SetIOReadCtx(ssl_c, &test_ctx);
ExpectIntEQ(wolfSSL_set_session(ssl_c, sess), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntLE(ssl_c->session->ticketLen, SESSION_TICKET_LEN);
ExpectIntEQ(ssl_c->session->ticketLen, ticketLen);
ExpectTrue(XMEMCMP(ssl_c->session->ticket, ticket, ticketLen) != 0);
wolfSSL_SESSION_free(sess);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_ticket_ret_create(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && \
defined(HAVE_SESSION_TICKET) && defined(OPENSSL_EXTRA) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
!defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
static void test_ticket_and_psk_mixing_on_result(WOLFSSL* ssl)
{
int ret;
WOLFSSL_SESSION* session = NULL;
AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301);
if (!wolfSSL_is_server(ssl)) {
session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl));
AssertNotNull(session);
}
do {
ret = wolfSSL_shutdown(ssl);
} while (ret == WOLFSSL_SHUTDOWN_NOT_DONE);
AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS);
wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384");
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
/* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */
wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL);
#endif
if (!wolfSSL_is_server(ssl)) {
/* client */
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
"TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
wolfSSL_set_session(ssl, session);
wolfSSL_SESSION_free(session);
wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb);
AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
}
else {
/* server */
/* Different ciphersuite so that the ticket will be invalidated based on
* the ciphersuite */
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384"),
WOLFSSL_SUCCESS);
wolfSSL_set_psk_server_tls13_callback(ssl, my_psk_server_tls13_cb);
AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
}
}
static void test_ticket_and_psk_mixing_ssl_ready(WOLFSSL* ssl)
{
AssertIntEQ(wolfSSL_UseSessionTicket(ssl), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
}
static int test_ticket_and_psk_mixing(void)
{
EXPECT_DECLS;
/* Test mixing tickets and regular PSK */
callback_functions client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfTLSv1_3_client_method;
server_cbs.method = wolfTLSv1_3_server_method;
client_cbs.ssl_ready = test_ticket_and_psk_mixing_ssl_ready;
client_cbs.on_result = test_ticket_and_psk_mixing_on_result;
server_cbs.on_result = test_ticket_and_psk_mixing_on_result;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
ExpectIntEQ(client_cbs.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbs.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_ticket_and_psk_mixing(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK) && defined(HAVE_SESSION_TICKET) \
&& defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(HAVE_AESGCM) && !defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
static int test_prioritize_psk_cb_called = FALSE;
static unsigned int test_prioritize_psk_cb(WOLFSSL* ssl,
const char* identity, unsigned char* key, unsigned int key_max_len,
const char** ciphersuite)
{
test_prioritize_psk_cb_called = TRUE;
return my_psk_server_tls13_cb(ssl, identity, key, key_max_len, ciphersuite);
}
static void test_prioritize_psk_on_result(WOLFSSL* ssl)
{
int ret;
WOLFSSL_SESSION* session = NULL;
AssertIntEQ(wolfSSL_get_current_cipher_suite(ssl), 0x1301);
if (!wolfSSL_is_server(ssl)) {
session = wolfSSL_SESSION_dup(wolfSSL_get_session(ssl));
AssertNotNull(session);
}
do {
ret = wolfSSL_shutdown(ssl);
} while (ret == WOLFSSL_SHUTDOWN_NOT_DONE);
AssertIntEQ(wolfSSL_clear(ssl), WOLFSSL_SUCCESS);
wolfSSL_set_psk_callback_ctx(ssl, (void*)"TLS13-AES256-GCM-SHA384");
/* Previous connection was made with TLS13-AES128-GCM-SHA256. Order is
* important. */
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
"TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
/* OpenSSL considers PSK to be verified. We error out with NO_PEER_CERT. */
wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, NULL);
#endif
if (!wolfSSL_is_server(ssl)) {
/* client */
wolfSSL_set_psk_client_tls13_callback(ssl, my_psk_client_tls13_cb);
wolfSSL_set_session(ssl, session);
wolfSSL_SESSION_free(session);
AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
}
else {
/* server */
wolfSSL_set_psk_server_tls13_callback(ssl, test_prioritize_psk_cb);
AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_PRIORITIZE_PSK
/* The ticket should be first tried with all ciphersuites and chosen */
AssertFalse(test_prioritize_psk_cb_called);
#else
/* Ciphersuites should be tried with each PSK. This triggers the PSK
* callback that sets this var. */
AssertTrue(test_prioritize_psk_cb_called);
#endif
}
}
static void test_prioritize_psk_ssl_ready(WOLFSSL* ssl)
{
if (!wolfSSL_is_server(ssl))
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
else
AssertIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
"TLS13-AES128-GCM-SHA256"), WOLFSSL_SUCCESS);
}
static int test_prioritize_psk(void)
{
EXPECT_DECLS;
/* We always send the ticket first. With WOLFSSL_PRIORITIZE_PSK the order
* of the PSK's will be followed instead of the ciphersuite. */
callback_functions client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfTLSv1_3_client_method;
server_cbs.method = wolfTLSv1_3_server_method;
client_cbs.ssl_ready = test_prioritize_psk_ssl_ready;
server_cbs.ssl_ready = test_prioritize_psk_ssl_ready;
client_cbs.on_result = test_prioritize_psk_on_result;
server_cbs.on_result = test_prioritize_psk_on_result;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
ExpectIntEQ(client_cbs.return_code, TEST_SUCCESS);
ExpectIntEQ(server_cbs.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_prioritize_psk(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_TLS13) && defined(OPENSSL_EXTRA) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
!defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
!defined(WOLFSSL_NO_TLS12)
static int test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectTrue(SSL_CTX_set_cipher_list(ctx, "DEFAULT"));
/* Set TLS 1.3 specific suite */
ExpectTrue(SSL_CTX_set_ciphersuites(ctx, "TLS13-AES128-GCM-SHA256"));
return EXPECT_RESULT();
}
static int test_wolfSSL_CTX_set_ciphersuites(void)
{
EXPECT_DECLS;
/* Test using SSL_CTX_set_cipher_list and SSL_CTX_set_ciphersuites and then
* do a 1.2 connection. */
test_ssl_cbf client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfTLSv1_2_client_method;
server_cbs.method = wolfTLS_server_method; /* Allow downgrade */
server_cbs.ctx_ready = test_wolfSSL_CTX_set_ciphersuites_ctx_ready_server;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CTX_set_ciphersuites(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(HAVE_CRL) && defined(WOLFSSL_CHECK_ALERT_ON_ERR) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready(WOLFSSL_CTX* ctx)
{
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
return TEST_SUCCESS;
}
static int test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_ALERT_HISTORY h;
ExpectIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_rx.level, alert_fatal);
ExpectIntEQ(h.last_rx.code, certificate_revoked);
return EXPECT_RESULT();
}
static int test_wolfSSL_CRL_CERT_REVOKED_alert(void)
{
EXPECT_DECLS;
test_ssl_cbf client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
server_cbs.certPemFile = "./certs/server-revoked-cert.pem";
server_cbs.keyPemFile = "./certs/server-revoked-key.pem";
client_cbs.crlPemFile = "./certs/crl/crl.revoked";
client_cbs.ctx_ready = test_wolfSSL_CRL_CERT_REVOKED_alert_ctx_ready;
server_cbs.on_cleanup = test_wolfSSL_CRL_CERT_REVOKED_alert_on_cleanup;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), -1001);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_CRL_CERT_REVOKED_alert(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) \
&& defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_AESGCM) && \
!defined(NO_SHA256) && defined(WOLFSSL_AES_128) && \
defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) && \
!defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
static WOLFSSL_CTX* test_TLS_13_ticket_different_ciphers_ctx = NULL;
static WOLFSSL_SESSION* test_TLS_13_ticket_different_ciphers_session = NULL;
static int test_TLS_13_ticket_different_ciphers_run = 0;
static int test_TLS_13_ticket_different_ciphers_ssl_ready(WOLFSSL* ssl)
{
EXPECT_DECLS;
switch (test_TLS_13_ticket_different_ciphers_run) {
case 0:
/* First run */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
if (wolfSSL_is_server(ssl)) {
ExpectNotNull(test_TLS_13_ticket_different_ciphers_ctx =
wolfSSL_get_SSL_CTX(ssl));
ExpectIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_up_ref(
test_TLS_13_ticket_different_ciphers_ctx));
}
break;
case 1:
/* Second run */
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "TLS13-AES256-GCM-SHA384:"
"TLS13-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
if (!wolfSSL_is_server(ssl)) {
ExpectIntEQ(wolfSSL_set_session(ssl,
test_TLS_13_ticket_different_ciphers_session),
WOLFSSL_SUCCESS);
}
break;
default:
/* Bad state? */
Fail(("Should not enter here"), ("Should not enter here"));
}
return EXPECT_RESULT();
}
static int test_TLS_13_ticket_different_ciphers_on_result(WOLFSSL* ssl)
{
EXPECT_DECLS;
switch (test_TLS_13_ticket_different_ciphers_run) {
case 0:
/* First run */
ExpectNotNull(test_TLS_13_ticket_different_ciphers_session =
wolfSSL_get1_session(ssl));
break;
case 1:
/* Second run */
ExpectTrue(wolfSSL_session_reused(ssl));
break;
default:
/* Bad state? */
Fail(("Should not enter here"), ("Should not enter here"));
}
return EXPECT_RESULT();
}
static int test_TLS_13_ticket_different_ciphers(void)
{
EXPECT_DECLS;
/* Check that we handle the connection when the ticket doesn't match
* the first ciphersuite. */
test_ssl_cbf client_cbs, server_cbs;
struct test_params {
method_provider client_meth;
method_provider server_meth;
int doUdp;
} params[] = {
#ifdef WOLFSSL_DTLS13
/* Test that the stateless code handles sessions correctly */
{wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, 1},
#endif
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, 0},
};
size_t i;
for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
test_TLS_13_ticket_different_ciphers_run = 0;
client_cbs.doUdp = server_cbs.doUdp = params[i].doUdp;
client_cbs.method = params[i].client_meth;
server_cbs.method = params[i].server_meth;
client_cbs.ssl_ready = test_TLS_13_ticket_different_ciphers_ssl_ready;
server_cbs.ssl_ready = test_TLS_13_ticket_different_ciphers_ssl_ready;
client_cbs.on_result = test_TLS_13_ticket_different_ciphers_on_result;
server_cbs.ticNoInit = 1;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_SUCCESS);
test_TLS_13_ticket_different_ciphers_run++;
server_cbs.ctx = test_TLS_13_ticket_different_ciphers_ctx;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), TEST_SUCCESS);
wolfSSL_SESSION_free(test_TLS_13_ticket_different_ciphers_session);
test_TLS_13_ticket_different_ciphers_session = NULL;
wolfSSL_CTX_free(test_TLS_13_ticket_different_ciphers_ctx);
test_TLS_13_ticket_different_ciphers_ctx = NULL;
}
return EXPECT_RESULT();
}
#else
static int test_TLS_13_ticket_different_ciphers(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_EXTRA_ALERTS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
#define TEST_WRONG_CS_CLIENT "DHE-RSA-AES128-SHA"
/* AKA TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
byte test_extra_alerts_wrong_cs_sh[] = {
0x16, 0x03, 0x03, 0x00, 0x56, 0x02, 0x00, 0x00, 0x52, 0x03, 0x03, 0xef,
0x0c, 0x30, 0x98, 0xa2, 0xac, 0xfa, 0x68, 0xe9, 0x3e, 0xaa, 0x5c, 0xcf,
0xa7, 0x42, 0x72, 0xaf, 0xa0, 0xe8, 0x39, 0x2b, 0x3e, 0x81, 0xa7, 0x7a,
0xa5, 0x62, 0x8a, 0x0e, 0x41, 0xba, 0xda, 0x20, 0x18, 0x9f, 0xe1, 0x8c,
0x1d, 0xc0, 0x37, 0x9c, 0xf4, 0x90, 0x5d, 0x8d, 0xa0, 0x79, 0xa7, 0x4b,
0xa8, 0x79, 0xdf, 0xcd, 0x8d, 0xf5, 0xb5, 0x50, 0x5f, 0xf1, 0xdb, 0x4d,
0xbb, 0x07, 0x54, 0x1c,
0x00, 0x02, /* TLS_RSA_WITH_NULL_SHA */
0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00,
0x02, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00
};
static int test_extra_alerts_wrong_cs(void)
{
EXPECT_DECLS;
#ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_ALERT_HISTORY h;
WOLFSSL *ssl_c = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfTLSv1_2_client_method, NULL), 0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, TEST_WRONG_CS_CLIENT),
WOLFSSL_SUCCESS);
/* CH */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
/* consume CH */
test_memio_clear_buffer(&test_ctx, 0);
/* inject SH */
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
(const char *)test_extra_alerts_wrong_cs_sh,
sizeof(test_extra_alerts_wrong_cs_sh)), 0);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_tx.code, handshake_failure);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
#endif
return EXPECT_RESULT();
}
#else
static int test_extra_alerts_wrong_cs(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_AES_256)
#define TEST_CS_DOWNGRADE_CLIENT "ECDHE-RSA-AES256-GCM-SHA384"
byte test_wrong_cs_downgrade_sh[] = {
0x16, 0x03, 0x03, 0x00, 0x56, 0x02, 0x00, 0x00, 0x52, 0x03, 0x03, 0x10,
0x2c, 0x88, 0xd9, 0x7a, 0x23, 0xc9, 0xbd, 0x11, 0x3b, 0x64, 0x24, 0xab,
0x5b, 0x45, 0x33, 0xf6, 0x2c, 0x34, 0xe4, 0xcf, 0xf4, 0x78, 0xc8, 0x62,
0x06, 0xc7, 0xe5, 0x30, 0x39, 0xbf, 0xa1, 0x20, 0xa3, 0x06, 0x74, 0xc3,
0xa9, 0x74, 0x52, 0x8a, 0xfb, 0xae, 0xf0, 0xd8, 0x6f, 0xb2, 0x9d, 0xfe,
0x78, 0xf0, 0x3f, 0x51, 0x8f, 0x9c, 0xcf, 0xbe, 0x61, 0x43, 0x9d, 0xf8,
0x85, 0xe5, 0x2f, 0x54,
0xc0, 0x2f, /* ECDHE-RSA-AES128-GCM-SHA256 */
0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00,
0x02, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00
};
static int test_wrong_cs_downgrade(void)
{
EXPECT_DECLS;
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL *ssl_c = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfSSLv23_client_method, NULL), 0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, TEST_CS_DOWNGRADE_CLIENT),
WOLFSSL_SUCCESS);
/* CH */
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
/* consume CH */
test_memio_clear_buffer(&test_ctx, 0);
/* inject SH */
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
(const char *)test_wrong_cs_downgrade_sh,
sizeof(test_wrong_cs_downgrade_sh)), 0);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
#ifdef OPENSSL_EXTRA
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WC_NO_ERR_TRACE(WOLFSSL_ERROR_SYSCALL));
#else
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WC_NO_ERR_TRACE(MATCH_SUITE_ERROR));
#endif /* OPENSSL_EXTRA */
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
#endif
return EXPECT_RESULT();
}
#else
static int test_wrong_cs_downgrade(void)
{
return TEST_SKIPPED;
}
#endif
#if !defined(WOLFSSL_NO_TLS12) && defined(WOLFSSL_EXTRA_ALERTS) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_SP_MATH)
static int test_remove_hs_msg_from_buffer(struct test_memio_ctx *test_ctx, byte type,
byte *found)
{
const unsigned int _HANDSHAKE_HEADER_SZ = 4;
const unsigned int _RECORD_HEADER_SZ = 5;
const int _change_cipher_hs = 55;
const int _change_cipher = 20;
const int _handshake = 22;
unsigned int tail_len;
byte *idx;
int curr;
word8 currType;
word16 rLength;
word32 hLength;
idx = test_ctx->c_buff;
tail_len = (unsigned int)test_ctx->c_len;
*found = 0;
while (tail_len > _RECORD_HEADER_SZ) {
curr = (int)(idx - test_ctx->c_buff);
currType = *idx;
ato16(idx + 3, &rLength);
idx += _RECORD_HEADER_SZ;
tail_len -= _RECORD_HEADER_SZ;
if (tail_len < rLength)
return -1;
if (type == _change_cipher_hs && currType == _change_cipher) {
if (rLength != 1)
return -1;
/* match */
test_memio_remove_from_buffer(test_ctx, 1, curr,
_RECORD_HEADER_SZ + rLength);
*found = 1;
return 0;
}
if (currType != _handshake) {
idx += rLength;
tail_len -= rLength;
continue;
}
if (rLength < _HANDSHAKE_HEADER_SZ)
return -1;
currType = *idx;
ato24(idx+1, &hLength);
hLength += _HANDSHAKE_HEADER_SZ;
if (tail_len < hLength)
return -1;
if (currType != type) {
idx += hLength;
tail_len -= hLength;
continue;
}
/* match */
test_memio_remove_from_buffer(test_ctx, 1, curr,
hLength + _RECORD_HEADER_SZ);
*found = 1;
return 0;
}
/* not found */
return 0;
}
static int test_remove_hs_message(byte hs_message_type,
int extra_round, byte alert_type)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
byte found = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
if (extra_round) {
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
/* this will complete handshake from server side */
ExpectIntEQ(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
}
ExpectIntEQ(test_remove_hs_msg_from_buffer(&test_ctx, hs_message_type, &found), 0);
if (!found) {
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
return TEST_SKIPPED;
}
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectTrue(alert_type == 0xff || h.last_tx.code == alert_type);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
static int test_extra_alerts_skip_hs(void)
{
EXPECT_DECLS;
const byte _server_key_exchange = 12;
const byte _server_hello = 2;
const byte _certificate = 11;
/* server_hello */
ExpectIntNE(test_remove_hs_message(_server_hello, 0,
unexpected_message), TEST_FAIL);
ExpectIntNE(test_remove_hs_message(_certificate, 0,
0xff), TEST_FAIL);
ExpectIntNE(test_remove_hs_message(_server_key_exchange, 0,
unexpected_message), TEST_FAIL);
return EXPECT_RESULT();
}
#else
static int test_extra_alerts_skip_hs(void)
{
return TEST_SKIPPED;
}
#endif
#if !defined(WOLFSSL_NO_TLS12) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)\
&& defined(WOLFSSL_EXTRA_ALERTS) && !defined(NO_PSK) && !defined(NO_DH)
static unsigned int test_server_psk_cb(WOLFSSL* ssl, const char* id,
unsigned char* key, unsigned int key_max_len)
{
(void)ssl;
(void)id;
(void)key_max_len;
/* zero means error */
key[0] = 0x10;
return 1;
}
static int test_extra_alerts_bad_psk(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_c, "DHE-PSK-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_cipher_list(ssl_s, "DHE-PSK-AES128-GCM-SHA256"),
WOLFSSL_SUCCESS);
wolfSSL_set_psk_server_callback(ssl_s, test_server_psk_cb);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_tx.code, handshake_failure);
ExpectIntEQ(h.last_tx.level, alert_fatal);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_extra_alerts_bad_psk(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
static int test_multiple_shutdown_nonblocking(void)
{
EXPECT_DECLS;
size_t size_of_last_packet = 0;
int dummy_recv_buffer;
/* declare wolfSSL objects */
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
/* Create and initialize WOLFSSL_CTX and WOLFSSL objects */
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectNotNull(ctx_c);
ExpectNotNull(ssl_c);
ExpectNotNull(ctx_s);
ExpectNotNull(ssl_s);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
/* buffers should be empty now */
ExpectIntEQ(test_ctx.c_len, 0);
ExpectIntEQ(test_ctx.s_len, 0);
ExpectIntEQ(ssl_c->buffers.outputBuffer.length, 0);
test_memio_simulate_want_write(&test_ctx, 1, 1);
/*
* We call wolfSSL_shutdown multiple times to to check that it doesn't add
* the CLOSE_NOTIFY packet multiple times on the output buffer.
* */
ExpectIntEQ(wolfSSL_shutdown(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, 0), WOLFSSL_ERROR_WANT_WRITE);
/* store the size of the packet */
if (ssl_c != NULL) {
size_of_last_packet = ssl_c->buffers.outputBuffer.length;
}
/* invoke it multiple times shouldn't change the wolfssl internal output buffer size */
ExpectIntEQ(wolfSSL_shutdown(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, 0), WOLFSSL_ERROR_WANT_WRITE);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, 0), WOLFSSL_ERROR_WANT_WRITE);
ExpectIntEQ(ssl_c->buffers.outputBuffer.length, size_of_last_packet);
/* now send the CLOSE_NOTIFY to the server for real, expecting shutdown not done */
test_memio_simulate_want_write(&test_ctx, 1, 0);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
/* output buffer should be empty and socket buffer should contain the message */
ExpectIntEQ(ssl_c->buffers.outputBuffer.length, 0);
ExpectIntEQ(test_ctx.s_len, size_of_last_packet);
/* this should try to read from the socket */
ExpectIntEQ(wolfSSL_shutdown(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* complete the bidirectional shutdown */
/* check that server received the shutdown alert */
ExpectIntEQ(wolfSSL_recv(ssl_s, &dummy_recv_buffer, 0, 0), 0);
ExpectIntEQ(wolfSSL_get_error(ssl_s, 0), WOLFSSL_ERROR_ZERO_RETURN);
/* send the shutdown from the server side */
ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SUCCESS);
/* This should return success and zero return */
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, 0), WOLFSSL_ERROR_ZERO_RETURN);
/* Cleanup and return */
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_s);
wolfSSL_free(ssl_s);
return EXPECT_RESULT();
}
#else
static int test_multiple_shutdown_nonblocking(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
static int test_harden_no_secure_renegotiation_io_cb(WOLFSSL *ssl, char *buf,
int sz, void *ctx)
{
static int sentServerHello = FALSE;
if (!sentServerHello) {
byte renegExt[] = { 0xFF, 0x01, 0x00, 0x01, 0x00 };
size_t i;
if (sz < (int)sizeof(renegExt))
return WOLFSSL_CBIO_ERR_GENERAL;
/* Remove SCR from ServerHello */
for (i = 0; i < sz - sizeof(renegExt); i++) {
if (XMEMCMP(buf + i, renegExt, sizeof(renegExt)) == 0) {
/* Found the extension. Change it to something unrecognized. */
buf[i+1] = 0x11;
break;
}
}
sentServerHello = TRUE;
}
return EmbedSend(ssl, buf, sz, ctx);
}
static void test_harden_no_secure_renegotiation_ssl_ready(WOLFSSL* ssl)
{
wolfSSL_SSLSetIOSend(ssl, test_harden_no_secure_renegotiation_io_cb);
}
static void test_harden_no_secure_renegotiation_on_cleanup(WOLFSSL* ssl)
{
WOLFSSL_ALERT_HISTORY h;
AssertIntEQ(wolfSSL_get_alert_history(ssl, &h), WOLFSSL_SUCCESS);
AssertIntEQ(h.last_rx.code, handshake_failure);
AssertIntEQ(h.last_rx.level, alert_fatal);
}
static int test_harden_no_secure_renegotiation(void)
{
EXPECT_DECLS;
callback_functions client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfTLSv1_2_client_method;
server_cbs.method = wolfTLSv1_2_server_method;
server_cbs.ssl_ready = test_harden_no_secure_renegotiation_ssl_ready;
server_cbs.on_cleanup = test_harden_no_secure_renegotiation_on_cleanup;
test_wolfSSL_client_server_nofail(&client_cbs, &server_cbs);
ExpectIntEQ(client_cbs.return_code, TEST_FAIL);
ExpectIntEQ(client_cbs.last_err, WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E));
ExpectIntEQ(server_cbs.return_code, TEST_FAIL);
ExpectTrue(server_cbs.last_err == WC_NO_ERR_TRACE(SOCKET_ERROR_E) ||
server_cbs.last_err == WC_NO_ERR_TRACE(FATAL_ERROR));
return EXPECT_RESULT();
}
#else
static int test_harden_no_secure_renegotiation(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(HAVE_OCSP) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
static int test_override_alt_cert_chain_cert_cb(int preverify,
WOLFSSL_X509_STORE_CTX* store)
{
fprintf(stderr, "preverify: %d\n", preverify);
fprintf(stderr, "store->error: %d\n", store->error);
fprintf(stderr, "error reason: %s\n", wolfSSL_ERR_reason_error_string(store->error));
if (store->error == WC_NO_ERR_TRACE(OCSP_INVALID_STATUS)) {
fprintf(stderr, "Overriding OCSP error\n");
return 1;
}
#ifndef WOLFSSL_ALT_CERT_CHAINS
else if ((store->error == WC_NO_ERR_TRACE(ASN_NO_SIGNER_E) ||
store->error == WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
|| store->error == WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
#endif
) && store->error_depth == store->totalCerts - 1) {
fprintf(stderr, "Overriding no signer error only for root cert\n");
return 1;
}
#endif
else
return preverify;
}
static int test_override_alt_cert_chain_ocsp_cb(void* ioCtx, const char* url,
int urlSz, unsigned char* request, int requestSz,
unsigned char** response)
{
(void)ioCtx;
(void)url;
(void)urlSz;
(void)request;
(void)requestSz;
(void)response;
return WOLFSSL_CBIO_ERR_GENERAL;
}
static int test_override_alt_cert_chain_client_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER,
test_override_alt_cert_chain_cert_cb);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL |
WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_SetOCSP_Cb(ctx,
test_override_alt_cert_chain_ocsp_cb, NULL, NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx, "not a url"),
WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_override_alt_cert_chain_client_ctx_ready2(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL |
WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_SetOCSP_Cb(ctx,
test_override_alt_cert_chain_ocsp_cb, NULL, NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx, "not a url"),
WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_override_alt_cert_chain_server_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_use_certificate_chain_file(ctx,
"./certs/intermediate/server-chain-alt.pem"), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_override_alt_cert_chain(void)
{
EXPECT_DECLS;
size_t i;
struct test_params {
ctx_cb client_ctx_cb;
ctx_cb server_ctx_cb;
int result;
} params[] = {
{test_override_alt_cert_chain_client_ctx_ready,
test_override_alt_cert_chain_server_ctx_ready, TEST_SUCCESS},
{test_override_alt_cert_chain_client_ctx_ready2,
test_override_alt_cert_chain_server_ctx_ready, -1001},
};
for (i = 0; i < sizeof(params)/sizeof(*params); i++) {
test_ssl_cbf client_cbs, server_cbs;
XMEMSET(&client_cbs, 0, sizeof(client_cbs));
XMEMSET(&server_cbs, 0, sizeof(server_cbs));
fprintf(stderr, "test config: %d\n", (int)i);
client_cbs.ctx_ready = params[i].client_ctx_cb;
server_cbs.ctx_ready = params[i].server_ctx_cb;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbs,
&server_cbs, NULL), params[i].result);
ExpectIntEQ(client_cbs.return_code,
params[i].result <= 0 ? -1000 : TEST_SUCCESS);
ExpectIntEQ(server_cbs.return_code,
params[i].result <= 0 ? -1000 : TEST_SUCCESS);
}
return EXPECT_RESULT();
}
#else
static int test_override_alt_cert_chain(void)
{
return TEST_SKIPPED;
}
#endif
static int test_rpk_set_xxx_cert_type(void)
{
EXPECT_DECLS;
#if defined(HAVE_RPK) && !defined(NO_TLS)
char ctype[MAX_CLIENT_CERT_TYPE_CNT + 1]; /* prepare bigger buffer */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
int tp;
ctx = wolfSSL_CTX_new(wolfTLS_client_method());
ExpectNotNull(ctx);
ssl = wolfSSL_new(ctx);
ExpectNotNull(ssl);
XMEMSET(ctype, 0, sizeof(ctype));
/*--------------------------------------------*/
/* tests for wolfSSL_CTX_set_client_cert_type */
/*--------------------------------------------*/
/* illegal parameter test caces */
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(NULL, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
sizeof(ctype)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_RPK; /* set an identical cert type */
ctype[1] = WOLFSSL_CERT_TYPE_RPK;
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_X509;
ctype[1] = 10; /* set unknown cert type */
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* pass larger type count */
ctype[0] = WOLFSSL_CERT_TYPE_RPK;
ctype[1] = WOLFSSL_CERT_TYPE_X509;
ctype[2] = 1; /* pass unacceptable type count */
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
MAX_CLIENT_CERT_TYPE_CNT + 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* should accept NULL for type buffer */
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, NULL,
MAX_CLIENT_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/* should accept zero for type count */
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
0),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_client_cert_type(ctx, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/*--------------------------------------------*/
/* tests for wolfSSL_CTX_set_server_cert_type */
/*--------------------------------------------*/
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(NULL, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
sizeof(ctype)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_RPK; /* set an identical cert type */
ctype[1] = WOLFSSL_CERT_TYPE_RPK;
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_X509;
ctype[1] = 10; /* set unknown cert type */
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* pass larger type count */
ctype[0] = WOLFSSL_CERT_TYPE_RPK;
ctype[1] = WOLFSSL_CERT_TYPE_X509;
ctype[2] = 1; /* pass unacceptable type count */
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
MAX_SERVER_CERT_TYPE_CNT + 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* should accept NULL for type buffer */
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, NULL,
MAX_SERVER_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/* should accept zero for type count */
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
0),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_set_server_cert_type(ctx, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/*--------------------------------------------*/
/* tests for wolfSSL_set_client_cert_type */
/*--------------------------------------------*/
ExpectIntEQ(wolfSSL_set_client_cert_type(NULL, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
sizeof(ctype)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_RPK; /* set an identical cert type */
ctype[1] = WOLFSSL_CERT_TYPE_RPK;
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_X509;
ctype[1] = 10; /* set unknown cert type */
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* pass larger type count */
ctype[0] = WOLFSSL_CERT_TYPE_RPK;
ctype[1] = WOLFSSL_CERT_TYPE_X509;
ctype[2] = 1; /* pass unacceptable type count */
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
MAX_CLIENT_CERT_TYPE_CNT + 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* should accept NULL for type buffer */
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, NULL,
MAX_CLIENT_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/* should accept zero for type count */
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
0),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_client_cert_type(ssl, ctype,
MAX_CLIENT_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/*--------------------------------------------*/
/* tests for wolfSSL_CTX_set_server_cert_type */
/*--------------------------------------------*/
ExpectIntEQ(wolfSSL_set_server_cert_type(NULL, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
sizeof(ctype)),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_RPK; /* set an identical cert type */
ctype[1] = WOLFSSL_CERT_TYPE_RPK;
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ctype[0] = WOLFSSL_CERT_TYPE_X509;
ctype[1] = 10; /* set unknown cert type */
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* pass larger type count */
ctype[0] = WOLFSSL_CERT_TYPE_RPK;
ctype[1] = WOLFSSL_CERT_TYPE_X509;
ctype[2] = 1; /* pass unacceptable type count */
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
MAX_SERVER_CERT_TYPE_CNT + 1),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* should accept NULL for type buffer */
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, NULL,
MAX_SERVER_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/* should accept zero for type count */
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
0),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_server_cert_type(ssl, ctype,
MAX_SERVER_CERT_TYPE_CNT),
WOLFSSL_SUCCESS);
/*------------------------------------------------*/
/* tests for wolfSSL_get_negotiated_xxx_cert_type */
/*------------------------------------------------*/
ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(NULL, &tp),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_get_negotiated_client_cert_type(ssl, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(NULL, &tp),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wolfSSL_get_negotiated_server_cert_type(ssl, NULL),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
/* clean up */
wolfSSL_free(ssl);
wolfSSL_CTX_free(ctx);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
static int test_dtls13_bad_epoch_ch(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const int EPOCH_OFF = 3;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
/* disable hrr cookie so we can later check msgsReceived.got_client_hello
* with just one message */
ExpectIntEQ(wolfSSL_disable_hrr_cookie(ssl_s), WOLFSSL_SUCCESS);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntGE(test_ctx.s_len, EPOCH_OFF + 2);
/* first CH should use epoch 0x0 */
ExpectTrue((test_ctx.s_buff[EPOCH_OFF] == 0x0) &&
(test_ctx.s_buff[EPOCH_OFF + 1] == 0x0));
/* change epoch to 2 */
test_ctx.s_buff[EPOCH_OFF + 1] = 0x2;
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntNE(ssl_s->msgsReceived.got_client_hello, 1);
/* resend the CH */
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_dtls13_bad_epoch_ch(void)
{
return TEST_SKIPPED;
}
#endif
#if ((defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID) && \
!defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)) || \
(!defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
!defined(NO_DES3))) || !defined(WOLFSSL_NO_TLS12)) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_SESSION_CACHE) && !defined(NO_SHA256)
static int test_short_session_id_ssl_ready(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_SESSION *sess = NULL;
/* Setup the session to avoid errors */
ssl->session->timeout = (word32)-1;
ssl->session->side = WOLFSSL_CLIENT_END;
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET))
ssl->session->version = ssl->version;
#endif
/* Force a short session ID to be sent */
ssl->session->sessionIDSz = 4;
#ifndef NO_SESSION_CACHE_REF
/* Allow the client cache to be used */
ssl->session->idLen = 4;
#endif
ssl->session->isSetup = 1;
ExpectNotNull(sess = wolfSSL_get_session(ssl));
ExpectIntEQ(wolfSSL_set_session(ssl, sess), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_short_session_id(void)
{
EXPECT_DECLS;
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* tls_version;
} params[] = {
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TICKET_HAVE_ID) && \
!defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS) && ((!defined(NO_AES) && !defined(NO_AES_CBC)) || \
!defined(NO_DES3))
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
};
fprintf(stderr, "\n");
for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
fprintf(stderr, "\tTesting short ID with %s\n", params[i].tls_version);
client_cbf.ssl_ready = test_short_session_id_ssl_ready;
client_cbf.method = params[i].client_meth;
server_cbf.method = params[i].server_meth;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
}
return EXPECT_RESULT();
}
#else
static int test_short_session_id(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(HAVE_NULL_CIPHER) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) \
&& defined(WOLFSSL_DTLS13)
static byte* test_find_string(const char *string,
byte *buf, int buf_size)
{
int string_size, i;
string_size = (int)XSTRLEN(string);
for (i = 0; i < buf_size - string_size - 1; i++) {
if (XSTRCMP((char*)&buf[i], string) == 0)
return &buf[i];
}
return NULL;
}
static int test_wolfSSL_dtls13_null_cipher(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char *test_str = "test";
int test_str_size;
byte buf[255], *ptr = NULL;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
test_ctx.c_ciphers = test_ctx.s_ciphers = "TLS13-SHA256-SHA256";
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
test_str_size = XSTRLEN("test") + 1;
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), test_str_size);
ExpectIntEQ(XSTRCMP((char*)buf, test_str), 0);
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
/* check that the packet was sent cleartext */
ExpectNotNull(ptr = test_find_string(test_str, test_ctx.s_buff,
test_ctx.s_len));
if (ptr != NULL) {
/* modify the message */
*ptr = 'H';
/* bad messages should be ignored in DTLS */
ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), -1);
ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(WANT_READ));
}
ExpectIntEQ(wolfSSL_shutdown(ssl_c), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
ExpectIntEQ(wolfSSL_shutdown(ssl_c), 1);
ExpectIntEQ(wolfSSL_shutdown(ssl_s), 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return TEST_SUCCESS;
}
#else
static int test_wolfSSL_dtls13_null_cipher(void)
{
return TEST_SKIPPED;
}
#endif
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
!defined(SINGLE_THREADED) && !defined(NO_RSA)
static int test_dtls_msg_get_connected_port(int fd, word16 *port)
{
SOCKADDR_S peer;
XSOCKLENT len;
int ret;
XMEMSET((byte*)&peer, 0, sizeof(peer));
len = sizeof(peer);
ret = getpeername(fd, (SOCKADDR*)&peer, &len);
if (ret != 0 || len > (XSOCKLENT)sizeof(peer))
return -1;
switch (peer.ss_family) {
#ifdef WOLFSSL_IPV6
case WOLFSSL_IP6: {
*port = ntohs(((SOCKADDR_IN6*)&peer)->sin6_port);
break;
}
#endif /* WOLFSSL_IPV6 */
case WOLFSSL_IP4:
*port = ntohs(((SOCKADDR_IN*)&peer)->sin_port);
break;
default:
return -1;
}
return 0;
}
static int test_dtls_msg_from_other_peer_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
{
char buf[1] = {'t'};
SOCKADDR_IN_T addr;
int sock_fd;
word16 port;
int err;
(void)ssl;
(void)ctx;
if (ssl == NULL)
return -1;
err = test_dtls_msg_get_connected_port(wolfSSL_get_fd(ssl), &port);
if (err != 0)
return -1;
sock_fd = socket(AF_INET_V, SOCK_DGRAM, 0);
if (sock_fd == -1)
return -1;
build_addr(&addr, wolfSSLIP, port, 1, 0);
/* send a packet to the server. Being another socket, the kernel will ensure
* the source port will be different. */
err = (int)sendto(sock_fd, buf, sizeof(buf), 0, (SOCKADDR*)&addr,
sizeof(addr));
close(sock_fd);
if (err == -1)
return -1;
return 0;
}
/* setup a SSL session but just after the handshake send a packet to the server
* with a source address different than the one of the connected client. The I/O
* callback EmbedRecvFrom should just ignore the packet. Sending of the packet
* is done in test_dtls_msg_from_other_peer_cb */
static int test_dtls_msg_from_other_peer(void)
{
EXPECT_DECLS;
callback_functions client_cbs;
callback_functions server_cbs;
XMEMSET((byte*)&client_cbs, 0, sizeof(client_cbs));
XMEMSET((byte*)&server_cbs, 0, sizeof(server_cbs));
client_cbs.method = wolfDTLSv1_2_client_method;
server_cbs.method = wolfDTLSv1_2_server_method;
client_cbs.doUdp = 1;
server_cbs.doUdp = 1;
test_wolfSSL_client_server_nofail_ex(&client_cbs, &server_cbs,
test_dtls_msg_from_other_peer_cb);
ExpectIntEQ(client_cbs.return_code, WOLFSSL_SUCCESS);
ExpectIntEQ(server_cbs.return_code, WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_dtls_msg_from_other_peer(void)
{
return TEST_SKIPPED;
}
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
* !defined(SINGLE_THREADED) && !defined(NO_RSA) */
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_IPV6) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) \
&& !defined(USE_WINDOWS_API)
static int test_dtls_ipv6_check(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
SOCKADDR_IN fake_addr6;
int sockfd = -1;
ExpectNotNull(ctx_c = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()));
ExpectNotNull(ssl_c = wolfSSL_new(ctx_c));
ExpectNotNull(ctx_s = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()));
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey_file(ctx_s, svrKeyFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_use_certificate_file(ctx_s, svrCertFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectNotNull(ssl_s = wolfSSL_new(ctx_s));
XMEMSET((byte*)&fake_addr6, 0, sizeof(fake_addr6));
/* mimic a sockaddr_in6 struct, this way we can't test without
* WOLFSSL_IPV6 */
fake_addr6.sin_family = WOLFSSL_IP6;
ExpectIntNE(sockfd = socket(AF_INET, SOCK_DGRAM, 0), -1);
ExpectIntEQ(wolfSSL_set_fd(ssl_c, sockfd), WOLFSSL_SUCCESS);
/* can't return error here, as the peer is opaque for wolfssl library at
* this point */
ExpectIntEQ(wolfSSL_dtls_set_peer(ssl_c, &fake_addr6, sizeof(fake_addr6)),
WOLFSSL_SUCCESS);
ExpectIntNE(fcntl(sockfd, F_SETFL, O_NONBLOCK), -1);
wolfSSL_dtls_set_using_nonblock(ssl_c, 1);
ExpectIntNE(wolfSSL_connect(ssl_c), WOLFSSL_SUCCESS);
ExpectIntEQ(ssl_c->error, WC_NO_ERR_TRACE(SOCKET_ERROR_E));
ExpectIntEQ(wolfSSL_dtls_set_peer(ssl_s, &fake_addr6, sizeof(fake_addr6)),
WOLFSSL_SUCCESS);
/* reuse the socket */
ExpectIntEQ(wolfSSL_set_fd(ssl_c, sockfd), WOLFSSL_SUCCESS);
wolfSSL_dtls_set_using_nonblock(ssl_s, 1);
ExpectIntNE(wolfSSL_accept(ssl_s), WOLFSSL_SUCCESS);
ExpectIntEQ(ssl_s->error, WC_NO_ERR_TRACE(SOCKET_ERROR_E));
if (sockfd != -1)
close(sockfd);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_dtls_ipv6_check(void)
{
return TEST_SKIPPED;
}
#endif
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
static WOLFSSL_SESSION* test_wolfSSL_SCR_after_resumption_session = NULL;
static void test_wolfSSL_SCR_after_resumption_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}
static void test_wolfSSL_SCR_after_resumption_on_result(WOLFSSL* ssl)
{
if (test_wolfSSL_SCR_after_resumption_session == NULL) {
test_wolfSSL_SCR_after_resumption_session = wolfSSL_get1_session(ssl);
AssertNotNull(test_wolfSSL_SCR_after_resumption_session);
}
else {
char testMsg[] = "Message after SCR";
char msgBuf[sizeof(testMsg)];
int ret;
if (!wolfSSL_is_server(ssl)) {
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_set_session(ssl,
test_wolfSSL_SCR_after_resumption_session));
}
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
sizeof(testMsg));
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
if (ret != sizeof(msgBuf)) /* Possibly APP_DATA_READY error. Retry. */
ret = wolfSSL_read(ssl, msgBuf, sizeof(msgBuf));
AssertIntEQ(ret, sizeof(msgBuf));
}
}
static void test_wolfSSL_SCR_after_resumption_ssl_ready(WOLFSSL* ssl)
{
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_set_session(ssl, test_wolfSSL_SCR_after_resumption_session));
}
static int test_wolfSSL_SCR_after_resumption(void)
{
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_client.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;
func_cb_client.on_result = test_wolfSSL_SCR_after_resumption_on_result;
func_cb_server.method = wolfTLSv1_2_server_method;
func_cb_server.ctx_ready = test_wolfSSL_SCR_after_resumption_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
if (EXPECT_SUCCESS()) {
func_cb_client.ssl_ready = test_wolfSSL_SCR_after_resumption_ssl_ready;
func_cb_server.on_result = test_wolfSSL_SCR_after_resumption_on_result;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
}
wolfSSL_SESSION_free(test_wolfSSL_SCR_after_resumption_session);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_SCR_after_resumption(void)
{
return TEST_SKIPPED;
}
#endif
static int test_wolfSSL_configure_args(void)
{
EXPECT_DECLS;
#if defined(LIBWOLFSSL_CONFIGURE_ARGS) && defined(HAVE_WC_INTROSPECTION)
ExpectNotNull(wolfSSL_configure_args());
#endif
return EXPECT_RESULT();
}
static int test_dtls_no_extensions(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_DTLS) && defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_NO_TLS12)
WOLFSSL *ssl_s = NULL;
WOLFSSL_CTX *ctx_s = NULL;
struct test_memio_ctx test_ctx;
const byte chNoExtensions[] = {
/* Handshake type */
0x16,
/* Version */
0xfe, 0xff,
/* Epoch */
0x00, 0x00,
/* Seq number */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* Length */
0x00, 0x40,
/* CH type */
0x01,
/* Length */
0x00, 0x00, 0x34,
/* Msg Seq */
0x00, 0x00,
/* Frag offset */
0x00, 0x00, 0x00,
/* Frag length */
0x00, 0x00, 0x34,
/* Version */
0xfe, 0xff,
/* Random */
0x62, 0xfe, 0xbc, 0xfe, 0x2b, 0xfe, 0x3f, 0xeb, 0x03, 0xc4, 0xea, 0x37,
0xe7, 0x47, 0x7e, 0x8a, 0xd9, 0xbf, 0x77, 0x0f, 0x6c, 0xb6, 0x77, 0x0b,
0x03, 0x3f, 0x82, 0x2b, 0x21, 0x64, 0x57, 0x1d,
/* Session Length */
0x00,
/* Cookie Length */
0x00,
/* CS Length */
0x00, 0x0c,
/* CS */
0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x39, 0x00, 0x33,
/* Comp Meths Length */
0x01,
/* Comp Meths */
0x00
/* And finally... no extensions */
};
int i;
#ifdef OPENSSL_EXTRA
int repeats = 2;
#else
int repeats = 1;
#endif
for (i = 0; i < repeats; i++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ssl_s = NULL;
ctx_s = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, NULL, &ctx_s, NULL, &ssl_s,
NULL, wolfDTLS_server_method), 0);
test_memio_clear_buffer(&test_ctx, 0);
ExpectIntEQ(
test_memio_inject_message(&test_ctx, 1,
(const char *)chNoExtensions, sizeof(chNoExtensions)), 0);
#ifdef OPENSSL_EXTRA
if (i > 0) {
ExpectIntEQ(wolfSSL_set_max_proto_version(ssl_s, DTLS1_2_VERSION),
WOLFSSL_SUCCESS);
}
#endif
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Expecting a handshake msg. Either HVR or SH. */
ExpectIntGT(test_ctx.c_len, 0);
ExpectIntEQ(test_ctx.c_buff[0], 0x16);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
}
#endif
return EXPECT_RESULT();
}
static int test_tls_alert_no_server_hello(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12)
WOLFSSL *ssl_c = NULL;
WOLFSSL_CTX *ctx_c = NULL;
struct test_memio_ctx test_ctx;
unsigned char alert_msg[] = { 0x15, 0x03, 0x01, 0x00, 0x02, 0x02, 0x28 };
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ssl_c = NULL;
ctx_c = NULL;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfTLSv1_2_client_method, NULL), 0);
test_memio_clear_buffer(&test_ctx, 1);
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
(const char *)alert_msg, sizeof(alert_msg)), 0);
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(FATAL_ERROR));
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
#endif
return EXPECT_RESULT();
}
static int test_TLSX_CA_NAMES_bad_extension(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
!defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES) && \
defined(OPENSSL_EXTRA) && defined(BUILD_TLS_CHACHA20_POLY1305_SHA256) && \
defined(HAVE_ECC) && !defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
/* This test should only fail (with BUFFER_ERROR) when we actually try to
* parse the CA Names extension. Otherwise it will return other non-related
* errors. If CA Names will be parsed in more configurations, that should
* be reflected in the macro guard above. */
WOLFSSL *ssl_c = NULL;
WOLFSSL_CTX *ctx_c = NULL;
struct test_memio_ctx test_ctx;
/* HRR + SH using TLS_CHACHA20_POLY1305_SHA256 */
const byte shBadCaNamesExt[] = {
0x16, 0x03, 0x04, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0xcf,
0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00,
0x13, 0x94, 0x7e, 0x00, 0x03, 0x0b, 0xf7, 0x03, 0x00, 0x2b, 0x00, 0x02,
0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x19, 0x16, 0x03, 0x03, 0x00,
0x5c, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0x03, 0xcf, 0x21, 0xad, 0x74,
0x00, 0x00, 0x83, 0x3f, 0x3b, 0x80, 0x01, 0xac, 0x65, 0x8c, 0x19, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x02, 0x00, 0x9e, 0x09, 0x1c, 0xe8,
0xa8, 0x09, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00, 0x11, 0x8f, 0x00, 0x00,
0x03, 0x3f, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x13, 0x05,
0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x01, 0xff,
0xff, 0xff, 0xff, 0xfa, 0x0d, 0x00, 0x00, 0x00, 0xad, 0x02
};
const byte shBadCaNamesExt2[] = {
0x16, 0x03, 0x04, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0xcf,
0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e,
0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07,
0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x00, 0x13, 0x03, 0x00, 0x00,
0x13, 0x94, 0x7e, 0x00, 0x03, 0x0b, 0xf7, 0x03, 0x00, 0x2b, 0x00, 0x02,
0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x19, 0x16, 0x03, 0x03, 0x00,
0x5e, 0x02, 0x00, 0x00, 0x3b, 0x03, 0x03, 0x7f, 0xd0, 0x2d, 0xea, 0x6e,
0x53, 0xa1, 0x6a, 0xc9, 0xc8, 0x54, 0xef, 0x75, 0xe4, 0xd9, 0xc6, 0x3e,
0x74, 0xcb, 0x30, 0x80, 0xcc, 0x83, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0x5a, 0x00, 0x13, 0x03, 0x00, 0x00, 0x11, 0x8f, 0x00, 0x00,
0x03, 0x03, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x53, 0x25,
0x00, 0x00, 0x08, 0x00, 0x00, 0x06, 0x00, 0x04, 0x02, 0x05, 0x00, 0x00,
0x0d, 0x00, 0x00, 0x11, 0x00, 0x00, 0x0d, 0x00, 0x2f, 0x00, 0x06, 0x00,
0x04, 0x00, 0x03, 0x30, 0x00, 0x13, 0x94, 0x00, 0x06, 0x00, 0x04, 0x02
};
int i = 0;
for (i = 0; i < 2; i++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfTLSv1_3_client_method, NULL), 0);
switch (i) {
case 0:
test_memio_clear_buffer(&test_ctx, 0);
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
(const char *)shBadCaNamesExt, sizeof(shBadCaNamesExt)), 0);
break;
case 1:
test_memio_clear_buffer(&test_ctx, 0);
ExpectIntEQ(test_memio_inject_message(&test_ctx, 1,
(const char *)shBadCaNamesExt2,
sizeof(shBadCaNamesExt2)), 0);
break;
}
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
#ifndef WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(OUT_OF_ORDER_E));
#else
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WC_NO_ERR_TRACE(BUFFER_ERROR));
#endif
wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_CTX_free(ctx_c);
ctx_c = NULL;
}
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
static void test_dtls_1_0_hvr_downgrade_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
WOLFSSL_SUCCESS);
}
static int test_dtls_1_0_hvr_downgrade(void)
{
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_client.method = wolfDTLS_client_method;
func_cb_server.method = wolfDTLSv1_2_server_method;
func_cb_client.ctx_ready = test_dtls_1_0_hvr_downgrade_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_dtls_1_0_hvr_downgrade(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_SESSION_TICKET)
static WOLFSSL_SESSION* test_session_ticket_no_id_session = NULL;
static void test_session_ticket_no_id_on_result(WOLFSSL* ssl)
{
test_session_ticket_no_id_session = wolfSSL_get1_session(ssl);
AssertNotNull(test_session_ticket_no_id_session);
}
static void test_session_ticket_no_id_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_UseSessionTicket(ctx), WOLFSSL_SUCCESS);
}
static void test_session_ticket_no_id_ssl_ready(WOLFSSL* ssl)
{
test_session_ticket_no_id_session->sessionIDSz = 0;
AssertIntEQ(WOLFSSL_SUCCESS,
wolfSSL_set_session(ssl, test_session_ticket_no_id_session));
}
static int test_session_ticket_no_id(void)
{
/* We are testing an expired (invalid crypto context in out case since the
* ctx changes) session ticket being sent with the session ID being 0
* length. */
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
func_cb_client.on_result = test_session_ticket_no_id_on_result;
func_cb_server.method = wolfTLSv1_2_server_method;
func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
XMEMSET(&func_cb_client, 0, sizeof(func_cb_client));
XMEMSET(&func_cb_server, 0, sizeof(func_cb_server));
func_cb_client.method = wolfTLSv1_2_client_method;
func_cb_client.ctx_ready = test_session_ticket_no_id_ctx_ready;
func_cb_client.ssl_ready = test_session_ticket_no_id_ssl_ready;
func_cb_server.method = wolfTLSv1_2_server_method;
func_cb_server.ctx_ready = test_session_ticket_no_id_ctx_ready;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
wolfSSL_SESSION_free(test_session_ticket_no_id_session);
return EXPECT_RESULT();
}
#else
static int test_session_ticket_no_id(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
static int test_session_ticket_hs_update(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB)
struct test_memio_ctx test_ctx;
struct test_memio_ctx test_ctx2;
struct test_memio_ctx test_ctx3;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_c2 = NULL;
WOLFSSL *ssl_c3 = NULL;
WOLFSSL *ssl_s = NULL;
WOLFSSL *ssl_s2 = NULL;
WOLFSSL *ssl_s3 = NULL;
WOLFSSL_SESSION *sess = NULL;
byte read_data[1];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
XMEMSET(&test_ctx2, 0, sizeof(test_ctx2));
XMEMSET(&test_ctx3, 0, sizeof(test_ctx3));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
/* Generate tickets */
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_SetLoggingPrefix("client");
/* Read the ticket msg */
ExpectIntEQ(wolfSSL_read(ssl_c, read_data, sizeof(read_data)),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
wolfSSL_SetLoggingPrefix(NULL);
ExpectIntEQ(test_memio_setup(&test_ctx2, &ctx_c, &ctx_s, &ssl_c2, &ssl_s2,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectIntEQ(test_memio_setup(&test_ctx3, &ctx_c, &ctx_s, &ssl_c3, &ssl_s3,
wolfTLSv1_3_client_method, wolfTLSv1_3_server_method), 0);
ExpectNotNull(sess = wolfSSL_get1_session(ssl_c));
ExpectIntEQ(wolfSSL_set_session(ssl_c2, sess), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_set_session(ssl_c3, sess), WOLFSSL_SUCCESS);
wolfSSL_SetLoggingPrefix("client");
/* Exchange initial flights for the second connection */
ExpectIntEQ(wolfSSL_connect(ssl_c2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_c2, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
wolfSSL_SetLoggingPrefix(NULL);
wolfSSL_SetLoggingPrefix("server");
ExpectIntEQ(wolfSSL_accept(ssl_s2), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_s2, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
wolfSSL_SetLoggingPrefix(NULL);
/* Complete third connection so that new tickets are exchanged */
ExpectIntEQ(test_memio_do_handshake(ssl_c3, ssl_s3, 10, NULL), 0);
/* Read the ticket msg */
wolfSSL_SetLoggingPrefix("client");
ExpectIntEQ(wolfSSL_read(ssl_c3, read_data, sizeof(read_data)),
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_c3, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
wolfSSL_SetLoggingPrefix(NULL);
/* Complete second connection */
ExpectIntEQ(test_memio_do_handshake(ssl_c2, ssl_s2, 10, NULL), 0);
ExpectIntEQ(wolfSSL_session_reused(ssl_c2), 1);
ExpectIntEQ(wolfSSL_session_reused(ssl_c3), 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_c2);
wolfSSL_free(ssl_c3);
wolfSSL_free(ssl_s);
wolfSSL_free(ssl_s2);
wolfSSL_free(ssl_s3);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
wolfSSL_SESSION_free(sess);
#endif
return EXPECT_RESULT();
}
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
static void test_dtls_downgrade_scr_server_ctx_ready_server(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}
static void test_dtls_downgrade_scr_server_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}
static void test_dtls_downgrade_scr_server_on_result(WOLFSSL* ssl)
{
char testMsg[] = "Message after SCR";
char msgBuf[sizeof(testMsg)];
if (wolfSSL_is_server(ssl)) {
AssertIntEQ(wolfSSL_Rehandshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
AssertIntEQ(wolfSSL_get_error(ssl, -1), WC_NO_ERR_TRACE(APP_DATA_READY));
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
sizeof(testMsg));
}
else {
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
sizeof(testMsg));
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
}
}
static int test_dtls_downgrade_scr_server(void)
{
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_client.method = wolfDTLSv1_2_client_method;
func_cb_server.method = wolfDTLS_server_method;
func_cb_client.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready;
func_cb_server.ctx_ready = test_dtls_downgrade_scr_server_ctx_ready_server;
func_cb_client.on_result = test_dtls_downgrade_scr_server_on_result;
func_cb_server.on_result = test_dtls_downgrade_scr_server_on_result;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_dtls_downgrade_scr_server(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(HAVE_SECURE_RENEGOTIATION)
static void test_dtls_downgrade_scr_ctx_ready(WOLFSSL_CTX* ctx)
{
AssertIntEQ(wolfSSL_CTX_SetMinVersion(ctx, WOLFSSL_DTLSV1_2),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_CTX_UseSecureRenegotiation(ctx), WOLFSSL_SUCCESS);
}
static void test_dtls_downgrade_scr_on_result(WOLFSSL* ssl)
{
char testMsg[] = "Message after SCR";
char msgBuf[sizeof(testMsg)];
if (wolfSSL_is_server(ssl)) {
AssertIntEQ(wolfSSL_Rehandshake(ssl), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
AssertIntEQ(wolfSSL_get_error(ssl, -1), WC_NO_ERR_TRACE(APP_DATA_READY));
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
AssertIntEQ(wolfSSL_Rehandshake(ssl), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
sizeof(testMsg));
}
else {
AssertIntEQ(wolfSSL_write(ssl, testMsg, sizeof(testMsg)),
sizeof(testMsg));
AssertIntEQ(wolfSSL_read(ssl, msgBuf, sizeof(msgBuf)), sizeof(msgBuf));
}
}
static int test_dtls_downgrade_scr(void)
{
EXPECT_DECLS;
callback_functions func_cb_client;
callback_functions func_cb_server;
XMEMSET(&func_cb_client, 0, sizeof(callback_functions));
XMEMSET(&func_cb_server, 0, sizeof(callback_functions));
func_cb_client.doUdp = func_cb_server.doUdp = 1;
func_cb_client.method = wolfDTLS_client_method;
func_cb_server.method = wolfDTLSv1_2_server_method;
func_cb_client.ctx_ready = test_dtls_downgrade_scr_ctx_ready;
func_cb_client.on_result = test_dtls_downgrade_scr_on_result;
func_cb_server.on_result = test_dtls_downgrade_scr_on_result;
test_wolfSSL_client_server_nofail(&func_cb_client, &func_cb_server);
ExpectIntEQ(func_cb_client.return_code, TEST_SUCCESS);
ExpectIntEQ(func_cb_server.return_code, TEST_SUCCESS);
return EXPECT_RESULT();
}
#else
static int test_dtls_downgrade_scr(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
&& !defined(WOLFSSL_NO_TLS12)
static int test_dtls_client_hello_timeout_downgrade_read_cb(WOLFSSL *ssl,
char *data, int sz, void *ctx)
{
static int call_counter = 0;
call_counter++;
(void)ssl;
(void)data;
(void)sz;
(void)ctx;
switch (call_counter) {
case 1:
case 2:
return WOLFSSL_CBIO_ERR_TIMEOUT;
case 3:
return WOLFSSL_CBIO_ERR_WANT_READ;
default:
AssertIntLE(call_counter, 3);
return -1;
}
}
#endif
/* Make sure we don't send acks before getting a server hello */
static int test_dtls_client_hello_timeout_downgrade(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
&& !defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
DtlsRecordLayerHeader* dtlsRH;
size_t len;
byte sequence_number[8];
int i;
for (i = 0; i < 2; i++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLS_client_method, wolfDTLSv1_2_server_method), 0);
if (i == 0) {
/* First time simulate timeout in IO layer */
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* SH flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Drop the SH */
if (EXPECT_SUCCESS()) {
ExpectIntEQ(test_memio_drop_message(&test_ctx, 1, 0), 0);
}
/* Read the remainder of the flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
wolfSSL_SSLSetIORecv(ssl_c,
test_dtls_client_hello_timeout_downgrade_read_cb);
/* CH3 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
wolfSSL_SSLSetIORecv(ssl_c, test_memio_read_cb);
}
else {
/* Second time call wolfSSL_dtls_got_timeout */
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* SH flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Drop the SH */
if (EXPECT_SUCCESS()) {
ExpectIntEQ(test_memio_drop_message(&test_ctx, 1, 0), 0);
}
/* Read the remainder of the flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Quick timeout should be set as we received at least one msg */
ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 1);
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
/* Quick timeout should be cleared after a quick timeout */
/* CH3 */
ExpectIntEQ(wolfSSL_dtls13_use_quick_timeout(ssl_c), 0);
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
}
/* Parse out to make sure we got exactly one ClientHello message */
XMEMSET(&sequence_number, 0, sizeof(sequence_number));
/* Second ClientHello after HVR */
sequence_number[7] = 2;
dtlsRH = (DtlsRecordLayerHeader*)test_ctx.s_buff;
ExpectIntEQ(dtlsRH->type, handshake);
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
sizeof(sequence_number)), 0);
len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
ExpectIntEQ(sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);
/* Connection should be able to continue */
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
ssl_c = NULL;
ssl_s = NULL;
ctx_c = NULL;
ctx_s = NULL;
if (!EXPECT_SUCCESS())
break;
}
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
static int test_dtls_client_hello_timeout_read_cb(WOLFSSL *ssl, char *data,
int sz, void *ctx)
{
static int call_counter = 0;
call_counter++;
(void)ssl;
(void)data;
(void)sz;
(void)ctx;
switch (call_counter) {
case 1:
return WOLFSSL_CBIO_ERR_TIMEOUT;
case 2:
return WOLFSSL_CBIO_ERR_WANT_READ;
default:
AssertIntLE(call_counter, 2);
return -1;
}
}
#endif
/* Make sure we don't send acks before getting a server hello */
static int test_dtls_client_hello_timeout(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
WOLFSSL *ssl_c = NULL;
WOLFSSL_CTX *ctx_c = NULL;
struct test_memio_ctx test_ctx;
DtlsRecordLayerHeader* dtlsRH;
size_t idx;
size_t len;
byte sequence_number[8];
int i;
for (i = 0; i < 2; i++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfDTLSv1_3_client_method, NULL), 0);
if (i == 0) {
/* First time simulate timeout in IO layer */
wolfSSL_SSLSetIORecv(ssl_c, test_dtls_client_hello_timeout_read_cb);
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
}
else {
/* Second time call wolfSSL_dtls_got_timeout */
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
}
/* Parse out to make sure we got exactly two ClientHello messages */
idx = 0;
XMEMSET(&sequence_number, 0, sizeof(sequence_number));
/* First ClientHello */
dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx);
ExpectIntEQ(dtlsRH->type, handshake);
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
sizeof(sequence_number)), 0);
len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
ExpectIntLT(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);
idx += sizeof(DtlsRecordLayerHeader) + len;
/* Second ClientHello */
sequence_number[7] = 1;
dtlsRH = (DtlsRecordLayerHeader*)(test_ctx.s_buff + idx);
ExpectIntEQ(dtlsRH->type, handshake);
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
sizeof(sequence_number)), 0);
len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
ExpectIntEQ(idx + sizeof(DtlsRecordLayerHeader) + len, test_ctx.s_len);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
ssl_c = NULL;
ctx_c = NULL;
if (!EXPECT_SUCCESS())
break;
}
#endif
return EXPECT_RESULT();
}
/* DTLS test when dropping the changed cipher spec message */
static int test_dtls_dropped_ccs(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
&& !defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
DtlsRecordLayerHeader* dtlsRH;
size_t len;
byte data[1];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server ccs + finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
/* Drop the ccs */
dtlsRH = (DtlsRecordLayerHeader*)test_ctx.c_buff;
len = (size_t)((dtlsRH->length[0] << 8) | dtlsRH->length[1]);
ExpectIntEQ(len, 1);
ExpectIntEQ(dtlsRH->type, change_cipher_spec);
if (EXPECT_SUCCESS()) {
ExpectIntEQ(test_memio_drop_message(&test_ctx, 1, 0), 0);
}
/* Client rtx flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
/* Server ccs + finished rtx */
ExpectIntEQ(wolfSSL_read(ssl_s, data, sizeof(data)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client processes finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
&& !defined(WOLFSSL_NO_TLS12)
static int test_dtls_seq_num_downgrade_check_num(byte* ioBuf, int ioBufLen,
byte seq_num)
{
EXPECT_DECLS;
DtlsRecordLayerHeader* dtlsRH;
byte sequence_number[8];
XMEMSET(&sequence_number, 0, sizeof(sequence_number));
ExpectIntGE(ioBufLen, sizeof(*dtlsRH));
dtlsRH = (DtlsRecordLayerHeader*)ioBuf;
ExpectIntEQ(dtlsRH->type, handshake);
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
sequence_number[7] = seq_num;
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
sizeof(sequence_number)), 0);
return EXPECT_RESULT();
}
#endif
/*
* Make sure that we send the correct sequence number after a HelloVerifyRequest
* and after a HelloRetryRequest. This is testing the server side as it is
* operating statelessly and should copy the sequence number of the ClientHello.
*/
static int test_dtls_seq_num_downgrade(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
&& !defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLS_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
test_ctx.s_len, 0), TEST_SUCCESS);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
test_ctx.c_len, 0), TEST_SUCCESS);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.s_buff,
test_ctx.s_len, 1), TEST_SUCCESS);
/* Server first flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_dtls_seq_num_downgrade_check_num(test_ctx.c_buff,
test_ctx.c_len, 1), TEST_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
/**
* Make sure we don't send RSA Signature Hash Algorithms in the
* CertificateRequest when we don't have any such ciphers set.
* @return EXPECT_RESULT()
*/
static int test_certreq_sighash_algos(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_MAX_STRENGTH) && defined(HAVE_ECC) && \
!defined(NO_SHA256) && defined(WOLFSSL_SHA384) && \
defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC) && \
!defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
int idx = 0;
int maxIdx = 0;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
test_ctx.c_ciphers = test_ctx.s_ciphers =
"ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA384";
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c,
caEccCertFile, NULL), WOLFSSL_SUCCESS);
wolfSSL_set_verify(ssl_s, WOLFSSL_VERIFY_PEER, NULL);
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ssl_s, eccKeyFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_certificate_file(ssl_s, eccCertFile,
CERT_FILETYPE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_connect(ssl_c), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_c, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_accept(ssl_s), WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
ExpectIntEQ(wolfSSL_get_error(ssl_s, WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)),
WOLFSSL_ERROR_WANT_READ);
/* Find the CertificateRequest message */
for (idx = 0; idx < test_ctx.c_len && EXPECT_SUCCESS();) {
word16 len;
ExpectIntEQ(test_ctx.c_buff[idx++], handshake);
ExpectIntEQ(test_ctx.c_buff[idx++], SSLv3_MAJOR);
ExpectIntEQ(test_ctx.c_buff[idx++], TLSv1_2_MINOR);
ato16(test_ctx.c_buff + idx, &len);
idx += OPAQUE16_LEN;
if (test_ctx.c_buff[idx] == certificate_request) {
idx++;
/* length */
idx += OPAQUE24_LEN;
/* cert types */
idx += 1 + test_ctx.c_buff[idx];
/* Sig algos */
ato16(test_ctx.c_buff + idx, &len);
idx += OPAQUE16_LEN;
maxIdx = idx + (int)len;
for (; idx < maxIdx && EXPECT_SUCCESS(); idx += OPAQUE16_LEN) {
if (test_ctx.c_buff[idx+1] == ED25519_SA_MINOR ||
test_ctx.c_buff[idx+1] == ED448_SA_MINOR)
ExpectIntEQ(test_ctx.c_buff[idx], NEW_SA_MAJOR);
else
ExpectIntEQ(test_ctx.c_buff[idx+1], ecc_dsa_sa_algo);
}
break;
}
else {
idx += (int)len;
}
}
ExpectIntLT(idx, test_ctx.c_len);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_CRL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
static int test_revoked_loaded_int_cert_ctx_ready1(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_USE_PREVERIFY;
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/extra-crls/ca-int-cert-revoked.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/ca-int.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_revoked_loaded_int_cert_ctx_ready2(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_USE_PREVERIFY;
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/intermediate/ca-int2-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/ca-int2.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/extra-crls/ca-int-cert-revoked.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/ca-int.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
static int test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb(int ret,
WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm, void* ctx)
{
(void)crl;
(void)cm;
(void)ctx;
if (ret == WC_NO_ERR_TRACE(CRL_MISSING))
return 1;
return 0;
}
/* Here we are allowing missing CRL's but want to error out when its revoked */
static int test_revoked_loaded_int_cert_ctx_ready3(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
myVerifyAction = VERIFY_USE_PREVERIFY;
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/ca-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/intermediate/ca-int-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations_ex(ctx,
"./certs/intermediate/ca-int2-cert.pem", NULL, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableCRL(ctx, WOLFSSL_CRL_CHECKALL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_LoadCRLFile(ctx,
"./certs/crl/extra-crls/ca-int-cert-revoked.pem",
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_SetCRL_ErrorCb(ctx,
test_revoked_loaded_int_cert_ctx_ready3_crl_missing_cb, NULL),
WOLFSSL_SUCCESS);
return EXPECT_RESULT();
}
#endif
static int test_revoked_loaded_int_cert(void)
{
EXPECT_DECLS;
#if defined(HAVE_CRL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_CRL_ALLOW_MISSING_CDP)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
struct {
const char* certPemFile;
const char* keyPemFile;
ctx_cb client_ctx_ready;
} test_params[] = {
{"./certs/intermediate/ca-int2-cert.pem",
"./certs/intermediate/ca-int2-key.pem",
test_revoked_loaded_int_cert_ctx_ready1},
{"./certs/intermediate/server-chain.pem",
"./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2},
{"./certs/intermediate/server-chain-short.pem",
"./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready2},
{"./certs/intermediate/server-chain-short.pem",
"./certs/server-key.pem", test_revoked_loaded_int_cert_ctx_ready3},
};
size_t i;
printf("\n");
for (i = 0; i < XELEM_CNT(test_params); i++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
printf("\tTesting with %s...\n", test_params[i].certPemFile);
server_cbf.certPemFile = test_params[i].certPemFile;
server_cbf.keyPemFile = test_params[i].keyPemFile;
client_cbf.ctx_ready = test_params[i].client_ctx_ready;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), -1001);
ExpectIntEQ(client_cbf.last_err, WC_NO_ERR_TRACE(CRL_CERT_REVOKED));
ExpectIntEQ(server_cbf.last_err, WC_NO_ERR_TRACE(FATAL_ERROR));
if (!EXPECT_SUCCESS())
break;
printf("\t%s passed\n", test_params[i].certPemFile);
}
#endif
return EXPECT_RESULT();
}
static int test_dtls13_frag_ch_pq(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
&& defined(WOLFSSL_DTLS_CH_FRAG) && defined(HAVE_LIBOQS)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char *test_str = "test";
int test_str_size;
byte buf[255];
#ifdef WOLFSSL_MLKEM_KYBER
int group = WOLFSSL_KYBER_LEVEL5;
#else
int group = WOLFSSL_ML_KEM_1024;
#endif
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
/* Add in a large post-quantum key share to make the CH long. */
ExpectIntEQ(wolfSSL_set_groups(ssl_c, &group, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, group), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls13_allow_ch_frag(ssl_s, 1), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
#ifdef WOLFSSL_MLKEM_KYBER
ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), "KYBER_LEVEL5");
ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), "KYBER_LEVEL5");
#else
ExpectStrEQ(wolfSSL_get_curve_name(ssl_c), "ML_KEM_1024");
ExpectStrEQ(wolfSSL_get_curve_name(ssl_s), "ML_KEM_1024");
#endif
test_str_size = XSTRLEN("test") + 1;
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
ExpectIntEQ(wolfSSL_read(ssl_s, buf, sizeof(buf)), test_str_size);
ExpectIntEQ(XSTRCMP((char*)buf, test_str), 0);
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, test_str_size), test_str_size);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) \
&& defined(WOLFSSL_DTLS_MTU) && defined(WOLFSSL_DTLS_CH_FRAG) && \
defined(WOLFSSL_AES_256)
static int test_dtls_frag_ch_count_records(byte* b, int len)
{
DtlsRecordLayerHeader* dtlsRH;
int records = 0;
size_t recordLen;
while (len > 0) {
records++;
dtlsRH = (DtlsRecordLayerHeader*)b;
recordLen = (dtlsRH->length[0] << 8) | dtlsRH->length[1];
if (recordLen > (size_t)len)
break;
b += sizeof(DtlsRecordLayerHeader) + recordLen;
len -= sizeof(DtlsRecordLayerHeader) + recordLen;
}
return records;
}
#endif
static int test_dtls_frag_ch(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13) \
&& defined(WOLFSSL_DTLS_MTU) && defined(WOLFSSL_DTLS_CH_FRAG) && \
defined(WOLFSSL_AES_256)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
static unsigned int DUMMY_MTU = 256;
unsigned int len;
unsigned char four_frag_CH[] = {
0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xda, 0x01, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xce, 0xfe, 0xfd, 0xf3, 0x94, 0x01, 0x33, 0x2c, 0xcf, 0x2c, 0x47, 0xb1,
0xe5, 0xa1, 0x7b, 0x19, 0x3e, 0xac, 0x68, 0xdd, 0xe6, 0x17, 0x6b, 0x85,
0xad, 0x5f, 0xfc, 0x7f, 0x6e, 0xf0, 0xb9, 0xe0, 0x2e, 0xca, 0x47, 0x00,
0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x02,
0x7c, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x0d, 0x00, 0x20,
0x00, 0x1e, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02, 0x03, 0x08, 0x06,
0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06, 0x01,
0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00, 0x0c,
0x00, 0x0a, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01, 0x00,
0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x02, 0x39, 0x02, 0x37, 0x00, 0x17,
0x00, 0x41, 0x04, 0x94, 0xdf, 0x36, 0xd7, 0xb3, 0x90, 0x6d, 0x01, 0xa1,
0xe6, 0xed, 0x67, 0xf4, 0xd9, 0x9d, 0x2c, 0xac, 0x57, 0x74, 0xff, 0x19,
0xbe, 0x5a, 0xc9, 0x30, 0x11, 0xb7, 0x2b, 0x59, 0x47, 0x80, 0x7c, 0xa9,
0xb7, 0x31, 0x8c, 0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0xda, 0x01, 0x00, 0x02, 0xdc, 0x00, 0x00, 0x00, 0x00,
0xce, 0x00, 0x00, 0xce, 0x9e, 0x13, 0x74, 0x3b, 0x86, 0xba, 0x69, 0x1f,
0x12, 0xf7, 0xcd, 0x78, 0x53, 0xe8, 0x50, 0x4d, 0x71, 0x3f, 0x4b, 0x4e,
0xeb, 0x3e, 0xe5, 0x43, 0x54, 0x78, 0x17, 0x6d, 0x00, 0x18, 0x00, 0x61,
0x04, 0xd1, 0x99, 0x66, 0x4f, 0xda, 0xc7, 0x12, 0x3b, 0xff, 0xb2, 0xd6,
0x2f, 0x35, 0xb6, 0x17, 0x1f, 0xb3, 0xd0, 0xb6, 0x52, 0xff, 0x97, 0x8b,
0x01, 0xe8, 0xd9, 0x68, 0x71, 0x40, 0x02, 0xd5, 0x68, 0x3a, 0x58, 0xb2,
0x5d, 0xee, 0xa4, 0xe9, 0x5f, 0xf4, 0xaf, 0x3e, 0x30, 0x9c, 0x3e, 0x2b,
0xda, 0x61, 0x43, 0x99, 0x02, 0x35, 0x33, 0x9f, 0xcf, 0xb5, 0xd3, 0x28,
0x19, 0x9d, 0x1c, 0xbe, 0x69, 0x07, 0x9e, 0xfc, 0xe4, 0x8e, 0xcd, 0x86,
0x4a, 0x1b, 0xf0, 0xfc, 0x17, 0x94, 0x66, 0x53, 0xda, 0x24, 0x5e, 0xaf,
0xce, 0xec, 0x62, 0x4c, 0x06, 0xb4, 0x52, 0x94, 0xb1, 0x4a, 0x7a, 0x8c,
0x4f, 0x00, 0x19, 0x00, 0x85, 0x04, 0x00, 0x27, 0xeb, 0x99, 0x49, 0x7f,
0xcb, 0x2c, 0x46, 0x54, 0x2d, 0x93, 0x5d, 0x25, 0x92, 0x58, 0x5e, 0x06,
0xc3, 0x7c, 0xfb, 0x9a, 0xa7, 0xec, 0xcd, 0x9f, 0xe1, 0x6b, 0x2d, 0x78,
0xf5, 0x16, 0xa9, 0x20, 0x52, 0x48, 0x19, 0x0f, 0x1a, 0xd0, 0xce, 0xd8,
0x68, 0xb1, 0x4e, 0x7f, 0x33, 0x03, 0x7d, 0x0c, 0x39, 0xdb, 0x9c, 0x4b,
0xf4, 0xe7, 0xc2, 0xf5, 0xdd, 0x51, 0x9b, 0x03, 0xa8, 0x53, 0x2b, 0xe6,
0x00, 0x15, 0x4b, 0xff, 0xd2, 0xa0, 0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xda, 0x01, 0x00, 0x02, 0xdc, 0x00,
0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0xce, 0x58, 0x30, 0x10, 0x3d, 0x46,
0xcc, 0xca, 0x1a, 0x44, 0xc8, 0x58, 0x9b, 0x27, 0x17, 0x67, 0x31, 0x96,
0x8a, 0x66, 0x39, 0xf4, 0xcc, 0xc1, 0x9f, 0x12, 0x1f, 0x01, 0x30, 0x50,
0x16, 0xd6, 0x89, 0x97, 0xa3, 0x66, 0xd7, 0x99, 0x50, 0x09, 0x6e, 0x80,
0x87, 0xe4, 0xa2, 0x88, 0xae, 0xb4, 0x23, 0x57, 0x2f, 0x12, 0x60, 0xe7,
0x7d, 0x44, 0x2d, 0xad, 0xbe, 0xe9, 0x0d, 0x01, 0x00, 0x01, 0x00, 0xd5,
0xdd, 0x62, 0xee, 0xf3, 0x0e, 0xd9, 0x30, 0x0e, 0x38, 0xf3, 0x48, 0xf4,
0xc9, 0x8f, 0x8c, 0x20, 0xf7, 0xd3, 0xa8, 0xb3, 0x87, 0x3c, 0x98, 0x5d,
0x70, 0xc5, 0x03, 0x76, 0xb7, 0xd5, 0x0b, 0x7b, 0x23, 0x97, 0x6b, 0xe3,
0xb5, 0x18, 0xeb, 0x64, 0x55, 0x18, 0xb2, 0x8a, 0x90, 0x1a, 0x8f, 0x0e,
0x15, 0xda, 0xb1, 0x8e, 0x7f, 0xee, 0x1f, 0xe0, 0x3b, 0xb9, 0xed, 0xfc,
0x4e, 0x3f, 0x78, 0x16, 0x39, 0x95, 0x5f, 0xb7, 0xcb, 0x65, 0x55, 0x72,
0x7b, 0x7d, 0x86, 0x2f, 0x8a, 0xe5, 0xee, 0xf7, 0x57, 0x40, 0xf3, 0xc4,
0x96, 0x4f, 0x11, 0x4d, 0x85, 0xf9, 0x56, 0xfa, 0x3d, 0xf0, 0xc9, 0xa4,
0xec, 0x1e, 0xaa, 0x47, 0x90, 0x53, 0xdf, 0xe1, 0xb7, 0x78, 0x18, 0xeb,
0xdd, 0x0d, 0x89, 0xb7, 0xf6, 0x15, 0x0e, 0x55, 0x12, 0xb3, 0x23, 0x17,
0x0b, 0x59, 0x6f, 0x83, 0x05, 0x6b, 0xa6, 0xf8, 0x6c, 0x3a, 0x9b, 0x1b,
0x50, 0x93, 0x51, 0xea, 0x95, 0x2d, 0x99, 0x96, 0x38, 0x16, 0xfe, 0xfd,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x7e, 0x01, 0x00,
0x02, 0xdc, 0x00, 0x00, 0x00, 0x02, 0x6a, 0x00, 0x00, 0x72, 0x2d, 0x66,
0x3e, 0xf2, 0x36, 0x5a, 0xf2, 0x23, 0x8f, 0x28, 0x09, 0xa9, 0x55, 0x8c,
0x8f, 0xc0, 0x0d, 0x61, 0x98, 0x33, 0x56, 0x87, 0x7a, 0xfd, 0xa7, 0x50,
0x71, 0x84, 0x2e, 0x41, 0x58, 0x00, 0x87, 0xd9, 0x27, 0xe5, 0x7b, 0xf4,
0x6d, 0x84, 0x4e, 0x2e, 0x0c, 0x80, 0x0c, 0xf3, 0x8a, 0x02, 0x4b, 0x99,
0x3a, 0x1f, 0x9f, 0x18, 0x7d, 0x1c, 0xec, 0xad, 0x60, 0x54, 0xa6, 0xa3,
0x2c, 0x82, 0x5e, 0xf8, 0x8f, 0xae, 0xe1, 0xc4, 0x82, 0x7e, 0x43, 0x43,
0xc5, 0x99, 0x49, 0x05, 0xd3, 0xf6, 0xdf, 0xa1, 0xb5, 0x2d, 0x0c, 0x13,
0x2f, 0x1e, 0xb6, 0x28, 0x7c, 0x5c, 0xa1, 0x02, 0x6b, 0x8d, 0xa3, 0xeb,
0xd4, 0x58, 0xe6, 0xa0, 0x7e, 0x6b, 0xaa, 0x09, 0x43, 0x67, 0x71, 0x87,
0xa5, 0xcb, 0x68, 0xf3
};
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
/* Fragment msgs */
ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl_c, DUMMY_MTU), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_dtls_set_mtu(ssl_s, DUMMY_MTU), WOLFSSL_SUCCESS);
/* Add in some key shares to make the CH long */
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP256R1),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP384R1),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_ECC_SECP521R1),
WOLFSSL_SUCCESS);
#ifdef HAVE_FFDHE_2048
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_FFDHE_2048),
WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_FFDHE_3072
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_FFDHE_3072),
WOLFSSL_SUCCESS);
#endif
#ifdef HAVE_FFDHE_4096
ExpectIntEQ(wolfSSL_UseKeyShare(ssl_c, WOLFSSL_FFDHE_4096),
WOLFSSL_SUCCESS);
#endif
ExpectIntEQ(wolfSSL_dtls13_allow_ch_frag(ssl_s, 1), WOLFSSL_SUCCESS);
/* Reject fragmented first CH */
ExpectIntEQ(test_dtls_frag_ch_count_records(four_frag_CH,
sizeof(four_frag_CH)), 4);
len = sizeof(four_frag_CH);
test_memio_clear_buffer(&test_ctx, 0);
while (len > 0 && EXPECT_SUCCESS()) {
unsigned int inj_len = len > DUMMY_MTU ? DUMMY_MTU : len;
unsigned char *idx = four_frag_CH + sizeof(four_frag_CH) - len;
ExpectIntEQ(test_memio_inject_message(&test_ctx, 0, (const char *)idx,
inj_len), 0);
len -= inj_len;
}
ExpectIntEQ(test_ctx.s_len, sizeof(four_frag_CH));
while (test_ctx.s_len > 0 && EXPECT_SUCCESS()) {
int s_len = test_ctx.s_len;
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Fail if we didn't advance the buffer to avoid infinite loops */
ExpectIntLT(test_ctx.s_len, s_len);
}
/* Expect all fragments read */
ExpectIntEQ(test_ctx.s_len, 0);
/* Expect quietly dropping fragmented first CH */
ExpectIntEQ(test_ctx.c_len, 0);
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
/* Disable ECH as it pushes it over our MTU */
wolfSSL_SetEchEnable(ssl_c, 0);
#endif
/* Limit options to make the CH a fixed length */
/* See wolfSSL_parse_cipher_list for reason why we provide 1.3 AND 1.2
* ciphersuite. This is only necessary when building with OPENSSL_EXTRA. */
#ifdef OPENSSL_EXTRA
ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"
":DHE-RSA-AES256-GCM-SHA384"));
#else
ExpectTrue(wolfSSL_set_cipher_list(ssl_c, "TLS13-AES256-GCM-SHA384"));
#endif
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Count records. Expect 1 unfragmented CH */
ExpectIntEQ(test_dtls_frag_ch_count_records(test_ctx.s_buff,
test_ctx.s_len), 1);
/* HRR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Count records. Expect fragmented CH */
ExpectIntGT(test_dtls_frag_ch_count_records(test_ctx.s_buff,
test_ctx.s_len), 1);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
ssl_c = ssl_s = NULL;
ctx_c = ctx_s = NULL;
#endif
return EXPECT_RESULT();
}
static int test_dtls_empty_keyshare_with_cookie(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
unsigned char ch_empty_keyshare_with_cookie[] = {
0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
0x12, 0x01, 0x00, 0x01, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
0x06, 0xfe, 0xfd, 0xfb, 0x8c, 0x9b, 0x28, 0xae, 0x50, 0x1c, 0x4d, 0xf3,
0xb8, 0xcf, 0x4d, 0xd8, 0x7e, 0x93, 0x13, 0x7b, 0x9e, 0xd9, 0xeb, 0xe9,
0x13, 0x4b, 0x0d, 0x7f, 0x2e, 0x43, 0x62, 0x8c, 0xe4, 0x57, 0x79, 0x00,
0x00, 0x00, 0x36, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2c, 0xc0,
0x2b, 0xc0, 0x30, 0xc0, 0x2f, 0x00, 0x9f, 0x00, 0x9e, 0xcc, 0xa9, 0xcc,
0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x28, 0xc0, 0x24, 0xc0,
0x0a, 0xc0, 0x09, 0xc0, 0x14, 0xc0, 0x13, 0x00, 0x6b, 0x00, 0x67, 0x00,
0x39, 0x00, 0x33, 0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0x01, 0x00, 0x00,
0xa6, 0x00, 0x2b, 0x00, 0x03, 0x02, 0xfe, 0xfc, 0x00, 0x2c, 0x00, 0x47,
0x00, 0x45, 0x20, 0xee, 0x4b, 0x17, 0x70, 0x63, 0xa0, 0x4c, 0x82, 0xbf,
0x43, 0x01, 0x7d, 0x8d, 0xc1, 0x1b, 0x4e, 0x9b, 0xa0, 0x3c, 0x53, 0x1f,
0xb7, 0xd1, 0x10, 0x81, 0xa8, 0xdf, 0xdf, 0x8c, 0x7f, 0xf3, 0x11, 0x13,
0x01, 0x02, 0x3d, 0x3b, 0x7d, 0x14, 0x2c, 0x31, 0xb3, 0x60, 0x72, 0x4d,
0xe5, 0x1a, 0xb2, 0xa3, 0x61, 0x77, 0x73, 0x03, 0x40, 0x0e, 0x5f, 0xc5,
0x61, 0x38, 0x43, 0x56, 0x21, 0x4a, 0x95, 0xd5, 0x35, 0xa8, 0x0d, 0x00,
0x0d, 0x00, 0x2a, 0x00, 0x28, 0x06, 0x03, 0x05, 0x03, 0x04, 0x03, 0x02,
0x03, 0xfe, 0x0b, 0xfe, 0x0e, 0xfe, 0xa0, 0xfe, 0xa3, 0xfe, 0xa5, 0x08,
0x06, 0x08, 0x0b, 0x08, 0x05, 0x08, 0x0a, 0x08, 0x04, 0x08, 0x09, 0x06,
0x01, 0x05, 0x01, 0x04, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 0x0a, 0x00,
0x18, 0x00, 0x16, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x15, 0x01,
0x00, 0x02, 0x3a, 0x02, 0x3c, 0x02, 0x3d, 0x2f, 0x3a, 0x2f, 0x3c, 0x2f,
0x3d, 0x00, 0x16, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x00
};
DtlsRecordLayerHeader* dtlsRH;
byte sequence_number[8];
XMEMSET(&sequence_number, 0, sizeof(sequence_number));
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, NULL, &ctx_s, NULL, &ssl_s,
NULL, wolfDTLSv1_3_server_method), 0);
ExpectIntEQ(test_memio_inject_message(&test_ctx, 0,
(const char *)ch_empty_keyshare_with_cookie,
sizeof(ch_empty_keyshare_with_cookie)), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Expect an alert. A plaintext alert should be exactly 15 bytes. */
ExpectIntEQ(test_ctx.c_len, 15);
dtlsRH = (DtlsRecordLayerHeader*)test_ctx.c_buff;
ExpectIntEQ(dtlsRH->type, alert);
ExpectIntEQ(dtlsRH->pvMajor, DTLS_MAJOR);
ExpectIntEQ(dtlsRH->pvMinor, DTLSv1_2_MINOR);
sequence_number[7] = 1;
ExpectIntEQ(XMEMCMP(sequence_number, dtlsRH->sequence_number,
sizeof(sequence_number)), 0);
ExpectIntEQ(dtlsRH->length[0], 0);
ExpectIntEQ(dtlsRH->length[1], 2);
ExpectIntEQ(test_ctx.c_buff[13], alert_fatal);
ExpectIntEQ(test_ctx.c_buff[14], illegal_parameter);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
static int test_dtls_old_seq_number(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) && \
!defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client second flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Modify the sequence number */
{
DtlsRecordLayerHeader* dtlsRH = (DtlsRecordLayerHeader*)test_ctx.s_buff;
XMEMSET(dtlsRH->sequence_number, 0, sizeof(dtlsRH->sequence_number));
}
/* Server second flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Server should not do anything as a pkt was dropped */
ExpectIntEQ(test_ctx.c_len, 0);
ExpectIntEQ(test_ctx.s_len, 0);
/* Trigger rtx */
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_c), WOLFSSL_SUCCESS);
/* Complete connection */
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
static int test_dtls12_missing_finished(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) && \
!defined(WOLFSSL_NO_TLS12)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char test_str[] = "test string";
char test_buf[sizeof(test_str)];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HVR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
/* Let's clear the output */
test_memio_clear_buffer(&test_ctx, 1);
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_s, test_str, sizeof(test_str)),
sizeof(test_str));
/* Client should not error out on a missing finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server rtx second flight with finished */
ExpectIntEQ(wolfSSL_dtls_got_timeout(ssl_s), 1);
/* Client process rest of handshake */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_s, test_str, sizeof(test_str)),
sizeof(test_str));
ExpectIntEQ(wolfSSL_read(ssl_c, test_buf, sizeof(test_buf)),
sizeof(test_str));
ExpectBufEQ(test_buf, test_str, sizeof(test_str));
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
static int test_dtls13_missing_finished_client(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char test_str[] = "test string";
char test_buf[sizeof(test_str)];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HRR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Let's clear the output */
test_memio_clear_buffer(&test_ctx, 1);
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_s, test_str, sizeof(test_str)),
sizeof(test_str));
/* Client second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server should not error out on a missing finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client rtx second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
/* Client */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), 1);
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_s, test_str, sizeof(test_str)),
sizeof(test_str));
ExpectIntEQ(wolfSSL_read(ssl_c, test_buf, sizeof(test_buf)),
sizeof(test_str));
ExpectBufEQ(test_buf, test_str, sizeof(test_str));
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
static int test_dtls13_missing_finished_server(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS13)
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
const char test_str[] = "test string";
char test_buf[sizeof(test_str)];
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* HRR */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* CH2 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Let's clear the output */
test_memio_clear_buffer(&test_ctx, 0);
ExpectFalse(wolfSSL_is_init_finished(ssl_c));
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, sizeof(test_str)),
sizeof(test_str));
/* Server should not error out on a missing finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* Client rtx second flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* Server first flight with finished */
ExpectIntEQ(wolfSSL_negotiate(ssl_s), 1);
/* Let's send some app data */
ExpectIntEQ(wolfSSL_write(ssl_c, test_str, sizeof(test_str)),
sizeof(test_str));
ExpectIntEQ(wolfSSL_read(ssl_s, test_buf, sizeof(test_buf)),
sizeof(test_str));
ExpectBufEQ(test_buf, test_str, sizeof(test_str));
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
static int test_self_signed_stapling_client_v1_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
ExpectIntEQ(wolfSSL_CTX_UseOCSPStapling(ctx, WOLFSSL_CSR_OCSP,
WOLFSSL_CSR_OCSP_USE_NONCE), 1);
return EXPECT_RESULT();
}
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
static int test_self_signed_stapling_client_v2_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP,
WOLFSSL_CSR2_OCSP_USE_NONCE), 1);
return EXPECT_RESULT();
}
static int test_self_signed_stapling_client_v2_multi_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
ExpectIntEQ(wolfSSL_CTX_UseOCSPStaplingV2(ctx, WOLFSSL_CSR2_OCSP_MULTI,
0), 1);
return EXPECT_RESULT();
}
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
static int test_self_signed_stapling_server_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx), 1);
return EXPECT_RESULT();
}
#endif
static int test_self_signed_stapling(void)
{
EXPECT_DECLS;
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
ctx_cb client_ctx;
const char* tls_version;
} params[] = {
#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method,
test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_3 v1" },
#endif
#ifndef WOLFSSL_NO_TLS12
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
test_self_signed_stapling_client_v1_ctx_ready, "TLSv1_2 v1" },
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
test_self_signed_stapling_client_v2_ctx_ready, "TLSv1_2 v2" },
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method,
test_self_signed_stapling_client_v2_multi_ctx_ready,
"TLSv1_2 v2 multi" },
#endif
#endif
};
for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
printf("\nTesting self-signed cert with status request: %s\n",
params[i].tls_version);
client_cbf.method = params[i].client_meth;
client_cbf.ctx_ready = params[i].client_ctx;
server_cbf.method = params[i].server_meth;
server_cbf.certPemFile = "certs/ca-cert.pem";
server_cbf.keyPemFile = "certs/ca-key.pem";
server_cbf.ctx_ready = test_self_signed_stapling_server_ctx_ready;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
}
#endif
return EXPECT_RESULT();
}
static int test_tls_multi_handshakes_one_record(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_NO_TLS12) && !defined(NO_SHA256)
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
RecordLayerHeader* rh = NULL;
byte *len ;
int newRecIdx;
int idx;
byte buff[64 * 1024];
word16 recLen;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLS_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_accept(ssl_s), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
XMEMSET(buff, 0, sizeof(buff));
rh = (RecordLayerHeader*)(test_ctx.c_buff);
len = &rh->length[0];
ato16((const byte*)len, &recLen);
ExpectIntLE(RECORD_HEADER_SZ + recLen, (int)sizeof(buff));
ExpectIntLE(RECORD_HEADER_SZ + recLen, test_ctx.c_len);
if (EXPECT_SUCCESS()) {
XMEMCPY(buff, test_ctx.c_buff, RECORD_HEADER_SZ + recLen);
newRecIdx = idx = RECORD_HEADER_SZ + recLen;
/* Combine server handshake msgs into one record */
while (idx < test_ctx.c_len) {
rh = (RecordLayerHeader*)(test_ctx.c_buff + idx);
len = &rh->length[0];
ato16((const byte*)len, &recLen);
ExpectIntLE(idx + RECORD_HEADER_SZ + recLen, test_ctx.c_len);
ExpectIntLE(newRecIdx + recLen, (int)sizeof(buff));
if (!EXPECT_SUCCESS()) {
break;
}
idx += RECORD_HEADER_SZ;
XMEMCPY(buff + newRecIdx, test_ctx.c_buff + idx,
(size_t)recLen);
newRecIdx += recLen;
idx += recLen;
}
if (EXPECT_SUCCESS()) {
rh = (RecordLayerHeader*)(buff);
len = &rh->length[0];
c16toa((word16)newRecIdx - RECORD_HEADER_SZ, len);
test_memio_clear_buffer(&test_ctx, 1);
test_memio_inject_message(&test_ctx, 1, (const char*)buff,
newRecIdx);
ExpectIntEQ(wolfSSL_connect(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
}
}
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
#endif
return EXPECT_RESULT();
}
static int test_write_dup(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && defined(HAVE_WRITE_DUP)
size_t i, j;
char hiWorld[] = "dup message";
char readData[sizeof(hiWorld) + 5];
struct {
method_provider client_meth;
method_provider server_meth;
const char* version_name;
int version;
} methods[] = {
#ifndef WOLFSSL_NO_TLS12
{wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLS 1.2", WOLFSSL_TLSV1_2},
#endif
#ifdef WOLFSSL_TLS13
{wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLS 1.3", WOLFSSL_TLSV1_3},
#endif
};
struct {
const char* cipher;
int version;
} ciphers[] = {
/* For simplicity the macros are copied from internal.h */
/* TLS 1.2 */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
#ifndef NO_RSA
{"ECDHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2},
#endif
#endif
#if !defined(NO_DH) && !defined(NO_RSA) && !defined(NO_TLS_DH)
{"DHE-RSA-CHACHA20-POLY1305", WOLFSSL_TLSV1_2},
#endif
#endif
#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && \
!defined(NO_RSA) && defined(HAVE_AESGCM) && !defined(NO_TLS_DH)
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
{"DHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2},
#endif
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
{"DHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2},
#endif
#endif
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) \
&& !defined(NO_TLS) && !defined(NO_AES)
#ifdef HAVE_AESGCM
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
#ifndef NO_RSA
{"ECDHE-RSA-AES128-GCM-SHA256", WOLFSSL_TLSV1_2},
#endif
#endif
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
#ifndef NO_RSA
{"ECDHE-RSA-AES256-GCM-SHA384", WOLFSSL_TLSV1_2},
#endif
#endif
#endif
#endif
/* TLS 1.3 */
#ifdef WOLFSSL_TLS13
#ifdef HAVE_AESGCM
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
{"TLS13-AES128-GCM-SHA256", WOLFSSL_TLSV1_3},
#endif
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256)
{"TLS13-AES256-GCM-SHA384", WOLFSSL_TLSV1_3},
#endif
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
#ifndef NO_SHA256
{"TLS13-CHACHA20-POLY1305-SHA256", WOLFSSL_TLSV1_3},
#endif
#endif
#ifdef HAVE_AESCCM
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
{"TLS13-AES128-CCM-SHA256", WOLFSSL_TLSV1_3},
#endif
#endif
#endif
};
for (i = 0; i < XELEM_CNT(methods); i++) {
for (j = 0; j < XELEM_CNT(ciphers) && !EXPECT_FAIL(); j++) {
struct test_memio_ctx test_ctx;
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
WOLFSSL *ssl_c2 = NULL;
if (methods[i].version != ciphers[j].version)
continue;
if (i == 0 && j == 0)
printf("\n");
printf("Testing %s with %s... ", methods[i].version_name,
ciphers[j].cipher);
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
test_ctx.c_ciphers = test_ctx.s_ciphers = ciphers[j].cipher;
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
methods[i].client_meth, methods[i].server_meth), 0);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectNotNull(ssl_c2 = wolfSSL_write_dup(ssl_c));
ExpectIntEQ(wolfSSL_write(ssl_c, hiWorld, sizeof(hiWorld)),
WC_NO_ERR_TRACE(WRITE_DUP_WRITE_E));
ExpectIntEQ(wolfSSL_write(ssl_c2, hiWorld, sizeof(hiWorld)),
sizeof(hiWorld));
ExpectIntEQ(wolfSSL_read(ssl_s, readData, sizeof(readData)),
sizeof(hiWorld));
ExpectIntEQ(wolfSSL_write(ssl_s, hiWorld, sizeof(hiWorld)),
sizeof(hiWorld));
ExpectIntEQ(wolfSSL_read(ssl_c2, readData, sizeof(readData)),
WC_NO_ERR_TRACE(WRITE_DUP_READ_E));
ExpectIntEQ(wolfSSL_read(ssl_c, readData, sizeof(readData)),
sizeof(hiWorld));
if (EXPECT_SUCCESS())
printf("ok\n");
else
printf("failed\n");
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_c2);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
}
}
#endif
return EXPECT_RESULT();
}
static int test_read_write_hs(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(WOLFSSL_NO_TLS12) && !defined(NO_SHA256)
WOLFSSL_CTX *ctx_s = NULL, *ctx_c = NULL;
WOLFSSL *ssl_s = NULL, *ssl_c = NULL;
struct test_memio_ctx test_ctx;
byte test_buffer[16];
unsigned int test;
/* test == 0 : client writes, server reads */
/* test == 1 : server writes, client reads */
for (test = 0; test < 2; test++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method,
wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_set_group_messages(ssl_s), WOLFSSL_SUCCESS);
/* CH -> */
if (test == 0) {
ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
} else {
ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
sizeof(test_buffer)), -1);
}
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* <- SH + SKE + SHD */
if (test == 0) {
ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
sizeof(test_buffer)), -1);
} else {
ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), -1);
}
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_READ);
/* -> CKE + CLIENT FINISHED */
if (test == 0) {
ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
} else {
ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
sizeof(test_buffer)), -1);
}
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
/* abide clang static analyzer */
if (ssl_s != NULL) {
/* disable group message to separate sending of ChangeCipherspec
* from Finished */
ssl_s->options.groupMessages = 0;
}
/* allow writing of CS, but not FINISHED */
test_ctx.c_len = TEST_MEMIO_BUF_SZ - 6;
/* <- CS */
if (test == 0) {
ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
sizeof(test_buffer)), -1);
} else {
ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), -1);
}
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WOLFSSL_ERROR_WANT_WRITE);
/* move CS message where the client can read it */
memmove(test_ctx.c_buff,
(test_ctx.c_buff + TEST_MEMIO_BUF_SZ - 6), 6);
test_ctx.c_len = 6;
/* read CS */
if (test == 0) {
ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), -1);
} else {
ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
sizeof(test_buffer)), -1);
}
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(test_ctx.c_len, 0);
if (test == 0) {
/* send SERVER FINISHED */
ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
sizeof(test_buffer)), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1),
WOLFSSL_ERROR_WANT_READ);
} else {
/* send SERVER FINISHED + App Data */
ExpectIntEQ(wolfSSL_write(ssl_s, "hello", 5), 5);
}
ExpectIntGT(test_ctx.c_len, 0);
/* Send and receive the data */
if (test == 0) {
ExpectIntEQ(wolfSSL_write(ssl_c, "hello", 5), 5);
ExpectIntEQ(wolfSSL_read(ssl_s, test_buffer,
sizeof(test_buffer)), 5);
} else {
ExpectIntEQ(wolfSSL_read(ssl_c, test_buffer,
sizeof(test_buffer)), 5);
}
ExpectBufEQ(test_buffer, "hello", 5);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
ssl_c = ssl_s = NULL;
ctx_c = ctx_s = NULL;
}
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(OPENSSL_EXTRA)
static const char* test_get_signature_nid_siglag;
static int test_get_signature_nid_sig;
static int test_get_signature_nid_hash;
static int test_get_signature_nid_ssl_ready(WOLFSSL* ssl)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_set_cipher_list(ssl, "ALL"), WOLFSSL_SUCCESS);
if (!wolfSSL_is_server(ssl)) {
ExpectIntEQ(wolfSSL_set1_sigalgs_list(ssl,
test_get_signature_nid_siglag), WOLFSSL_SUCCESS);
}
return EXPECT_RESULT();
}
static int test_get_signature_nid_on_hs_client(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
EXPECT_DECLS;
int nid = 0;
(void)ctx;
if (XSTRSTR(wolfSSL_get_cipher(*ssl), "TLS_RSA_") == NULL) {
ExpectIntEQ(SSL_get_peer_signature_type_nid(*ssl, &nid), WOLFSSL_SUCCESS);
ExpectIntEQ(nid, test_get_signature_nid_sig);
ExpectIntEQ(SSL_get_peer_signature_nid(*ssl, &nid), WOLFSSL_SUCCESS);
ExpectIntEQ(nid, test_get_signature_nid_hash);
}
else /* No sigalg info on static ciphersuite */
return TEST_SUCCESS;
return EXPECT_RESULT();
}
static int test_get_signature_nid_on_hs_server(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
EXPECT_DECLS;
int nid = 0;
(void)ctx;
ExpectIntEQ(SSL_get_signature_type_nid(*ssl, &nid), WOLFSSL_SUCCESS);
ExpectIntEQ(nid, test_get_signature_nid_sig);
ExpectIntEQ(SSL_get_signature_nid(*ssl, &nid), WOLFSSL_SUCCESS);
ExpectIntEQ(nid, test_get_signature_nid_hash);
return EXPECT_RESULT();
}
#endif
static int test_get_signature_nid(void)
{
EXPECT_DECLS;
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && defined(OPENSSL_EXTRA)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
size_t i;
#define TGSN_TLS12_RSA(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_2, svrCertFile, svrKeyFile, \
caCertFile }
#define TGSN_TLS12_ECDSA(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_2, eccCertFile, eccKeyFile, \
caEccCertFile }
#define TGSN_TLS13_RSA(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, svrCertFile, svrKeyFile, \
caCertFile }
#define TGSN_TLS13_ECDSA(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, eccCertFile, eccKeyFile, \
caEccCertFile }
#define TGSN_TLS13_ED25519(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, edCertFile, edKeyFile, \
caEdCertFile }
#define TGSN_TLS13_ED448(sigalg, sig_nid, hash_nid) \
{ sigalg, sig_nid, hash_nid, WOLFSSL_TLSV1_3, ed448CertFile, ed448KeyFile, \
caEd448CertFile }
struct {
const char* siglag;
int sig_nid;
int hash_nid;
int tls_ver;
const char* server_cert;
const char* server_key;
const char* client_ca;
} params[] = {
#ifndef NO_RSA
#ifndef NO_SHA256
TGSN_TLS12_RSA("RSA+SHA256", NID_rsaEncryption, NID_sha256),
#ifdef WC_RSA_PSS
TGSN_TLS12_RSA("RSA-PSS+SHA256", NID_rsassaPss, NID_sha256),
TGSN_TLS13_RSA("RSA-PSS+SHA256", NID_rsassaPss, NID_sha256),
#endif
#endif
#ifdef WOLFSSL_SHA512
TGSN_TLS12_RSA("RSA+SHA512", NID_rsaEncryption, NID_sha512),
#ifdef WC_RSA_PSS
TGSN_TLS12_RSA("RSA-PSS+SHA512", NID_rsassaPss, NID_sha512),
TGSN_TLS13_RSA("RSA-PSS+SHA512", NID_rsassaPss, NID_sha512),
#endif
#endif
#endif
#ifdef HAVE_ECC
#ifndef NO_SHA256
TGSN_TLS12_ECDSA("ECDSA+SHA256", NID_X9_62_id_ecPublicKey, NID_sha256),
TGSN_TLS13_ECDSA("ECDSA+SHA256", NID_X9_62_id_ecPublicKey, NID_sha256),
#endif
#endif
#ifdef HAVE_ED25519
TGSN_TLS13_ED25519("ED25519", NID_ED25519, NID_sha512),
#endif
#ifdef HAVE_ED448
TGSN_TLS13_ED448("ED448", NID_ED448, NID_sha512),
#endif
};
/* These correspond to WOLFSSL_SSLV3...WOLFSSL_DTLSV1_3 */
const char* tls_desc[] = {
"SSLv3", "TLSv1.0", "TLSv1.1", "TLSv1.2", "TLSv1.3",
"DTLSv1.0", "DTLSv1.2", "DTLSv1.3"
};
printf("\n");
for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
printf("Testing %s with %s...", tls_desc[params[i].tls_ver],
params[i].siglag);
switch (params[i].tls_ver) {
#ifndef WOLFSSL_NO_TLS12
case WOLFSSL_TLSV1_2:
client_cbf.method = wolfTLSv1_2_client_method;
server_cbf.method = wolfTLSv1_2_server_method;
break;
#endif
#ifdef WOLFSSL_TLS13
case WOLFSSL_TLSV1_3:
client_cbf.method = wolfTLSv1_3_client_method;
server_cbf.method = wolfTLSv1_3_server_method;
break;
#endif
default:
printf("skipping\n");
continue;
}
test_get_signature_nid_siglag = params[i].siglag;
test_get_signature_nid_sig = params[i].sig_nid;
test_get_signature_nid_hash = params[i].hash_nid;
client_cbf.ssl_ready = test_get_signature_nid_ssl_ready;
server_cbf.ssl_ready = test_get_signature_nid_ssl_ready;
client_cbf.on_handshake = test_get_signature_nid_on_hs_client;
server_cbf.on_handshake = test_get_signature_nid_on_hs_server;
server_cbf.certPemFile = params[i].server_cert;
server_cbf.keyPemFile = params[i].server_key;
client_cbf.caPemFile = params[i].client_ca;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
if (EXPECT_SUCCESS())
printf("passed\n");
}
#endif
return EXPECT_RESULT();
}
#ifndef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_SHA256)
static word32 test_tls_cert_store_unchanged_HashCaTable(Signer** caTable)
{
#ifndef NO_MD5
enum wc_HashType hashType = WC_HASH_TYPE_MD5;
#elif !defined(NO_SHA)
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
#elif !defined(NO_SHA256)
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
#else
#error "We need a digest to hash the Signer object"
#endif
byte hashBuf[WC_MAX_DIGEST_SIZE];
wc_HashAlg hash;
size_t i;
AssertIntEQ(wc_HashInit(&hash, hashType), 0);
for (i = 0; i < CA_TABLE_SIZE; i++) {
Signer* cur;
for (cur = caTable[i]; cur != NULL; cur = cur->next)
AssertIntEQ(wc_HashUpdate(&hash, hashType, (byte*)cur,
sizeof(*cur)), 0);
}
AssertIntEQ(wc_HashFinal(&hash, hashType, hashBuf), 0);
AssertIntEQ(wc_HashFree(&hash, hashType), 0);
return MakeWordFromHash(hashBuf);
}
static word32 test_tls_cert_store_unchanged_before_hashes[2];
static size_t test_tls_cert_store_unchanged_before_hashes_idx;
static word32 test_tls_cert_store_unchanged_after_hashes[2];
static size_t test_tls_cert_store_unchanged_after_hashes_idx;
static int test_tls_cert_store_unchanged_ctx_ready(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntNE(test_tls_cert_store_unchanged_before_hashes
[test_tls_cert_store_unchanged_before_hashes_idx++] =
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER |
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
return EXPECT_RESULT();
}
static int test_tls_cert_store_unchanged_ctx_cleanup(WOLFSSL_CTX* ctx)
{
EXPECT_DECLS;
ExpectIntEQ(wolfSSL_CTX_UnloadIntermediateCerts(ctx), WOLFSSL_SUCCESS);
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
[test_tls_cert_store_unchanged_after_hashes_idx++] =
test_tls_cert_store_unchanged_HashCaTable(ctx->cm->caTable), 0);
return EXPECT_RESULT();
}
static int test_tls_cert_store_unchanged_on_hs(WOLFSSL_CTX **ctx, WOLFSSL **ssl)
{
EXPECT_DECLS;
WOLFSSL_CERT_MANAGER* cm;
(void)ssl;
/* WARNING: this approach bypasses the reference counter check in
* wolfSSL_CTX_UnloadIntermediateCerts. It is not recommended as it may
* cause unexpected behaviour when other active connections try accessing
* the caTable. */
ExpectNotNull(cm = wolfSSL_CTX_GetCertManager(*ctx));
ExpectIntEQ(wolfSSL_CertManagerUnloadIntermediateCerts(cm),
WOLFSSL_SUCCESS);
ExpectIntNE(test_tls_cert_store_unchanged_after_hashes
[test_tls_cert_store_unchanged_after_hashes_idx++] =
test_tls_cert_store_unchanged_HashCaTable((*ctx)->cm->caTable), 0);
return EXPECT_RESULT();
}
static int test_tls_cert_store_unchanged_ssl_ready(WOLFSSL* ssl)
{
EXPECT_DECLS;
WOLFSSL_CTX* ctx;
ExpectNotNull(ctx = wolfSSL_get_SSL_CTX(ssl));
return EXPECT_RESULT();
}
#endif
static int test_tls_cert_store_unchanged(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
!defined(NO_SHA256)
test_ssl_cbf client_cbf;
test_ssl_cbf server_cbf;
int i;
for (i = 0; i < 2; i++) {
XMEMSET(&client_cbf, 0, sizeof(client_cbf));
XMEMSET(&server_cbf, 0, sizeof(server_cbf));
test_tls_cert_store_unchanged_before_hashes_idx = 0;
XMEMSET(test_tls_cert_store_unchanged_before_hashes, 0,
sizeof(test_tls_cert_store_unchanged_before_hashes));
test_tls_cert_store_unchanged_after_hashes_idx = 0;
XMEMSET(test_tls_cert_store_unchanged_after_hashes, 0,
sizeof(test_tls_cert_store_unchanged_after_hashes));
client_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
server_cbf.ctx_ready = test_tls_cert_store_unchanged_ctx_ready;
client_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
server_cbf.ssl_ready = test_tls_cert_store_unchanged_ssl_ready;
switch (i) {
case 0:
client_cbf.on_ctx_cleanup =
test_tls_cert_store_unchanged_ctx_cleanup;
server_cbf.on_ctx_cleanup =
test_tls_cert_store_unchanged_ctx_cleanup;
break;
case 1:
client_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
server_cbf.on_handshake = test_tls_cert_store_unchanged_on_hs;
break;
default:
Fail(("Should not enter here"), ("Entered here"));
}
#ifdef WOLFSSL_PEM_TO_DER
client_cbf.certPemFile = "certs/intermediate/client-chain.pem";
server_cbf.certPemFile = "certs/intermediate/server-chain.pem";
#else
client_cbf.certPemFile = "certs/intermediate/client-chain.der";
server_cbf.certPemFile = "certs/intermediate/server-chain.der";
#endif
server_cbf.caPemFile = caCertFile;
ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&client_cbf,
&server_cbf, NULL), TEST_SUCCESS);
ExpectBufEQ(test_tls_cert_store_unchanged_before_hashes,
test_tls_cert_store_unchanged_after_hashes,
sizeof(test_tls_cert_store_unchanged_after_hashes));
}
#endif
return EXPECT_RESULT();
}
#endif /* !WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
static int test_wolfSSL_SendUserCanceled(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES)
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* tls_version;
} params[] = {
#if defined(WOLFSSL_TLS13)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS)
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
};
for (i = 0; i < sizeof(params)/sizeof(*params) && !EXPECT_FAIL(); i++) {
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
printf("Testing %s\n", params[i].tls_version);
XMEMSET(&h, 0, sizeof(h));
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
params[i].client_meth, params[i].server_meth), 0);
/* CH1 */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
ExpectIntEQ(wolfSSL_SendUserCanceled(ssl_s), WOLFSSL_SHUTDOWN_NOT_DONE);
/* Alert closed connection */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_ZERO_RETURN);
/* Last alert will be close notify because user_canceled should be
* followed by a close_notify */
ExpectIntEQ(wolfSSL_get_alert_history(ssl_c, &h), WOLFSSL_SUCCESS);
ExpectIntEQ(h.last_rx.code, close_notify);
ExpectIntEQ(h.last_rx.level, alert_warning);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
}
#endif
return EXPECT_RESULT();
}
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_OCSP) && \
defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
!defined(WOLFSSL_NO_TLS12)
static int test_ocsp_callback_fails_cb(void* ctx, const char* url, int urlSz,
byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
{
(void)ctx;
(void)url;
(void)urlSz;
(void)ocspReqBuf;
(void)ocspReqSz;
(void)ocspRespBuf;
return WOLFSSL_CBIO_ERR_GENERAL;
}
static int test_ocsp_callback_fails(void)
{
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
EXPECT_DECLS;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
wolfTLSv1_2_client_method, wolfTLSv1_2_server_method), 0);
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx_c), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSPStapling(ctx_s), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_UseOCSPStapling(ssl_c, WOLFSSL_CSR_OCSP,0), WOLFSSL_SUCCESS);
/* override URL to avoid exing from SendCertificateStatus because of no AuthInfo on the certificate */
ExpectIntEQ(wolfSSL_CTX_SetOCSP_OverrideURL(ctx_s, "http://dummy.test"), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_EnableOCSP(ctx_s, WOLFSSL_OCSP_NO_NONCE | WOLFSSL_OCSP_URL_OVERRIDE), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_s, caCertFile, 0), WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_SetOCSP_Cb(ssl_s, test_ocsp_callback_fails_cb, NULL, NULL), WOLFSSL_SUCCESS);
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1), WC_NO_ERR_TRACE(OCSP_INVALID_STATUS));
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
return EXPECT_RESULT();
}
#else
static int test_ocsp_callback_fails(void)
{
return TEST_SKIPPED;
}
#endif /* defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(HAVE_OCSP) && \
defined(HAVE_CERTIFICATE_STATUS_REQUEST) */
#ifdef HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES
static int test_wolfSSL_SSLDisableRead_recv(WOLFSSL *ssl, char *buf, int sz,
void *ctx)
{
(void)ssl;
(void)buf;
(void)sz;
(void)ctx;
return WOLFSSL_CBIO_ERR_GENERAL;
}
static int test_wolfSSL_SSLDisableRead(void)
{
EXPECT_DECLS;
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL *ssl_c = NULL;
struct test_memio_ctx test_ctx;
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, NULL, &ssl_c, NULL,
wolfTLS_client_method, NULL), 0);
wolfSSL_SSLSetIORecv(ssl_c, test_wolfSSL_SSLDisableRead_recv);
wolfSSL_SSLDisableRead(ssl_c);
/* Disabling reading should not even go into the IO layer */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), WOLFSSL_ERROR_WANT_READ);
wolfSSL_SSLEnableRead(ssl_c);
/* By enabling reading we should reach the IO that will return an error */
ExpectIntEQ(wolfSSL_negotiate(ssl_c), -1);
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1), SOCKET_ERROR_E);
wolfSSL_free(ssl_c);
wolfSSL_CTX_free(ctx_c);
return EXPECT_RESULT();
}
#else
static int test_wolfSSL_SSLDisableRead(void)
{
EXPECT_DECLS;
return EXPECT_RESULT();
}
#endif
static int test_wolfSSL_inject(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_SHA256)
size_t i;
struct {
method_provider client_meth;
method_provider server_meth;
const char* tls_version;
} params[] = {
#if defined(WOLFSSL_TLS13)
/* With WOLFSSL_TLS13_MIDDLEBOX_COMPAT a short ID will result in an error */
{ wolfTLSv1_3_client_method, wolfTLSv1_3_server_method, "TLSv1_3" },
#ifdef WOLFSSL_DTLS13
{ wolfDTLSv1_3_client_method, wolfDTLSv1_3_server_method, "DTLSv1_3" },
#endif
#endif
#ifndef WOLFSSL_NO_TLS12
{ wolfTLSv1_2_client_method, wolfTLSv1_2_server_method, "TLSv1_2" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_2_client_method, wolfDTLSv1_2_server_method, "DTLSv1_2" },
#endif
#endif
#if !defined(NO_OLD_TLS)
{ wolfTLSv1_1_client_method, wolfTLSv1_1_server_method, "TLSv1_1" },
#ifdef WOLFSSL_DTLS
{ wolfDTLSv1_client_method, wolfDTLSv1_server_method, "DTLSv1_0" },
#endif
#endif
};
for (i = 0; i < XELEM_CNT(params) && !EXPECT_FAIL(); i++) {
WOLFSSL_CTX *ctx_c = NULL;
WOLFSSL_CTX *ctx_s = NULL;
WOLFSSL *ssl_c = NULL;
WOLFSSL *ssl_s = NULL;
struct test_memio_ctx test_ctx;
WOLFSSL_ALERT_HISTORY h;
int rounds;
int hs_c = 0;
int hs_s = 0;
printf("Testing %s\n", params[i].tls_version);
XMEMSET(&h, 0, sizeof(h));
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c, &ssl_s,
params[i].client_meth, params[i].server_meth), 0);
for (rounds = 0; rounds < 10 && EXPECT_SUCCESS(); rounds++) {
if (!hs_c) {
wolfSSL_SetLoggingPrefix("client");
if (wolfSSL_negotiate(ssl_c) != 1) {
ExpectIntEQ(wolfSSL_get_error(ssl_c, -1),
WOLFSSL_ERROR_WANT_READ);
}
else
hs_c = 1;
}
if (!hs_s) {
wolfSSL_SetLoggingPrefix("server");
if (test_ctx.s_len > 0) {
ExpectIntEQ(wolfSSL_inject(ssl_s, test_ctx.s_buff,
test_ctx.s_len), 1);
test_memio_clear_buffer(&test_ctx, 0);
}
if (wolfSSL_negotiate(ssl_s) != 1) {
ExpectIntEQ(wolfSSL_get_error(ssl_s, -1),
WOLFSSL_ERROR_WANT_READ);
}
else
hs_s = 1;
}
if (!hs_c) {
wolfSSL_SetLoggingPrefix("client");
if (test_ctx.c_len > 0) {
ExpectIntEQ(wolfSSL_inject(ssl_c, test_ctx.c_buff,
test_ctx.c_len), 1);
test_memio_clear_buffer(&test_ctx, 1);
}
}
wolfSSL_SetLoggingPrefix(NULL);
}
ExpectIntEQ(hs_c, 1);
ExpectIntEQ(hs_s, 1);
wolfSSL_free(ssl_c);
wolfSSL_free(ssl_s);
wolfSSL_CTX_free(ctx_c);
wolfSSL_CTX_free(ctx_s);
}
#endif
return EXPECT_RESULT();
}
/*----------------------------------------------------------------------------*
| Main
*----------------------------------------------------------------------------*/
int testAll = 1;
int stopOnFail = 0;
TEST_CASE testCases[] = {
TEST_DECL(test_fileAccess),
/*********************************
* wolfcrypt
*********************************/
TEST_DECL(test_ForceZero),
TEST_DECL(test_wolfCrypt_Init),
TEST_DECL(test_wc_LoadStaticMemory_ex),
TEST_DECL(test_wc_LoadStaticMemory_CTX),
TEST_DECL(test_wc_FreeCertList),
/* Locking with Compat Mutex */
TEST_DECL(test_wc_SetMutexCb),
TEST_DECL(test_wc_LockMutex_ex),
/* Digests */
/* test_md2.c */
TEST_MD2_DECLS,
/* test_md4.c */
TEST_MD4_DECLS,
/* test_md5.c */
TEST_MD5_DECLS,
/* test_sha.c */
TEST_SHA_DECLS,
/* test_sha256.c */
TEST_SHA256_DECLS,
TEST_SHA224_DECLS,
/* test_sha512.c */
TEST_SHA512_DECLS,
TEST_SHA512_224_DECLS,
TEST_SHA512_256_DECLS,
TEST_SHA384_DECLS,
/* test_sha3.c */
TEST_SHA3_DECLS,
TEST_SHAKE128_DECLS,
TEST_SHAKE256_DECLS,
/* test_blake.c */
TEST_BLAKE2B_DECLS,
TEST_BLAKE2S_DECLS,
/* test_sm3.c: SM3 Digest */
TEST_SM3_DECLS,
/* test_ripemd.c */
TEST_RIPEMD_DECLS,
/* test_hash.c */
TEST_HASH_DECLS,
/* HMAC */
TEST_HMAC_DECLS,
/* CMAC */
TEST_CMAC_DECLS,
/* Cipher */
/* Triple-DES */
TEST_DES3_DECLS,
/* Chacha20 */
TEST_CHACHA_DECLS,
/* Poly1305 */
TEST_POLY1305_DECLS,
/* Chacha20-Poly1305 */
TEST_CHACHA20_POLY1305_DECLS,
/* Camellia */
TEST_CAMELLIA_DECLS,
/* ARC4 */
TEST_ARC4_DECLS,
/* RC2 */
TEST_RC2_DECLS,
/* AES cipher and GMAC. */
TEST_AES_DECLS,
#if defined(WOLFSSL_AES_EAX) && defined(WOLFSSL_AES_256) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
TEST_AES_EAX_DECLS,
#endif /* WOLFSSL_AES_EAX */
TEST_GMAC_DECLS,
/* Ascon */
TEST_ASCON_DECLS,
/* SM4 cipher */
TEST_SM4_DECLS,
/* wc_encrypt API */
TEST_WC_ENCRYPT_DECLS,
/* RNG tests */
TEST_RANDOM_DECLS,
/* Public key */
/* wolfmath MP API tests */
TEST_WOLFMATH_DECLS,
/* RSA */
TEST_RSA_DECLS,
/* DSA */
TEST_DSA_DECLS,
/* DH */
TEST_DH_DECLS,
/* wolfCrypt ECC tests */
TEST_ECC_DECLS,
/* SM2 elliptic curve */
TEST_SM2_DECLS,
/* Curve25519 */
TEST_CURVE25519_DECLS,
/* ED25519 */
TEST_ED25519_DECLS,
/* Curve448 */
TEST_CURVE448_DECLS,
/* Ed448 */
TEST_ED448_DECLS,
/* Kyber */
TEST_MLKEM_DECLS,
/* Dilithium */
TEST_MLDSA_DECLS,
/* Signature API */
TEST_SIGNATURE_DECLS,
/* ASN */
TEST_ASN_DECLS,
/* PEM and DER APIs. */
TEST_DECL(test_wc_PemToDer),
TEST_DECL(test_wc_AllocDer),
TEST_DECL(test_wc_CertPemToDer),
TEST_DECL(test_wc_KeyPemToDer),
TEST_DECL(test_wc_PubKeyPemToDer),
TEST_DECL(test_wc_PemPubKeyToDer),
TEST_DECL(test_wc_GetPubKeyDerFromCert),
TEST_DECL(test_wc_GetSubjectPubKeyInfoDerFromCert),
TEST_DECL(test_wc_CheckCertSigPubKey),
/* wolfCrypt ASN tests */
TEST_DECL(test_ToTraditional),
TEST_DECL(test_wc_CreateEncryptedPKCS8Key),
TEST_DECL(test_wc_DecryptedPKCS8Key),
TEST_DECL(test_wc_GetPkcs8TraditionalOffset),
/* Certificate */
TEST_DECL(test_wc_SetSubjectRaw),
TEST_DECL(test_wc_GetSubjectRaw),
TEST_DECL(test_wc_SetIssuerRaw),
TEST_DECL(test_wc_SetIssueBuffer),
TEST_DECL(test_wc_SetSubjectKeyId),
TEST_DECL(test_wc_SetSubject),
TEST_DECL(test_CheckCertSignature),
TEST_DECL(test_wc_ParseCert),
TEST_DECL(test_wc_ParseCert_Error),
TEST_DECL(test_MakeCertWithPathLen),
TEST_DECL(test_MakeCertWith0Ser),
TEST_DECL(test_MakeCertWithCaFalse),
TEST_DECL(test_wc_SetKeyUsage),
TEST_DECL(test_wc_SetAuthKeyIdFromPublicKey_ex),
TEST_DECL(test_wc_SetSubjectBuffer),
TEST_DECL(test_wc_SetSubjectKeyIdFromPublicKey_ex),
/* wolfcrypt PKCS#7 */
TEST_PKCS7_DECLS,
TEST_PKCS7_SIGNED_DATA_DECLS,
TEST_PKCS7_ENCRYPTED_DATA_DECLS,
TEST_PKCS7_SIGNED_ENCRYPTED_DATA_DECLS,
TEST_PKCS7_COMPRESSED_DATA_DECLS,
/* wolfCrypt PKCS#12 */
TEST_PKCS12_DECLS,
/*
* test_wolfCrypt_Cleanup needs to come after the above wolfCrypt tests to
* avoid memory leaks.
*/
TEST_DECL(test_wolfCrypt_Cleanup),
TEST_DECL(test_wolfSSL_Init),
/* x509 -- must appear after test_wolfSSL_Init(). */
TEST_X509_DECLS,
TEST_DECL(test_dual_alg_support),
TEST_DECL(test_dual_alg_crit_ext_support),
TEST_DECL(test_dual_alg_ecdsa_mldsa),
/*********************************
* OpenSSL compatibility API tests
*********************************/
/* If at some point a stub get implemented this test should fail indicating
* a need to implement a new test case
*/
TEST_DECL(test_stubs_are_stubs),
/* ASN.1 compatibility API tests */
TEST_OSSL_ASN1_BIT_STRING_DECLS,
TEST_OSSL_ASN1_INTEGER_DECLS,
TEST_OSSL_ASN1_OBJECT_DECLS,
TEST_OSSL_ASN1_STRING_DECLS,
TEST_OSSL_ASN1_TIME_DECLS,
TEST_OSSL_ASN1_TYPE_DECLS,
TEST_SSL_SK_DECLS,
TEST_DECL(test_wolfSSL_lhash),
TEST_DECL(test_wolfSSL_certs),
TEST_DECL(test_wolfSSL_X509_ext_d2i),
TEST_DECL(test_wolfSSL_private_keys),
TEST_SSL_PEM_DECLS,
/* EVP API testing */
TEST_EVP_ENC_DECLS,
TEST_EVP_DIGEST_DECLS,
TEST_EVP_CIPHER_DECLS,
TEST_EVP_PKEY_DECLS,
TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey),
TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey_ecc),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_d2i_PUBKEY),
#endif
TEST_DECL(test_wolfSSL_d2i_and_i2d_DSAparams),
TEST_DECL(test_wolfSSL_i2d_PrivateKey),
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA) && \
!defined(NO_TLS)
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_d2i_PrivateKeys_bio),
#endif /* !NO_BIO */
#endif
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
TEST_DECL(test_wolfSSL_ERR_peek_last_error_line),
#endif
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_ERR_print_errors_cb),
TEST_DECL(test_wolfSSL_GetLoggingCb),
TEST_DECL(test_WOLFSSL_ERROR_MSG),
TEST_DECL(test_wc_ERR_remove_state),
TEST_DECL(test_wc_ERR_print_errors_fp),
#endif
TEST_DECL(test_wolfSSL_configure_args),
TEST_DECL(test_wolfSSL_sk_SSL_CIPHER),
TEST_DECL(test_wolfSSL_set1_curves_list),
TEST_DECL(test_wolfSSL_curves_mismatch),
TEST_DECL(test_wolfSSL_set1_sigalgs_list),
TEST_DECL(test_wolfSSL_OtherName),
TEST_DECL(test_wolfSSL_FPKI),
TEST_DECL(test_wolfSSL_URI),
/* X509 tests */
TEST_OSSL_X509_DECLS,
TEST_OSSL_X509_NAME_DECLS,
TEST_OSSL_X509_EXT_DECLS,
TEST_OSSL_X509_PK_DECLS,
TEST_OSSL_X509_VFY_PARAMS_DECLS,
TEST_OSSL_X509_IO_DECLS,
TEST_OSSL_X509_CRYPTO_DECLS,
TEST_OSSL_X509_ACERT_DECLS,
TEST_OSSL_X509_INFO_DECLS,
TEST_DECL(test_wolfSSL_X509_ALGOR_get0),
TEST_DECL(test_wolfSSL_X509_SEP),
TEST_DECL(test_wolfSSL_X509_CRL),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_X509_print),
TEST_DECL(test_wolfSSL_X509_CRL_print),
#endif
/* X509 Store tests */
TEST_OSSL_X509_STORE_DECLS,
TEST_OSSL_X509_LOOKUP_DECLS,
TEST_DECL(test_GENERAL_NAME_set0_othername),
TEST_DECL(test_RID_GENERAL_NAME_free),
TEST_DECL(test_RID_X509_get_ext_d2i),
TEST_DECL(test_othername_and_SID_ext),
TEST_DECL(test_wolfSSL_dup_CA_list),
/* OpenSSL sk_X509 API test */
TEST_DECL(test_sk_X509),
/* OpenSSL sk_X509_CRL API test */
TEST_DECL(test_sk_X509_CRL),
/* OpenSSL X509 REQ API test */
TEST_DECL(test_wolfSSL_d2i_X509_REQ),
TEST_DECL(test_X509_REQ),
TEST_DECL(test_wolfSSL_X509_REQ_print),
/* RAND compatibility API */
TEST_OSSL_RAND_DECLS,
/* BN compatibility API */
TEST_OSSL_ASN1_BN_DECLS,
/* OpenSSL PKCS5 API test */
TEST_DECL(test_wolfSSL_PKCS5),
/* OpenSSL PKCS8 API test */
TEST_DECL(test_wolfSSL_PKCS8_Compat),
TEST_DECL(test_wolfSSL_PKCS8_d2i),
/* OpenSSL PKCS7 API test */
TEST_OSSL_PKCS7_DECLS,
TEST_OSSL_SMIME_DECLS,
/* OpenSSL PKCS12 API test */
TEST_OSSL_PKCS12_DECLS,
/* Can't memory test as callbacks use Assert. */
TEST_DECL(test_error_queue_per_thread),
TEST_DECL(test_wolfSSL_ERR_put_error),
TEST_DECL(test_wolfSSL_ERR_get_error_order),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_ERR_print_errors),
#endif
TEST_OSSL_OBJ_DECLS,
#ifndef NO_BIO
TEST_OSSL_BIO_DECLS,
#endif
TEST_DECL(test_wolfSSL_check_domain),
TEST_DECL(test_wolfSSL_check_domain_basic),
TEST_DECL(test_wolfSSL_cert_cb),
TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers),
TEST_DECL(test_wolfSSL_ciphersuite_auth),
TEST_DECL(test_wolfSSL_sigalg_info),
/* Can't memory test as tcp_connect aborts. */
TEST_DECL(test_wolfSSL_SESSION),
TEST_DECL(test_wolfSSL_SESSION_expire_downgrade),
TEST_DECL(test_wolfSSL_CTX_sess_set_remove_cb),
TEST_DECL(test_wolfSSL_ticket_keys),
TEST_DECL(test_wolfSSL_sk_GENERAL_NAME),
TEST_DECL(test_wolfSSL_GENERAL_NAME_print),
TEST_DECL(test_wolfSSL_sk_DIST_POINT),
TEST_DECL(test_wolfSSL_verify_mode),
TEST_DECL(test_wolfSSL_verify_depth),
TEST_DECL(test_wolfSSL_verify_result),
TEST_DECL(test_wolfSSL_msg_callback),
TEST_DECL(test_wolfSSL_OCSP_id_get0_info),
TEST_DECL(test_wolfSSL_i2d_OCSP_CERTID),
TEST_DECL(test_wolfSSL_d2i_OCSP_CERTID),
TEST_DECL(test_wolfSSL_OCSP_id_cmp),
TEST_DECL(test_wolfSSL_OCSP_SINGLERESP_get0_id),
TEST_DECL(test_wolfSSL_OCSP_single_get0_status),
TEST_DECL(test_wolfSSL_OCSP_resp_count),
TEST_DECL(test_wolfSSL_OCSP_resp_get0),
TEST_DECL(test_wolfSSL_OCSP_parse_url),
TEST_DECL(test_wolfSSL_OCSP_REQ_CTX),
TEST_DECL(test_wolfSSL_PEM_read),
TEST_DECL(test_wolfSSL_OpenSSL_version),
TEST_DECL(test_wolfSSL_OpenSSL_add_all_algorithms),
TEST_DECL(test_wolfSSL_OPENSSL_hexstr2buf),
TEST_DECL(test_CONF_modules_xxx),
#ifdef OPENSSL_ALL
TEST_DECL(test_wolfSSL_TXT_DB),
TEST_DECL(test_wolfSSL_NCONF),
#endif
TEST_DECL(test_wolfSSL_CRYPTO_memcmp),
TEST_DECL(test_wolfSSL_CRYPTO_get_ex_new_index),
TEST_DECL(test_wolfSSL_SESSION_get_ex_new_index),
TEST_DECL(test_CRYPTO_set_dynlock_xxx),
TEST_DECL(test_CRYPTO_THREADID_xxx),
TEST_DECL(test_ENGINE_cleanup),
/* test the no op functions for compatibility */
TEST_DECL(test_no_op_functions),
/* OpenSSL error API tests */
TEST_DECL(test_ERR_load_crypto_strings),
#ifdef OPENSSL_ALL
TEST_DECL(test_wolfSSL_sk_CIPHER_description),
TEST_DECL(test_wolfSSL_get_ciphers_compat),
TEST_DECL(test_wolfSSL_CTX_ctrl),
#endif /* OPENSSL_ALL */
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA)
TEST_DECL(test_wolfSSL_CTX_use_certificate_ASN1),
#endif /* (OPENSSL_ALL || WOLFSSL_ASIO) && !NO_RSA */
/*********************************
* Crypto API tests
*********************************/
TEST_OSSL_DIGEST_DECLS,
TEST_OSSL_MAC_DECLS,
TEST_OSSL_CIPHER_DECLS,
TEST_OSSL_RSA_DECLS,
TEST_OSSL_DH_DECLS,
#if defined(HAVE_ECC) && !defined(OPENSSL_NO_PK)
TEST_OSSL_EC_DECLS,
#endif
#ifdef OPENSSL_EXTRA
TEST_OSSL_ECX_DECLS,
#endif
TEST_OSSL_DSA_DECLS,
TEST_DECL(test_openssl_generate_key_and_cert),
TEST_DECL(test_wolfSSL_FIPS_mode),
TEST_DECL(test_openssl_FIPS_drbg),
/*********************************
* CertManager API tests
*********************************/
TEST_CERTMAN_DECLS,
TEST_DECL(test_wolfSSL_CheckOCSPResponse),
/*********************************
* SSL/TLS API tests
*********************************/
TEST_DECL(test_wolfSSL_Method_Allocators),
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
TEST_DECL(test_wolfSSL_CTX_new),
#endif
TEST_DECL(test_server_wolfSSL_new),
TEST_DECL(test_client_wolfSSL_new),
#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
!defined(NO_TLS) && \
(!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_FILESYSTEM)
TEST_DECL(test_for_double_Free),
#endif
TEST_DECL(test_wolfSSL_set_options),
TEST_TLS13_DECLS,
TEST_DECL(test_wolfSSL_tmp_dh),
TEST_DECL(test_wolfSSL_ctrl),
TEST_DECL(test_wolfSSL_get0_param),
TEST_DECL(test_wolfSSL_set1_host),
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
(defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
TEST_DECL(test_wolfSSL_set_SSL_CTX),
#endif
TEST_DECL(test_wolfSSL_CTX_get_min_proto_version),
TEST_DECL(test_wolfSSL_security_level),
TEST_DECL(test_wolfSSL_crypto_policy),
TEST_DECL(test_wolfSSL_crypto_policy_certs_and_keys),
TEST_DECL(test_wolfSSL_crypto_policy_tls_methods),
TEST_DECL(test_wolfSSL_crypto_policy_ciphers),
TEST_DECL(test_wolfSSL_SSL_in_init),
TEST_DECL(test_wolfSSL_CTX_set_timeout),
TEST_DECL(test_wolfSSL_set_psk_use_session_callback),
TEST_DECL(test_CONF_CTX_FILE),
TEST_DECL(test_CONF_CTX_CMDLINE),
#if !defined(NO_CERTS) && (!defined(NO_WOLFSSL_CLIENT) || \
!defined(WOLFSSL_NO_CLIENT_AUTH)) && !defined(NO_FILESYSTEM) && \
!defined(WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION) && \
(!defined(NO_RSA) || defined(HAVE_ECC)) && !defined(NO_SHA256)
/* Use the Cert Manager(CM) API to generate the error ASN_SIG_CONFIRM_E */
/* Bad certificate signature tests */
TEST_DECL(test_EccSigFailure_cm),
TEST_DECL(test_RsaSigFailure_cm),
#endif
/* PKCS8 testing */
TEST_DECL(test_wolfSSL_no_password_cb),
TEST_DECL(test_wolfSSL_PKCS8),
TEST_DECL(test_wolfSSL_PKCS8_ED25519),
TEST_DECL(test_wolfSSL_PKCS8_ED448),
#ifdef HAVE_IO_TESTS_DEPENDENCIES
TEST_DECL(test_wolfSSL_get_finished),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_CTX_add_session),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls13),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls13),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls12),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls12),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_tls11),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_add_session_ext_dtls1),
#endif
TEST_DECL(test_SSL_CIPHER_get_xxx),
TEST_DECL(test_wolfSSL_ERR_strings),
TEST_DECL(test_wolfSSL_CTX_set_cipher_list_bytes),
TEST_DECL(test_wolfSSL_set_cipher_list_tls12_keeps_tls13),
TEST_DECL(test_wolfSSL_set_cipher_list_tls13_keeps_tls12),
TEST_DECL(test_wolfSSL_set_cipher_list_tls12_with_version),
TEST_DECL(test_wolfSSL_set_cipher_list_tls13_with_version),
TEST_DECL(test_wolfSSL_CTX_use_certificate),
TEST_DECL(test_wolfSSL_CTX_use_certificate_file),
TEST_DECL(test_wolfSSL_CTX_use_certificate_buffer),
TEST_DECL(test_wolfSSL_use_certificate_buffer),
TEST_DECL(test_wolfSSL_CTX_use_PrivateKey_file),
TEST_DECL(test_wolfSSL_CTX_use_RSAPrivateKey_file),
TEST_DECL(test_wolfSSL_use_RSAPrivateKey_file),
TEST_DECL(test_wolfSSL_CTX_use_PrivateKey),
TEST_DECL(test_wolfSSL_CTX_load_verify_locations),
/* Large number of memory allocations. */
TEST_DECL(test_wolfSSL_CTX_load_system_CA_certs),
TEST_DECL(test_wolfSSL_CTX_add_extra_chain_cert),
#if defined(HAVE_CERT_CHAIN_VALIDATION) && \
!defined(WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION)
TEST_DECL(test_wolfSSL_CertRsaPss),
#endif
TEST_DECL(test_wolfSSL_CTX_load_verify_locations_ex),
TEST_DECL(test_wolfSSL_CTX_load_verify_buffer_ex),
TEST_DECL(test_wolfSSL_CTX_load_verify_chain_buffer_format),
TEST_DECL(test_wolfSSL_CTX_add1_chain_cert),
TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_buffer_format),
TEST_DECL(test_wolfSSL_CTX_use_certificate_chain_file_format),
TEST_DECL(test_wolfSSL_use_certificate_chain_file),
TEST_DECL(test_wolfSSL_CTX_trust_peer_cert),
TEST_DECL(test_wolfSSL_CTX_LoadCRL),
TEST_DECL(test_wolfSSL_CTX_LoadCRL_largeCRLnum),
TEST_DECL(test_wolfSSL_crl_update_cb),
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_file),
TEST_DECL(test_wolfSSL_CTX_SetTmpDH_buffer),
TEST_DECL(test_wolfSSL_CTX_SetMinMaxDhKey_Sz),
TEST_DECL(test_wolfSSL_CTX_der_load_verify_locations),
TEST_DECL(test_wolfSSL_CTX_enable_disable),
TEST_DECL(test_wolfSSL_CTX_ticket_API),
TEST_DECL(test_wolfSSL_SetTmpDH_file),
TEST_DECL(test_wolfSSL_SetTmpDH_buffer),
TEST_DECL(test_wolfSSL_SetMinMaxDhKey_Sz),
TEST_DECL(test_SetTmpEC_DHE_Sz),
TEST_DECL(test_wolfSSL_CTX_get0_privatekey),
#ifdef WOLFSSL_DTLS
TEST_DECL(test_wolfSSL_DtlsUpdateWindow),
TEST_DECL(test_wolfSSL_DTLS_fragment_buckets),
#endif
TEST_DECL(test_wolfSSL_dtls_set_mtu),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_dtls_plaintext),
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
TEST_DECL(test_wolfSSL_read_write),
TEST_DECL(test_wolfSSL_read_write_ex),
/* Can't memory test as server hangs if client fails before second connect.
*/
TEST_DECL(test_wolfSSL_reuse_WOLFSSLobj),
TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_1),
TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_2),
TEST_DECL(test_wolfSSL_CTX_verifyDepth_ServerClient_3),
TEST_DECL(test_wolfSSL_CTX_set_cipher_list),
/* Can't memory test as server hangs. */
TEST_DECL(test_wolfSSL_dtls_export),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_tls_export),
#endif
TEST_DECL(test_wolfSSL_dtls_export_peers),
TEST_DECL(test_wolfSSL_SetMinVersion),
TEST_DECL(test_wolfSSL_CTX_SetMinVersion),
/* wolfSSL handshake APIs. */
TEST_DECL(test_wolfSSL_CTX_get0_set1_param),
TEST_DECL(test_wolfSSL_a2i_IPADDRESS),
TEST_DECL(test_wolfSSL_BUF),
TEST_DECL(test_wolfSSL_set_tlsext_status_type),
TEST_DECL(test_wolfSSL_get_client_ciphers),
/* Can't memory test as server hangs. */
TEST_DECL(test_wolfSSL_CTX_set_client_CA_list),
TEST_DECL(test_wolfSSL_CTX_add_client_CA),
TEST_DECL(test_wolfSSL_CTX_set_srp_username),
TEST_DECL(test_wolfSSL_CTX_set_srp_password),
TEST_DECL(test_wolfSSL_CTX_set_keylog_callback),
TEST_DECL(test_wolfSSL_CTX_get_keylog_callback),
TEST_DECL(test_wolfSSL_Tls12_Key_Logging_test),
/* Can't memory test as server hangs. */
TEST_DECL(test_wolfSSL_Tls13_Key_Logging_test),
TEST_DECL(test_wolfSSL_Tls13_postauth),
TEST_DECL(test_wolfSSL_set_ecdh_auto),
TEST_DECL(test_wolfSSL_CTX_set_ecdh_auto),
TEST_DECL(test_wolfSSL_set_minmax_proto_version),
TEST_DECL(test_wolfSSL_CTX_set_max_proto_version),
TEST_DECL(test_wolfSSL_THREADID_hash),
/* TLS extensions tests */
#ifdef HAVE_IO_TESTS_DEPENDENCIES
#ifdef HAVE_SNI
TEST_DECL(test_wolfSSL_UseSNI_params),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_UseSNI_connection),
TEST_DECL(test_wolfSSL_SNI_GetFromBuffer),
#endif /* HAVE_SNI */
#endif
TEST_DECL(test_wolfSSL_UseTrustedCA),
TEST_DECL(test_wolfSSL_UseMaxFragment),
TEST_DECL(test_wolfSSL_UseTruncatedHMAC),
TEST_DECL(test_wolfSSL_UseSupportedCurve),
#if defined(HAVE_ALPN) && defined(HAVE_IO_TESTS_DEPENDENCIES)
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_UseALPN_connection),
TEST_DECL(test_wolfSSL_UseALPN_params),
#endif
#ifdef HAVE_ALPN_PROTOS_SUPPORT
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_set_alpn_protos),
#endif
TEST_DECL(test_tls_ems_downgrade),
TEST_DECL(test_wolfSSL_DisableExtendedMasterSecret),
TEST_DECL(test_certificate_authorities_certificate_request),
TEST_DECL(test_certificate_authorities_client_hello),
TEST_DECL(test_wolfSSL_wolfSSL_UseSecureRenegotiation),
TEST_DECL(test_wolfSSL_SCR_Reconnect),
TEST_DECL(test_tls_ext_duplicate),
TEST_DECL(test_tls_bad_legacy_version),
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) && \
defined(HAVE_IO_TESTS_DEPENDENCIES)
TEST_DECL(test_wolfSSL_Tls13_ECH_params),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_Tls13_ECH),
TEST_DECL(test_wolfSSL_Tls13_ECH_HRR),
#endif
TEST_DECL(test_wolfSSL_X509_TLS_version_test_1),
TEST_DECL(test_wolfSSL_X509_TLS_version_test_2),
/* OCSP Stapling */
TEST_DECL(test_wolfSSL_UseOCSPStapling),
TEST_DECL(test_wolfSSL_UseOCSPStaplingV2),
TEST_DECL(test_self_signed_stapling),
TEST_DECL(test_ocsp_callback_fails),
/* Multicast */
TEST_DECL(test_wolfSSL_mcast),
TEST_DECL(test_wolfSSL_read_detect_TCP_disconnect),
TEST_DECL(test_wolfSSL_msgCb),
TEST_DECL(test_wolfSSL_either_side),
TEST_DECL(test_wolfSSL_DTLS_either_side),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_dtls_fragments),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_dtls_AEAD_limit),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_ignore_alert_before_cookie),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_dtls_bad_record),
/* Uses Assert in handshake callback. */
TEST_DECL(test_wolfSSL_dtls_stateless),
TEST_DECL(test_generate_cookie),
#ifndef NO_BIO
TEST_OSSL_BIO_TLS_DECLS,
#endif
#if defined(HAVE_PK_CALLBACKS) && !defined(WOLFSSL_NO_TLS12)
TEST_DECL(test_DhCallbacks),
#endif
#if defined(HAVE_KEYING_MATERIAL) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
TEST_DECL(test_export_keying_material),
#endif
/* Can't memory test as client/server Asserts in thread. */
TEST_DECL(test_ticket_and_psk_mixing),
/* Can't memory test as client/server Asserts in thread. */
TEST_DECL(test_prioritize_psk),
/* Can't memory test as client/server hangs. */
TEST_DECL(test_wc_CryptoCb),
/* Can't memory test as client/server hangs. */
TEST_DECL(test_wolfSSL_CTX_StaticMemory),
#if !defined(NO_FILESYSTEM) && \
defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
#ifdef WOLFSSL_DTLS_NO_HVR_ON_RESUME
TEST_DECL(test_wolfSSL_dtls_stateless_resume),
#endif /* WOLFSSL_DTLS_NO_HVR_ON_RESUME */
#ifdef HAVE_MAX_FRAGMENT
TEST_DECL(test_wolfSSL_dtls_stateless_maxfrag),
#endif /* HAVE_MAX_FRAGMENT */
#ifndef NO_RSA
TEST_DECL(test_wolfSSL_dtls_stateless2),
#if !defined(NO_OLD_TLS)
TEST_DECL(test_wolfSSL_dtls_stateless_downgrade),
#endif /* !defined(NO_OLD_TLS) */
#endif /* ! NO_RSA */
#endif /* defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12) && \
* !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) */
TEST_DECL(test_wolfSSL_CTX_set_ciphersuites),
TEST_DECL(test_wolfSSL_CRL_CERT_REVOKED_alert),
TEST_DECL(test_TLS_13_ticket_different_ciphers),
TEST_DECL(test_WOLFSSL_dtls_version_alert),
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) && defined(HAVE_SESSION_TICKET) \
&& defined(WOLFSSL_TLS13) && \
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
TEST_DECL(test_ticket_nonce_malloc),
#endif
TEST_DECL(test_ticket_ret_create),
TEST_DECL(test_wrong_cs_downgrade),
TEST_DECL(test_extra_alerts_wrong_cs),
TEST_DECL(test_extra_alerts_skip_hs),
TEST_DECL(test_extra_alerts_bad_psk),
TEST_DECL(test_multiple_shutdown_nonblocking),
/* Can't memory test as client/server Asserts. */
TEST_DECL(test_harden_no_secure_renegotiation),
TEST_DECL(test_override_alt_cert_chain),
TEST_DECL(test_rpk_set_xxx_cert_type),
TEST_DECL(test_dtls13_bad_epoch_ch),
TEST_DECL(test_short_session_id),
TEST_DECL(test_wolfSSL_dtls13_null_cipher),
/* Can't memory test as client/server hangs. */
TEST_DECL(test_dtls_msg_from_other_peer),
TEST_DECL(test_dtls_ipv6_check),
TEST_DECL(test_wolfSSL_SCR_after_resumption),
TEST_DECL(test_dtls_no_extensions),
TEST_DECL(test_tls_alert_no_server_hello),
TEST_DECL(test_TLSX_CA_NAMES_bad_extension),
TEST_DECL(test_dtls_1_0_hvr_downgrade),
TEST_DECL(test_session_ticket_no_id),
TEST_DECL(test_session_ticket_hs_update),
TEST_DECL(test_dtls_downgrade_scr_server),
TEST_DECL(test_dtls_downgrade_scr),
TEST_DECL(test_dtls_client_hello_timeout_downgrade),
TEST_DECL(test_dtls_client_hello_timeout),
TEST_DECL(test_dtls_dropped_ccs),
TEST_DECL(test_dtls_seq_num_downgrade),
TEST_DECL(test_certreq_sighash_algos),
TEST_DECL(test_revoked_loaded_int_cert),
TEST_DECL(test_dtls_frag_ch),
TEST_DECL(test_dtls13_frag_ch_pq),
TEST_DECL(test_dtls_empty_keyshare_with_cookie),
TEST_DECL(test_dtls_old_seq_number),
TEST_DECL(test_dtls12_missing_finished),
TEST_DECL(test_dtls13_missing_finished_client),
TEST_DECL(test_dtls13_missing_finished_server),
TEST_DTLS_DECLS,
TEST_DECL(test_tls_multi_handshakes_one_record),
TEST_DECL(test_write_dup),
TEST_DECL(test_read_write_hs),
TEST_DECL(test_get_signature_nid),
#ifndef WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION
TEST_DECL(test_tls_cert_store_unchanged),
#endif
TEST_DECL(test_wolfSSL_SendUserCanceled),
TEST_DECL(test_wolfSSL_SSLDisableRead),
TEST_DECL(test_wolfSSL_inject),
TEST_DECL(test_ocsp_status_callback),
TEST_DECL(test_ocsp_basic_verify),
TEST_DECL(test_ocsp_response_parsing),
TEST_DECL(test_ocsp_certid_enc_dec),
TEST_DECL(test_ocsp_tls_cert_cb),
TEST_TLS_DECLS,
TEST_DECL(test_wc_DhSetNamedKey),
/* This test needs to stay at the end to clean up any caches allocated. */
TEST_DECL(test_wolfSSL_Cleanup)
};
#define TEST_CASE_CNT (int)(sizeof(testCases) / sizeof(*testCases))
static void TestSetup(void)
{
/* Stub, for now. Add common test setup code here. */
}
static void TestCleanup(void)
{
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
/* Clear any errors added to the error queue during the test run. */
wolfSSL_ERR_clear_error();
#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */
}
void ApiTest_StopOnFail(void)
{
stopOnFail = 1;
}
/* Print out all API test cases with numeric identifier.
*/
void ApiTest_PrintTestCases(void)
{
int i;
const char* lastGroup = NULL;
printf("All Test Cases:\n");
for (i = 0; i < TEST_CASE_CNT; i++) {
if ((lastGroup != NULL) && ((testCases[i].group == NULL) ||
XSTRCMP(testCases[i].group, lastGroup) != 0)) {
printf("End Group : %s\n", lastGroup);
}
if ((testCases[i].group != NULL) && ((lastGroup == NULL) ||
XSTRCMP(testCases[i].group, lastGroup) != 0)) {
printf("Begin Group: %s\n", testCases[i].group);
}
lastGroup = testCases[i].group;
printf("%3d: %s\n", i + 1, testCases[i].name);
}
}
/* Print out all API group names.
*/
void ApiTest_PrintGroups(void)
{
int i;
const char* lastGroup = NULL;
printf("All Groups:\n");
for (i = 0; i < TEST_CASE_CNT; i++) {
if ((testCases[i].group != NULL) && ((lastGroup == NULL) ||
XSTRCMP(testCases[i].group, lastGroup) != 0)) {
printf(" %s\n", testCases[i].group);
}
lastGroup = testCases[i].group;
}
}
/* Add test case with group name to the list to run.
*
* @param [in] name Group name of test case to run.
* @return 0 on success.
* @return BAD_FUNC_ARG when group name does not select any tests.
*/
int ApiTest_RunGroup(char* name)
{
int i;
int cnt = 0;
for (i = 0; i < TEST_CASE_CNT; i++) {
if ((testCases[i].group != NULL) &&
(XSTRCMP(testCases[i].group, name) == 0)) {
testAll = 0;
testCases[i].run = 1;
cnt++;
}
}
if (cnt == 0) {
printf("Group name not found: %s\n", name);
printf("Use --groups to see all test group names.\n");
return BAD_FUNC_ARG;
}
return 0;
}
/* Add test case with index to the list to run.
*
* @param [in] idx Index of test case to run starting at 1.
* @return 0 on success.
* @return BAD_FUNC_ARG when index is out of range of test case identifiers.
*/
int ApiTest_RunIdx(int idx)
{
if (idx < 1 || idx > TEST_CASE_CNT) {
printf("Index out of range (1 - %d): %d\n", TEST_CASE_CNT, idx);
return BAD_FUNC_ARG;
}
testAll = 0;
testCases[idx-1].run = 1;
return 0;
}
/* Add test cases with part of the name to the list to run.
*
* @param [in] name Part of the name of test cases to run.
* @return 0 on success.
* @return BAD_FUNC_ARG when name is not a known test case name.
*/
int ApiTest_RunPartName(char* name)
{
int i;
int cnt = 0;
for (i = 0; i < TEST_CASE_CNT; i++) {
if (XSTRSTR(testCases[i].name, name) != NULL) {
cnt++;
testAll = 0;
testCases[i].run = 1;
}
}
if (cnt > 0)
return 0;
printf("Not found a test case with: %s\n", name);
printf("Use --list to see all test case names.\n");
return BAD_FUNC_ARG;
}
/* Add test case with name to the list to run.
*
* @param [in] name Name of test case to run.
* @return 0 on success.
* @return BAD_FUNC_ARG when name is not a known test case name.
*/
int ApiTest_RunName(char* name)
{
int i;
for (i = 0; i < TEST_CASE_CNT; i++) {
if (XSTRCMP(testCases[i].name, name) == 0) {
testAll = 0;
testCases[i].run = 1;
return 0;
}
}
printf("Test case name not found: %s\n", name);
printf("Use --list to see all test case names.\n");
return BAD_FUNC_ARG;
}
/* Converts the result code to a string.
*
* @param [in] res Test result code.
* @return String describing test result.
*/
static const char* apitest_res_string(int res)
{
const char* str = "invalid result";
switch (res) {
case TEST_SUCCESS:
str = "passed";
break;
case TEST_FAIL:
str = "failed";
break;
case TEST_SKIPPED:
str = "skipped";
break;
}
return str;
}
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
static double gettime_secs(void)
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__))
{
/* there's no gettimeofday for Windows, so we'll use system time */
#define EPOCH_DIFF 11644473600LL
FILETIME currentFileTime;
ULARGE_INTEGER uli = { 0, 0 };
#if defined(__WATCOMC__)
GetSystemTimeAsFileTime(&currentFileTime);
#else
GetSystemTimePreciseAsFileTime(&currentFileTime);
#endif
uli.LowPart = currentFileTime.dwLowDateTime;
uli.HighPart = currentFileTime.dwHighDateTime;
/* Convert to seconds since Unix epoch */
return (double)((uli.QuadPart - (EPOCH_DIFF * 10000000)) / 10000000.0);
}
#else
{
struct timeval tv;
LIBCALL_CHECK_RET(gettimeofday(&tv, 0));
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
#endif
#endif
int ApiTest(void)
{
int i;
int ret;
int res = 0;
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
double timeDiff;
#endif
int passed = 0;
int skipped = 0;
int failed = 0;
printf(" Begin API Tests\n");
fflush(stdout);
/* we must perform init and cleanup if not all tests are running */
if (!testAll) {
#ifdef WOLFCRYPT_ONLY
if (wolfCrypt_Init() != 0) {
printf("wolfCrypt Initialization failed\n");
res = 1;
}
#else
if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
printf("wolfSSL Initialization failed\n");
res = 1;
}
#endif
}
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
if (res == 0) {
if (create_tmp_dir(tmpDirName, sizeof(tmpDirName) - 1) == NULL) {
printf("failed to create tmp dir\n");
res = 1;
}
else {
tmpDirNameSet = 1;
}
}
#endif
if (res == 0) {
const char* lastGroup = NULL;
for (i = 0; i < TEST_CASE_CNT; ++i) {
EXPECT_DECLS;
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
currentTestName = testCases[i].name;
#endif
/* When not testing all cases then skip if not marked for running.
*/
if (!testAll && !testCases[i].run) {
continue;
}
TestSetup();
if ((lastGroup != NULL) && ((testCases[i].group == NULL) ||
XSTRCMP(testCases[i].group, lastGroup) != 0)) {
printf(" End Group : %s\n", lastGroup);
}
if ((testCases[i].group != NULL) && ((lastGroup == NULL) ||
XSTRCMP(testCases[i].group, lastGroup) != 0)) {
printf(" Begin Group: %s\n", testCases[i].group);
}
lastGroup = testCases[i].group;
printf(" %4d: %-51s:", i + 1, testCases[i].name);
fflush(stdout);
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
timeDiff = gettime_secs();
#endif
ret = testCases[i].func();
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
timeDiff = gettime_secs() - timeDiff;
#endif
#ifndef WOLFSSL_UNIT_TEST_NO_TIMING
if (ret != TEST_SKIPPED) {
printf(" %s (%9.5lf)\n", apitest_res_string(ret), timeDiff);
}
else
#endif
{
printf(" %s\n", apitest_res_string(ret));
}
fflush(stdout);
/* if return code is < 0 and not skipped then assert error */
Expect((ret > 0 || ret == TEST_SKIPPED),
("Test failed\n"),
("ret %d", ret));
testCases[i].fail = ((ret <= 0) && (ret != TEST_SKIPPED));
res |= ((ret <= 0) && (ret != TEST_SKIPPED));
if (testCases[i].fail)
failed++;
else if (ret == TEST_SKIPPED)
skipped++;
else
passed++;
TestCleanup();
if (testCases[i].fail && stopOnFail) {
testAll = 0;
break;
}
}
if (lastGroup != NULL) {
printf(" End Group : %s\n", lastGroup);
}
}
#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) \
&& (defined(NO_MAIN_DRIVER) || defined(HAVE_STACK_SIZE))
wc_ecc_fp_free(); /* free per thread cache */
#endif
if (!testAll) {
#ifdef WOLFCRYPT_ONLY
wolfCrypt_Cleanup();
#else
wolfSSL_Cleanup();
#endif
}
(void)testDevId;
if (res != 0) {
printf("\nFAILURES:\n");
for (i = 0; i < TEST_CASE_CNT; ++i) {
if (testCases[i].fail) {
printf(" %3d: %s\n", i + 1, testCases[i].name);
}
}
printf("\n");
fflush(stdout);
}
#ifdef WOLFSSL_DUMP_MEMIO_STREAM
if (tmpDirNameSet) {
printf("\nBinary dumps of the memio streams can be found in the\n"
"%s directory. This can be imported into\n"
"Wireshark by transforming the file with\n"
"\tod -Ax -tx1 -v stream.dump > stream.dump.hex\n"
"And then loading test_output.dump.hex into Wireshark using\n"
"the \"Import from Hex Dump...\" option and selecting the\n"
"TCP encapsulation option.\n", tmpDirName);
}
#endif
printf(" End API Tests\n");
printf(" Failed/Skipped/Passed/All: %d/%d/%d/%d\n", failed, skipped, passed,
failed + skipped + passed);
fflush(stdout);
return res;
}