forked from wolfSSL/wolfssl
added:
- max fragment length extension; - CyaSSL_SNI_GetRequest() to get client's request at server side; - Automated tests for SNI;
This commit is contained in:
25
configure.ac
25
configure.ac
@ -1061,6 +1061,29 @@ then
|
|||||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI"
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Maximum Fragment Length
|
||||||
|
AC_ARG_ENABLE([maxfragment],
|
||||||
|
[ --enable-maxfragment Enable Maximum Fragment Length (default: disabled)],
|
||||||
|
[ ENABLED_MAX_FRAGMENT=$enableval ],
|
||||||
|
[ ENABLED_MAX_FRAGMENT=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "x$ENABLED_MAX_FRAGMENT" = "xyes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_MAX_FRAGMENT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TLS Extensions
|
||||||
|
AC_ARG_ENABLE([tlsx],
|
||||||
|
[ --enable-tlsx Enable all TLS Extensions (default: disabled)],
|
||||||
|
[ ENABLED_TLSX=$enableval ],
|
||||||
|
[ ENABLED_TLSX=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "x$ENABLED_TLSX" = "xyes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_SNI -DHAVE_MAX_FRAGMENT"
|
||||||
|
fi
|
||||||
|
|
||||||
#valgrind
|
#valgrind
|
||||||
AC_ARG_ENABLE([valgrind],
|
AC_ARG_ENABLE([valgrind],
|
||||||
@ -1429,6 +1452,8 @@ echo " * Persistent session cache: $ENABLED_SAVESESSION"
|
|||||||
echo " * Persistent cert cache: $ENABLED_SAVECERT"
|
echo " * Persistent cert cache: $ENABLED_SAVECERT"
|
||||||
echo " * NTRU: $ENABLED_NTRU"
|
echo " * NTRU: $ENABLED_NTRU"
|
||||||
echo " * SNI: $ENABLED_SNI"
|
echo " * SNI: $ENABLED_SNI"
|
||||||
|
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
|
||||||
|
echo " * All TLS Extensions: $ENABLED_TLSX"
|
||||||
echo " * valgrind unit tests: $ENABLED_VALGRIND"
|
echo " * valgrind unit tests: $ENABLED_VALGRIND"
|
||||||
echo " * LIBZ: $ENABLED_LIBZ"
|
echo " * LIBZ: $ENABLED_LIBZ"
|
||||||
echo " * Examples: $ENABLED_EXAMPLES"
|
echo " * Examples: $ENABLED_EXAMPLES"
|
||||||
|
169
cyassl/error.h
169
cyassl/error.h
@ -30,95 +30,96 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum CyaSSL_ErrorCodes {
|
enum CyaSSL_ErrorCodes {
|
||||||
INPUT_CASE_ERROR = -201, /* process input state error */
|
INPUT_CASE_ERROR = -201, /* process input state error */
|
||||||
PREFIX_ERROR = -202, /* bad index to key rounds */
|
PREFIX_ERROR = -202, /* bad index to key rounds */
|
||||||
MEMORY_ERROR = -203, /* out of memory */
|
MEMORY_ERROR = -203, /* out of memory */
|
||||||
VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
|
VERIFY_FINISHED_ERROR = -204, /* verify problem on finished */
|
||||||
VERIFY_MAC_ERROR = -205, /* verify mac problem */
|
VERIFY_MAC_ERROR = -205, /* verify mac problem */
|
||||||
PARSE_ERROR = -206, /* parse error on header */
|
PARSE_ERROR = -206, /* parse error on header */
|
||||||
UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
|
UNKNOWN_HANDSHAKE_TYPE = -207, /* weird handshake type */
|
||||||
SOCKET_ERROR_E = -208, /* error state on socket */
|
SOCKET_ERROR_E = -208, /* error state on socket */
|
||||||
SOCKET_NODATA = -209, /* expected data, not there */
|
SOCKET_NODATA = -209, /* expected data, not there */
|
||||||
INCOMPLETE_DATA = -210, /* don't have enough data to
|
INCOMPLETE_DATA = -210, /* don't have enough data to
|
||||||
complete task */
|
complete task */
|
||||||
UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
|
UNKNOWN_RECORD_TYPE = -211, /* unknown type in record hdr */
|
||||||
DECRYPT_ERROR = -212, /* error during decryption */
|
DECRYPT_ERROR = -212, /* error during decryption */
|
||||||
FATAL_ERROR = -213, /* recvd alert fatal error */
|
FATAL_ERROR = -213, /* recvd alert fatal error */
|
||||||
ENCRYPT_ERROR = -214, /* error during encryption */
|
ENCRYPT_ERROR = -214, /* error during encryption */
|
||||||
FREAD_ERROR = -215, /* fread problem */
|
FREAD_ERROR = -215, /* fread problem */
|
||||||
NO_PEER_KEY = -216, /* need peer's key */
|
NO_PEER_KEY = -216, /* need peer's key */
|
||||||
NO_PRIVATE_KEY = -217, /* need the private key */
|
NO_PRIVATE_KEY = -217, /* need the private key */
|
||||||
RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
|
RSA_PRIVATE_ERROR = -218, /* error during rsa priv op */
|
||||||
NO_DH_PARAMS = -219, /* server missing DH params */
|
NO_DH_PARAMS = -219, /* server missing DH params */
|
||||||
BUILD_MSG_ERROR = -220, /* build message failure */
|
BUILD_MSG_ERROR = -220, /* build message failure */
|
||||||
|
|
||||||
BAD_HELLO = -221, /* client hello malformed */
|
BAD_HELLO = -221, /* client hello malformed */
|
||||||
DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
|
DOMAIN_NAME_MISMATCH = -222, /* peer subject name mismatch */
|
||||||
WANT_READ = -223, /* want read, call again */
|
WANT_READ = -223, /* want read, call again */
|
||||||
NOT_READY_ERROR = -224, /* handshake layer not ready */
|
NOT_READY_ERROR = -224, /* handshake layer not ready */
|
||||||
PMS_VERSION_ERROR = -225, /* pre m secret version error */
|
PMS_VERSION_ERROR = -225, /* pre m secret version error */
|
||||||
VERSION_ERROR = -226, /* record layer version error */
|
VERSION_ERROR = -226, /* record layer version error */
|
||||||
WANT_WRITE = -227, /* want write, call again */
|
WANT_WRITE = -227, /* want write, call again */
|
||||||
BUFFER_ERROR = -228, /* malformed buffer input */
|
BUFFER_ERROR = -228, /* malformed buffer input */
|
||||||
VERIFY_CERT_ERROR = -229, /* verify cert error */
|
VERIFY_CERT_ERROR = -229, /* verify cert error */
|
||||||
VERIFY_SIGN_ERROR = -230, /* verify sign error */
|
VERIFY_SIGN_ERROR = -230, /* verify sign error */
|
||||||
CLIENT_ID_ERROR = -231, /* psk client identity error */
|
CLIENT_ID_ERROR = -231, /* psk client identity error */
|
||||||
SERVER_HINT_ERROR = -232, /* psk server hint error */
|
SERVER_HINT_ERROR = -232, /* psk server hint error */
|
||||||
PSK_KEY_ERROR = -233, /* psk key error */
|
PSK_KEY_ERROR = -233, /* psk key error */
|
||||||
ZLIB_INIT_ERROR = -234, /* zlib init error */
|
ZLIB_INIT_ERROR = -234, /* zlib init error */
|
||||||
ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
|
ZLIB_COMPRESS_ERROR = -235, /* zlib compression error */
|
||||||
ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
|
ZLIB_DECOMPRESS_ERROR = -236, /* zlib decompression error */
|
||||||
|
|
||||||
GETTIME_ERROR = -237, /* gettimeofday failed ??? */
|
GETTIME_ERROR = -237, /* gettimeofday failed ??? */
|
||||||
GETITIMER_ERROR = -238, /* getitimer failed ??? */
|
GETITIMER_ERROR = -238, /* getitimer failed ??? */
|
||||||
SIGACT_ERROR = -239, /* sigaction failed ??? */
|
SIGACT_ERROR = -239, /* sigaction failed ??? */
|
||||||
SETITIMER_ERROR = -240, /* setitimer failed ??? */
|
SETITIMER_ERROR = -240, /* setitimer failed ??? */
|
||||||
LENGTH_ERROR = -241, /* record layer length error */
|
LENGTH_ERROR = -241, /* record layer length error */
|
||||||
PEER_KEY_ERROR = -242, /* can't decode peer key */
|
PEER_KEY_ERROR = -242, /* can't decode peer key */
|
||||||
ZERO_RETURN = -243, /* peer sent close notify */
|
ZERO_RETURN = -243, /* peer sent close notify */
|
||||||
SIDE_ERROR = -244, /* wrong client/server type */
|
SIDE_ERROR = -244, /* wrong client/server type */
|
||||||
NO_PEER_CERT = -245, /* peer didn't send key */
|
NO_PEER_CERT = -245, /* peer didn't send key */
|
||||||
NTRU_KEY_ERROR = -246, /* NTRU key error */
|
NTRU_KEY_ERROR = -246, /* NTRU key error */
|
||||||
NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
|
NTRU_DRBG_ERROR = -247, /* NTRU drbg error */
|
||||||
NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
|
NTRU_ENCRYPT_ERROR = -248, /* NTRU encrypt error */
|
||||||
NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
|
NTRU_DECRYPT_ERROR = -249, /* NTRU decrypt error */
|
||||||
ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
|
ECC_CURVETYPE_ERROR = -250, /* Bad ECC Curve Type */
|
||||||
ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
|
ECC_CURVE_ERROR = -251, /* Bad ECC Curve */
|
||||||
ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
|
ECC_PEERKEY_ERROR = -252, /* Bad Peer ECC Key */
|
||||||
ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
|
ECC_MAKEKEY_ERROR = -253, /* Bad Make ECC Key */
|
||||||
ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
|
ECC_EXPORT_ERROR = -254, /* Bad ECC Export Key */
|
||||||
ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
|
ECC_SHARED_ERROR = -255, /* Bad ECC Shared Secret */
|
||||||
BAD_MUTEX_ERROR = -256, /* Bad mutex */
|
BAD_MUTEX_ERROR = -256, /* Bad mutex */
|
||||||
NOT_CA_ERROR = -257, /* Not a CA cert error */
|
NOT_CA_ERROR = -257, /* Not a CA cert error */
|
||||||
BAD_PATH_ERROR = -258, /* Bad path for opendir */
|
BAD_PATH_ERROR = -258, /* Bad path for opendir */
|
||||||
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
|
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
|
||||||
OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
|
OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
|
||||||
CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
|
CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
|
||||||
CRL_MISSING = -262, /* CRL Not loaded */
|
CRL_MISSING = -262, /* CRL Not loaded */
|
||||||
MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
|
MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
|
||||||
THREAD_CREATE_E = -264, /* Thread Create Error */
|
THREAD_CREATE_E = -264, /* Thread Create Error */
|
||||||
OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
|
OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
|
||||||
OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
|
OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
|
||||||
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
|
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
|
||||||
MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
|
MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */
|
||||||
COOKIE_ERROR = -269, /* dtls cookie error */
|
COOKIE_ERROR = -269, /* dtls cookie error */
|
||||||
SEQUENCE_ERROR = -270, /* dtls sequence error */
|
SEQUENCE_ERROR = -270, /* dtls sequence error */
|
||||||
SUITES_ERROR = -271, /* suites pointer error */
|
SUITES_ERROR = -271, /* suites pointer error */
|
||||||
SSL_NO_PEM_HEADER = -272, /* no PEM header found */
|
SSL_NO_PEM_HEADER = -272, /* no PEM header found */
|
||||||
OUT_OF_ORDER_E = -273, /* out of order message */
|
OUT_OF_ORDER_E = -273, /* out of order message */
|
||||||
BAD_KEA_TYPE_E = -274, /* bad KEA type found */
|
BAD_KEA_TYPE_E = -274, /* bad KEA type found */
|
||||||
SANITY_CIPHER_E = -275, /* sanity check on cipher error */
|
SANITY_CIPHER_E = -275, /* sanity check on cipher error */
|
||||||
RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
|
RECV_OVERFLOW_E = -276, /* RXCB returned more than rqed */
|
||||||
GEN_COOKIE_E = -277, /* Generate Cookie Error */
|
GEN_COOKIE_E = -277, /* Generate Cookie Error */
|
||||||
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
|
NO_PEER_VERIFY = -278, /* Need peer cert verify Error */
|
||||||
FWRITE_ERROR = -279, /* fwrite problem */
|
FWRITE_ERROR = -279, /* fwrite problem */
|
||||||
CACHE_MATCH_ERROR = -280, /* chache hdr match error */
|
CACHE_MATCH_ERROR = -280, /* chache hdr match error */
|
||||||
UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */
|
UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */
|
||||||
|
UNKNOWN_MAX_FRAG_LEN_E = -282, /* Unrecognized max frag len Error */
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
|
UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */
|
||||||
MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
|
MATCH_SUITE_ERROR = -291 /* can't match cipher suite */
|
||||||
/* end negotiation parameter errors only 10 for now */
|
/* end negotiation parameter errors only 10 for now */
|
||||||
/* add strings to SetErrorString !!!!! */
|
/* add strings to SetErrorString !!!!! */
|
||||||
};
|
};
|
||||||
|
@ -1116,9 +1116,13 @@ typedef struct CYASSL_DTLS_CTX {
|
|||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SERVER_NAME_INDICATION = 0,/*
|
#ifdef HAVE_SNI
|
||||||
|
SERVER_NAME_INDICATION = 0,
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
MAX_FRAGMENT_LENGTH = 1,
|
MAX_FRAGMENT_LENGTH = 1,
|
||||||
CLIENT_CERTIFICATE_URL = 2,
|
#endif
|
||||||
|
/*CLIENT_CERTIFICATE_URL = 2,
|
||||||
TRUSTED_CA_KEYS = 3,
|
TRUSTED_CA_KEYS = 3,
|
||||||
TRUNCATED_HMAC = 4,
|
TRUNCATED_HMAC = 4,
|
||||||
STATUS_REQUEST = 5,
|
STATUS_REQUEST = 5,
|
||||||
@ -1157,7 +1161,7 @@ typedef struct SNI {
|
|||||||
struct SNI* next; /* List Behavior */
|
struct SNI* next; /* List Behavior */
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
byte options; /* Behaviour options */
|
byte options; /* Behaviour options */
|
||||||
byte matched; /* Matching result */
|
byte status; /* Matching result */
|
||||||
#endif
|
#endif
|
||||||
} SNI;
|
} SNI;
|
||||||
|
|
||||||
@ -1165,13 +1169,22 @@ CYASSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
|
|||||||
word16 size);
|
word16 size);
|
||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
CYASSL_LOCAL byte TLSX_SNI_Matched(TLSX* extensions, byte type);
|
CYASSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type,
|
||||||
CYASSL_LOCAL void TLSX_SNI_SetOptions(TLSX* extensions, byte type,
|
|
||||||
byte options);
|
byte options);
|
||||||
|
CYASSL_LOCAL byte TLSX_SNI_Status(TLSX* extensions, byte type);
|
||||||
|
CYASSL_LOCAL word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type,
|
||||||
|
void** data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* HAVE_SNI */
|
#endif /* HAVE_SNI */
|
||||||
|
|
||||||
|
/* Maximum Fragment Length */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
|
||||||
|
CYASSL_LOCAL int TLSX_UseMaxFragment(TLSX** extensions, byte mfl);
|
||||||
|
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
|
||||||
#endif /* HAVE_TLS_EXTENSIONS */
|
#endif /* HAVE_TLS_EXTENSIONS */
|
||||||
|
|
||||||
/* CyaSSL context type */
|
/* CyaSSL context type */
|
||||||
@ -1778,6 +1791,9 @@ struct CYASSL {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
TLSX* extensions; /* RFC 6066 TLS Extensions data */
|
TLSX* extensions; /* RFC 6066 TLS Extensions data */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
word16 max_fragment;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
CYASSL_ALERT_HISTORY alert_history;
|
CYASSL_ALERT_HISTORY alert_history;
|
||||||
};
|
};
|
||||||
|
39
cyassl/ssl.h
39
cyassl/ssl.h
@ -929,7 +929,9 @@ CYASSL_API void CyaSSL_FreeArrays(CYASSL*);
|
|||||||
CYASSL_API int CyaSSL_UseCavium(CYASSL*, int devId);
|
CYASSL_API int CyaSSL_UseCavium(CYASSL*, int devId);
|
||||||
CYASSL_API int CyaSSL_CTX_UseCavium(CYASSL_CTX*, int devId);
|
CYASSL_API int CyaSSL_CTX_UseCavium(CYASSL_CTX*, int devId);
|
||||||
|
|
||||||
/* tls extensions */
|
/* TLS Extensions */
|
||||||
|
|
||||||
|
/* Server Name Indication */
|
||||||
#ifdef HAVE_SNI
|
#ifdef HAVE_SNI
|
||||||
/* SNI types */
|
/* SNI types */
|
||||||
enum {
|
enum {
|
||||||
@ -948,14 +950,41 @@ enum {
|
|||||||
CYASSL_SNI_ANSWER_ON_MISMATCH = 0x02 /* fake match on mismatch flag */
|
CYASSL_SNI_ANSWER_ON_MISMATCH = 0x02 /* fake match on mismatch flag */
|
||||||
};
|
};
|
||||||
|
|
||||||
CYASSL_API unsigned char CyaSSL_SNI_Matched(CYASSL* ssl, unsigned char type);
|
|
||||||
|
|
||||||
CYASSL_API void CyaSSL_SNI_SetOptions(CYASSL* ssl, unsigned char type,
|
CYASSL_API void CyaSSL_SNI_SetOptions(CYASSL* ssl, unsigned char type,
|
||||||
unsigned char options);
|
unsigned char options);
|
||||||
CYASSL_API void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, unsigned char type,
|
CYASSL_API void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, unsigned char type,
|
||||||
unsigned char options);
|
unsigned char options);
|
||||||
#endif
|
|
||||||
#endif
|
/* SNI status */
|
||||||
|
enum {
|
||||||
|
CYASSL_SNI_NO_MATCH = 0,
|
||||||
|
CYASSL_SNI_FAKE_MATCH = 1, /* if CYASSL_SNI_ANSWER_ON_MISMATCH is enabled */
|
||||||
|
CYASSL_SNI_REAL_MATCH = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
CYASSL_API unsigned char CyaSSL_SNI_Status(CYASSL* ssl, unsigned char type);
|
||||||
|
|
||||||
|
CYASSL_API unsigned short CyaSSL_SNI_GetRequest(CYASSL *ssl, unsigned char type,
|
||||||
|
void** data);
|
||||||
|
|
||||||
|
#endif /* NO_CYASSL_SERVER */
|
||||||
|
#endif /* HAVE_SNI */
|
||||||
|
|
||||||
|
/* Maximum Fragment Length */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
/* Fragment lengths */
|
||||||
|
enum {
|
||||||
|
CYASSL_MFL_2_9 = 1, /* 512 bytes */
|
||||||
|
CYASSL_MFL_2_10 = 2, /* 1024 bytes */
|
||||||
|
CYASSL_MFL_2_11 = 3, /* 2048 bytes */
|
||||||
|
CYASSL_MFL_2_12 = 4, /* 4096 bytes */
|
||||||
|
CYASSL_MFL_2_13 = 5 /* 8192 bytes *//* CyaSSL ONLY!!! */
|
||||||
|
};
|
||||||
|
|
||||||
|
CYASSL_API int CyaSSL_UseMaxFragment(CYASSL* ssl, unsigned char mfl);
|
||||||
|
CYASSL_API int CyaSSL_CTX_UseMaxFragment(CYASSL_CTX* ctx, unsigned char mfl);
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
|
||||||
|
|
||||||
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
|
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
|
||||||
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */
|
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */
|
||||||
|
@ -158,12 +158,23 @@ typedef struct tcp_ready {
|
|||||||
void InitTcpReady(tcp_ready*);
|
void InitTcpReady(tcp_ready*);
|
||||||
void FreeTcpReady(tcp_ready*);
|
void FreeTcpReady(tcp_ready*);
|
||||||
|
|
||||||
|
typedef CYASSL_METHOD* (*method_provider)(void);
|
||||||
|
typedef void (*ctx_callback)(CYASSL_CTX* ctx);
|
||||||
|
typedef void (*ssl_callback)(CYASSL* ssl);
|
||||||
|
|
||||||
|
typedef struct callback_functions {
|
||||||
|
method_provider method;
|
||||||
|
ctx_callback ctx_ready;
|
||||||
|
ssl_callback ssl_ready;
|
||||||
|
ssl_callback on_result;
|
||||||
|
} callback_functions;
|
||||||
|
|
||||||
typedef struct func_args {
|
typedef struct func_args {
|
||||||
int argc;
|
int argc;
|
||||||
char** argv;
|
char** argv;
|
||||||
int return_code;
|
int return_code;
|
||||||
tcp_ready* signal;
|
tcp_ready* signal;
|
||||||
|
callback_functions *callbacks;
|
||||||
} func_args;
|
} func_args;
|
||||||
|
|
||||||
void wait_tcp_ready(func_args*);
|
void wait_tcp_ready(func_args*);
|
||||||
|
@ -1444,6 +1444,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
|
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
ssl->extensions = NULL;
|
ssl->extensions = NULL;
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
ssl->max_fragment = MAX_RECORD_SIZE;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssl->rng = NULL;
|
ssl->rng = NULL;
|
||||||
@ -2619,8 +2622,13 @@ static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/* record layer length check */
|
/* record layer length check */
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
|
||||||
|
return LENGTH_ERROR;
|
||||||
|
#else
|
||||||
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
|
if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
|
||||||
return LENGTH_ERROR;
|
return LENGTH_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* verify record type here as well */
|
/* verify record type here as well */
|
||||||
switch ((enum ContentType)rh->type) {
|
switch ((enum ContentType)rh->type) {
|
||||||
@ -2942,8 +2950,13 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
c24to32(&input[i], &certSz);
|
c24to32(&input[i], &certSz);
|
||||||
i += CERT_HEADER_SZ;
|
i += CERT_HEADER_SZ;
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
if (listSz > ssl->max_fragment || certSz > ssl->max_fragment)
|
||||||
|
return BUFFER_E;
|
||||||
|
#else
|
||||||
if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
|
if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
certs[totalCerts].length = certSz;
|
certs[totalCerts].length = certSz;
|
||||||
certs[totalCerts].buffer = input + i;
|
certs[totalCerts].buffer = input + i;
|
||||||
@ -5348,7 +5361,11 @@ int SendData(CYASSL* ssl, const void* data, int sz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
|
||||||
|
#else
|
||||||
int len = min(sz - sent, OUTPUT_RECORD_SIZE);
|
int len = min(sz - sent, OUTPUT_RECORD_SIZE);
|
||||||
|
#endif
|
||||||
byte* out;
|
byte* out;
|
||||||
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
|
byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
|
||||||
int buffSz = len; /* may switch on comp */
|
int buffSz = len; /* may switch on comp */
|
||||||
|
47
src/ssl.c
47
src/ssl.c
@ -454,7 +454,12 @@ static int CyaSSL_read_internal(CYASSL* ssl, void* data, int sz, int peek)
|
|||||||
ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
|
ssl->dtls_expected_rx = max(sz + 100, MAX_MTU);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
ret = ReceiveData(ssl, (byte*)data,
|
||||||
|
min(sz, min(ssl->max_fragment, OUTPUT_RECORD_SIZE)), peek);
|
||||||
|
#else
|
||||||
ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
|
ret = ReceiveData(ssl, (byte*)data, min(sz, OUTPUT_RECORD_SIZE), peek);
|
||||||
|
#endif
|
||||||
|
|
||||||
CYASSL_LEAVE("CyaSSL_read_internal()", ret);
|
CYASSL_LEAVE("CyaSSL_read_internal()", ret);
|
||||||
|
|
||||||
@ -528,10 +533,6 @@ int CyaSSL_CTX_UseSNI(CYASSL_CTX* ctx, byte type, const void* data, word16 size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
byte CyaSSL_SNI_Matched(CYASSL* ssl, byte type)
|
|
||||||
{
|
|
||||||
return TLSX_SNI_Matched(ssl ? ssl->extensions : NULL, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CyaSSL_SNI_SetOptions(CYASSL* ssl, byte type, byte options)
|
void CyaSSL_SNI_SetOptions(CYASSL* ssl, byte type, byte options)
|
||||||
{
|
{
|
||||||
@ -544,10 +545,46 @@ void CyaSSL_CTX_SNI_SetOptions(CYASSL_CTX* ctx, byte type, byte options)
|
|||||||
if (ctx && ctx->extensions)
|
if (ctx && ctx->extensions)
|
||||||
TLSX_SNI_SetOptions(ctx->extensions, type, options);
|
TLSX_SNI_SetOptions(ctx->extensions, type, options);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
byte CyaSSL_SNI_Status(CYASSL* ssl, byte type)
|
||||||
|
{
|
||||||
|
return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
word16 CyaSSL_SNI_GetRequest(CYASSL* ssl, byte type, void** data)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
*data = NULL;
|
||||||
|
|
||||||
|
if (ssl && ssl->extensions)
|
||||||
|
return TLSX_SNI_GetRequest(ssl->extensions, type, data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_CYASSL_SERVER */
|
||||||
|
|
||||||
#endif /* HAVE_SNI */
|
#endif /* HAVE_SNI */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAX_FRAGMENT_LENGTH
|
||||||
|
int CyaSSL_UseMaxFragment(CYASSL* ssl, byte mfl)
|
||||||
|
{
|
||||||
|
if (ssl == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseMaxFragment(ssl->extensions, mfl);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CyaSSL_CTX_UseMaxFragment(CYASSL_CTX* ctx, byte mfl)
|
||||||
|
{
|
||||||
|
if (ctx == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
return TLSX_UseMaxFragment(ctx->extensions, mfl);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
|
||||||
#ifndef CYASSL_LEANPSK
|
#ifndef CYASSL_LEANPSK
|
||||||
int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
|
int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
|
||||||
{
|
{
|
||||||
|
163
src/tls.c
163
src/tls.c
@ -585,7 +585,7 @@ static int TLSX_SNI_Append(SNI** list, byte type, const void* data, word16 size)
|
|||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
sni->options = 0;
|
sni->options = 0;
|
||||||
sni->matched = 0;
|
sni->status = CYASSL_SNI_NO_MATCH;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*list = sni;
|
*list = sni;
|
||||||
@ -654,24 +654,24 @@ static SNI* TLSX_SNI_Find(SNI *list, byte type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
static void TLSX_SNI_SetMatched(TLSX* extensions, byte type)
|
static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
|
||||||
{
|
{
|
||||||
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
||||||
SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
|
SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
|
||||||
|
|
||||||
if (sni) {
|
if (sni) {
|
||||||
sni->matched = 1;
|
sni->status = status;
|
||||||
CYASSL_MSG("SNI did match!");
|
CYASSL_MSG("SNI did match!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte TLSX_SNI_Matched(TLSX* extensions, byte type)
|
byte TLSX_SNI_Status(TLSX* extensions, byte type)
|
||||||
{
|
{
|
||||||
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
||||||
SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
|
SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
|
||||||
|
|
||||||
if (sni)
|
if (sni)
|
||||||
return sni->matched;
|
return sni->status;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -742,11 +742,14 @@ static int TLSX_SNI_Parse(CYASSL* ssl, byte* input, word16 length,
|
|||||||
(const char *) input + offset, size) == 0);
|
(const char *) input + offset, size) == 0);
|
||||||
|
|
||||||
if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
|
if (matched || sni->options & CYASSL_SNI_ANSWER_ON_MISMATCH) {
|
||||||
int r = TLSX_UseSNI(&ssl->extensions, type, (byte *) "", 0);
|
int r = TLSX_UseSNI(&ssl->extensions,
|
||||||
|
type, input + offset, size);
|
||||||
|
|
||||||
if (r) return r; /* throw error */
|
if (r) return r; /* throw error */
|
||||||
|
|
||||||
if (matched) TLSX_SNI_SetMatched(ssl->extensions, type);
|
TLSX_SNI_SetStatus(ssl->extensions, type,
|
||||||
|
matched ? CYASSL_SNI_REAL_MATCH : CYASSL_SNI_FAKE_MATCH);
|
||||||
|
|
||||||
} else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) {
|
} else if (!(sni->options & CYASSL_SNI_CONTINUE_ON_MISMATCH)) {
|
||||||
SendAlert(ssl, alert_fatal, unrecognized_name);
|
SendAlert(ssl, alert_fatal, unrecognized_name);
|
||||||
|
|
||||||
@ -797,7 +800,7 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
|
|||||||
extension->data = (void*) sni;
|
extension->data = (void*) sni;
|
||||||
|
|
||||||
/* look for another server name of the same type to remove (replacement) */
|
/* look for another server name of the same type to remove (replacement) */
|
||||||
while ((sni = sni->next)) {
|
do {
|
||||||
if (sni->next && sni->next->type == type) {
|
if (sni->next && sni->next->type == type) {
|
||||||
SNI *next = sni->next;
|
SNI *next = sni->next;
|
||||||
|
|
||||||
@ -806,12 +809,28 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while ((sni = sni->next));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_CYASSL_SERVER
|
#ifndef NO_CYASSL_SERVER
|
||||||
|
word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data)
|
||||||
|
{
|
||||||
|
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
||||||
|
SNI* sni = TLSX_SNI_Find(extension ? extension->data : NULL, type);
|
||||||
|
|
||||||
|
if (sni && sni->status != CYASSL_SNI_NO_MATCH) {
|
||||||
|
switch (sni->type) {
|
||||||
|
case CYASSL_SNI_HOST_NAME:
|
||||||
|
*data = sni->data.host_name;
|
||||||
|
return XSTRLEN(*data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
|
void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
|
||||||
{
|
{
|
||||||
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
TLSX* extension = TLSX_Find(extensions, SERVER_NAME_INDICATION);
|
||||||
@ -829,13 +848,113 @@ void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define SNI_FREE_ALL(x)
|
#define SNI_FREE_ALL(list)
|
||||||
#define SNI_GET_SIZE(x) 0
|
#define SNI_GET_SIZE(list) 0
|
||||||
#define SNI_WRITE(x) 0
|
#define SNI_WRITE(a, b) 0
|
||||||
#define SNI_PARSE(x) 0
|
#define SNI_PARSE(a, b, c, d) 0
|
||||||
|
|
||||||
#endif /* HAVE_SNI */
|
#endif /* HAVE_SNI */
|
||||||
|
|
||||||
|
#ifdef HAVE_MAX_FRAGMENT
|
||||||
|
|
||||||
|
static word16 TLSX_MFL_Write(byte* data, byte* output)
|
||||||
|
{
|
||||||
|
output[0] = data[0];
|
||||||
|
|
||||||
|
return ENUM_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TLSX_MFL_Parse(CYASSL* ssl, byte* input, word16 length,
|
||||||
|
byte isRequest)
|
||||||
|
{
|
||||||
|
if (length != ENUM_LEN)
|
||||||
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
|
switch (*input) {
|
||||||
|
case CYASSL_MFL_2_9 : ssl->max_fragment = 512; break;
|
||||||
|
case CYASSL_MFL_2_10: ssl->max_fragment = 1024; break;
|
||||||
|
case CYASSL_MFL_2_11: ssl->max_fragment = 2048; break;
|
||||||
|
case CYASSL_MFL_2_12: ssl->max_fragment = 4096; break;
|
||||||
|
case CYASSL_MFL_2_13: ssl->max_fragment = 8192; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SendAlert(ssl, alert_fatal, illegal_parameter);
|
||||||
|
|
||||||
|
return UNKNOWN_MAX_FRAG_LEN_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_CYASSL_SERVER
|
||||||
|
if (isRequest) {
|
||||||
|
int r = TLSX_UseMaxFragment(&ssl->extensions, *input);
|
||||||
|
|
||||||
|
if (r) return r; /* throw error */
|
||||||
|
|
||||||
|
TLSX_SetResponse(ssl, MAX_FRAGMENT_LENGTH);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TLSX_UseMaxFragment(TLSX** extensions, byte mfl)
|
||||||
|
{
|
||||||
|
TLSX* extension = NULL;
|
||||||
|
byte* data = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (extensions == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (CYASSL_MFL_2_9 <= mfl && mfl <= CYASSL_MFL_2_12) {
|
||||||
|
if ((data = XMALLOC(ENUM_LEN, 0, DYNAMIC_TYPE_TLSX)) == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
data[0] = mfl;
|
||||||
|
} else
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
/* push new MFL extension. */
|
||||||
|
if ((ret = TLSX_Append(extensions, MAX_FRAGMENT_LENGTH)) != 0) {
|
||||||
|
XFREE(data, 0, DYNAMIC_TYPE_TLSX);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* place new mfl to extension data. */
|
||||||
|
extension = *extensions;
|
||||||
|
extension->data = (void*) data;
|
||||||
|
|
||||||
|
/* remove duplicated extensions */
|
||||||
|
do {
|
||||||
|
if (extension->next && extension->next->type == MAX_FRAGMENT_LENGTH) {
|
||||||
|
TLSX *next = extension->next;
|
||||||
|
|
||||||
|
extension->next = next->next;
|
||||||
|
next->next = NULL;
|
||||||
|
|
||||||
|
TLSX_FreeAll(next);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((extension = extension->next));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MFL_FREE_ALL(data) XFREE(data, 0, DYNAMIC_TYPE_TLSX)
|
||||||
|
#define MFL_GET_SIZE(data) ENUM_LEN
|
||||||
|
#define MFL_WRITE TLSX_MFL_Write
|
||||||
|
#define MFL_PARSE TLSX_MFL_Parse
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MFL_FREE_ALL(a)
|
||||||
|
#define MFL_GET_SIZE(a) 0
|
||||||
|
#define MFL_WRITE(a, b) 0
|
||||||
|
#define MFL_PARSE(a, b, c, d) 0
|
||||||
|
|
||||||
|
#endif /* HAVE_MAX_FRAGMENT */
|
||||||
|
|
||||||
TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
|
TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
|
||||||
{
|
{
|
||||||
TLSX* extension = list;
|
TLSX* extension = list;
|
||||||
@ -857,6 +976,10 @@ void TLSX_FreeAll(TLSX* list)
|
|||||||
case SERVER_NAME_INDICATION:
|
case SERVER_NAME_INDICATION:
|
||||||
SNI_FREE_ALL((SNI *) extension->data);
|
SNI_FREE_ALL((SNI *) extension->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAX_FRAGMENT_LENGTH:
|
||||||
|
MFL_FREE_ALL(extension->data);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
|
XFREE(extension, 0, DYNAMIC_TYPE_TLSX);
|
||||||
@ -889,6 +1012,9 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte isRequest)
|
|||||||
if (isRequest)
|
if (isRequest)
|
||||||
length += SNI_GET_SIZE((SNI *) extension->data);
|
length += SNI_GET_SIZE((SNI *) extension->data);
|
||||||
break;
|
break;
|
||||||
|
case MAX_FRAGMENT_LENGTH:
|
||||||
|
length += MFL_GET_SIZE(extension->data);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TURN_ON(semaphore, extension->type);
|
TURN_ON(semaphore, extension->type);
|
||||||
@ -924,6 +1050,11 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
|
|||||||
offset += SNI_WRITE((SNI *) extension->data,
|
offset += SNI_WRITE((SNI *) extension->data,
|
||||||
output + offset);
|
output + offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAX_FRAGMENT_LENGTH:
|
||||||
|
offset += MFL_WRITE((byte *) extension->data,
|
||||||
|
output + offset);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writing extension data length */
|
/* writing extension data length */
|
||||||
@ -1078,6 +1209,12 @@ int TLSX_Parse(CYASSL* ssl, byte* input, word16 length, byte isRequest,
|
|||||||
ret = SNI_PARSE(ssl, input + offset, size, isRequest);
|
ret = SNI_PARSE(ssl, input + offset, size, isRequest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAX_FRAGMENT_LENGTH:
|
||||||
|
CYASSL_MSG("Max Fragment Length extension received");
|
||||||
|
|
||||||
|
ret = MFL_PARSE(ssl, input + offset, size, isRequest);
|
||||||
|
break;
|
||||||
|
|
||||||
case HELLO_EXT_SIG_ALGO:
|
case HELLO_EXT_SIG_ALGO:
|
||||||
if (isRequest) {
|
if (isRequest) {
|
||||||
/* do not mess with offset inside the switch! */
|
/* do not mess with offset inside the switch! */
|
||||||
|
306
tests/api.c
306
tests/api.c
@ -68,6 +68,13 @@ static int test_lvl(CYASSL_CTX *ctx, const char* file, const char* path,
|
|||||||
|
|
||||||
THREAD_RETURN CYASSL_THREAD test_server_nofail(void*);
|
THREAD_RETURN CYASSL_THREAD test_server_nofail(void*);
|
||||||
void test_client_nofail(void*);
|
void test_client_nofail(void*);
|
||||||
|
|
||||||
|
void run_cyassl_client(void* args);
|
||||||
|
THREAD_RETURN CYASSL_THREAD run_cyassl_server(void* args);
|
||||||
|
|
||||||
|
void test_CyaSSL_client_server(callback_functions* client_callbacks,
|
||||||
|
callback_functions* server_callbacks);
|
||||||
|
|
||||||
static const char* bogusFile = "/dev/null";
|
static const char* bogusFile = "/dev/null";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -223,8 +230,105 @@ int test_CyaSSL_CTX_new(CYASSL_METHOD *method)
|
|||||||
|
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
#ifdef HAVE_SNI
|
#ifdef HAVE_SNI
|
||||||
|
static void use_SNI_at_ctx(CYASSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char name[] = "www.yassl.com";
|
||||||
|
|
||||||
|
AssertIntEQ(0, CyaSSL_CTX_UseSNI(ctx, type, (void *) name, XSTRLEN(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void use_SNI_at_ssl(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char name[] = "www.yassl.com";
|
||||||
|
|
||||||
|
AssertIntEQ(0, CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void different_SNI_at_ssl(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char name[] = "ww2.yassl.com";
|
||||||
|
|
||||||
|
AssertIntEQ(0, CyaSSL_UseSNI(ssl, type, (void *) name, XSTRLEN(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void use_SNI_WITH_CONTINUE_at_ssl(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
|
||||||
|
use_SNI_at_ssl(ssl);
|
||||||
|
|
||||||
|
CyaSSL_SNI_SetOptions(ssl, type, CYASSL_SNI_CONTINUE_ON_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void use_SNI_WITH_FAKE_ANSWER_at_ssl(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
|
||||||
|
use_SNI_at_ssl(ssl);
|
||||||
|
|
||||||
|
CyaSSL_SNI_SetOptions(ssl, type, CYASSL_SNI_ANSWER_ON_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_SNI_abort_on_client(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
/* FATAL_ERROR */
|
||||||
|
AssertIntEQ(-213, CyaSSL_get_error(ssl, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_SNI_abort_on_server(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
/* UNKNOWN_SNI_HOST_NAME_E */
|
||||||
|
AssertIntEQ(-281, CyaSSL_get_error(ssl, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_SNI_no_matching(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char* request = (char*) &type; /* to be overwriten */
|
||||||
|
|
||||||
|
AssertIntEQ(CYASSL_SNI_NO_MATCH, CyaSSL_SNI_Status(ssl, type));
|
||||||
|
|
||||||
|
AssertNotNull(request);
|
||||||
|
AssertIntEQ(0, CyaSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
||||||
|
AssertNull(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_SNI_real_matching(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char* request = NULL;
|
||||||
|
char name[] = "www.yassl.com";
|
||||||
|
word16 length = XSTRLEN(name);
|
||||||
|
|
||||||
|
AssertIntEQ(CYASSL_SNI_REAL_MATCH, CyaSSL_SNI_Status(ssl, type));
|
||||||
|
|
||||||
|
AssertIntEQ(length, CyaSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
||||||
|
AssertNotNull(request);
|
||||||
|
AssertStrEQ(name, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void verify_SNI_fake_matching(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
byte type = CYASSL_SNI_HOST_NAME;
|
||||||
|
char* request = NULL;
|
||||||
|
char name[] = "ww2.yassl.com";
|
||||||
|
word16 length = XSTRLEN(name);
|
||||||
|
|
||||||
|
AssertIntEQ(CYASSL_SNI_FAKE_MATCH, CyaSSL_SNI_Status(ssl, type));
|
||||||
|
|
||||||
|
AssertIntEQ(length, CyaSSL_SNI_GetRequest(ssl, type, (void**) &request));
|
||||||
|
AssertNotNull(request);
|
||||||
|
AssertStrEQ(name, request);
|
||||||
|
}
|
||||||
|
|
||||||
void test_CyaSSL_UseSNI(void)
|
void test_CyaSSL_UseSNI(void)
|
||||||
{
|
{
|
||||||
|
callback_functions client_callbacks = {CyaSSLv23_client_method, 0, 0, 0};
|
||||||
|
callback_functions server_callbacks = {CyaSSLv23_server_method, 0, 0, 0};
|
||||||
|
|
||||||
CYASSL_CTX *ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
|
CYASSL_CTX *ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
|
||||||
CYASSL *ssl = CyaSSL_new(ctx);
|
CYASSL *ssl = CyaSSL_new(ctx);
|
||||||
|
|
||||||
@ -245,6 +349,40 @@ void test_CyaSSL_UseSNI(void)
|
|||||||
|
|
||||||
CyaSSL_free(ssl);
|
CyaSSL_free(ssl);
|
||||||
CyaSSL_CTX_free(ctx);
|
CyaSSL_CTX_free(ctx);
|
||||||
|
|
||||||
|
/* Testing success case at ctx */
|
||||||
|
client_callbacks.ctx_ready = server_callbacks.ctx_ready = use_SNI_at_ctx;
|
||||||
|
server_callbacks.on_result = verify_SNI_real_matching;
|
||||||
|
|
||||||
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
|
||||||
|
/* Testing success case at ssl */
|
||||||
|
client_callbacks.ctx_ready = server_callbacks.ctx_ready = NULL;
|
||||||
|
client_callbacks.ssl_ready = server_callbacks.ssl_ready = use_SNI_at_ssl;
|
||||||
|
|
||||||
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
|
||||||
|
/* Testing default mismatch behaviour */
|
||||||
|
client_callbacks.ssl_ready = different_SNI_at_ssl;
|
||||||
|
client_callbacks.on_result = verify_SNI_abort_on_client;
|
||||||
|
server_callbacks.on_result = verify_SNI_abort_on_server;
|
||||||
|
|
||||||
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
client_callbacks.on_result = NULL;
|
||||||
|
|
||||||
|
/* Testing continue on mismatch */
|
||||||
|
client_callbacks.ssl_ready = different_SNI_at_ssl;
|
||||||
|
server_callbacks.ssl_ready = use_SNI_WITH_CONTINUE_at_ssl;
|
||||||
|
server_callbacks.on_result = verify_SNI_no_matching;
|
||||||
|
|
||||||
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
|
||||||
|
/* Testing fake answer on mismatch */
|
||||||
|
server_callbacks.ssl_ready = use_SNI_WITH_FAKE_ANSWER_at_ssl;
|
||||||
|
server_callbacks.on_result = verify_SNI_fake_matching;
|
||||||
|
|
||||||
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SNI */
|
#endif /* HAVE_SNI */
|
||||||
#endif /* HAVE_TLS_EXTENSIONS */
|
#endif /* HAVE_TLS_EXTENSIONS */
|
||||||
@ -789,9 +927,173 @@ done2:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_cyassl_client(void* args)
|
||||||
|
{
|
||||||
|
callback_functions* callbacks = ((func_args*)args)->callbacks;
|
||||||
|
|
||||||
|
CYASSL_CTX* ctx = CyaSSL_CTX_new(callbacks->method());
|
||||||
|
CYASSL* ssl = NULL;
|
||||||
|
SOCKET_T sfd = 0;
|
||||||
|
|
||||||
|
char msg[] = "hello cyassl server!";
|
||||||
|
int len = (int) XSTRLEN(msg);
|
||||||
|
char input[1024];
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
((func_args*)args)->return_code = TEST_FAIL;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_EXTRA
|
||||||
|
CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_load_verify_locations(ctx, caCert, 0));
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS,
|
||||||
|
CyaSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS,
|
||||||
|
CyaSSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
if (callbacks->ctx_ready)
|
||||||
|
callbacks->ctx_ready(ctx);
|
||||||
|
|
||||||
|
tcp_connect(&sfd, yasslIP, yasslPort, 0);
|
||||||
|
|
||||||
|
ssl = CyaSSL_new(ctx);
|
||||||
|
CyaSSL_set_fd(ssl, sfd);
|
||||||
|
|
||||||
|
if (callbacks->ssl_ready)
|
||||||
|
callbacks->ssl_ready(ssl);
|
||||||
|
|
||||||
|
if (CyaSSL_connect(ssl) != SSL_SUCCESS) {
|
||||||
|
int err = CyaSSL_get_error(ssl, 0);
|
||||||
|
char buffer[80];
|
||||||
|
printf("error = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
AssertIntEQ(len, CyaSSL_write(ssl, msg, len));
|
||||||
|
|
||||||
|
if (0 < (idx = CyaSSL_read(ssl, input, sizeof(input)-1))) {
|
||||||
|
input[idx] = 0;
|
||||||
|
printf("Server response: %s\n", input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbacks->on_result)
|
||||||
|
callbacks->on_result(ssl);
|
||||||
|
|
||||||
|
CyaSSL_free(ssl);
|
||||||
|
CyaSSL_CTX_free(ctx);
|
||||||
|
CloseSocket(sfd);
|
||||||
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
THREAD_RETURN CYASSL_THREAD run_cyassl_server(void* args)
|
||||||
|
{
|
||||||
|
callback_functions* callbacks = ((func_args*)args)->callbacks;
|
||||||
|
|
||||||
|
CYASSL_CTX* ctx = CyaSSL_CTX_new(callbacks->method());
|
||||||
|
CYASSL* ssl = NULL;
|
||||||
|
SOCKET_T sfd = 0;
|
||||||
|
SOCKET_T cfd = 0;
|
||||||
|
|
||||||
|
char msg[] = "I hear you fa shizzle!";
|
||||||
|
int len = (int) XSTRLEN(msg);
|
||||||
|
char input[1024];
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
((func_args*)args)->return_code = TEST_FAIL;
|
||||||
|
|
||||||
|
CyaSSL_CTX_set_verify(ctx,
|
||||||
|
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
||||||
|
|
||||||
|
#ifdef OPENSSL_EXTRA
|
||||||
|
CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS, CyaSSL_CTX_load_verify_locations(ctx, cliCert, 0));
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS,
|
||||||
|
CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
AssertIntEQ(SSL_SUCCESS,
|
||||||
|
CyaSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));
|
||||||
|
|
||||||
|
if (callbacks->ctx_ready)
|
||||||
|
callbacks->ctx_ready(ctx);
|
||||||
|
|
||||||
|
ssl = CyaSSL_new(ctx);
|
||||||
|
|
||||||
|
tcp_accept(&sfd, &cfd, (func_args*)args, yasslPort, 0, 0);
|
||||||
|
CloseSocket(sfd);
|
||||||
|
|
||||||
|
CyaSSL_set_fd(ssl, cfd);
|
||||||
|
|
||||||
|
#ifdef NO_PSK
|
||||||
|
#if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
|
||||||
|
CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
|
||||||
|
#else
|
||||||
|
SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (callbacks->ssl_ready)
|
||||||
|
callbacks->ssl_ready(ssl);
|
||||||
|
|
||||||
|
/* AssertIntEQ(SSL_SUCCESS, CyaSSL_accept(ssl)); */
|
||||||
|
if (CyaSSL_accept(ssl) != SSL_SUCCESS) {
|
||||||
|
int err = CyaSSL_get_error(ssl, 0);
|
||||||
|
char buffer[80];
|
||||||
|
printf("error = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (0 < (idx = CyaSSL_read(ssl, input, sizeof(input)-1))) {
|
||||||
|
input[idx] = 0;
|
||||||
|
printf("Client message: %s\n", input);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertIntEQ(len, CyaSSL_write(ssl, msg, len));
|
||||||
|
|
||||||
|
CyaSSL_shutdown(ssl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callbacks->on_result)
|
||||||
|
callbacks->on_result(ssl);
|
||||||
|
|
||||||
|
CyaSSL_free(ssl);
|
||||||
|
CyaSSL_CTX_free(ctx);
|
||||||
|
CloseSocket(cfd);
|
||||||
|
|
||||||
|
((func_args*)args)->return_code = TEST_SUCCESS;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_CyaSSL_client_server(callback_functions* client_callbacks,
|
||||||
|
callback_functions* server_callbacks)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* RUN Server side */
|
||||||
|
InitTcpReady(&ready);
|
||||||
|
server_args.signal = &ready;
|
||||||
|
start_thread(run_cyassl_server, &server_args, &serverThread);
|
||||||
|
wait_tcp_ready(&server_args);
|
||||||
|
|
||||||
|
/* RUN Client side */
|
||||||
|
run_cyassl_client(&client_args);
|
||||||
|
join_thread(serverThread);
|
||||||
|
|
||||||
|
FreeTcpReady(&ready);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* NO_FILESYSTEM */
|
#endif /* NO_FILESYSTEM */
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,8 +119,8 @@ static int execute_test_case(int svr_argc, char** svr_argv,
|
|||||||
int cli_argc, char** cli_argv,
|
int cli_argc, char** cli_argv,
|
||||||
int addNoVerify, int addNonBlocking)
|
int addNoVerify, int addNonBlocking)
|
||||||
{
|
{
|
||||||
func_args cliArgs = {cli_argc, cli_argv, 0, NULL};
|
func_args cliArgs = {cli_argc, cli_argv, 0, NULL, NULL};
|
||||||
func_args svrArgs = {svr_argc, svr_argv, 0, NULL};
|
func_args svrArgs = {svr_argc, svr_argv, 0, NULL, NULL};
|
||||||
|
|
||||||
tcp_ready ready;
|
tcp_ready ready;
|
||||||
THREAD_TYPE serverThread;
|
THREAD_TYPE serverThread;
|
||||||
|
Reference in New Issue
Block a user