mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-02-05 03:35:08 +01:00
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.
32339 lines
1.1 MiB
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(¤tFileTime);
|
|
#else
|
|
GetSystemTimePreciseAsFileTime(¤tFileTime);
|
|
#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;
|
|
}
|