2299 lines
70 KiB
C
2299 lines
70 KiB
C
/* api.c API unit tests
|
|
*
|
|
* Copyright (C) 2006-2016 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 2 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
|
|
*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Includes
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <wolfssl/wolfcrypt/settings.h>
|
|
|
|
#if defined(WOLFSSL_STATIC_MEMORY)
|
|
#include <wolfssl/wolfcrypt/memory.h>
|
|
#endif /* WOLFSSL_STATIC_MEMORY */
|
|
#ifdef HAVE_ECC
|
|
#include <wolfssl/wolfcrypt/ecc.h> /* wc_ecc_fp_free */
|
|
#endif
|
|
#include <wolfssl/error-ssl.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <wolfssl/ssl.h> /* compatibility layer */
|
|
#include <wolfssl/test.h>
|
|
#include <tests/unit.h>
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
#include <wolfssl/openssl/ssl.h>
|
|
#include <wolfssl/openssl/pkcs12.h>
|
|
#ifndef NO_DES3
|
|
#include <wolfssl/openssl/des.h>
|
|
#endif
|
|
#endif /* OPENSSL_EXTRA */
|
|
|
|
/* enable testing buffer load functions */
|
|
#ifndef USE_CERT_BUFFERS_2048
|
|
#define USE_CERT_BUFFERS_2048
|
|
#endif
|
|
#include <wolfssl/certs_test.h>
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Constants
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#define TEST_SUCCESS (1)
|
|
#define TEST_FAIL (0)
|
|
|
|
#define testingFmt " %s:"
|
|
#define resultFmt " %s\n"
|
|
static const char* passed = "passed";
|
|
static const char* failed = "failed";
|
|
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
static const char* bogusFile =
|
|
#ifdef _WIN32
|
|
"NUL"
|
|
#else
|
|
"/dev/null"
|
|
#endif
|
|
;
|
|
#endif
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Setup
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
static int test_wolfSSL_Init(void)
|
|
{
|
|
int result;
|
|
|
|
printf(testingFmt, "wolfSSL_Init()");
|
|
result = wolfSSL_Init();
|
|
printf(resultFmt, result == SSL_SUCCESS ? passed : failed);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
static int test_wolfSSL_Cleanup(void)
|
|
{
|
|
int result;
|
|
|
|
printf(testingFmt, "wolfSSL_Cleanup()");
|
|
result = wolfSSL_Cleanup();
|
|
printf(resultFmt, result == SSL_SUCCESS ? passed : failed);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/* Initialize the wolfCrypt state.
|
|
* POST: 0 success.
|
|
*/
|
|
static int test_wolfCrypt_Init(void)
|
|
{
|
|
int result;
|
|
|
|
printf(testingFmt, "wolfCrypt_Init()");
|
|
result = wolfCrypt_Init();
|
|
printf(resultFmt, result == 0 ? passed : failed);
|
|
|
|
return result;
|
|
|
|
} /* END test_wolfCrypt_Init */
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Method Allocators
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
static void test_wolfSSL_Method_Allocators(void)
|
|
{
|
|
#define TEST_METHOD_ALLOCATOR(allocator, condition) \
|
|
do { \
|
|
WOLFSSL_METHOD *method; \
|
|
condition(method = allocator()); \
|
|
XFREE(method, 0, DYNAMIC_TYPE_METHOD); \
|
|
} while(0)
|
|
|
|
#define TEST_VALID_METHOD_ALLOCATOR(a) \
|
|
TEST_METHOD_ALLOCATOR(a, AssertNotNull)
|
|
|
|
#define TEST_INVALID_METHOD_ALLOCATOR(a) \
|
|
TEST_METHOD_ALLOCATOR(a, AssertNull)
|
|
|
|
#ifndef NO_OLD_TLS
|
|
#ifdef WOLFSSL_ALLOW_SSLV3
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv3_client_method);
|
|
#endif
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_client_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_1_client_method);
|
|
#endif
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfTLSv1_2_client_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfSSLv23_client_method);
|
|
|
|
#ifdef WOLFSSL_DTLS
|
|
#ifndef NO_OLD_TLS
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_client_method);
|
|
#endif
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_server_method);
|
|
TEST_VALID_METHOD_ALLOCATOR(wolfDTLSv1_2_client_method);
|
|
#endif
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_server_method);
|
|
TEST_INVALID_METHOD_ALLOCATOR(wolfSSLv2_client_method);
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Context
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
static void test_wolfSSL_CTX_new(WOLFSSL_METHOD *method)
|
|
{
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNull(ctx = wolfSSL_CTX_new(NULL));
|
|
|
|
AssertNotNull(method);
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(method));
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
}
|
|
|
|
|
|
static void test_wolfSSL_CTX_use_certificate_file(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
|
|
/* invalid context */
|
|
AssertFalse(wolfSSL_CTX_use_certificate_file(NULL, svrCert,
|
|
SSL_FILETYPE_PEM));
|
|
/* invalid cert file */
|
|
AssertFalse(wolfSSL_CTX_use_certificate_file(ctx, bogusFile,
|
|
SSL_FILETYPE_PEM));
|
|
/* invalid cert type */
|
|
AssertFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCert, 9999));
|
|
|
|
#ifdef NO_RSA
|
|
/* rsa needed */
|
|
AssertFalse(wolfSSL_CTX_use_certificate_file(ctx, svrCert,SSL_FILETYPE_PEM));
|
|
#else
|
|
/* success */
|
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM));
|
|
#endif
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
/* 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)
|
|
{
|
|
#if !defined(NO_CERTS) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
|
|
WOLFSSL_CTX* ctx;
|
|
int ret;
|
|
|
|
printf(testingFmt, "wolfSSL_CTX_use_certificate_buffer()");
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
|
|
ret = wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
|
|
sizeof_server_cert_der_2048, SSL_FILETYPE_ASN1);
|
|
|
|
printf(resultFmt, ret == SSL_SUCCESS ? passed : failed);
|
|
wolfSSL_CTX_free(ctx);
|
|
|
|
return ret;
|
|
#else
|
|
return SSL_SUCCESS;
|
|
#endif
|
|
|
|
} /*END test_wolfSSL_CTX_use_certificate_buffer*/
|
|
|
|
static void test_wolfSSL_CTX_use_PrivateKey_file(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
|
|
/* invalid context */
|
|
AssertFalse(wolfSSL_CTX_use_PrivateKey_file(NULL, svrKey,
|
|
SSL_FILETYPE_PEM));
|
|
/* invalid key file */
|
|
AssertFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, bogusFile,
|
|
SSL_FILETYPE_PEM));
|
|
/* invalid key type */
|
|
AssertFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, 9999));
|
|
|
|
/* success */
|
|
#ifdef NO_RSA
|
|
/* rsa needed */
|
|
AssertFalse(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));
|
|
#else
|
|
/* success */
|
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));
|
|
#endif
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* test both file and buffer versions along with unloading trusted peer certs */
|
|
static void test_wolfSSL_CTX_trust_peer_cert(void)
|
|
{
|
|
#if !defined(NO_CERTS) && defined(WOLFSSL_TRUST_PEER_CERT)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
|
|
#if !defined(NO_FILESYSTEM)
|
|
/* invalid file */
|
|
assert(wolfSSL_CTX_trust_peer_cert(ctx, NULL,
|
|
SSL_FILETYPE_PEM) != SSL_SUCCESS);
|
|
assert(wolfSSL_CTX_trust_peer_cert(ctx, bogusFile,
|
|
SSL_FILETYPE_PEM) != SSL_SUCCESS);
|
|
assert(wolfSSL_CTX_trust_peer_cert(ctx, cliCert,
|
|
SSL_FILETYPE_ASN1) != SSL_SUCCESS);
|
|
|
|
/* success */
|
|
assert(wolfSSL_CTX_trust_peer_cert(ctx, cliCert, SSL_FILETYPE_PEM)
|
|
== SSL_SUCCESS);
|
|
|
|
/* unload cert */
|
|
assert(wolfSSL_CTX_Unload_trust_peers(NULL) != SSL_SUCCESS);
|
|
assert(wolfSSL_CTX_Unload_trust_peers(ctx) == SSL_SUCCESS);
|
|
#endif
|
|
|
|
/* Test of loading certs from buffers */
|
|
|
|
/* invalid buffer */
|
|
assert(wolfSSL_CTX_trust_peer_buffer(ctx, NULL, -1,
|
|
SSL_FILETYPE_ASN1) != SSL_SUCCESS);
|
|
|
|
/* success */
|
|
#ifdef USE_CERT_BUFFERS_1024
|
|
assert(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_1024,
|
|
sizeof_client_cert_der_1024, SSL_FILETYPE_ASN1) == SSL_SUCCESS);
|
|
#endif
|
|
#ifdef USE_CERT_BUFFERS_2048
|
|
assert(wolfSSL_CTX_trust_peer_buffer(ctx, client_cert_der_2048,
|
|
sizeof_client_cert_der_2048, SSL_FILETYPE_ASN1) == SSL_SUCCESS);
|
|
#endif
|
|
|
|
/* unload cert */
|
|
assert(wolfSSL_CTX_Unload_trust_peers(NULL) != SSL_SUCCESS);
|
|
assert(wolfSSL_CTX_Unload_trust_peers(ctx) == SSL_SUCCESS);
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
|
|
static void test_wolfSSL_CTX_load_verify_locations(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
|
|
/* invalid context */
|
|
AssertFalse(wolfSSL_CTX_load_verify_locations(NULL, caCert, 0));
|
|
|
|
/* invalid ca file */
|
|
AssertFalse(wolfSSL_CTX_load_verify_locations(ctx, NULL, 0));
|
|
AssertFalse(wolfSSL_CTX_load_verify_locations(ctx, bogusFile, 0));
|
|
|
|
#ifndef WOLFSSL_TIRTOS
|
|
/* invalid path */
|
|
/* not working... investigate! */
|
|
/* AssertFalse(wolfSSL_CTX_load_verify_locations(ctx, caCert, bogusFile)); */
|
|
#endif
|
|
|
|
/* success */
|
|
AssertTrue(wolfSSL_CTX_load_verify_locations(ctx, caCert, 0));
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_CTX_SetTmpDH_file(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_DH)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
|
|
/* invalid context */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(NULL,
|
|
dhParam, SSL_FILETYPE_PEM));
|
|
|
|
/* invalid dhParam file */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
|
|
NULL, SSL_FILETYPE_PEM));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx,
|
|
bogusFile, SSL_FILETYPE_PEM));
|
|
|
|
/* success */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_file(ctx, dhParam,
|
|
SSL_FILETYPE_PEM));
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_CTX_SetTmpDH_buffer(void)
|
|
{
|
|
#if !defined(NO_CERTS) && !defined(NO_DH)
|
|
WOLFSSL_CTX *ctx;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
|
|
/* invalid context */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL, dh_key_der_2048,
|
|
sizeof_dh_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
/* invalid dhParam file */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(NULL, NULL,
|
|
0, SSL_FILETYPE_ASN1));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, dsa_key_der_2048,
|
|
sizeof_dsa_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
/* success */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048,
|
|
sizeof_dh_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| SSL
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
static void test_server_wolfSSL_new(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)
|
|
WOLFSSL_CTX *ctx;
|
|
WOLFSSL_CTX *ctx_nocert;
|
|
WOLFSSL *ssl;
|
|
|
|
AssertNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
|
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM));
|
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));
|
|
|
|
/* invalid context */
|
|
AssertNull(ssl = wolfSSL_new(NULL));
|
|
#ifndef WOLFSSL_SESSION_EXPORT
|
|
AssertNull(ssl = wolfSSL_new(ctx_nocert));
|
|
#endif
|
|
|
|
/* success */
|
|
AssertNotNull(ssl = wolfSSL_new(ctx));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
wolfSSL_CTX_free(ctx_nocert);
|
|
#endif
|
|
}
|
|
|
|
|
|
static void test_client_wolfSSL_new(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA)
|
|
WOLFSSL_CTX *ctx;
|
|
WOLFSSL_CTX *ctx_nocert;
|
|
WOLFSSL *ssl;
|
|
|
|
AssertNotNull(ctx_nocert = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
|
|
|
AssertTrue(wolfSSL_CTX_load_verify_locations(ctx, caCert, 0));
|
|
|
|
/* invalid context */
|
|
AssertNull(ssl = wolfSSL_new(NULL));
|
|
|
|
/* success */
|
|
AssertNotNull(ssl = wolfSSL_new(ctx_nocert));
|
|
wolfSSL_free(ssl);
|
|
|
|
/* success */
|
|
AssertNotNull(ssl = wolfSSL_new(ctx));
|
|
wolfSSL_free(ssl);
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
wolfSSL_CTX_free(ctx_nocert);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_SetTmpDH_file(void)
|
|
{
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_DH)
|
|
WOLFSSL_CTX *ctx;
|
|
WOLFSSL *ssl;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
#ifndef NO_RSA
|
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCert,
|
|
SSL_FILETYPE_PEM));
|
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey,
|
|
SSL_FILETYPE_PEM));
|
|
#else
|
|
AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCert,
|
|
SSL_FILETYPE_PEM));
|
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKey,
|
|
SSL_FILETYPE_PEM));
|
|
#endif
|
|
AssertNotNull(ssl = wolfSSL_new(ctx));
|
|
|
|
/* invalid ssl */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_file(NULL,
|
|
dhParam, SSL_FILETYPE_PEM));
|
|
|
|
/* invalid dhParam file */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
|
|
NULL, SSL_FILETYPE_PEM));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl,
|
|
bogusFile, SSL_FILETYPE_PEM));
|
|
|
|
/* success */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_SetTmpDH_file(ssl, dhParam,
|
|
SSL_FILETYPE_PEM));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_SetTmpDH_buffer(void)
|
|
{
|
|
#if !defined(NO_CERTS) && !defined(NO_DH)
|
|
WOLFSSL_CTX *ctx;
|
|
WOLFSSL *ssl;
|
|
|
|
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
|
AssertTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
|
|
sizeof_server_cert_der_2048, SSL_FILETYPE_ASN1));
|
|
AssertTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
|
|
sizeof_server_key_der_2048, SSL_FILETYPE_ASN1));
|
|
AssertNotNull(ssl = wolfSSL_new(ctx));
|
|
|
|
/* invalid ssl */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, dh_key_der_2048,
|
|
sizeof_dh_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
/* invalid dhParam file */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_buffer(NULL, NULL,
|
|
0, SSL_FILETYPE_ASN1));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dsa_key_der_2048,
|
|
sizeof_dsa_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
/* success */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048,
|
|
sizeof_dh_key_der_2048, SSL_FILETYPE_ASN1));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
printf("SUCCESS4\n");
|
|
#endif
|
|
}
|
|
|
|
|
|
/* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version
|
|
* allowed.
|
|
* POST: return 1 on success.
|
|
*/
|
|
static int test_wolfSSL_SetMinVersion(void)
|
|
{
|
|
WOLFSSL_CTX* ctx;
|
|
WOLFSSL* ssl;
|
|
int failFlag, itr;
|
|
|
|
#ifndef NO_OLD_TLS
|
|
const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1,
|
|
WOLFSSL_TLSV1_2};
|
|
#else
|
|
const int versions[] = { WOLFSSL_TLSV1_2 };
|
|
#endif
|
|
failFlag = SSL_SUCCESS;
|
|
|
|
AssertTrue(wolfSSL_Init());
|
|
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
|
ssl = wolfSSL_new(ctx);
|
|
|
|
printf(testingFmt, "wolfSSL_SetMinVersion()");
|
|
|
|
for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++){
|
|
if(wolfSSL_SetMinVersion(ssl, *(versions + itr)) != SSL_SUCCESS){
|
|
failFlag = SSL_FAILURE;
|
|
}
|
|
}
|
|
|
|
printf(resultFmt, failFlag == SSL_SUCCESS ? passed : failed);
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
AssertTrue(wolfSSL_Cleanup());
|
|
|
|
return failFlag;
|
|
|
|
} /* END test_wolfSSL_SetMinVersion */
|
|
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| IO
|
|
*----------------------------------------------------------------------------*/
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \
|
|
!defined(NO_RSA) && !defined(SINGLE_THREADED)
|
|
#define HAVE_IO_TESTS_DEPENDENCIES
|
|
#endif
|
|
|
|
/* helper functions */
|
|
#ifdef HAVE_IO_TESTS_DEPENDENCIES
|
|
#ifdef WOLFSSL_SESSION_EXPORT
|
|
/* set up function for sending session information */
|
|
static int test_export(WOLFSSL* inSsl, byte* buf, word32 sz, void* userCtx)
|
|
{
|
|
WOLFSSL_CTX* ctx;
|
|
WOLFSSL* ssl;
|
|
|
|
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 SSL_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
|
|
static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
|
|
{
|
|
SOCKET_T sockfd = 0;
|
|
SOCKET_T clientfd = 0;
|
|
word16 port;
|
|
|
|
WOLFSSL_METHOD* method = 0;
|
|
WOLFSSL_CTX* ctx = 0;
|
|
WOLFSSL* ssl = 0;
|
|
|
|
char msg[] = "I hear you fa shizzle!";
|
|
char input[1024];
|
|
int idx;
|
|
int ret, err = 0;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
((func_args*)args)->return_code = TEST_FAIL;
|
|
method = wolfSSLv23_server_method();
|
|
ctx = wolfSSL_CTX_new(method);
|
|
|
|
#if defined(USE_WINDOWS_API)
|
|
/* Generate random port for testing */
|
|
port = GetRandomPort();
|
|
#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,
|
|
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
|
#endif
|
|
|
|
if (wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0) != SSL_SUCCESS)
|
|
{
|
|
/*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
|
|
goto done;
|
|
}
|
|
if (wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
|
|
!= SSL_SUCCESS)
|
|
{
|
|
/*err_sys("can't load server cert chain file, "
|
|
"Please run from wolfSSL home dir");*/
|
|
goto done;
|
|
}
|
|
if (wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
|
|
!= SSL_SUCCESS)
|
|
{
|
|
/*err_sys("can't load server key file, "
|
|
"Please run from wolfSSL home dir");*/
|
|
goto done;
|
|
}
|
|
|
|
ssl = wolfSSL_new(ctx);
|
|
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 0, 1);
|
|
CloseSocket(sockfd);
|
|
|
|
if (wolfSSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
|
|
/*err_sys("SSL_set_fd failed");*/
|
|
goto done;
|
|
}
|
|
|
|
#ifdef NO_PSK
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
|
|
wolfSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
|
|
#elif !defined(NO_DH)
|
|
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
|
|
#endif
|
|
#endif
|
|
|
|
do {
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
if (err == WC_PENDING_E) {
|
|
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
|
}
|
|
#endif
|
|
|
|
err = 0; /* Reset error */
|
|
ret = wolfSSL_accept(ssl);
|
|
if (ret != SSL_SUCCESS) {
|
|
err = wolfSSL_get_error(ssl, 0);
|
|
}
|
|
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
|
|
|
|
if (ret != SSL_SUCCESS) {
|
|
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
|
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));
|
|
/*err_sys("SSL_accept failed");*/
|
|
goto done;
|
|
}
|
|
|
|
idx = wolfSSL_read(ssl, input, sizeof(input)-1);
|
|
if (idx > 0) {
|
|
input[idx] = 0;
|
|
printf("Client message: %s\n", input);
|
|
}
|
|
|
|
if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
|
|
{
|
|
/*err_sys("SSL_write failed");*/
|
|
#ifdef WOLFSSL_TIRTOS
|
|
return;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
Task_yield();
|
|
#endif
|
|
|
|
done:
|
|
wolfSSL_shutdown(ssl);
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
|
|
CloseSocket(clientfd);
|
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
|
|
|
#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
|
|
|
|
#ifndef WOLFSSL_TIRTOS
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
static void test_client_nofail(void* args)
|
|
{
|
|
SOCKET_T sockfd = 0;
|
|
|
|
WOLFSSL_METHOD* method = 0;
|
|
WOLFSSL_CTX* ctx = 0;
|
|
WOLFSSL* ssl = 0;
|
|
|
|
char msg[64] = "hello wolfssl!";
|
|
char reply[1024];
|
|
int input;
|
|
int msgSz = (int)XSTRLEN(msg);
|
|
int ret, err = 0;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
((func_args*)args)->return_code = TEST_FAIL;
|
|
method = wolfSSLv23_client_method();
|
|
ctx = wolfSSL_CTX_new(method);
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
|
#endif
|
|
|
|
if (wolfSSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
|
|
{
|
|
/* err_sys("can't load ca file, Please run from wolfSSL home dir");*/
|
|
goto done2;
|
|
}
|
|
if (wolfSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM)
|
|
!= SSL_SUCCESS)
|
|
{
|
|
/*err_sys("can't load client cert file, "
|
|
"Please run from wolfSSL home dir");*/
|
|
goto done2;
|
|
}
|
|
if (wolfSSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM)
|
|
!= SSL_SUCCESS)
|
|
{
|
|
/*err_sys("can't load client key file, "
|
|
"Please run from wolfSSL home dir");*/
|
|
goto done2;
|
|
}
|
|
|
|
ssl = wolfSSL_new(ctx);
|
|
tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port,
|
|
0, 0, ssl);
|
|
if (wolfSSL_set_fd(ssl, sockfd) != SSL_SUCCESS) {
|
|
/*err_sys("SSL_set_fd failed");*/
|
|
goto done2;
|
|
}
|
|
|
|
do {
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
if (err == WC_PENDING_E) {
|
|
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
|
}
|
|
#endif
|
|
|
|
err = 0; /* Reset error */
|
|
ret = wolfSSL_connect(ssl);
|
|
if (ret != SSL_SUCCESS) {
|
|
err = wolfSSL_get_error(ssl, 0);
|
|
}
|
|
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
|
|
|
|
if (ret != SSL_SUCCESS) {
|
|
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
|
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));
|
|
/*err_sys("SSL_connect failed");*/
|
|
goto done2;
|
|
}
|
|
|
|
if (wolfSSL_write(ssl, msg, msgSz) != msgSz)
|
|
{
|
|
/*err_sys("SSL_write failed");*/
|
|
goto done2;
|
|
}
|
|
|
|
input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
|
if (input > 0)
|
|
{
|
|
reply[input] = 0;
|
|
printf("Server response: %s\n", reply);
|
|
}
|
|
|
|
done2:
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
|
|
CloseSocket(sockfd);
|
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdCloseSession(Task_self());
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/* SNI / ALPN / session export helper functions */
|
|
#if defined(HAVE_SNI) || defined(HAVE_ALPN) || defined(WOLFSSL_SESSION_EXPORT)
|
|
|
|
static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
|
|
{
|
|
callback_functions* callbacks = ((func_args*)args)->callbacks;
|
|
|
|
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(callbacks->method());
|
|
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;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
((func_args*)args)->return_code = TEST_FAIL;
|
|
|
|
#if defined(USE_WINDOWS_API)
|
|
/* Generate random port for testing */
|
|
port = GetRandomPort();
|
|
#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,
|
|
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
|
#endif
|
|
#ifdef WOLFSSL_SESSION_EXPORT
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_dtls_set_export(ctx, test_export));
|
|
#endif
|
|
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0));
|
|
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM));
|
|
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));
|
|
|
|
if (callbacks->ctx_ready)
|
|
callbacks->ctx_ready(ctx);
|
|
|
|
ssl = wolfSSL_new(ctx);
|
|
if (wolfSSL_dtls(ssl)) {
|
|
SOCKADDR_IN_T cliAddr;
|
|
socklen_t cliLen;
|
|
|
|
cliLen = sizeof(cliAddr);
|
|
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 1, 0, 0, 0);
|
|
idx = (int)recvfrom(sfd, input, sizeof(input), MSG_PEEK,
|
|
(struct sockaddr*)&cliAddr, &cliLen);
|
|
AssertIntGT(idx, 0);
|
|
wolfSSL_dtls_set_peer(ssl, &cliAddr, cliLen);
|
|
}
|
|
else {
|
|
tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0, 0, 1);
|
|
CloseSocket(sfd);
|
|
}
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, cfd));
|
|
|
|
#ifdef NO_PSK
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_DH)
|
|
wolfSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
|
|
#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);
|
|
|
|
do {
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
if (err == WC_PENDING_E) {
|
|
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
|
}
|
|
#endif
|
|
|
|
err = 0; /* Reset error */
|
|
ret = wolfSSL_accept(ssl);
|
|
if (ret != SSL_SUCCESS) {
|
|
err = wolfSSL_get_error(ssl, 0);
|
|
}
|
|
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
|
|
|
|
if (ret != SSL_SUCCESS) {
|
|
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
|
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));
|
|
/*err_sys("SSL_accept failed");*/
|
|
}
|
|
else {
|
|
if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
|
|
input[idx] = 0;
|
|
printf("Client message: %s\n", input);
|
|
}
|
|
|
|
AssertIntEQ(len, wolfSSL_write(ssl, msg, len));
|
|
#if defined(WOLFSSL_SESSION_EXPORT) && !defined(HAVE_IO_POOL)
|
|
if (wolfSSL_dtls(ssl)) {
|
|
byte* import;
|
|
word32 sz;
|
|
|
|
wolfSSL_dtls_export(ssl, NULL, &sz);
|
|
import = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
AssertNotNull(import);
|
|
idx = wolfSSL_dtls_export(ssl, import, &sz);
|
|
AssertIntGE(idx, 0);
|
|
AssertIntGE(wolfSSL_dtls_import(ssl, import, idx), 0);
|
|
XFREE(import, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
|
}
|
|
#endif
|
|
#ifdef WOLFSSL_TIRTOS
|
|
Task_yield();
|
|
#endif
|
|
wolfSSL_shutdown(ssl);
|
|
}
|
|
|
|
if (callbacks->on_result)
|
|
callbacks->on_result(ssl);
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
CloseSocket(cfd);
|
|
|
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
|
|
|
#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
|
|
|
|
#ifndef WOLFSSL_TIRTOS
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
static void run_wolfssl_client(void* args)
|
|
{
|
|
callback_functions* callbacks = ((func_args*)args)->callbacks;
|
|
|
|
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(callbacks->method());
|
|
WOLFSSL* ssl = NULL;
|
|
SOCKET_T sfd = 0;
|
|
|
|
char msg[] = "hello wolfssl server!";
|
|
int len = (int) XSTRLEN(msg);
|
|
char input[1024];
|
|
int idx;
|
|
int ret, err = 0;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
((func_args*)args)->return_code = TEST_FAIL;
|
|
|
|
#ifdef OPENSSL_EXTRA
|
|
wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
|
#endif
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx, caCert, 0));
|
|
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM));
|
|
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM));
|
|
|
|
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);
|
|
}
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_set_fd(ssl, sfd));
|
|
|
|
if (callbacks->ssl_ready)
|
|
callbacks->ssl_ready(ssl);
|
|
|
|
do {
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
if (err == WC_PENDING_E) {
|
|
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
|
}
|
|
#endif
|
|
|
|
err = 0; /* Reset error */
|
|
ret = wolfSSL_connect(ssl);
|
|
if (ret != SSL_SUCCESS) {
|
|
err = wolfSSL_get_error(ssl, 0);
|
|
}
|
|
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
|
|
|
|
if (ret != SSL_SUCCESS) {
|
|
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
|
printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));
|
|
/*err_sys("SSL_connect failed");*/
|
|
}
|
|
else {
|
|
AssertIntEQ(len, wolfSSL_write(ssl, msg, len));
|
|
|
|
if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
|
|
input[idx] = 0;
|
|
printf("Server response: %s\n", input);
|
|
}
|
|
}
|
|
|
|
if (callbacks->on_result)
|
|
callbacks->on_result(ssl);
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
CloseSocket(sfd);
|
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdCloseSession(Task_self());
|
|
#endif
|
|
}
|
|
|
|
#endif /* defined(HAVE_SNI) || defined(HAVE_ALPN) ||
|
|
defined(WOLFSSL_SESSION_EXPORT) */
|
|
#endif /* io tests dependencies */
|
|
|
|
|
|
static void test_wolfSSL_read_write(void)
|
|
{
|
|
#ifdef HAVE_IO_TESTS_DEPENDENCIES
|
|
/* The unit testing for read and write shall happen simutaneously, 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;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
StartTCP();
|
|
InitTcpReady(&ready);
|
|
|
|
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);
|
|
join_thread(serverThread);
|
|
|
|
AssertTrue(client_args.return_code);
|
|
AssertTrue(server_args.return_code);
|
|
|
|
FreeTcpReady(&ready);
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
static void test_wolfSSL_dtls_export(void)
|
|
{
|
|
#if defined(HAVE_IO_TESTS_DEPENDENCIES) && 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);
|
|
|
|
/* set using dtls */
|
|
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);
|
|
|
|
AssertTrue(client_args.return_code);
|
|
AssertTrue(server_args.return_code);
|
|
|
|
FreeTcpReady(&ready);
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
printf(testingFmt, "wolfSSL_dtls_export()");
|
|
printf(resultFmt, passed);
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| TLS extensions tests
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
#if defined(HAVE_SNI) || defined(HAVE_ALPN)
|
|
/* connection test runner */
|
|
static void test_wolfSSL_client_server(callback_functions* client_callbacks,
|
|
callback_functions* server_callbacks)
|
|
{
|
|
#ifdef HAVE_IO_TESTS_DEPENDENCIES
|
|
tcp_ready ready;
|
|
func_args client_args;
|
|
func_args server_args;
|
|
THREAD_TYPE serverThread;
|
|
|
|
StartTCP();
|
|
|
|
client_args.callbacks = client_callbacks;
|
|
server_args.callbacks = server_callbacks;
|
|
|
|
#ifdef WOLFSSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
/* RUN Server side */
|
|
InitTcpReady(&ready);
|
|
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
|
|
|
|
#else
|
|
(void)client_callbacks;
|
|
(void)server_callbacks;
|
|
#endif
|
|
}
|
|
|
|
#endif /* defined(HAVE_SNI) || defined(HAVE_ALPN) */
|
|
|
|
|
|
#ifdef HAVE_SNI
|
|
static void test_wolfSSL_UseSNI_params(void)
|
|
{
|
|
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
|
WOLFSSL *ssl = wolfSSL_new(ctx);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
/* invalid [ctx|ssl] */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseSNI(NULL, 0, "ctx", 3));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseSNI( NULL, 0, "ssl", 3));
|
|
/* invalid type */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, -1, "ctx", 3));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseSNI( ssl, -1, "ssl", 3));
|
|
/* invalid data */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, 0, NULL, 3));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseSNI( ssl, 0, NULL, 3));
|
|
/* success case */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseSNI(ctx, 0, "ctx", 3));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseSNI( ssl, 0, "ssl", 3));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
}
|
|
|
|
/* BEGIN of connection tests callbacks */
|
|
static void use_SNI_at_ctx(WOLFSSL_CTX* ctx)
|
|
{
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
|
|
}
|
|
|
|
static void use_SNI_at_ssl(WOLFSSL* ssl)
|
|
{
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, "www.wolfssl.com", 15));
|
|
}
|
|
|
|
static void different_SNI_at_ssl(WOLFSSL* ssl)
|
|
{
|
|
AssertIntEQ(SSL_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(UNKNOWN_SNI_HOST_NAME_E, wolfSSL_get_error(ssl, 0));
|
|
}
|
|
|
|
static void verify_SNI_ABSENT_on_server(WOLFSSL* ssl)
|
|
{
|
|
AssertIntEQ(SNI_ABSENT_ERROR, wolfSSL_get_error(ssl, 0));
|
|
}
|
|
|
|
static void verify_SNI_no_matching(WOLFSSL* ssl)
|
|
{
|
|
byte type = WOLFSSL_SNI_HOST_NAME;
|
|
char* request = (char*) &type; /* to be overwriten */
|
|
|
|
AssertIntEQ(WOLFSSL_SNI_NO_MATCH, wolfSSL_SNI_Status(ssl, type));
|
|
AssertNotNull(request);
|
|
AssertIntEQ(0, wolfSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
|
AssertNull(request);
|
|
}
|
|
|
|
static void verify_SNI_real_matching(WOLFSSL* ssl)
|
|
{
|
|
byte type = WOLFSSL_SNI_HOST_NAME;
|
|
char* request = NULL;
|
|
|
|
AssertIntEQ(WOLFSSL_SNI_REAL_MATCH, wolfSSL_SNI_Status(ssl, type));
|
|
AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
|
AssertNotNull(request);
|
|
AssertStrEQ("www.wolfssl.com", request);
|
|
}
|
|
|
|
static void verify_SNI_fake_matching(WOLFSSL* ssl)
|
|
{
|
|
byte type = WOLFSSL_SNI_HOST_NAME;
|
|
char* request = NULL;
|
|
|
|
AssertIntEQ(WOLFSSL_SNI_FAKE_MATCH, wolfSSL_SNI_Status(ssl, type));
|
|
AssertIntEQ(15, wolfSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
|
AssertNotNull(request);
|
|
AssertStrEQ("ww2.wolfssl.com", request);
|
|
}
|
|
|
|
static void verify_FATAL_ERROR_on_client(WOLFSSL* ssl)
|
|
{
|
|
AssertIntEQ(FATAL_ERROR, wolfSSL_get_error(ssl, 0));
|
|
}
|
|
/* END of connection tests callbacks */
|
|
|
|
static void test_wolfSSL_UseSNI_connection(void)
|
|
{
|
|
unsigned long i;
|
|
callback_functions callbacks[] = {
|
|
/* success case at ctx */
|
|
{0, use_SNI_at_ctx, 0, 0},
|
|
{0, use_SNI_at_ctx, 0, verify_SNI_real_matching},
|
|
|
|
/* success case at ssl */
|
|
{0, 0, use_SNI_at_ssl, 0},
|
|
{0, 0, use_SNI_at_ssl, verify_SNI_real_matching},
|
|
|
|
/* default missmatch behavior */
|
|
{0, 0, different_SNI_at_ssl, verify_FATAL_ERROR_on_client},
|
|
{0, 0, use_SNI_at_ssl, verify_UNKNOWN_SNI_on_server},
|
|
|
|
/* continue on missmatch */
|
|
{0, 0, different_SNI_at_ssl, 0},
|
|
{0, 0, use_SNI_WITH_CONTINUE_at_ssl, verify_SNI_no_matching},
|
|
|
|
/* fake answer on missmatch */
|
|
{0, 0, different_SNI_at_ssl, 0},
|
|
{0, 0, use_SNI_WITH_FAKE_ANSWER_at_ssl, verify_SNI_fake_matching},
|
|
|
|
/* sni abort - success */
|
|
{0, use_SNI_at_ctx, 0, 0},
|
|
{0, use_MANDATORY_SNI_at_ctx, 0, verify_SNI_real_matching},
|
|
|
|
/* sni abort - abort when absent (ctx) */
|
|
{0, 0, 0, verify_FATAL_ERROR_on_client},
|
|
{0, use_MANDATORY_SNI_at_ctx, 0, verify_SNI_ABSENT_on_server},
|
|
|
|
/* sni abort - abort when absent (ssl) */
|
|
{0, 0, 0, verify_FATAL_ERROR_on_client},
|
|
{0, 0, use_MANDATORY_SNI_at_ssl, verify_SNI_ABSENT_on_server},
|
|
|
|
/* sni abort - success when overwriten */
|
|
{0, 0, 0, 0},
|
|
{0, use_MANDATORY_SNI_at_ctx, use_SNI_at_ssl, verify_SNI_no_matching},
|
|
|
|
/* sni abort - success when allowing missmatches */
|
|
{0, 0, different_SNI_at_ssl, 0},
|
|
{0, use_PSEUDO_MANDATORY_SNI_at_ctx, 0, verify_SNI_fake_matching},
|
|
};
|
|
|
|
for (i = 0; i < sizeof(callbacks) / sizeof(callback_functions); i += 2) {
|
|
callbacks[i ].method = wolfSSLv23_client_method;
|
|
callbacks[i + 1].method = wolfSSLv23_server_method;
|
|
test_wolfSSL_client_server(&callbacks[i], &callbacks[i + 1]);
|
|
}
|
|
}
|
|
|
|
static void test_wolfSSL_SNI_GetFromBuffer(void)
|
|
{
|
|
byte buffer[] = { /* 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 buffer2[] = { /* 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 buffer3[] = { /* 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 buffer4[] = { /* 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 buffer5[] = { /* SSL v2.0 client hello */
|
|
0x00, 0x2b, 0x01, 0x03, 0x01, 0x00, 0x09, 0x00, 0x00,
|
|
/* dummy bytes bellow, 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;
|
|
|
|
AssertIntEQ(0, wolfSSL_SNI_GetFromBuffer(buffer4, sizeof(buffer4),
|
|
0, result, &length));
|
|
|
|
AssertIntEQ(0, wolfSSL_SNI_GetFromBuffer(buffer3, sizeof(buffer3),
|
|
0, result, &length));
|
|
|
|
AssertIntEQ(0, wolfSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2),
|
|
1, result, &length));
|
|
|
|
AssertIntEQ(BUFFER_ERROR, wolfSSL_SNI_GetFromBuffer(buffer, sizeof(buffer),
|
|
0, result, &length));
|
|
buffer[0] = 0x16;
|
|
|
|
AssertIntEQ(BUFFER_ERROR, wolfSSL_SNI_GetFromBuffer(buffer, sizeof(buffer),
|
|
0, result, &length));
|
|
buffer[1] = 0x03;
|
|
|
|
AssertIntEQ(SNI_UNSUPPORTED, wolfSSL_SNI_GetFromBuffer(buffer,
|
|
sizeof(buffer), 0, result, &length));
|
|
buffer[2] = 0x03;
|
|
|
|
AssertIntEQ(INCOMPLETE_DATA, wolfSSL_SNI_GetFromBuffer(buffer,
|
|
sizeof(buffer), 0, result, &length));
|
|
buffer[4] = 0x64;
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buffer, sizeof(buffer),
|
|
0, result, &length));
|
|
result[length] = 0;
|
|
AssertStrEQ("www.paypal.com", (const char*) result);
|
|
|
|
length = 32;
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_SNI_GetFromBuffer(buffer2, sizeof(buffer2),
|
|
0, result, &length));
|
|
result[length] = 0;
|
|
AssertStrEQ("api.textmate.org", (const char*) result);
|
|
|
|
/* SSL v2.0 tests */
|
|
AssertIntEQ(SNI_UNSUPPORTED, wolfSSL_SNI_GetFromBuffer(buffer5,
|
|
sizeof(buffer5), 0, result, &length));
|
|
|
|
buffer5[2] = 0x02;
|
|
AssertIntEQ(BUFFER_ERROR, wolfSSL_SNI_GetFromBuffer(buffer5,
|
|
sizeof(buffer5), 0, result, &length));
|
|
|
|
buffer5[2] = 0x01; buffer5[6] = 0x08;
|
|
AssertIntEQ(BUFFER_ERROR, wolfSSL_SNI_GetFromBuffer(buffer5,
|
|
sizeof(buffer5), 0, result, &length));
|
|
|
|
buffer5[6] = 0x09; buffer5[8] = 0x01;
|
|
AssertIntEQ(BUFFER_ERROR, wolfSSL_SNI_GetFromBuffer(buffer5,
|
|
sizeof(buffer5), 0, result, &length));
|
|
}
|
|
|
|
#endif /* HAVE_SNI */
|
|
|
|
static void test_wolfSSL_UseSNI(void)
|
|
{
|
|
#ifdef HAVE_SNI
|
|
test_wolfSSL_UseSNI_params();
|
|
test_wolfSSL_UseSNI_connection();
|
|
|
|
test_wolfSSL_SNI_GetFromBuffer();
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_UseMaxFragment(void)
|
|
{
|
|
#ifdef HAVE_MAX_FRAGMENT
|
|
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
|
WOLFSSL *ssl = wolfSSL_new(ctx);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
/* error cases */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(NULL, WOLFSSL_MFL_2_9));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseMaxFragment( NULL, WOLFSSL_MFL_2_9));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, 0));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, 6));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseMaxFragment(ssl, 0));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseMaxFragment(ssl, 6));
|
|
|
|
/* success case */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_9));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_10));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_11));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_12));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseMaxFragment(ctx, WOLFSSL_MFL_2_13));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseMaxFragment( ssl, WOLFSSL_MFL_2_9));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseMaxFragment( ssl, WOLFSSL_MFL_2_10));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseMaxFragment( ssl, WOLFSSL_MFL_2_11));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseMaxFragment( ssl, WOLFSSL_MFL_2_12));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseMaxFragment( ssl, WOLFSSL_MFL_2_13));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_UseTruncatedHMAC(void)
|
|
{
|
|
#ifdef HAVE_TRUNCATED_HMAC
|
|
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
|
WOLFSSL *ssl = wolfSSL_new(ctx);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
/* error cases */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(NULL));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseTruncatedHMAC(NULL));
|
|
|
|
/* success case */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_UseTruncatedHMAC(ctx));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseTruncatedHMAC(ssl));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_UseSupportedCurve(void)
|
|
{
|
|
#ifdef HAVE_SUPPORTED_CURVES
|
|
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
|
WOLFSSL *ssl = wolfSSL_new(ctx);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
#ifndef NO_WOLFSSL_CLIENT
|
|
/* error cases */
|
|
AssertIntNE(SSL_SUCCESS,
|
|
wolfSSL_CTX_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_UseSupportedCurve(ctx, 0));
|
|
|
|
AssertIntNE(SSL_SUCCESS,
|
|
wolfSSL_UseSupportedCurve(NULL, WOLFSSL_ECC_SECP256R1));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseSupportedCurve(ssl, 0));
|
|
|
|
/* success case */
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP256R1));
|
|
AssertIntEQ(SSL_SUCCESS,
|
|
wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1));
|
|
#endif
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
#ifdef HAVE_ALPN
|
|
|
|
static void verify_ALPN_FATAL_ERROR_on_client(WOLFSSL* ssl)
|
|
{
|
|
AssertIntEQ(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(SSL_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(SSL_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(SSL_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(SSL_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(SSL_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;
|
|
word16 protoSz = 0;
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_GetProtocol(ssl, &proto, &protoSz));
|
|
|
|
/* check value */
|
|
AssertIntNE(1, sizeof(nego_proto) == protoSz);
|
|
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(SSL_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(SSL_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(SSL_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(SSL_SUCCESS, wolfSSL_ALPN_GetPeerProtocol(ssl, &clist,
|
|
&clistSz));
|
|
|
|
/* check value */
|
|
AssertIntEQ(1, sizeof(alpn_list) == clistSz);
|
|
AssertIntEQ(0, XMEMCMP(alpn_list, clist, clistSz));
|
|
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_ALPN_FreePeerProtocol(ssl, &clist));
|
|
}
|
|
|
|
static void test_wolfSSL_UseALPN_connection(void)
|
|
{
|
|
unsigned long i;
|
|
callback_functions callbacks[] = {
|
|
/* success case same list */
|
|
{0, 0, use_ALPN_all, 0},
|
|
{0, 0, use_ALPN_all, verify_ALPN_matching_http1},
|
|
|
|
/* success case only one for server */
|
|
{0, 0, use_ALPN_all, 0},
|
|
{0, 0, use_ALPN_one, verify_ALPN_matching_spdy2},
|
|
|
|
/* success case only one for client */
|
|
{0, 0, use_ALPN_one, 0},
|
|
{0, 0, use_ALPN_all, verify_ALPN_matching_spdy2},
|
|
|
|
/* success case none for client */
|
|
{0, 0, 0, 0},
|
|
{0, 0, use_ALPN_all, 0},
|
|
|
|
/* success case missmatch behavior but option 'continue' set */
|
|
{0, 0, use_ALPN_all_continue, verify_ALPN_not_matching_continue},
|
|
{0, 0, use_ALPN_unknown_continue, 0},
|
|
|
|
/* success case read protocol send by client */
|
|
{0, 0, use_ALPN_all, 0},
|
|
{0, 0, use_ALPN_one, verify_ALPN_client_list},
|
|
|
|
/* missmatch behavior with same list
|
|
* the first and only this one must be taken */
|
|
{0, 0, use_ALPN_all, 0},
|
|
{0, 0, use_ALPN_all, verify_ALPN_not_matching_spdy3},
|
|
|
|
/* default missmatch behavior */
|
|
{0, 0, use_ALPN_all, 0},
|
|
{0, 0, use_ALPN_unknown, verify_ALPN_FATAL_ERROR_on_client},
|
|
};
|
|
|
|
for (i = 0; i < sizeof(callbacks) / sizeof(callback_functions); i += 2) {
|
|
callbacks[i ].method = wolfSSLv23_client_method;
|
|
callbacks[i + 1].method = wolfSSLv23_server_method;
|
|
test_wolfSSL_client_server(&callbacks[i], &callbacks[i + 1]);
|
|
}
|
|
}
|
|
|
|
static void test_wolfSSL_UseALPN_params(void)
|
|
{
|
|
/* "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);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
/* error cases */
|
|
AssertIntNE(SSL_SUCCESS,
|
|
wolfSSL_UseALPN(NULL, http1, sizeof(http1),
|
|
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_UseALPN(ssl, NULL, 0,
|
|
WOLFSSL_ALPN_FAILED_ON_MISMATCH));
|
|
|
|
/* success case */
|
|
/* http1 only */
|
|
AssertIntEQ(SSL_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);
|
|
AssertIntEQ(SSL_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);
|
|
AssertIntEQ(SSL_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);
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_UseALPN(ssl, buff, idx,
|
|
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
}
|
|
#endif /* HAVE_ALPN */
|
|
|
|
static void test_wolfSSL_UseALPN(void)
|
|
{
|
|
#ifdef HAVE_ALPN
|
|
test_wolfSSL_UseALPN_connection();
|
|
test_wolfSSL_UseALPN_params();
|
|
#endif
|
|
}
|
|
|
|
static void test_wolfSSL_DisableExtendedMasterSecret(void)
|
|
{
|
|
#ifdef HAVE_EXTENDED_MASTER
|
|
WOLFSSL_CTX *ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
|
|
WOLFSSL *ssl = wolfSSL_new(ctx);
|
|
|
|
AssertNotNull(ctx);
|
|
AssertNotNull(ssl);
|
|
|
|
/* error cases */
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(NULL));
|
|
AssertIntNE(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(NULL));
|
|
|
|
/* success cases */
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_DisableExtendedMasterSecret(ctx));
|
|
AssertIntEQ(SSL_SUCCESS, wolfSSL_DisableExtendedMasterSecret(ssl));
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| X509 Tests
|
|
*----------------------------------------------------------------------------*/
|
|
static void test_wolfSSL_X509_NAME_get_entry(void)
|
|
{
|
|
#ifndef NO_CERTS
|
|
#if defined(OPENSSL_EXTRA) && (defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)) \
|
|
&& (defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE))
|
|
printf(testingFmt, "wolfSSL_X509_NAME_get_entry()");
|
|
|
|
{
|
|
/* use openssl like name to test mapping */
|
|
X509_NAME_ENTRY* ne = NULL;
|
|
X509_NAME* name = NULL;
|
|
char* subCN = NULL;
|
|
X509* x509;
|
|
ASN1_STRING* asn;
|
|
int idx;
|
|
|
|
#ifndef NO_FILESYSTEM
|
|
x509 = wolfSSL_X509_load_certificate_file(cliCert, SSL_FILETYPE_PEM);
|
|
AssertNotNull(x509);
|
|
|
|
name = X509_get_subject_name(x509);
|
|
|
|
idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
|
|
AssertIntGE(idx, 0);
|
|
|
|
ne = X509_NAME_get_entry(name, idx);
|
|
AssertNotNull(ne);
|
|
|
|
asn = X509_NAME_ENTRY_get_data(ne);
|
|
AssertNotNull(asn);
|
|
|
|
subCN = (char*)ASN1_STRING_data(asn);
|
|
AssertNotNull(subCN);
|
|
|
|
wolfSSL_FreeX509(x509);
|
|
#endif
|
|
|
|
}
|
|
|
|
printf(resultFmt, passed);
|
|
#endif /* OPENSSL_EXTRA */
|
|
#endif /* !NO_CERTS */
|
|
}
|
|
|
|
|
|
/* Testing functions dealing with PKCS12 parsing out X509 certs */
|
|
static void test_wolfSSL_PKCS12(void)
|
|
{
|
|
/* .p12 file is encrypted with DES3 */
|
|
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
|
|
!defined(NO_ASN) && !defined(NO_PWDBASED)
|
|
byte buffer[5300];
|
|
char file[] = "./certs/test-servercert.p12";
|
|
FILE *f;
|
|
int bytes, ret;
|
|
WOLFSSL_BIO *bio;
|
|
WOLFSSL_EVP_PKEY *pkey;
|
|
WC_PKCS12 *pkcs12;
|
|
WOLFSSL_X509 *cert;
|
|
WOLFSSL_X509 *tmp;
|
|
STACK_OF(WOLFSSL_X509) *ca;
|
|
|
|
printf(testingFmt, "wolfSSL_PKCS12()");
|
|
|
|
f = fopen(file, "rb");
|
|
AssertNotNull(f);
|
|
bytes = (int)fread(buffer, 1, sizeof(buffer), f);
|
|
fclose(f);
|
|
|
|
bio = BIO_new_mem_buf((void*)buffer, bytes);
|
|
AssertNotNull(bio);
|
|
|
|
pkcs12 = d2i_PKCS12_bio(bio, NULL);
|
|
AssertNotNull(pkcs12);
|
|
PKCS12_free(pkcs12);
|
|
|
|
d2i_PKCS12_bio(bio, &pkcs12);
|
|
AssertNotNull(pkcs12);
|
|
|
|
/* check verify MAC fail case */
|
|
ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL);
|
|
AssertIntEQ(ret, 0);
|
|
AssertNull(pkey);
|
|
AssertNull(cert);
|
|
|
|
/* check parse with no extra certs kept */
|
|
ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, NULL);
|
|
AssertIntEQ(ret, 1);
|
|
AssertNotNull(pkey);
|
|
AssertNotNull(cert);
|
|
|
|
wolfSSL_EVP_PKEY_free(pkey);
|
|
wolfSSL_X509_free(cert);
|
|
|
|
/* check parse with extra certs kept */
|
|
ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca);
|
|
AssertIntEQ(ret, 1);
|
|
AssertNotNull(pkey);
|
|
AssertNotNull(cert);
|
|
AssertNotNull(ca);
|
|
|
|
/* should be 2 other certs on stack */
|
|
tmp = sk_X509_pop(ca);
|
|
AssertNotNull(tmp);
|
|
X509_free(tmp);
|
|
tmp = sk_X509_pop(ca);
|
|
AssertNotNull(tmp);
|
|
X509_free(tmp);
|
|
AssertNull(sk_X509_pop(ca));
|
|
|
|
EVP_PKEY_free(pkey);
|
|
X509_free(cert);
|
|
BIO_free(bio);
|
|
PKCS12_free(pkcs12);
|
|
sk_X509_free(ca);
|
|
|
|
printf(resultFmt, passed);
|
|
#endif /* OPENSSL_EXTRA */
|
|
}
|
|
|
|
|
|
/* Testing function wolfSSL_CTX_SetMinVersion; sets the minimum downgrade
|
|
* version allowed.
|
|
* POST: 1 on success.
|
|
*/
|
|
static int test_wolfSSL_CTX_SetMinVersion(void)
|
|
{
|
|
WOLFSSL_CTX* ctx;
|
|
int failFlag, itr;
|
|
|
|
#ifndef NO_OLD_TLS
|
|
const int versions[] = { WOLFSSL_TLSV1, WOLFSSL_TLSV1_1,
|
|
WOLFSSL_TLSV1_2 };
|
|
#else
|
|
const int versions[] = { WOLFSSL_TLSV1_2 };
|
|
#endif
|
|
|
|
failFlag = SSL_SUCCESS;
|
|
|
|
AssertTrue(wolfSSL_Init());
|
|
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
|
|
|
printf(testingFmt, "wolfSSL_CTX_SetMinVersion()");
|
|
|
|
for (itr = 0; itr < (int)(sizeof(versions)/sizeof(int)); itr++){
|
|
if(wolfSSL_CTX_SetMinVersion(ctx, *(versions + itr)) != SSL_SUCCESS){
|
|
failFlag = SSL_FAILURE;
|
|
}
|
|
}
|
|
|
|
printf(resultFmt, failFlag == SSL_SUCCESS ? passed : failed);
|
|
|
|
wolfSSL_CTX_free(ctx);
|
|
AssertTrue(wolfSSL_Cleanup());
|
|
|
|
return failFlag;
|
|
|
|
} /* 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)
|
|
{
|
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && defined(HAVE_OCSP)
|
|
int ret;
|
|
WOLFSSL_CTX* ctx;
|
|
WOLFSSL* ssl;
|
|
|
|
wolfSSL_Init();
|
|
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
|
ssl = wolfSSL_new(ctx);
|
|
printf(testingFmt, "wolfSSL_UseOCSPStapling()");
|
|
|
|
ret = wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR2_OCSP,
|
|
WOLFSSL_CSR2_OCSP_USE_NONCE);
|
|
|
|
printf(resultFmt, ret == SSL_SUCCESS ? passed : failed);
|
|
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
|
|
if(ret != SSL_SUCCESS){
|
|
wolfSSL_Cleanup();
|
|
return SSL_FAILURE;
|
|
}
|
|
|
|
return wolfSSL_Cleanup();
|
|
#else
|
|
return SSL_SUCCESS;
|
|
#endif
|
|
|
|
} /*END test_wolfSSL_UseOCSPStapling */
|
|
|
|
|
|
/* Testing OCSP stapling version 2, wolfSSL_UseOCSPStaplingV2 funciton. OCSP
|
|
* stapling eliminates the need ot contact the CA and lowers cert revocation
|
|
* check.
|
|
* PRE: HAVE_CERTIFICATE_STATUS_REQUEST_V2 and HAVE_OCSP defined.
|
|
*/
|
|
static int test_wolfSSL_UseOCSPStaplingV2(void)
|
|
{
|
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && defined(HAVE_OCSP)
|
|
int ret;
|
|
WOLFSSL_CTX* ctx;
|
|
WOLFSSL* ssl;
|
|
|
|
wolfSSL_Init();
|
|
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
|
ssl = wolfSSL_new(ctx);
|
|
printf(testingFmt, "wolfSSL_UseOCSPStaplingV2()");
|
|
|
|
ret = wolfSSL_UseOCSPStaplingV2(ssl, WOLFSSL_CSR2_OCSP,
|
|
WOLFSSL_CSR2_OCSP_USE_NONCE );
|
|
|
|
printf(resultFmt, ret == SSL_SUCCESS ? passed : failed);
|
|
|
|
wolfSSL_free(ssl);
|
|
wolfSSL_CTX_free(ctx);
|
|
|
|
if(ret != SSL_SUCCESS){
|
|
wolfSSL_Cleanup();
|
|
return SSL_FAILURE;
|
|
}
|
|
|
|
return wolfSSL_Cleanup();
|
|
#else
|
|
return SSL_SUCCESS;
|
|
#endif
|
|
|
|
} /*END test_wolfSSL_UseOCSPStaplingV2*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Compatibility Tests
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
|
|
static void test_wolfSSL_DES(void)
|
|
{
|
|
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3)
|
|
const_DES_cblock myDes;
|
|
DES_key_schedule key;
|
|
word32 i;
|
|
|
|
printf(testingFmt, "wolfSSL_DES()");
|
|
|
|
DES_check_key(1);
|
|
DES_set_key(&myDes, &key);
|
|
|
|
/* check, check of odd parity */
|
|
XMEMSET(key, 4, sizeof(DES_key_schedule)); key[0] = 3; /*set even parity*/
|
|
XMEMSET(myDes, 5, sizeof(const_DES_cblock));
|
|
DES_set_key_checked(&myDes, &key);
|
|
AssertIntNE(key[0], myDes[0]); /* should not have copied over key */
|
|
|
|
/* set odd parity for success case */
|
|
key[0] = 4;
|
|
DES_set_key_checked(&myDes, &key);
|
|
for (i = 0; i < sizeof(DES_key_schedule); i++) {
|
|
AssertIntEQ(key[i], myDes[i]);
|
|
}
|
|
|
|
/* check weak key */
|
|
XMEMSET(key, 1, sizeof(DES_key_schedule));
|
|
XMEMSET(myDes, 5, sizeof(const_DES_cblock));
|
|
DES_set_key_checked(&myDes, &key);
|
|
AssertIntNE(key[0], myDes[0]); /* should not have copied over key */
|
|
|
|
/* now do unchecked copy of a weak key over */
|
|
DES_set_key_unchecked(&myDes, &key);
|
|
/* compare arrays, should be the same */
|
|
for (i = 0; i < sizeof(DES_key_schedule); i++) {
|
|
AssertIntEQ(key[i], myDes[i]);
|
|
}
|
|
|
|
printf(resultFmt, passed);
|
|
#endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Main
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
void ApiTest(void)
|
|
{
|
|
printf(" Begin API Tests\n");
|
|
AssertIntEQ(test_wolfSSL_Init(), SSL_SUCCESS);
|
|
/* wolfcrypt initialization tests */
|
|
AssertFalse(test_wolfCrypt_Init());
|
|
test_wolfSSL_Method_Allocators();
|
|
test_wolfSSL_CTX_new(wolfSSLv23_server_method());
|
|
test_wolfSSL_CTX_use_certificate_file();
|
|
AssertIntEQ(test_wolfSSL_CTX_use_certificate_buffer(), SSL_SUCCESS);
|
|
test_wolfSSL_CTX_use_PrivateKey_file();
|
|
test_wolfSSL_CTX_load_verify_locations();
|
|
test_wolfSSL_CTX_trust_peer_cert();
|
|
test_wolfSSL_CTX_SetTmpDH_file();
|
|
test_wolfSSL_CTX_SetTmpDH_buffer();
|
|
test_server_wolfSSL_new();
|
|
test_client_wolfSSL_new();
|
|
test_wolfSSL_SetTmpDH_file();
|
|
test_wolfSSL_SetTmpDH_buffer();
|
|
test_wolfSSL_read_write();
|
|
test_wolfSSL_dtls_export();
|
|
AssertIntEQ(test_wolfSSL_SetMinVersion(), SSL_SUCCESS);
|
|
AssertIntEQ(test_wolfSSL_CTX_SetMinVersion(), SSL_SUCCESS);
|
|
|
|
/* TLS extensions tests */
|
|
test_wolfSSL_UseSNI();
|
|
test_wolfSSL_UseMaxFragment();
|
|
test_wolfSSL_UseTruncatedHMAC();
|
|
test_wolfSSL_UseSupportedCurve();
|
|
test_wolfSSL_UseALPN();
|
|
test_wolfSSL_DisableExtendedMasterSecret();
|
|
|
|
/* X509 tests */
|
|
test_wolfSSL_X509_NAME_get_entry();
|
|
test_wolfSSL_PKCS12();
|
|
|
|
/*OCSP Stapling. */
|
|
AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS);
|
|
AssertIntEQ(test_wolfSSL_UseOCSPStaplingV2(), SSL_SUCCESS);
|
|
|
|
/* compatibility tests */
|
|
test_wolfSSL_DES();
|
|
|
|
AssertIntEQ(test_wolfSSL_Cleanup(), SSL_SUCCESS);
|
|
printf(" End API Tests\n");
|
|
|
|
}
|