add client side initiated secure r, same specs

This commit is contained in:
toddouska 2014-09-24 18:48:23 -07:00
parent 74c6f35766
commit 0c20584ed3
9 changed files with 347 additions and 91 deletions

View File

@ -77,9 +77,10 @@ include testsuite/include.am
include tests/include.am
include sslSniffer/sslSnifferTest/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_client/Sources/include.am
#include mqx/cyassl_client/Sources/include.am
include mqx/util_lib/Sources/include.am
include mplabx/include.am
include mplabx/ctaocrypt_benchmark.X/nbproject/include.am

View File

@ -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])

View File

@ -1165,6 +1165,66 @@ typedef struct CYASSL_DTLS_CTX {
int fd;
} 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 */
#ifdef HAVE_TLS_EXTENSIONS
@ -1260,11 +1320,22 @@ CYASSL_LOCAL int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first,
#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 */
typedef struct SecureRenegotiation {
byte enabled; /* secure_renegotiation flag from rfc */
byte client_verify_data[TLS_FINISHED_SZ];
byte server_verify_data[TLS_FINISHED_SZ];
byte enabled; /* secure_renegotiation flag in rfc */
enum key_cache_state cache_status; /* track key cache state */
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;
CYASSL_LOCAL int TLSX_UseSecureRenegotiation(TLSX** extensions);
@ -1464,62 +1535,8 @@ enum ClientCertificateType {
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 */
@ -2002,8 +2019,8 @@ struct CYASSL {
byte truncated_hmac;
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
SecureRenegotiation* secure_renegotiation;
#endif
SecureRenegotiation* secure_renegotiation; /* valid pointer indicates */
#endif /* user turned on */
#endif /* HAVE_TLS_EXTENSIONS */
#ifdef HAVE_NETX
NetX_Ctx nxCtx; /* NetX IO Context */

View File

@ -1312,12 +1312,11 @@ CYASSL_API int CyaSSL_CTX_UseSupportedCurve(CYASSL_CTX* ctx,
/* Secure Renegotiation */
#ifdef HAVE_SECURE_RENEGOTIATION
#ifndef NO_CYASSL_CLIENT
CYASSL_API int CyaSSL_UseSecureRenegotiation(CYASSL* ssl);
CYASSL_API int CyaSSL_Rehandshake(CYASSL* ssl);
#endif
#endif
#endif /* HAVE_SECURE_RENEGOTIATION */
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */

View File

@ -26,8 +26,8 @@
extern "C" {
#endif
#define LIBCYASSL_VERSION_STRING "3.2.0"
#define LIBCYASSL_VERSION_HEX 0x03002000
#define LIBCYASSL_VERSION_STRING "3.2.1b"
#define LIBCYASSL_VERSION_HEX 0x03002001
#ifdef __cplusplus
}

View File

@ -135,6 +135,9 @@ static void Usage(void)
printf("-m Match domain name in cert\n");
printf("-N Use Non-blocking sockets\n");
printf("-r Resume session\n");
#ifdef HAVE_SECURE_RENEGOTIATION
printf("-R Secure Renegotiation\n");
#endif
printf("-f Fewer packets/group messages\n");
printf("-x Disable client cert/key loading\n");
#ifdef SHOW_SIZES
@ -193,6 +196,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
int doPeerCheck = 1;
int nonBlocking = 0;
int resumeSession = 0;
int scr = 0; /* secure renegotiation */
int trackMemory = 0;
int useClientCert = 1;
int fewerPackets = 0;
@ -236,11 +240,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
(void)trackMemory;
(void)atomicUser;
(void)pkCallbacks;
(void)scr;
StackTrap();
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) {
case '?' :
Usage();
@ -349,6 +354,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
resumeSession = 1;
break;
case 'R' :
#ifdef HAVE_SECURE_RENEGOTIATION
scr = 1;
#endif
break;
case 'z' :
#ifndef CYASSL_LEANPSK
CyaSSL_GetObjectSize();
@ -640,6 +651,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
err_sys("can't set crl callback");
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
if (scr) {
if (CyaSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
err_sys("can't enable secure renegotiation");
}
#endif
#ifdef ATOMIC_USER
if (atomicUser)
SetupAtomicUser(ctx, ssl);
@ -672,6 +689,22 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
#endif
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) {
printf("SSL connect ok, sending GET...\n");
msgSz = 28;

View File

@ -63,6 +63,8 @@
CYASSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
#endif
static int BuildMessage(CYASSL* ssl, byte* output, int outSz,
const byte* input, int inSz, int type);
#ifndef NO_CYASSL_CLIENT
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 */
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 */
if (ssl->buffers.inputBuffer.dynamicFlag)
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)
ssl->options.serverState = SERVER_CERT_COMPLETE;
if (ssl->keys.encryptionOn) {
*inOutIdx += ssl->keys.padSz;
}
return ret;
}
@ -4468,9 +4482,11 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx,
if (*inOutIdx + size > totalSz)
return INCOMPLETE_DATA;
ret = HashInput(ssl, input + *inOutIdx, size);
if (ret != 0)
return ret;
/* hello_request not hashed */
if (type != hello_request) {
ret = HashInput(ssl, input + *inOutIdx, size);
if (ret != 0) return ret;
}
#ifdef CYASSL_CALLBACKS
/* 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);
#endif
ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
if (ssl->keys.encryptionOn) {
*inOutIdx += ssl->keys.padSz;
}
break;
case finished:
@ -6245,6 +6264,11 @@ int ProcessReply(CYASSL* ssl)
}
#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) {
CYASSL_MSG("Malicious or corrupted ChangeCipher msg");
return LENGTH_ERROR;
@ -6371,6 +6395,11 @@ int SendChangeCipher(CYASSL* ssl)
}
#endif
/* are we in scr */
if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
sendSz += MAX_MSG_EXTRA;
}
/* check for avalaible size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -6383,6 +6412,17 @@ int SendChangeCipher(CYASSL* ssl)
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
if (ssl->options.dtls) {
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
@ -8623,6 +8663,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#endif
if (ssl->keys.encryptionOn)
sendSz += MAX_MSG_EXTRA;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -8710,6 +8753,26 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#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
if (ssl->options.dtls) {
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
@ -8717,10 +8780,6 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
#ifdef CYASSL_CALLBACKS
@ -8938,6 +8997,10 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#endif
if (ssl->keys.encryptionOn) {
*inOutIdx += ssl->keys.padSz;
}
return SetCipherSpecs(ssl);
}
@ -9820,6 +9883,9 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#endif
if (ssl->keys.encryptionOn)
sendSz += MAX_MSG_EXTRA;
/* check for available size */
if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
return ret;
@ -9835,8 +9901,29 @@ static void PickHashSigAlgo(CYASSL* ssl,
idx += 2;
}
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
if (ssl->options.dtls) {
if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
@ -9844,10 +9931,6 @@ static void PickHashSigAlgo(CYASSL* ssl,
}
#endif
ret = HashOutput(ssl, output, sendSz, 0);
if (ret != 0)
return ret;
#ifdef CYASSL_CALLBACKS
if (ssl->hsInfoOn)
AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);

View File

@ -2282,14 +2282,24 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
/* Set encrypt/decrypt or both sides of key setup */
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* decrypt = NULL;
Keys* keys = &ssl->keys;
(void)copy;
#ifdef HAVE_CAVIUM
devId = ssl->devId;
#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) {
case ENCRYPT_SIDE_ONLY:
encrypt = &ssl->encrypt;
@ -2308,8 +2318,50 @@ int SetKeysSide(CYASSL* ssl, enum encrypt_side side)
return BAD_FUNC_ARG;
}
return SetKeys(encrypt, decrypt, &ssl->keys, &ssl->specs, ssl->options.side,
ssl->heap, devId);
ret = SetKeys(encrypt, decrypt, keys, &ssl->specs, ssl->options.side,
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 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) {
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;
XMEMCPY(ssl->keys.server_write_MAC_secret,&keyData[i], sz);
XMEMCPY(keys->server_write_MAC_secret,&keyData[i], sz);
i += sz;
}
sz = ssl->specs.key_size;
XMEMCPY(ssl->keys.client_write_key, &keyData[i], sz);
XMEMCPY(keys->client_write_key, &keyData[i], sz);
i += sz;
XMEMCPY(ssl->keys.server_write_key, &keyData[i], sz);
XMEMCPY(keys->server_write_key, &keyData[i], sz);
i += sz;
sz = ssl->specs.iv_size;
XMEMCPY(ssl->keys.client_write_IV, &keyData[i], sz);
XMEMCPY(keys->client_write_IV, &keyData[i], sz);
i += sz;
XMEMCPY(ssl->keys.server_write_IV, &keyData[i], sz);
XMEMCPY(keys->server_write_IV, &keyData[i], sz);
#ifdef HAVE_AEAD
if (ssl->specs.cipher_type == aead) {
/* 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

View File

@ -717,6 +717,7 @@ int CyaSSL_CTX_UseSupportedCurve(CYASSL_CTX* ctx, word16 name)
/* Secure Renegotiation */
#ifdef HAVE_SECURE_RENEGOTIATION
/* user is forcing ability to use secure renegotiation, we discourage it */
int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
{
int ret = BAD_FUNC_ARG;
@ -734,9 +735,70 @@ int CyaSSL_UseSecureRenegotiation(CYASSL* ssl)
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
ret = CyaSSL_negotiate(ssl);
return ret;
}
#endif /* HAVE_SECURE_RENEGOTIATION */
#ifndef CYASSL_LEANPSK
int CyaSSL_send(CYASSL* ssl, const void* data, int sz, int flags)
{
int ret;