forked from wolfSSL/wolfssl
add client side initiated secure r, same specs
This commit is contained in:
@ -77,9 +77,10 @@ include testsuite/include.am
|
|||||||
include tests/include.am
|
include tests/include.am
|
||||||
include sslSniffer/sslSnifferTest/include.am
|
include sslSniffer/sslSnifferTest/include.am
|
||||||
include rpm/include.am
|
include rpm/include.am
|
||||||
include mqx/wolfcrypt_test/Sources/include.am
|
# TODO: fix, this commented out mqx ones have spaces in file names
|
||||||
|
#include mqx/wolfcrypt_test/Sources/include.am
|
||||||
include mqx/cyassl/include.am
|
include mqx/cyassl/include.am
|
||||||
include mqx/cyassl_client/Sources/include.am
|
#include mqx/cyassl_client/Sources/include.am
|
||||||
include mqx/util_lib/Sources/include.am
|
include mqx/util_lib/Sources/include.am
|
||||||
include mplabx/include.am
|
include mplabx/include.am
|
||||||
include mplabx/ctaocrypt_benchmark.X/nbproject/include.am
|
include mplabx/ctaocrypt_benchmark.X/nbproject/include.am
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
AC_INIT([cyassl],[3.2.0],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com])
|
AC_INIT([cyassl],[3.2.1b],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
|
||||||
|
@ -1165,6 +1165,66 @@ typedef struct CYASSL_DTLS_CTX {
|
|||||||
int fd;
|
int fd;
|
||||||
} CYASSL_DTLS_CTX;
|
} CYASSL_DTLS_CTX;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
|
||||||
|
#ifdef WORD64_AVAILABLE
|
||||||
|
typedef word64 DtlsSeq;
|
||||||
|
#else
|
||||||
|
typedef word32 DtlsSeq;
|
||||||
|
#endif
|
||||||
|
#define DTLS_SEQ_BITS (sizeof(DtlsSeq) * CHAR_BIT)
|
||||||
|
|
||||||
|
typedef struct DtlsState {
|
||||||
|
DtlsSeq window; /* Sliding window for current epoch */
|
||||||
|
word16 nextEpoch; /* Expected epoch in next record */
|
||||||
|
word32 nextSeq; /* Expected sequence in next record */
|
||||||
|
|
||||||
|
word16 curEpoch; /* Received epoch in current record */
|
||||||
|
word32 curSeq; /* Received sequence in current record */
|
||||||
|
|
||||||
|
DtlsSeq prevWindow; /* Sliding window for old epoch */
|
||||||
|
word32 prevSeq; /* Next sequence in allowed old epoch */
|
||||||
|
} DtlsState;
|
||||||
|
|
||||||
|
#endif /* CYASSL_DTLS */
|
||||||
|
|
||||||
|
|
||||||
|
/* keys and secrets */
|
||||||
|
typedef struct Keys {
|
||||||
|
byte client_write_MAC_secret[MAX_DIGEST_SIZE]; /* max sizes */
|
||||||
|
byte server_write_MAC_secret[MAX_DIGEST_SIZE];
|
||||||
|
byte client_write_key[AES_256_KEY_SIZE]; /* max sizes */
|
||||||
|
byte server_write_key[AES_256_KEY_SIZE];
|
||||||
|
byte client_write_IV[AES_IV_SIZE]; /* max sizes */
|
||||||
|
byte server_write_IV[AES_IV_SIZE];
|
||||||
|
#ifdef HAVE_AEAD
|
||||||
|
byte aead_exp_IV[AEAD_EXP_IV_SZ];
|
||||||
|
byte aead_enc_imp_IV[AEAD_IMP_IV_SZ];
|
||||||
|
byte aead_dec_imp_IV[AEAD_IMP_IV_SZ];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
word32 peer_sequence_number;
|
||||||
|
word32 sequence_number;
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
DtlsState dtls_state; /* Peer's state */
|
||||||
|
word16 dtls_peer_handshake_number;
|
||||||
|
word16 dtls_expected_peer_handshake_number;
|
||||||
|
|
||||||
|
word16 dtls_epoch; /* Current tx epoch */
|
||||||
|
word32 dtls_sequence_number; /* Current tx sequence */
|
||||||
|
word16 dtls_handshake_number; /* Current tx handshake seq */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
word32 encryptSz; /* last size of encrypted data */
|
||||||
|
word32 padSz; /* how much to advance after decrypt part */
|
||||||
|
byte encryptionOn; /* true after change cipher spec */
|
||||||
|
byte decryptedCur; /* only decrypt current record once */
|
||||||
|
} Keys;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* RFC 6066 TLS Extensions */
|
/* RFC 6066 TLS Extensions */
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
|
|
||||||
@ -1260,11 +1320,22 @@ CYASSL_LOCAL int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first,
|
|||||||
|
|
||||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
|
||||||
|
enum key_cache_state {
|
||||||
|
SCR_CACHE_NULL = 0, /* empty / begin state */
|
||||||
|
SCR_CACHE_NEEDED, /* need to cache keys */
|
||||||
|
SCR_CACHE_COPY, /* we have a cached copy */
|
||||||
|
SCR_CACHE_PARTIAL, /* partial restore to real keys */
|
||||||
|
SCR_CACHE_COMPLETE /* complete restore to real keys */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Additional Conection State according to rfc5746 section 3.1 */
|
/* Additional Conection State according to rfc5746 section 3.1 */
|
||||||
typedef struct SecureRenegotiation {
|
typedef struct SecureRenegotiation {
|
||||||
byte enabled; /* secure_renegotiation flag from rfc */
|
byte enabled; /* secure_renegotiation flag in rfc */
|
||||||
byte client_verify_data[TLS_FINISHED_SZ];
|
enum key_cache_state cache_status; /* track key cache state */
|
||||||
byte server_verify_data[TLS_FINISHED_SZ];
|
byte client_verify_data[TLS_FINISHED_SZ]; /* cached */
|
||||||
|
byte server_verify_data[TLS_FINISHED_SZ]; /* cached */
|
||||||
|
Keys tmp_keys; /* can't overwrite real keys yet */
|
||||||
} SecureRenegotiation;
|
} SecureRenegotiation;
|
||||||
|
|
||||||
CYASSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions);
|
CYASSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions);
|
||||||
@ -1464,62 +1535,8 @@ enum ClientCertificateType {
|
|||||||
enum CipherType { stream, block, aead };
|
enum CipherType { stream, block, aead };
|
||||||
|
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
|
||||||
|
|
||||||
#ifdef WORD64_AVAILABLE
|
|
||||||
typedef word64 DtlsSeq;
|
|
||||||
#else
|
|
||||||
typedef word32 DtlsSeq;
|
|
||||||
#endif
|
|
||||||
#define DTLS_SEQ_BITS (sizeof(DtlsSeq) * CHAR_BIT)
|
|
||||||
|
|
||||||
typedef struct DtlsState {
|
|
||||||
DtlsSeq window; /* Sliding window for current epoch */
|
|
||||||
word16 nextEpoch; /* Expected epoch in next record */
|
|
||||||
word32 nextSeq; /* Expected sequence in next record */
|
|
||||||
|
|
||||||
word16 curEpoch; /* Received epoch in current record */
|
|
||||||
word32 curSeq; /* Received sequence in current record */
|
|
||||||
|
|
||||||
DtlsSeq prevWindow; /* Sliding window for old epoch */
|
|
||||||
word32 prevSeq; /* Next sequence in allowed old epoch */
|
|
||||||
} DtlsState;
|
|
||||||
|
|
||||||
#endif /* CYASSL_DTLS */
|
|
||||||
|
|
||||||
|
|
||||||
/* keys and secrets */
|
|
||||||
typedef struct Keys {
|
|
||||||
byte client_write_MAC_secret[MAX_DIGEST_SIZE]; /* max sizes */
|
|
||||||
byte server_write_MAC_secret[MAX_DIGEST_SIZE];
|
|
||||||
byte client_write_key[AES_256_KEY_SIZE]; /* max sizes */
|
|
||||||
byte server_write_key[AES_256_KEY_SIZE];
|
|
||||||
byte client_write_IV[AES_IV_SIZE]; /* max sizes */
|
|
||||||
byte server_write_IV[AES_IV_SIZE];
|
|
||||||
#ifdef HAVE_AEAD
|
|
||||||
byte aead_exp_IV[AEAD_EXP_IV_SZ];
|
|
||||||
byte aead_enc_imp_IV[AEAD_IMP_IV_SZ];
|
|
||||||
byte aead_dec_imp_IV[AEAD_IMP_IV_SZ];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
word32 peer_sequence_number;
|
|
||||||
word32 sequence_number;
|
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
|
||||||
DtlsState dtls_state; /* Peer's state */
|
|
||||||
word16 dtls_peer_handshake_number;
|
|
||||||
word16 dtls_expected_peer_handshake_number;
|
|
||||||
|
|
||||||
word16 dtls_epoch; /* Current tx epoch */
|
|
||||||
word32 dtls_sequence_number; /* Current tx sequence */
|
|
||||||
word16 dtls_handshake_number; /* Current tx handshake seq */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
word32 encryptSz; /* last size of encrypted data */
|
|
||||||
word32 padSz; /* how much to advance after decrypt part */
|
|
||||||
byte encryptionOn; /* true after change cipher spec */
|
|
||||||
byte decryptedCur; /* only decrypt current record once */
|
|
||||||
} Keys;
|
|
||||||
|
|
||||||
|
|
||||||
/* cipher for now */
|
/* cipher for now */
|
||||||
@ -2002,8 +2019,8 @@ struct CYASSL {
|
|||||||
byte truncated_hmac;
|
byte truncated_hmac;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
SecureRenegotiation* secure_renegotiation;
|
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
|
||||||
#endif
|
#endif /* user turned on */
|
||||||
#endif /* HAVE_TLS_EXTENSIONS */
|
#endif /* HAVE_TLS_EXTENSIONS */
|
||||||
#ifdef HAVE_NETX
|
#ifdef HAVE_NETX
|
||||||
NetX_Ctx nxCtx; /* NetX IO Context */
|
NetX_Ctx nxCtx; /* NetX IO Context */
|
||||||
|
@ -1312,12 +1312,11 @@ CYASSL_API int CyaSSL_CTX_UseSupportedCurve(CYASSL_CTX* ctx,
|
|||||||
|
|
||||||
/* Secure Renegotiation */
|
/* Secure Renegotiation */
|
||||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
#ifndef NO_CYASSL_CLIENT
|
|
||||||
|
|
||||||
CYASSL_API int CyaSSL_UseSecureRenegotiation(CYASSL* ssl);
|
CYASSL_API int CyaSSL_UseSecureRenegotiation(CYASSL* ssl);
|
||||||
|
CYASSL_API int CyaSSL_Rehandshake(CYASSL* ssl);
|
||||||
|
|
||||||
#endif
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
#endif
|
|
||||||
|
|
||||||
#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 */
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LIBCYASSL_VERSION_STRING "3.2.0"
|
#define LIBCYASSL_VERSION_STRING "3.2.1b"
|
||||||
#define LIBCYASSL_VERSION_HEX 0x03002000
|
#define LIBCYASSL_VERSION_HEX 0x03002001
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,9 @@ static void Usage(void)
|
|||||||
printf("-m Match domain name in cert\n");
|
printf("-m Match domain name in cert\n");
|
||||||
printf("-N Use Non-blocking sockets\n");
|
printf("-N Use Non-blocking sockets\n");
|
||||||
printf("-r Resume session\n");
|
printf("-r Resume session\n");
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
printf("-R Secure Renegotiation\n");
|
||||||
|
#endif
|
||||||
printf("-f Fewer packets/group messages\n");
|
printf("-f Fewer packets/group messages\n");
|
||||||
printf("-x Disable client cert/key loading\n");
|
printf("-x Disable client cert/key loading\n");
|
||||||
#ifdef SHOW_SIZES
|
#ifdef SHOW_SIZES
|
||||||
@ -193,6 +196,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
int doPeerCheck = 1;
|
int doPeerCheck = 1;
|
||||||
int nonBlocking = 0;
|
int nonBlocking = 0;
|
||||||
int resumeSession = 0;
|
int resumeSession = 0;
|
||||||
|
int scr = 0; /* secure renegotiation */
|
||||||
int trackMemory = 0;
|
int trackMemory = 0;
|
||||||
int useClientCert = 1;
|
int useClientCert = 1;
|
||||||
int fewerPackets = 0;
|
int fewerPackets = 0;
|
||||||
@ -236,11 +240,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
(void)trackMemory;
|
(void)trackMemory;
|
||||||
(void)atomicUser;
|
(void)atomicUser;
|
||||||
(void)pkCallbacks;
|
(void)pkCallbacks;
|
||||||
|
(void)scr;
|
||||||
|
|
||||||
StackTrap();
|
StackTrap();
|
||||||
|
|
||||||
while ((ch = mygetopt(argc, argv,
|
while ((ch = mygetopt(argc, argv,
|
||||||
"?gdDusmNrtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) {
|
"?gdDusmNrRtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?' :
|
case '?' :
|
||||||
Usage();
|
Usage();
|
||||||
@ -349,6 +354,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
resumeSession = 1;
|
resumeSession = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'R' :
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
scr = 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
case 'z' :
|
case 'z' :
|
||||||
#ifndef CYASSL_LEANPSK
|
#ifndef CYASSL_LEANPSK
|
||||||
CyaSSL_GetObjectSize();
|
CyaSSL_GetObjectSize();
|
||||||
@ -640,6 +651,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
|
if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
|
||||||
err_sys("can't set crl callback");
|
err_sys("can't set crl callback");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (scr) {
|
||||||
|
if (CyaSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
|
||||||
|
err_sys("can't enable secure renegotiation");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef ATOMIC_USER
|
#ifdef ATOMIC_USER
|
||||||
if (atomicUser)
|
if (atomicUser)
|
||||||
SetupAtomicUser(ctx, ssl);
|
SetupAtomicUser(ctx, ssl);
|
||||||
@ -672,6 +689,22 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
showPeer(ssl);
|
showPeer(ssl);
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (scr) {
|
||||||
|
if (nonBlocking) {
|
||||||
|
printf("not doing secure renegotiation on example with"
|
||||||
|
" nonblocking yet");
|
||||||
|
}
|
||||||
|
else if (CyaSSL_Rehandshake(ssl) != SSL_SUCCESS) {
|
||||||
|
int err = CyaSSL_get_error(ssl, 0);
|
||||||
|
char buffer[CYASSL_MAX_ERROR_SZ];
|
||||||
|
printf("err = %d, %s\n", err,
|
||||||
|
CyaSSL_ERR_error_string(err, buffer));
|
||||||
|
err_sys("CyaSSL_Rehandshake failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
if (sendGET) {
|
if (sendGET) {
|
||||||
printf("SSL connect ok, sending GET...\n");
|
printf("SSL connect ok, sending GET...\n");
|
||||||
msgSz = 28;
|
msgSz = 28;
|
||||||
|
109
src/internal.c
109
src/internal.c
@ -63,6 +63,8 @@
|
|||||||
CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
|
||||||
|
const byte* input, int inSz, int type);
|
||||||
|
|
||||||
#ifndef NO_CYASSL_CLIENT
|
#ifndef NO_CYASSL_CLIENT
|
||||||
static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*,
|
static int DoHelloVerifyRequest(CYASSL* ssl, const byte* input, word32*,
|
||||||
@ -2008,6 +2010,14 @@ void SSL_ResourceFree(CYASSL* ssl)
|
|||||||
/* Free any handshake resources no longer needed */
|
/* Free any handshake resources no longer needed */
|
||||||
void FreeHandshakeResources(CYASSL* ssl)
|
void FreeHandshakeResources(CYASSL* ssl)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
|
||||||
|
CYASSL_MSG("Secure Renegottation needs to retain handshake resources");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* input buffer */
|
/* input buffer */
|
||||||
if (ssl->buffers.inputBuffer.dynamicFlag)
|
if (ssl->buffers.inputBuffer.dynamicFlag)
|
||||||
ShrinkInputBuffer(ssl, NO_FORCED_FREE);
|
ShrinkInputBuffer(ssl, NO_FORCED_FREE);
|
||||||
@ -4351,6 +4361,10 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END)
|
if (ret == 0 && ssl->options.side == CYASSL_CLIENT_END)
|
||||||
ssl->options.serverState = SERVER_CERT_COMPLETE;
|
ssl->options.serverState = SERVER_CERT_COMPLETE;
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn) {
|
||||||
|
*inOutIdx += ssl->keys.padSz;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4468,9 +4482,11 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
if (*inOutIdx + size > totalSz)
|
if (*inOutIdx + size > totalSz)
|
||||||
return INCOMPLETE_DATA;
|
return INCOMPLETE_DATA;
|
||||||
|
|
||||||
ret = HashInput(ssl, input + *inOutIdx, size);
|
/* hello_request not hashed */
|
||||||
if (ret != 0)
|
if (type != hello_request) {
|
||||||
return ret;
|
ret = HashInput(ssl, input + *inOutIdx, size);
|
||||||
|
if (ret != 0) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
/* add name later, add on record and handshake header part back on */
|
/* add name later, add on record and handshake header part back on */
|
||||||
@ -4558,6 +4574,9 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
AddLateName("ServerHelloDone", &ssl->timeoutInfo);
|
AddLateName("ServerHelloDone", &ssl->timeoutInfo);
|
||||||
#endif
|
#endif
|
||||||
ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
|
ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
|
||||||
|
if (ssl->keys.encryptionOn) {
|
||||||
|
*inOutIdx += ssl->keys.padSz;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case finished:
|
case finished:
|
||||||
@ -6245,6 +6264,11 @@ int ProcessReply(CYASSL* ssl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
|
||||||
|
ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
|
||||||
|
ssl->curSize -= ssl->buffers.inputBuffer.idx;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssl->curSize != 1) {
|
if (ssl->curSize != 1) {
|
||||||
CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
|
CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
|
||||||
return LENGTH_ERROR;
|
return LENGTH_ERROR;
|
||||||
@ -6371,6 +6395,11 @@ int SendChangeCipher(CYASSL* ssl)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* are we in scr */
|
||||||
|
if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
|
||||||
|
sendSz += MAX_MSG_EXTRA;
|
||||||
|
}
|
||||||
|
|
||||||
/* check for avalaible size */
|
/* check for avalaible size */
|
||||||
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -6383,6 +6412,17 @@ int SendChangeCipher(CYASSL* ssl)
|
|||||||
|
|
||||||
output[idx] = 1; /* turn it on */
|
output[idx] = 1; /* turn it on */
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
|
||||||
|
byte input[ENUM_LEN];
|
||||||
|
int inputSz = ENUM_LEN;
|
||||||
|
|
||||||
|
input[0] = 1; /* turn it on */
|
||||||
|
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
|
||||||
|
change_cipher_spec);
|
||||||
|
if (sendSz < 0)
|
||||||
|
return sendSz;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
@ -8623,6 +8663,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn)
|
||||||
|
sendSz += MAX_MSG_EXTRA;
|
||||||
|
|
||||||
/* check for available size */
|
/* check for available size */
|
||||||
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -8710,6 +8753,26 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn) {
|
||||||
|
byte* input;
|
||||||
|
int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
|
||||||
|
|
||||||
|
input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (input == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
|
||||||
|
sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
|
||||||
|
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (sendSz < 0)
|
||||||
|
return sendSz;
|
||||||
|
} else {
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
@ -8717,10 +8780,6 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
@ -8938,6 +8997,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn) {
|
||||||
|
*inOutIdx += ssl->keys.padSz;
|
||||||
|
}
|
||||||
|
|
||||||
return SetCipherSpecs(ssl);
|
return SetCipherSpecs(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9820,6 +9883,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ssl->keys.encryptionOn)
|
||||||
|
sendSz += MAX_MSG_EXTRA;
|
||||||
|
|
||||||
/* check for available size */
|
/* check for available size */
|
||||||
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -9835,8 +9901,29 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
idx += 2;
|
idx += 2;
|
||||||
}
|
}
|
||||||
XMEMCPY(output + idx, encSecret, encSz);
|
XMEMCPY(output + idx, encSecret, encSz);
|
||||||
/* if add more to output, adjust idx
|
idx += encSz;
|
||||||
idx += encSz; */
|
|
||||||
|
if (ssl->keys.encryptionOn) {
|
||||||
|
byte* input;
|
||||||
|
int inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
|
||||||
|
|
||||||
|
input = (byte*)XMALLOC(inputSz, ssl->heap,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (input == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
|
||||||
|
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
|
||||||
|
handshake);
|
||||||
|
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (sendSz < 0)
|
||||||
|
return sendSz;
|
||||||
|
} else {
|
||||||
|
ret = HashOutput(ssl, output, sendSz, 0);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
if (ssl->options.dtls) {
|
if (ssl->options.dtls) {
|
||||||
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
|
||||||
@ -9844,10 +9931,6 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = HashOutput(ssl, output, sendSz, 0);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn)
|
if (ssl->hsInfoOn)
|
||||||
AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
|
AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
|
||||||
|
81
src/keys.c
81
src/keys.c
@ -2282,14 +2282,24 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
|||||||
/* Set encrypt/decrypt or both sides of key setup */
|
/* Set encrypt/decrypt or both sides of key setup */
|
||||||
int SetKeysSide(CYASSL* ssl, enum encrypt_side side)
|
int SetKeysSide(CYASSL* ssl, enum encrypt_side side)
|
||||||
{
|
{
|
||||||
int devId = NO_CAVIUM_DEVICE;
|
int devId = NO_CAVIUM_DEVICE, ret, copy = 0;
|
||||||
Ciphers* encrypt = NULL;
|
Ciphers* encrypt = NULL;
|
||||||
Ciphers* decrypt = NULL;
|
Ciphers* decrypt = NULL;
|
||||||
|
Keys* keys = &ssl->keys;
|
||||||
|
|
||||||
|
(void)copy;
|
||||||
|
|
||||||
#ifdef HAVE_CAVIUM
|
#ifdef HAVE_CAVIUM
|
||||||
devId = ssl->devId;
|
devId = ssl->devId;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status) {
|
||||||
|
keys = &ssl->secure_renegotiation->tmp_keys;
|
||||||
|
copy = 1;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
switch (side) {
|
switch (side) {
|
||||||
case ENCRYPT_SIDE_ONLY:
|
case ENCRYPT_SIDE_ONLY:
|
||||||
encrypt = &ssl->encrypt;
|
encrypt = &ssl->encrypt;
|
||||||
@ -2308,8 +2318,50 @@ int SetKeysSide(CYASSL* ssl, enum encrypt_side side)
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetKeys(encrypt, decrypt, &ssl->keys, &ssl->specs, ssl->options.side,
|
ret = SetKeys(encrypt, decrypt, keys, &ssl->specs, ssl->options.side,
|
||||||
ssl->heap, devId);
|
ssl->heap, devId);
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (copy) {
|
||||||
|
int clientCopy = 0;
|
||||||
|
|
||||||
|
if (ssl->options.side == CYASSL_CLIENT_END && encrypt)
|
||||||
|
clientCopy = 1;
|
||||||
|
else if (ssl->options.side == CYASSL_SERVER_END && decrypt)
|
||||||
|
clientCopy = 1;
|
||||||
|
|
||||||
|
if (clientCopy) {
|
||||||
|
XMEMCPY(ssl->keys.client_write_MAC_secret,
|
||||||
|
keys->client_write_MAC_secret, MAX_DIGEST_SIZE);
|
||||||
|
XMEMCPY(ssl->keys.client_write_key,
|
||||||
|
keys->client_write_key, AES_256_KEY_SIZE);
|
||||||
|
XMEMCPY(ssl->keys.client_write_IV,
|
||||||
|
keys->client_write_IV, AES_IV_SIZE);
|
||||||
|
} else {
|
||||||
|
XMEMCPY(ssl->keys.server_write_MAC_secret,
|
||||||
|
keys->server_write_MAC_secret, MAX_DIGEST_SIZE);
|
||||||
|
XMEMCPY(ssl->keys.server_write_key,
|
||||||
|
keys->server_write_key, AES_256_KEY_SIZE);
|
||||||
|
XMEMCPY(ssl->keys.server_write_IV,
|
||||||
|
keys->server_write_IV, AES_IV_SIZE);
|
||||||
|
}
|
||||||
|
if (encrypt) {
|
||||||
|
ssl->keys.sequence_number = keys->sequence_number;
|
||||||
|
#ifdef HAVE_AEAD
|
||||||
|
if (ssl->specs.cipher_type == aead) {
|
||||||
|
/* Initialize the AES-GCM/CCM explicit IV to a zero. */
|
||||||
|
XMEMCPY(ssl->keys.aead_exp_IV, keys->aead_exp_IV,
|
||||||
|
AEAD_EXP_IV_SZ);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (decrypt)
|
||||||
|
ssl->keys.peer_sequence_number = keys->peer_sequence_number;
|
||||||
|
ssl->secure_renegotiation->cache_status++;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2317,29 +2369,38 @@ int SetKeysSide(CYASSL* ssl, enum encrypt_side side)
|
|||||||
int StoreKeys(CYASSL* ssl, const byte* keyData)
|
int StoreKeys(CYASSL* ssl, const byte* keyData)
|
||||||
{
|
{
|
||||||
int sz, i = 0;
|
int sz, i = 0;
|
||||||
|
Keys* keys = &ssl->keys;
|
||||||
|
|
||||||
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
if (ssl->secure_renegotiation && ssl->secure_renegotiation->cache_status ==
|
||||||
|
SCR_CACHE_NEEDED) {
|
||||||
|
keys = &ssl->secure_renegotiation->tmp_keys;
|
||||||
|
ssl->secure_renegotiation->cache_status++;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
if (ssl->specs.cipher_type != aead) {
|
if (ssl->specs.cipher_type != aead) {
|
||||||
sz = ssl->specs.hash_size;
|
sz = ssl->specs.hash_size;
|
||||||
XMEMCPY(ssl->keys.client_write_MAC_secret,&keyData[i], sz);
|
XMEMCPY(keys->client_write_MAC_secret,&keyData[i], sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
|
XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
}
|
}
|
||||||
sz = ssl->specs.key_size;
|
sz = ssl->specs.key_size;
|
||||||
XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz);
|
XMEMCPY(keys->client_write_key, &keyData[i], sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
XMEMCPY(ssl->keys.server_write_key, &keyData[i], sz);
|
XMEMCPY(keys->server_write_key, &keyData[i], sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
|
|
||||||
sz = ssl->specs.iv_size;
|
sz = ssl->specs.iv_size;
|
||||||
XMEMCPY(ssl->keys.client_write_IV, &keyData[i], sz);
|
XMEMCPY(keys->client_write_IV, &keyData[i], sz);
|
||||||
i += sz;
|
i += sz;
|
||||||
XMEMCPY(ssl->keys.server_write_IV, &keyData[i], sz);
|
XMEMCPY(keys->server_write_IV, &keyData[i], sz);
|
||||||
|
|
||||||
#ifdef HAVE_AEAD
|
#ifdef HAVE_AEAD
|
||||||
if (ssl->specs.cipher_type == aead) {
|
if (ssl->specs.cipher_type == aead) {
|
||||||
/* Initialize the AES-GCM/CCM explicit IV to a zero. */
|
/* Initialize the AES-GCM/CCM explicit IV to a zero. */
|
||||||
XMEMSET(ssl->keys.aead_exp_IV, 0, AEAD_EXP_IV_SZ);
|
XMEMSET(keys->aead_exp_IV, 0, AEAD_EXP_IV_SZ);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
62
src/ssl.c
62
src/ssl.c
@ -717,6 +717,7 @@ int CyaSSL_CTX_UseSupportedCurve(CYASSL_CTX* ctx, word16 name)
|
|||||||
/* Secure Renegotiation */
|
/* Secure Renegotiation */
|
||||||
#ifdef HAVE_SECURE_RENEGOTIATION
|
#ifdef HAVE_SECURE_RENEGOTIATION
|
||||||
|
|
||||||
|
/* user is forcing ability to use secure renegotiation, we discourage it */
|
||||||
int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
|
int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
|
||||||
{
|
{
|
||||||
int ret = BAD_FUNC_ARG;
|
int ret = BAD_FUNC_ARG;
|
||||||
@ -734,9 +735,70 @@ int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* do a secure renegotiation handshake, use forced, we discourage */
|
||||||
|
int CyaSSL_Rehandshake(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ssl == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (ssl->secure_renegotiation == NULL) {
|
||||||
|
CYASSL_MSG("Secure Renegotiation not forced on by user");
|
||||||
|
return SECURE_RENEGOTIATION_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl->secure_renegotiation->enabled == 0) {
|
||||||
|
CYASSL_MSG("Secure Renegotiation not enabled at extension level");
|
||||||
|
return SECURE_RENEGOTIATION_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
|
||||||
|
CYASSL_MSG("Can't renegotiate until previous handshake complete");
|
||||||
|
return SECURE_RENEGOTIATION_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset handshake states */
|
||||||
|
ssl->options.serverState = NULL_STATE;
|
||||||
|
ssl->options.clientState = NULL_STATE;
|
||||||
|
ssl->options.connectState = CONNECT_BEGIN;
|
||||||
|
ssl->options.acceptState = ACCEPT_BEGIN;
|
||||||
|
ssl->options.handShakeState = NULL_STATE;
|
||||||
|
ssl->options.processReply = 0; /* TODO, move states in internal.h */
|
||||||
|
|
||||||
|
ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
|
||||||
|
|
||||||
|
#ifndef NO_OLD_TLS
|
||||||
|
#ifndef NO_MD5
|
||||||
|
InitMd5(&ssl->hashMd5);
|
||||||
|
#endif
|
||||||
|
#ifndef NO_SHA
|
||||||
|
ret = InitSha(&ssl->hashSha);
|
||||||
|
if (ret !=0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
#endif /* NO_OLD_TLS */
|
||||||
|
#ifndef NO_SHA256
|
||||||
|
ret = InitSha256(&ssl->hashSha256);
|
||||||
|
if (ret !=0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
#ifdef CYASSL_SHA384
|
||||||
|
ret = InitSha384(&ssl->hashSha384);
|
||||||
|
if (ret !=0)
|
||||||
|
return ret;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ret = CyaSSL_negotiate(ssl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||||
|
|
||||||
|
|
||||||
#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)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
Reference in New Issue
Block a user