merge in sni

This commit is contained in:
toddouska 2013-05-21 14:37:50 -07:00
parent b347df8d9a
commit d2003bb8b7
15 changed files with 1012 additions and 127 deletions

View File

@ -1049,6 +1049,18 @@ then
AC_MSG_ERROR([cannot enable ntru and small, ntru requires TLS which small turns off.])
fi
# SNI
AC_ARG_ENABLE([sni],
[ --enable-sni Enable SNI (default: disabled)],
[ ENABLED_SNI=$enableval ],
[ ENABLED_SNI=no ]
)
if test "x$ENABLED_SNI" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI"
fi
#valgrind
AC_ARG_ENABLE([valgrind],
@ -1415,6 +1427,7 @@ echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR"
echo " * Persistent session cache: $ENABLED_SAVESESSION"
echo " * Persistent cert cache: $ENABLED_SAVECERT"
echo " * NTRU: $ENABLED_NTRU"
echo " * SNI: $ENABLED_SNI"
echo " * valgrind unit tests: $ENABLED_VALGRIND"
echo " * LIBZ: $ENABLED_LIBZ"
echo " * Examples: $ENABLED_EXAMPLES"

View File

@ -25,6 +25,8 @@
#include <cyassl/ctaocrypt/settings.h>
/* submitted by eof */
#ifdef USE_CYASSL_MEMORY
#include <cyassl/ctaocrypt/memory.h>

View File

@ -26,7 +26,7 @@
*/
/**
* Edited by Moisés Guimarães (moises.guimaraes@phoebus.com.br)
* Edited by Moisés Guimarães (moisesguimaraesm@gmail.com)
* to fit CyaSSL's needs.
*/

View File

@ -89,7 +89,6 @@
#ifdef MICROCHIP_PIC32
#define SIZEOF_LONG_LONG 8
#define SINGLE_THREADED
#define CYASSL_USER_IO
#define NO_WRITEV
#define NO_DEV_RANDOM
#define NO_FILESYSTEM

View File

@ -202,30 +202,30 @@ enum {
/* memory allocation types for user hints */
enum {
DYNAMIC_TYPE_CA = 1,
DYNAMIC_TYPE_CERT = 2,
DYNAMIC_TYPE_KEY = 3,
DYNAMIC_TYPE_FILE = 4,
DYNAMIC_TYPE_SUBJECT_CN = 5,
DYNAMIC_TYPE_PUBLIC_KEY = 6,
DYNAMIC_TYPE_SIGNER = 7,
DYNAMIC_TYPE_NONE = 8,
DYNAMIC_TYPE_BIGINT = 9,
DYNAMIC_TYPE_RSA = 10,
DYNAMIC_TYPE_METHOD = 11,
DYNAMIC_TYPE_OUT_BUFFER = 12,
DYNAMIC_TYPE_IN_BUFFER = 13,
DYNAMIC_TYPE_INFO = 14,
DYNAMIC_TYPE_DH = 15,
DYNAMIC_TYPE_DOMAIN = 16,
DYNAMIC_TYPE_SSL = 17,
DYNAMIC_TYPE_CTX = 18,
DYNAMIC_TYPE_WRITEV = 19,
DYNAMIC_TYPE_OPENSSL = 20,
DYNAMIC_TYPE_DSA = 21,
DYNAMIC_TYPE_CRL = 22,
DYNAMIC_TYPE_REVOKED = 23,
DYNAMIC_TYPE_CRL_ENTRY = 24,
DYNAMIC_TYPE_CA = 1,
DYNAMIC_TYPE_CERT = 2,
DYNAMIC_TYPE_KEY = 3,
DYNAMIC_TYPE_FILE = 4,
DYNAMIC_TYPE_SUBJECT_CN = 5,
DYNAMIC_TYPE_PUBLIC_KEY = 6,
DYNAMIC_TYPE_SIGNER = 7,
DYNAMIC_TYPE_NONE = 8,
DYNAMIC_TYPE_BIGINT = 9,
DYNAMIC_TYPE_RSA = 10,
DYNAMIC_TYPE_METHOD = 11,
DYNAMIC_TYPE_OUT_BUFFER = 12,
DYNAMIC_TYPE_IN_BUFFER = 13,
DYNAMIC_TYPE_INFO = 14,
DYNAMIC_TYPE_DH = 15,
DYNAMIC_TYPE_DOMAIN = 16,
DYNAMIC_TYPE_SSL = 17,
DYNAMIC_TYPE_CTX = 18,
DYNAMIC_TYPE_WRITEV = 19,
DYNAMIC_TYPE_OPENSSL = 20,
DYNAMIC_TYPE_DSA = 21,
DYNAMIC_TYPE_CRL = 22,
DYNAMIC_TYPE_REVOKED = 23,
DYNAMIC_TYPE_CRL_ENTRY = 24,
DYNAMIC_TYPE_CERT_MANAGER = 25,
DYNAMIC_TYPE_CRL_MONITOR = 26,
DYNAMIC_TYPE_OCSP_STATUS = 27,
@ -243,7 +243,8 @@ enum {
DYNAMIC_TYPE_DTLS_MSG = 39,
DYNAMIC_TYPE_CAVIUM_TMP = 40,
DYNAMIC_TYPE_CAVIUM_RSA = 41,
DYNAMIC_TYPE_X509 = 42
DYNAMIC_TYPE_X509 = 42,
DYNAMIC_TYPE_TLSX = 43
};
/* stack protection */

View File

@ -30,94 +30,95 @@
#endif
enum CyaSSL_ErrorCodes {
INPUT_CASE_ERROR = -201, /* process input state error */
PREFIX_ERROR = -202, /* bad index to key rounds */
MEMORY_ERROR = -203, /* out of memory */
VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
VERIFY_MAC_ERROR = -205, /* verify mac problem */
PARSE_ERROR = -206, /* parse error on header */
UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
SOCKET_ERROR_E = -208, /* error state on socket */
SOCKET_NODATA = -209, /* expected data, not there */
INCOMPLETE_DATA = -210, /* don't have enough data to
complete task */
UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
DECRYPT_ERROR = -212, /* error during decryption */
FATAL_ERROR = -213, /* recvd alert fatal error */
ENCRYPT_ERROR = -214, /* error during encryption */
FREAD_ERROR = -215, /* fread problem */
NO_PEER_KEY = -216, /* need peer's key */
NO_PRIVATE_KEY = -217, /* need the private key */
RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
NO_DH_PARAMS = -219, /* server missing DH params */
BUILD_MSG_ERROR = -220, /* build message failure */
INPUT_CASE_ERROR = -201, /* process input state error */
PREFIX_ERROR = -202, /* bad index to key rounds */
MEMORY_ERROR = -203, /* out of memory */
VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
VERIFY_MAC_ERROR = -205, /* verify mac problem */
PARSE_ERROR = -206, /* parse error on header */
UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
SOCKET_ERROR_E = -208, /* error state on socket */
SOCKET_NODATA = -209, /* expected data, not there */
INCOMPLETE_DATA = -210, /* don't have enough data to
complete task */
UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
DECRYPT_ERROR = -212, /* error during decryption */
FATAL_ERROR = -213, /* recvd alert fatal error */
ENCRYPT_ERROR = -214, /* error during encryption */
FREAD_ERROR = -215, /* fread problem */
NO_PEER_KEY = -216, /* need peer's key */
NO_PRIVATE_KEY = -217, /* need the private key */
RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
NO_DH_PARAMS = -219, /* server missing DH params */
BUILD_MSG_ERROR = -220, /* build message failure */
BAD_HELLO = -221, /* client hello malformed */
DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
WANT_READ = -223, /* want read, call again */
NOT_READY_ERROR = -224, /* handshake layer not ready */
PMS_VERSION_ERROR = -225, /* pre m secret version error */
VERSION_ERROR = -226, /* record layer version error */
WANT_WRITE = -227, /* want write, call again */
BUFFER_ERROR = -228, /* malformed buffer input */
VERIFY_CERT_ERROR = -229, /* verify cert error */
VERIFY_SIGN_ERROR = -230, /* verify sign error */
CLIENT_ID_ERROR = -231, /* psk client identity error */
SERVER_HINT_ERROR = -232, /* psk server hint error */
PSK_KEY_ERROR = -233, /* psk key error */
ZLIB_INIT_ERROR = -234, /* zlib init error */
ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
BAD_HELLO = -221, /* client hello malformed */
DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
WANT_READ = -223, /* want read, call again */
NOT_READY_ERROR = -224, /* handshake layer not ready */
PMS_VERSION_ERROR = -225, /* pre m secret version error */
VERSION_ERROR = -226, /* record layer version error */
WANT_WRITE = -227, /* want write, call again */
BUFFER_ERROR = -228, /* malformed buffer input */
VERIFY_CERT_ERROR = -229, /* verify cert error */
VERIFY_SIGN_ERROR = -230, /* verify sign error */
CLIENT_ID_ERROR = -231, /* psk client identity error */
SERVER_HINT_ERROR = -232, /* psk server hint error */
PSK_KEY_ERROR = -233, /* psk key error */
ZLIB_INIT_ERROR = -234, /* zlib init error */
ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
GETTIME_ERROR = -237, /* gettimeofday failed ??? */
GETITIMER_ERROR = -238, /* getitimer failed ??? */
SIGACT_ERROR = -239, /* sigaction failed ??? */
SETITIMER_ERROR = -240, /* setitimer failed ??? */
LENGTH_ERROR = -241, /* record layer length error */
PEER_KEY_ERROR = -242, /* can't decode peer key */
ZERO_RETURN = -243, /* peer sent close notify */
SIDE_ERROR = -244, /* wrong client/server type */
NO_PEER_CERT = -245, /* peer didn't send key */
NTRU_KEY_ERROR = -246, /* NTRU key error */
NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
BAD_MUTEX_ERROR = -256, /* Bad mutex */
NOT_CA_ERROR = -257, /* Not a CA cert error */
BAD_PATH_ERROR = -258, /* Bad path for opendir */
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
CRL_MISSING = -262, /* CRL Not loaded */
MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
THREAD_CREATE_E = -264, /* Thread Create Error */
OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
COOKIE_ERROR = -269, /* dtls cookie error */
SEQUENCE_ERROR = -270, /* dtls sequence error */
SUITES_ERROR = -271, /* suites pointer error */
SSL_NO_PEM_HEADER = -272, /* no PEM header found */
OUT_OF_ORDER_E = -273, /* out of order message */
BAD_KEA_TYPE_E = -274, /* bad KEA type found */
SANITY_CIPHER_E = -275, /* sanity check on cipher error */
RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
GEN_COOKIE_E = -277, /* Generate Cookie Error */
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
FWRITE_ERROR = -279, /* fwrite problem */
CACHE_MATCH_ERROR = -280, /* cache hdr match err */
GETTIME_ERROR = -237, /* gettimeofday failed ??? */
GETITIMER_ERROR = -238, /* getitimer failed ??? */
SIGACT_ERROR = -239, /* sigaction failed ??? */
SETITIMER_ERROR = -240, /* setitimer failed ??? */
LENGTH_ERROR = -241, /* record layer length error */
PEER_KEY_ERROR = -242, /* can't decode peer key */
ZERO_RETURN = -243, /* peer sent close notify */
SIDE_ERROR = -244, /* wrong client/server type */
NO_PEER_CERT = -245, /* peer didn't send key */
NTRU_KEY_ERROR = -246, /* NTRU key error */
NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
BAD_MUTEX_ERROR = -256, /* Bad mutex */
NOT_CA_ERROR = -257, /* Not a CA cert error */
BAD_PATH_ERROR = -258, /* Bad path for opendir */
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
CRL_MISSING = -262, /* CRL Not loaded */
MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
THREAD_CREATE_E = -264, /* Thread Create Error */
OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
COOKIE_ERROR = -269, /* dtls cookie error */
SEQUENCE_ERROR = -270, /* dtls sequence error */
SUITES_ERROR = -271, /* suites pointer error */
SSL_NO_PEM_HEADER = -272, /* no PEM header found */
OUT_OF_ORDER_E = -273, /* out of order message */
BAD_KEA_TYPE_E = -274, /* bad KEA type found */
SANITY_CIPHER_E = -275, /* sanity check on cipher error */
RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
GEN_COOKIE_E = -277, /* Generate Cookie Error */
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
FWRITE_ERROR = -279, /* fwrite problem */
CACHE_MATCH_ERROR = -280, /* chache hdr match error */
UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */
/* add strings to SetErrorString !!!!! */
/* begin negotiation parameter errors */
UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
/* end negotiation parameter errors only 10 for now */
/* add strings to SetErrorString !!!!! */
};

View File

@ -592,18 +592,20 @@ enum Misc {
COOKIE_SZ = 20, /* use a 20 byte cookie */
SUITE_LEN = 2, /* cipher suite sz length */
ENUM_LEN = 1, /* always a byte */
OPAQUE16_LEN = 2, /* always 2 bytes */
COMP_LEN = 1, /* compression length */
CURVE_LEN = 2, /* ecc named curve length */
SERVER_ID_LEN = 20, /* server session id length */
HANDSHAKE_HEADER_SZ = 4, /* type + length(3) */
RECORD_HEADER_SZ = 5, /* type + version + len(2) */
CERT_HEADER_SZ = 3, /* always 3 bytes */
REQ_HEADER_SZ = 2, /* cert request header sz */
HINT_LEN_SZ = 2, /* length of hint size field */
HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */
HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */
HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */
HANDSHAKE_HEADER_SZ = 4, /* type + length(3) */
RECORD_HEADER_SZ = 5, /* type + version + len(2) */
CERT_HEADER_SZ = 3, /* always 3 bytes */
REQ_HEADER_SZ = 2, /* cert request header sz */
HINT_LEN_SZ = 2, /* length of hint size field */
HELLO_EXT_TYPE_SZ = 2, /* length of a hello extension type */
HELLO_EXT_SZ = 8, /* total length of the lazy hello extensions */
HELLO_EXT_LEN = 6, /* length of the lazy hello extensions */
HELLO_EXT_SIGALGO_SZ = 2, /* length of signature algo extension */
HELLO_EXT_SIGALGO_MAX = 32, /* number of items in the signature algo list */
DTLS_HANDSHAKE_HEADER_SZ = 12, /* normal + seq(2) + offset(3) + length(3) */
@ -1110,6 +1112,61 @@ typedef struct CYASSL_DTLS_CTX {
int fd;
} CYASSL_DTLS_CTX;
/* RFC 6066 TLS Extensions */
#ifdef HAVE_TLS_EXTENSIONS
typedef enum {
SERVER_NAME_INDICATION = 0,/*
MAX_FRAGMENT_LENGTH = 1,
CLIENT_CERTIFICATE_URL = 2,
TRUSTED_CA_KEYS = 3,
TRUNCATED_HMAC = 4,
STATUS_REQUEST = 5,
SIGNATURE_ALGORITHMS = 13,*/
} TLSX_Type;
typedef struct TLSX {
TLSX_Type type; /* Extension Type */
void* data; /* Extension Data */
byte resp; /* IsResponse Flag */
struct TLSX* next; /* List Behavior */
} TLSX;
CYASSL_LOCAL TLSX* TLSX_Find(TLSX* list, TLSX_Type type);
CYASSL_LOCAL void TLSX_FreeAll(TLSX* list);
#ifndef NO_CYASSL_CLIENT
CYASSL_LOCAL word16 TLSX_GetRequestSize(CYASSL* ssl);
CYASSL_LOCAL word16 TLSX_WriteRequest(CYASSL* ssl, byte* output);
#endif
#ifndef NO_CYASSL_SERVER
CYASSL_LOCAL word16 TLSX_GetResponseSize(CYASSL* ssl);
CYASSL_LOCAL word16 TLSX_WriteResponse(CYASSL* ssl, byte* output);
#endif
CYASSL_LOCAL int TLSX_Parse(CYASSL* ssl, byte* input, word16 length,
byte isRequest, Suites *suites);
/* Server Name Indication */
#ifdef HAVE_SNI
typedef enum {
HOST_NAME = 0
} SNI_Type;
typedef struct SNI {
SNI_Type type; /* SNI Type */
union { char* host_name; } data; /* SNI Data */
struct SNI* next; /* List Behavior */
} SNI;
CYASSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
word16 size);
#endif /* HAVE_SNI */
#endif /* HAVE_TLS_EXTENSIONS */
/* CyaSSL context type */
struct CYASSL_CTX {
@ -1167,6 +1224,9 @@ struct CYASSL_CTX {
#ifdef HAVE_CAVIUM
int devId; /* cavium device id to use */
#endif
#ifdef HAVE_TLS_EXTENSIONS
TLSX* extensions; /* RFC 6066 TLS Extensions data */
#endif
};
@ -1709,6 +1769,9 @@ struct CYASSL {
#endif
#ifdef HAVE_CAVIUM
int devId; /* cavium device id to use */
#endif
#ifdef HAVE_TLS_EXTENSIONS
TLSX* extensions; /* RFC 6066 TLS Extensions data */
#endif
CYASSL_ALERT_HISTORY alert_history;
};
@ -1829,7 +1892,8 @@ enum AlertDescription {
illegal_parameter = 47,
decrypt_error = 51,
protocol_version = 70,
no_renegotiation = 100
no_renegotiation = 100,
unrecognized_name = 112
};

View File

@ -929,6 +929,13 @@ CYASSL_API void CyaSSL_FreeArrays(CYASSL*);
CYASSL_API int CyaSSL_UseCavium(CYASSL*, int devId);
CYASSL_API int CyaSSL_CTX_UseCavium(CYASSL_CTX*, int devId);
/* tls extensions */
#ifdef HAVE_SNI
CYASSL_API int CyaSSL_UseSNI(CYASSL* ssl, unsigned char type, const void* data,
unsigned short size);
CYASSL_API int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type,
const void* data, unsigned short size);
#endif
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */

View File

@ -32,6 +32,8 @@
#include <cyassl/ctaocrypt/settings.h>
#include <cyassl/ctaocrypt/settings.h>
#if !defined(CYASSL_TRACK_MEMORY) && !defined(NO_MAIN_DRIVER)
/* in case memory tracker wants stats */
#define CYASSL_TRACK_MEMORY
@ -130,6 +132,7 @@ static void Usage(void)
#ifdef SHOW_SIZES
printf("-z Print structure sizes\n");
#endif
printf("-S <str> Use Host Name Indication\n");
}
@ -178,6 +181,10 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
char* ourCert = (char*)cliCert;
char* ourKey = (char*)cliKey;
#ifdef HAVE_SNI
char* sniHostName = NULL;
#endif
int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv;
@ -193,7 +200,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
(void)sslResume;
(void)trackMemory;
while ((ch = mygetopt(argc, argv, "?gdusmNrtfxh:p:v:l:A:c:k:b:z")) != -1) {
while ((ch = mygetopt(argc, argv, "?gdusmNrtfxh:p:v:l:A:c:k:b:zS:")) != -1){
switch (ch) {
case '?' :
Usage();
@ -292,6 +299,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
#endif
break;
case 'S' :
#ifdef HAVE_SNI
sniHostName = myoptarg;
#endif
break;
default:
Usage();
exit(MY_EX_USAGE);
@ -358,6 +371,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
default:
err_sys("Bad SSL version");
break;
}
if (method == NULL)
@ -445,6 +459,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
CyaSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
#endif
#ifdef HAVE_SNI
if (sniHostName)
if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)))
err_sys("UseSNI failed");
#endif
if (benchmark) {
/* time passed in number of connects give average */
int times = benchmark;

View File

@ -122,6 +122,7 @@ static void Usage(void)
" add -v 2 for DTLSv1 (default), -v 3 for DTLSv1.2\n");
printf("-f Fewer packets/group messages\n");
printf("-N Use Non-blocking sockets\n");
printf("-S <str> Use Host Name Indication\n");
}
#ifdef CYASSL_MDK_SHELL
@ -159,6 +160,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv;
#ifdef HAVE_SNI
char* sniHostName = NULL;
#endif
((func_args*)args)->return_code = -1; /* error state */
#ifdef NO_RSA
@ -168,7 +173,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif
(void)trackMemory;
while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:")) != -1) {
while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) {
switch (ch) {
case '?' :
Usage();
@ -240,6 +245,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
nonBlocking = 1;
break;
case 'S' :
#ifdef HAVE_SNI
sniHostName = myoptarg;
#endif
break;
default:
Usage();
exit(MY_EX_USAGE);
@ -396,6 +407,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
}
#endif
#ifdef HAVE_SNI
if (sniHostName)
if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)))
err_sys("UseSNI failed");
#endif
ssl = SSL_new(ctx);
if (ssl == NULL)
err_sys("unable to get SSL");

View File

@ -421,6 +421,9 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
#ifdef HAVE_CAVIUM
ctx->devId = NO_CAVIUM_DEVICE;
#endif
#ifdef HAVE_TLS_EXTENSIONS
ctx->extensions = NULL;
#endif
if (InitMutex(&ctx->countMutex) < 0) {
CYASSL_MSG("Mutex error on CTX init");
@ -452,6 +455,9 @@ void SSL_CtxResourceFree(CYASSL_CTX* ctx)
#ifdef HAVE_OCSP
CyaSSL_OCSP_Cleanup(&ctx->ocsp);
#endif
#ifdef HAVE_TLS_EXTENSIONS
TLSX_FreeAll(ctx->extensions);
#endif
}
@ -1436,6 +1442,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
ssl->devId = ctx->devId;
#endif
#ifdef HAVE_TLS_EXTENSIONS
ssl->extensions = NULL;
#endif
ssl->rng = NULL;
ssl->arrays = NULL;
@ -1655,6 +1665,9 @@ void SSL_ResourceFree(CYASSL* ssl)
XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
}
#endif
#ifdef HAVE_TLS_EXTENSIONS
TLSX_FreeAll(ssl->extensions);
#endif
}
@ -5802,6 +5815,10 @@ void SetErrorString(int error, char* str)
XSTRNCPY(str, "Cache restore header match Error", max);
break;
case UNKNOWN_SNI_HOST_NAME_E:
XSTRNCPY(str, "Unrecognized host name Error", max);
break;
default :
XSTRNCPY(str, "unknown error number", max);
}
@ -6693,9 +6710,13 @@ int SetCipherList(Suites* s, const char* list)
+ ssl->suites->suiteSz + SUITE_LEN
+ COMP_LEN + ENUM_LEN;
#ifdef HAVE_TLS_EXTENSIONS
length += TLSX_GetRequestSize(ssl);
#else
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
}
#endif
sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
#ifdef CYASSL_DTLS
@ -6768,6 +6789,11 @@ int SetCipherList(Suites* s, const char* list)
else
output[idx++] = NO_COMPRESSION;
#ifdef HAVE_TLS_EXTENSIONS
idx += TLSX_WriteRequest(ssl, output + idx);
(void)idx; /* suppress analyzer warning, keep idx current */
#else
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
{
int i;
@ -6785,6 +6811,7 @@ int SetCipherList(Suites* s, const char* list)
output[idx] = ssl->suites->hashSigAlgo[i];
}
}
#endif
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
@ -6906,8 +6933,29 @@ int SetCipherList(Suites* s, const char* list)
}
*inOutIdx = i;
if ( (i - begin) < helloSz)
*inOutIdx = begin + helloSz; /* skip extensions */
if ( (i - begin) < helloSz) {
#ifdef HAVE_TLS_EXTENSIONS
if (IsTLS(ssl)) {
int ret = 0;
word16 totalExtSz;
Suites clSuites; /* just for compatibility right now */
ato16(&input[i], &totalExtSz);
i += LENGTH_SZ;
if (totalExtSz > helloSz + begin - i)
return INCOMPLETE_DATA;
if ((ret = TLSX_Parse(ssl, (byte *) input + i,
totalExtSz, 0, &clSuites)))
return ret;
i += totalExtSz;
*inOutIdx = i;
}
else
#endif
*inOutIdx = begin + helloSz; /* skip extensions */
}
ssl->options.serverState = SERVER_HELLO_COMPLETE;
@ -7779,7 +7827,11 @@ int SetCipherList(Suites* s, const char* list)
+ SUITE_LEN
+ ENUM_LEN;
/* check for available size */
#ifdef HAVE_TLS_EXTENSIONS
length += TLSX_GetResponseSize(ssl);
#endif
/* check for avalaible size */
if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
return ret;
@ -7827,11 +7879,17 @@ int SetCipherList(Suites* s, const char* list)
output[idx++] = ssl->options.cipherSuite0;
output[idx++] = ssl->options.cipherSuite;
/* last, compression */
/* then compression */
if (ssl->options.usingCompression)
output[idx++] = ZLIB_COMPRESSION;
else
output[idx++] = NO_COMPRESSION;
/* last, extensions */
#ifdef HAVE_TLS_EXTENSIONS
if (IsTLS(ssl))
TLSX_WriteResponse(ssl, output + idx);
#endif
ssl->buffers.outputBuffer.length += sendSz;
#ifdef CYASSL_DTLS
@ -9324,11 +9382,14 @@ int SetCipherList(Suites* s, const char* list)
else
i += b; /* ignore, since we're not on */
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
*inOutIdx = i;
if ( (i - begin) < helloSz) {
#ifdef HAVE_TLS_EXTENSIONS
if (IsTLS(ssl)) {
int ret = 0;
#else
if (IsAtLeastTLSv1_2(ssl)) {
#endif
/* Process the hello extension. Skip unsupported. */
word16 totalExtSz;
@ -9336,6 +9397,14 @@ int SetCipherList(Suites* s, const char* list)
i += LENGTH_SZ;
if (totalExtSz > helloSz + begin - i)
return INCOMPLETE_DATA;
#ifdef HAVE_TLS_EXTENSIONS
if ((ret = TLSX_Parse(ssl, (byte *) input + i,
totalExtSz, 1, &clSuites)))
return ret;
i += totalExtSz;
#else
while (totalExtSz) {
word16 extId, extSz;
@ -9361,11 +9430,14 @@ int SetCipherList(Suites* s, const char* list)
totalExtSz -= LENGTH_SZ + EXT_ID_SZ + extSz;
}
#endif
*inOutIdx = i;
}
else
*inOutIdx = begin + helloSz; /* skip extensions */
}
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
ssl->options.haveSessionId = 1;
/* ProcessOld uses same resume code */

View File

@ -509,6 +509,27 @@ int CyaSSL_CTX_UseCavium(CYASSL_CTX* ctx, int devId)
#endif /* HAVE_CAVIUM */
#ifdef HAVE_SNI
int CyaSSL_UseSNI(CYASSL* ssl, unsigned char type, const void* data,
unsigned short size)
{
if (ssl == NULL)
return BAD_FUNC_ARG;
return TLSX_UseSNI(&ssl->extensions, type, data, size);
}
int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, unsigned char type, const void* data,
unsigned short size)
{
if (ctx == NULL)
return BAD_FUNC_ARG;
return TLSX_UseSNI(&ctx->extensions, type, data, size);
}
#endif /* HAVE_SNI */
#ifndef CYASSL_LEANPSK
int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)

580
src/tls.c
View File

@ -370,6 +370,12 @@ static INLINE void c16toa(word16 u16, byte* c)
c[1] = u16 & 0xff;
}
/* convert opaque to 16 bit integer */
static INLINE void ato16(const byte* c, word16* u16)
{
*u16 = (c[0] << 8) | (c[1]);
}
/* convert 32 bit integer to opaque */
static INLINE void c32toa(word32 u32, byte* c)
@ -484,6 +490,580 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
HmacFinal(&hmac, digest);
}
#ifdef HAVE_TLS_EXTENSIONS
static int TLSX_Append(TLSX** list, TLSX_Type type)
{
TLSX* extension;
if (list == NULL) /* won't check type since this function is static */
return BAD_FUNC_ARG;
if ((extension = XMALLOC(sizeof(TLSX), 0, DYNAMIC_TYPE_TLSX)) == NULL)
return MEMORY_E;
extension->type = type;
extension->data = NULL;
extension->resp = 0;
extension->next = *list;
*list = extension;
return 0;
}
#ifndef NO_CYASSL_SERVER
static void TLSX_SetResponse(CYASSL* ssl, TLSX_Type type)
{
TLSX *ext = TLSX_Find(ssl->extensions, type);
if (ext)
ext->resp = 1;
}
#endif
/* SNI - Server Name Indication */
#ifdef HAVE_SNI
static void TLSX_SNI_Free(SNI* sni)
{
if (sni) {
switch (sni->type) {
case HOST_NAME:
XFREE(sni->data.host_name, 0, DYNAMIC_TYPE_TLSX);
break;
}
XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
}
}
static void TLSX_SNI_FreeAll(SNI* list)
{
SNI* sni;
while ((sni = list)) {
list = sni->next;
TLSX_SNI_Free(sni);
}
}
static int TLSX_SNI_Append(SNI** list, SNI_Type type, const void* data,
word16 size)
{
SNI* sni;
if (list == NULL)
return BAD_FUNC_ARG;
if ((sni = XMALLOC(sizeof(SNI), 0, DYNAMIC_TYPE_TLSX)) == NULL)
return MEMORY_E;
switch (type) {
case HOST_NAME: {
sni->data.host_name = XMALLOC(size + 1, 0, DYNAMIC_TYPE_TLSX);
if (sni->data.host_name) {
XSTRNCPY(sni->data.host_name, (const char*) data, size);
sni->data.host_name[size] = 0;
} else {
XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
return MEMORY_E;
}
}
break;
default: /* invalid type */
XFREE(sni, 0, DYNAMIC_TYPE_TLSX);
return BAD_FUNC_ARG;
break;
}
sni->type = type;
sni->next = *list;
*list = sni;
return 0;
}
static word16 TLSX_SNI_GetSize(SNI* list)
{
SNI* sni;
word16 length = OPAQUE16_LEN; /* list length */
while ((sni = list)) {
list = sni->next;
length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
switch (sni->type) {
case HOST_NAME:
length += XSTRLEN((char*) sni->data.host_name);
break;
}
}
return length;
}
static word16 TLSX_SNI_Write(SNI* list, byte* output)
{
SNI* sni;
word16 length = 0;
word16 offset = OPAQUE16_LEN; /* list length offset */
while ((sni = list)) {
list = sni->next;
output[offset++] = sni->type; /* sni type */
switch (sni->type) {
case HOST_NAME:
length = XSTRLEN((char*) sni->data.host_name);
c16toa(length, output + offset); /* sni length */
offset += OPAQUE16_LEN;
XMEMCPY(output + offset, sni->data.host_name, length);
offset += length;
break;
}
}
c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
return offset;
}
static SNI* TLSX_SNI_Find(SNI *list, SNI_Type type)
{
SNI *sni = list;
while (sni && sni->type != type)
sni = sni->next;
return sni;
}
static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
byte isRequest)
{
#ifndef NO_CYASSL_SERVER
word16 size = 0;
word16 offset = 0;
#endif
TLSX *extension = TLSX_Find(ssl->extensions, SERVER_NAME_INDICATION);
if (!extension)
extension = TLSX_Find(ssl->ctx->extensions, SERVER_NAME_INDICATION);
if (!extension || !extension->data) {
if (!isRequest) {
CYASSL_MSG("Unexpected SNI response from server");
}
return 0; /* not using SNI */
}
if (!isRequest) {
if (length) {
CYASSL_MSG("SNI response should be empty!");
}
return 0; /* nothing to do */
}
#ifndef NO_CYASSL_SERVER
if (OPAQUE16_LEN > length)
return INCOMPLETE_DATA;
ato16(input, &size);
offset += OPAQUE16_LEN;
/* validating sni list length */
if (length != OPAQUE16_LEN + size)
return INCOMPLETE_DATA;
for (size = 0; offset < length; offset += size) {
SNI *sni;
SNI_Type type = input[offset++];
if (offset + OPAQUE16_LEN > length)
return INCOMPLETE_DATA;
ato16(input + offset, &size);
offset += OPAQUE16_LEN;
if (offset + size > length)
return INCOMPLETE_DATA;
if (!(sni = TLSX_SNI_Find((SNI *) extension->data, type))) {
continue; /* not using this SNI type */
}
switch(type) {
case HOST_NAME:
if (XSTRNCMP(sni->data.host_name,
(const char *) input + offset, size)) {
SendAlert(ssl, alert_fatal, unrecognized_name);
return UNKNOWN_SNI_HOST_NAME_E;
} else {
int r = TLSX_UseSNI(&ssl->extensions, type, (byte *) "", 0);
if (r) return r; /* throw error */
}
break;
}
TLSX_SetResponse(ssl, SERVER_NAME_INDICATION);
}
#endif
return 0;
}
int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
{
TLSX* extension = NULL;
SNI* sni = NULL;
int ret = 0;
if (extensions == NULL || data == NULL)
return BAD_FUNC_ARG;
if ((ret = TLSX_SNI_Append(&sni, type, data, size)) != 0)
return ret;
extension = *extensions;
/* find SNI extension if it already exists. */
while (extension && extension->type != SERVER_NAME_INDICATION)
extension = extension->next;
/* push new SNI extension if it doesn't exists. */
if (!extension) {
if ((ret = TLSX_Append(extensions, SERVER_NAME_INDICATION)) != 0) {
TLSX_SNI_Free(sni);
return ret;
}
extension = *extensions;
}
/* push new SNI object to extension data. */
sni->next = (SNI*) extension->data;
extension->data = (void*) sni;
/* look for another server name of the same type to remove (replacement) */
while ((sni = sni->next)) {
if (sni->next && sni->next->type == type) {
SNI *next = sni->next;
sni->next = next->next;
TLSX_SNI_Free(next);
break;
}
}
return 0;
}
#define SNI_FREE_ALL TLSX_SNI_FreeAll
#define SNI_GET_SIZE TLSX_SNI_GetSize
#define SNI_WRITE TLSX_SNI_Write
#define SNI_PARSE TLSX_SNI_Parse
#else
#define SNI_FREE_ALL(x)
#define SNI_GET_SIZE(x) 0
#define SNI_WRITE(x) 0
#define SNI_PARSE(x) 0
#endif /* HAVE_SNI */
TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
{
TLSX* extension = list;
while (extension && extension->type != type)
extension = extension->next;
return extension;
}
void TLSX_FreeAll(TLSX* list)
{
TLSX* extension;
while ((extension = list)) {
list = extension->next;
switch (extension->type) {
case SERVER_NAME_INDICATION:
SNI_FREE_ALL((SNI *) extension->data);
break;
}
XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
}
}
#define IS_OFF(cemaphor, light) \
((cemaphor)[(light) / 8] ^ (0x01 >> ((light) % 8)))
#define TURN_ON(cemaphor, light) \
((cemaphor)[(light) / 8] |= (0x01 >> ((light) % 8)))
static word16 TLSX_GetSize(TLSX* list, byte* cemaphor, byte isRequest)
{
TLSX* extension;
word16 length = 0;
while ((extension = list)) {
list = extension->next;
if (!isRequest && !extension->resp)
continue; /* skip! */
if (IS_OFF(cemaphor, extension->type)) {
/* type + data length */
length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
switch (extension->type) {
case SERVER_NAME_INDICATION:
if (isRequest)
length += SNI_GET_SIZE((SNI *) extension->data);
break;
}
TURN_ON(cemaphor, extension->type);
}
}
return length;
}
static word16 TLSX_Write(TLSX* list, byte* output, byte* cemaphor,
byte isRequest)
{
TLSX* extension;
word16 offset = 0;
word16 length_offset = 0;
while ((extension = list)) {
list = extension->next;
if (!isRequest && !extension->resp)
continue; /* skip! */
if (IS_OFF(cemaphor, extension->type)) {
/* extension type */
c16toa(extension->type, output + offset);
offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
length_offset = offset;
/* extension data should be written internally */
switch (extension->type) {
case SERVER_NAME_INDICATION:
if (isRequest)
offset += SNI_WRITE((SNI *) extension->data,
output + offset);
break;
}
/* writing extension data length */
c16toa(offset - length_offset,
output + length_offset - OPAQUE16_LEN);
TURN_ON(cemaphor, extension->type);
}
}
return offset;
}
#ifndef NO_CYASSL_CLIENT
word16 TLSX_GetRequestSize(CYASSL* ssl)
{
word16 length = 0;
if (ssl && IsTLS(ssl)) {
byte cemaphor[16] = {0};
if (ssl->extensions)
length += TLSX_GetSize(ssl->extensions, cemaphor, 1);
if (ssl->ctx && ssl->ctx->extensions)
length += TLSX_GetSize(ssl->ctx->extensions, cemaphor, 1);
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
length += ssl->suites->hashSigAlgoSz + HELLO_EXT_LEN;
}
if (length)
length += OPAQUE16_LEN; /* for total length storage */
return length;
}
word16 TLSX_WriteRequest(CYASSL* ssl, byte* output)
{
word16 offset = 0;
if (ssl && IsTLS(ssl) && output) {
byte cemaphor[16] = {0};
offset += OPAQUE16_LEN; /* extensions length */
if (ssl->extensions)
offset += TLSX_Write(ssl->extensions, output + offset,
cemaphor, 1);
if (ssl->ctx && ssl->ctx->extensions)
offset += TLSX_Write(ssl->ctx->extensions, output + offset,
cemaphor, 1);
if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
{
int i;
/* extension type */
c16toa(HELLO_EXT_SIG_ALGO, output + offset);
offset += HELLO_EXT_TYPE_SZ;
/* extension data length */
c16toa(OPAQUE16_LEN + ssl->suites->hashSigAlgoSz, output + offset);
offset += OPAQUE16_LEN;
/* sig algos length */
c16toa(ssl->suites->hashSigAlgoSz, output + offset);
offset += OPAQUE16_LEN;
/* sig algos */
for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, offset++)
output[offset] = ssl->suites->hashSigAlgo[i];
}
if (offset > OPAQUE16_LEN)
c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
}
return offset;
}
#endif /* NO_CYASSL_CLIENT */
#ifndef NO_CYASSL_SERVER
word16 TLSX_GetResponseSize(CYASSL* ssl)
{
word16 length = 0;
byte cemaphor[16] = {0};
if (ssl && IsTLS(ssl))
length += TLSX_GetSize(ssl->extensions, cemaphor, 0);
/* All the response data is set at the ssl object only, so no ctx here. */
if (length)
length += OPAQUE16_LEN; /* for total length storage */
return length;
}
word16 TLSX_WriteResponse(CYASSL *ssl, byte* output)
{
word16 offset = 0;
if (ssl && IsTLS(ssl) && output) {
byte cemaphor[16] = {0};
offset += OPAQUE16_LEN; /* extensions length */
offset += TLSX_Write(ssl->extensions, output + offset, cemaphor, 0);
if (offset > OPAQUE16_LEN)
c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
}
return offset;
}
#endif /* NO_CYASSL_SERVER */
int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
Suites *suites)
{
int ret = 0;
word16 offset = 0;
if (!ssl || !input || !suites)
return BAD_FUNC_ARG;
while (ret == 0 && offset < length) {
word16 type;
word16 size;
if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
return INCOMPLETE_DATA;
ato16(input + offset, &type);
offset += HELLO_EXT_TYPE_SZ;
ato16(input + offset, &size);
offset += OPAQUE16_LEN;
if (offset + size > length)
return INCOMPLETE_DATA;
switch (type) {
case SERVER_NAME_INDICATION:
ret = SNI_PARSE(ssl, input + offset, size, isRequest);
break;
case HELLO_EXT_SIG_ALGO:
if (isRequest) {
/* do not mess with offset inside the switch! */
if (IsAtLeastTLSv1_2(ssl)) {
ato16(input + offset, &suites->hashSigAlgoSz);
if (suites->hashSigAlgoSz > size - OPAQUE16_LEN)
return INCOMPLETE_DATA;
XMEMCPY(suites->hashSigAlgo,
input + offset + OPAQUE16_LEN,
min(suites->hashSigAlgoSz,
HELLO_EXT_SIGALGO_MAX));
}
} else {
CYASSL_MSG("Servers MUST NOT send SIG ALGO extension.");
}
break;
}
/* offset should be updated here! */
offset += size;
}
return ret;
}
/* undefining cemaphor macros */
#undef IS_OFF
#undef TURN_ON
#endif /* HAVE_TLS_EXTENSIONS */
#ifndef NO_CYASSL_CLIENT

View File

@ -47,6 +47,11 @@ static int test_client_CyaSSL_new(void);
static int test_CyaSSL_read_write(void);
#endif /* NO_RSA */
#endif /* NO_FILESYSTEM */
#ifdef HAVE_TLS_EXTENSIONS
#ifdef HAVE_SNI
static void test_CyaSSL_UseSNI(void);
#endif /* HAVE_TLS_EXTENSIONS */
#endif /* HAVE_SNI */
/* test function helpers */
static int test_method(CYASSL_METHOD *method, const char *name);
@ -91,6 +96,11 @@ int ApiTest(void)
test_CyaSSL_read_write();
#endif /* NO_RSA */
#endif /* NO_FILESYSTEM */
#ifdef HAVE_TLS_EXTENSIONS
#ifdef HAVE_SNI
test_CyaSSL_UseSNI();
#endif /* HAVE_SNI */
#endif /* HAVE_TLS_EXTENSIONS */
test_CyaSSL_Cleanup();
printf(" End API Tests\n");
@ -211,6 +221,34 @@ int test_CyaSSL_CTX_new(CYASSL_METHOD *method)
return TEST_SUCCESS;
}
#ifdef HAVE_TLS_EXTENSIONS
#ifdef HAVE_SNI
void test_CyaSSL_UseSNI(void)
{
CYASSL_CTX *ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
CYASSL *ssl = CyaSSL_new(ctx);
AssertNotNull(ctx);
AssertNotNull(ssl);
/* error cases */
AssertIntNE(0, CyaSSL_CTX_UseSNI(NULL, 0, (void *) "ctx", XSTRLEN("ctx")));
AssertIntNE(0, CyaSSL_UseSNI( NULL, 0, (void *) "ssl", XSTRLEN("ssl")));
AssertIntNE(0, CyaSSL_CTX_UseSNI(ctx, -1, (void *) "ctx", XSTRLEN("ctx")));
AssertIntNE(0, CyaSSL_UseSNI( ssl, -1, (void *) "ssl", XSTRLEN("ssl")));
AssertIntNE(0, CyaSSL_CTX_UseSNI(ctx, 0, (void *) NULL, XSTRLEN("ctx")));
AssertIntNE(0, CyaSSL_UseSNI( ssl, 0, (void *) NULL, XSTRLEN("ssl")));
/* success case */
AssertIntEQ(0, CyaSSL_CTX_UseSNI(ctx, 0, (void *) "ctx", XSTRLEN("ctx")));
AssertIntEQ(0, CyaSSL_UseSNI( ssl, 0, (void *) "ssl", XSTRLEN("ssl")));
CyaSSL_free(ssl);
CyaSSL_CTX_free(ctx);
}
#endif /* HAVE_SNI */
#endif /* HAVE_TLS_EXTENSIONS */
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
/* Helper for testing CyaSSL_CTX_use_certificate_file() */
int test_ucf(CYASSL_CTX *ctx, const char* file, int type, int cond,

View File

@ -5,6 +5,56 @@
#include <cyassl/test.h> /* thread and tcp stuff */
#define Fail(description, result) do { \
printf("\nERROR - %s line %d failed with:", __FILE__, __LINE__); \
printf("\n\n test: "); printf description; \
printf("\n\n result: "); printf result; \
abort(); \
} while(0)
#define Assert(test, description, result) if (!(test)) Fail(description, result)
#define AssertTrue(x) Assert( (x), ("%s is true", #x), (#x " => FALSE"))
#define AssertFalse(x) Assert(!(x), ("%s is false", #x), (#x " => TRUE"))
#define AssertNotNull(x) Assert( (x), ("%s is not null", #x), (#x " => NULL"))
#define AssertNull(x) do { \
void* _x = (void *) (x); \
\
Assert(!_x, ("%s is null", #x), (#x " => %p", _x)); \
} while(0)
#define AssertInt(x, y, op, er) do { \
int _x = x; \
int _y = y; \
\
Assert(_x op _y, ("%s " #op " %s", #x, #y), ("%d " #er " %d", _x, _y)); \
} while(0)
#define AssertIntEQ(x, y) AssertInt(x, y, ==, !=)
#define AssertIntNE(x, y) AssertInt(x, y, !=, ==)
#define AssertIntGT(x, y) AssertInt(x, y, >, <=)
#define AssertIntLT(x, y) AssertInt(x, y, <, >=)
#define AssertIntGE(x, y) AssertInt(x, y, >=, <)
#define AssertIntLE(x, y) AssertInt(x, y, <=, >)
#define AssertStr(x, y, op, er) do { \
const char* _x = x; \
const char* _y = y; \
int _z = strcmp(_x, _y); \
\
Assert(_z op 0, ("%s " #op " %s", #x, #y), \
("\"%s\" " #er " \"%s\"", _x, _y));\
} while(0)
#define AssertStrEQ(x, y) AssertStr(x, y, ==, !=)
#define AssertStrNE(x, y) AssertStr(x, y, !=, ==)
#define AssertStrGT(x, y) AssertStr(x, y, >, <=)
#define AssertStrLT(x, y) AssertStr(x, y, <, >=)
#define AssertStrGE(x, y) AssertStr(x, y, >=, <)
#define AssertStrLE(x, y) AssertStr(x, y, <=, >)
int ApiTest(void);
int SuiteTest(void);
int HashTest(void);