diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index e8399f2f8..fe3c77400 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -215,7 +215,8 @@ enum { DYNAMIC_TYPE_CRL_MONITOR = 26, DYNAMIC_TYPE_OCSP_STATUS = 27, DYNAMIC_TYPE_OCSP_ENTRY = 28, - DYNAMIC_TYPE_ALTNAME = 29 + DYNAMIC_TYPE_ALTNAME = 29, + DYNAMIC_TYPE_SUITES = 30 }; /* stack protection */ diff --git a/cyassl/error.h b/cyassl/error.h index 82df03500..d9d35ff75 100644 --- a/cyassl/error.h +++ b/cyassl/error.h @@ -103,6 +103,7 @@ enum CyaSSL_ErrorCodes { MAX_CHAIN_ERROR = -268, /* max chain depth exceeded */ COOKIE_ERROR = -269, /* dtls cookie error */ SEQUENCE_ERROR = -270, /* dtls sequence error */ + SUITES_ERROR = -271, /* suites pointer error */ /* add strings to SetErrorString !!!!! */ /* begin negotiation parameter errors */ diff --git a/cyassl/internal.h b/cyassl/internal.h index 6bc38919a..c7e9f2aab 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1211,7 +1211,7 @@ struct CYASSL { int error; ProtocolVersion version; /* negotiated version */ ProtocolVersion chVersion; /* client hello version */ - Suites suites; + Suites* suites; /* only need during handshake */ Ciphers encrypt; Ciphers decrypt; CipherSpecs specs; @@ -1444,6 +1444,7 @@ CYASSL_LOCAL int StoreKeys(CYASSL* ssl, const byte* keyData); CYASSL_LOCAL int IsTLS(const CYASSL* ssl); CYASSL_LOCAL int IsAtLeastTLSv1_2(const CYASSL* ssl); +CYASSL_LOCAL void FreeHandshakeResources(CYASSL* ssl); CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree); CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl); CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash); diff --git a/src/internal.c b/src/internal.c index d60257960..35ff59f83 100644 --- a/src/internal.c +++ b/src/internal.c @@ -450,6 +450,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, (void)haveNTRU; (void)haveStaticECC; + if (suites == NULL) { + CYASSL_MSG("InitSuites pointer error"); + return; + } + if (suites->setSuites) return; /* trust user settings, don't override */ @@ -815,7 +820,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) ssl->ctx = ctx; /* only for passing to calls, options could change */ ssl->version = ctx->method->version; - ssl->suites = ctx->suites; + ssl->suites = NULL; #ifdef HAVE_LIBZ ssl->didStreamInit = 0; @@ -1010,6 +1015,14 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) if ( (ret = InitRng(&ssl->rng)) != 0) return ret; + ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + DYNAMIC_TYPE_SUITES); + if (ssl->suites == NULL) { + CYASSL_MSG("Suites Memory error"); + return MEMORY_E; + } + *ssl->suites = ctx->suites; + /* make sure server has cert and key unless using PSK */ if (ssl->options.side == SERVER_END && !havePSK) if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) { @@ -1019,11 +1032,11 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) /* make sure server has DH parms, and add PSK if there, add NTRU too */ if (ssl->options.side == SERVER_END) - InitSuites(&ssl->suites, ssl->version,ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version,ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); else - InitSuites(&ssl->suites, ssl->version, TRUE, havePSK, + InitSuites(ssl->suites, ssl->version, TRUE, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -1034,6 +1047,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) /* In case holding SSL object in array and don't want to free actual ssl */ void SSL_ResourceFree(CYASSL* ssl) { + XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH); /* parameters (p,g) may be owned by ctx */ @@ -1078,6 +1092,17 @@ void SSL_ResourceFree(CYASSL* ssl) } +/* Free any handshake resources no longer needed */ +void FreeHandshakeResources(CYASSL* ssl) +{ + if (ssl->buffers.inputBuffer.dynamicFlag) + ShrinkInputBuffer(ssl, NO_FORCED_FREE); + + XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->suites = NULL; +} + + void FreeSSL(CYASSL* ssl) { FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */ @@ -3959,6 +3984,10 @@ void SetErrorString(int error, char* str) XSTRNCPY(str, "DTLS Sequence Error", max); break; + case SUITES_ERROR: + XSTRNCPY(str, "Suites Pointer Error", max); + break; + default : XSTRNCPY(str, "unknown error number", max); } @@ -4380,6 +4409,11 @@ int SetCipherList(Suites* s, const char* list) const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]); int idx = 0; + if (s == NULL) { + CYASSL_MSG("SetCipherList suite pointer error"); + return 0; + } + if (!list) return 0; @@ -4579,9 +4613,14 @@ int SetCipherList(Suites* s, const char* list) int idSz = ssl->options.resuming ? ID_LEN : 0; int ret; + if (ssl->suites == NULL) { + CYASSL_MSG("Bad suites pointer in SendClientHello"); + return SUITES_ERROR; + } + length = sizeof(ProtocolVersion) + RAN_LEN + idSz + ENUM_LEN - + ssl->suites.suiteSz + SUITE_LEN + + ssl->suites->suiteSz + SUITE_LEN + COMP_LEN + ENUM_LEN; if (IsAtLeastTLSv1_2(ssl)) @@ -4647,10 +4686,10 @@ int SetCipherList(Suites* s, const char* list) } #endif /* then cipher suites */ - c16toa(ssl->suites.suiteSz, output + idx); + c16toa(ssl->suites->suiteSz, output + idx); idx += 2; - XMEMCPY(output + idx, &ssl->suites.suites, ssl->suites.suiteSz); - idx += ssl->suites.suiteSz; + XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz); + idx += ssl->suites->suiteSz; /* last, compression */ output[idx++] = COMP_LEN; @@ -6301,11 +6340,19 @@ int SetCipherList(Suites* s, const char* list) { int haveRSA = !ssl->options.haveStaticECC; int havePSK = 0; - byte first = ssl->suites.suites[idx]; - byte second = ssl->suites.suites[idx+1]; + byte first; + byte second; CYASSL_ENTER("VerifySuite"); + if (ssl->suites == NULL) { + CYASSL_MSG("Suites pointer error"); + return 0; + } + + first = ssl->suites->suites[idx]; + second = ssl->suites->suites[idx+1]; + #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif @@ -6385,16 +6432,19 @@ int SetCipherList(Suites* s, const char* list) if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1) return MATCH_SUITE_ERROR; + if (ssl->suites == NULL) + return SUITES_ERROR; + /* start with best, if a match we are good */ - for (i = 0; i < ssl->suites.suiteSz; i += 2) + for (i = 0; i < ssl->suites->suiteSz; i += 2) for (j = 0; j < peerSuites->suiteSz; j += 2) - if (ssl->suites.suites[i] == peerSuites->suites[j] && - ssl->suites.suites[i+1] == peerSuites->suites[j+1] ) { + if (ssl->suites->suites[i] == peerSuites->suites[j] && + ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) { if (VerifySuite(ssl, i)) { CYASSL_MSG("Verified suite validity"); - ssl->options.cipherSuite0 = ssl->suites.suites[i]; - ssl->options.cipherSuite = ssl->suites.suites[i+1]; + ssl->options.cipherSuite0 = ssl->suites->suites[i]; + ssl->options.cipherSuite = ssl->suites->suites[i+1]; return SetCipherSpecs(ssl); } else { @@ -6469,7 +6519,7 @@ int SetCipherList(Suites* s, const char* list) havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -6600,7 +6650,7 @@ int SetCipherList(Suites* s, const char* list) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } diff --git a/src/ssl.c b/src/ssl.c index 9352d8192..144d6215b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -278,7 +278,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -564,7 +564,7 @@ int CyaSSL_SetVersion(CYASSL* ssl, int version) havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -2188,14 +2188,14 @@ int CyaSSL_CTX_set_cipher_list(CYASSL_CTX* ctx, const char* list) int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list) { CYASSL_ENTER("CyaSSL_set_cipher_list"); - if (SetCipherList(&ssl->suites, list)) { + if (SetCipherList(ssl->suites, list)) { byte havePSK = 0; #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -2414,8 +2414,7 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list) CYASSL_MSG("connect state: SECOND_REPLY_DONE"); case SECOND_REPLY_DONE: - if (ssl->buffers.inputBuffer.dynamicFlag) - ShrinkInputBuffer(ssl, NO_FORCED_FREE); + FreeHandshakeResources(ssl); CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS); return SSL_SUCCESS; @@ -2651,8 +2650,7 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list) CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE"); case ACCEPT_THIRD_REPLY_DONE : - if (ssl->buffers.inputBuffer.dynamicFlag) - ShrinkInputBuffer(ssl, NO_FORCED_FREE); + FreeHandshakeResources(ssl); CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS); return SSL_SUCCESS; @@ -3222,7 +3220,7 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->options.havePSK = 1; ssl->options.client_psk_cb = cb; - InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU, + InitSuites(ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -3243,7 +3241,7 @@ int CyaSSL_set_compression(CYASSL* ssl) ssl->options.havePSK = 1; ssl->options.server_psk_cb = cb; - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, TRUE, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -3468,7 +3466,7 @@ int CyaSSL_set_compression(CYASSL* ssl) #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); }