diff --git a/src/crl.c b/src/crl.c index b39e2e77f..dde30a28e 100644 --- a/src/crl.c +++ b/src/crl.c @@ -263,7 +263,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type) { int ret = SSL_SUCCESS; const byte* myBuffer = buff; /* if DER ok, otherwise switch */ - DerBuffer der; + DerBuffer* der = NULL; #ifdef WOLFSSL_SMALL_STACK DecodedCRL* dcrl; #else @@ -275,11 +275,6 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type) if (crl == NULL || buff == NULL || sz == 0) return BAD_FUNC_ARG; - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - if (type == SSL_FILETYPE_PEM) { int eccKey = 0; /* not used */ EncryptedInfo info; @@ -287,8 +282,8 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type) ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey); if (ret == 0) { - myBuffer = der.buffer; - sz = der.length; + myBuffer = der->buffer; + sz = der->length; } else { WOLFSSL_MSG("Pem to Der failed"); diff --git a/src/internal.c b/src/internal.c index 7cebc84d4..eadc88134 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1643,7 +1643,7 @@ void InitX509(WOLFSSL_X509* x509, int dynamicFlag) x509->version = 0; x509->pubKey.buffer = NULL; x509->sig.buffer = NULL; - InitDer(&x509->derCert); + x509->derCert = NULL; x509->altNames = NULL; x509->altNamesNext = NULL; x509->dynamicMemory = (byte)dynamicFlag; @@ -1861,9 +1861,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) #ifndef NO_CERTS /* ctx still owns certificate, certChain, key, dh, and cm */ - XMEMCPY(&ssl->buffers.certificate, &ctx->certificate, sizeof(DerBuffer)); - XMEMCPY(&ssl->buffers.certChain, &ctx->certChain, sizeof(DerBuffer)); - XMEMCPY(&ssl->buffers.key, &ctx->privateKey, sizeof(DerBuffer)); + ssl->buffers.certificate = ctx->certificate; + ssl->buffers.certChain = ctx->certChain; + ssl->buffers.key = ctx->privateKey; #endif #ifdef HAVE_CAVIUM @@ -1898,7 +1898,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) /* make sure server has cert and key unless using PSK or Anon * This should be true even if just switching ssl ctx */ if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon) - if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) { + if (!ssl->buffers.certificate || !ssl->buffers.certificate->buffer || + !ssl->buffers.key || !ssl->buffers.key->buffer) { WOLFSSL_MSG("Server missing certificate and/or private key"); return NO_PRIVATE_KEY; } @@ -4472,7 +4473,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) /* store cert for potential retrieval */ if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, NULL) == 0) { - XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx); + XMEMCPY(x509->derCert->buffer, dCert->source, dCert->maxIdx); } else { ret = MEMORY_E; @@ -4544,7 +4545,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, int anyError = 0; int totalCerts = 0; /* number of certs in certs buffer */ int count; - DerBuffer certs[MAX_CHAIN_DEPTH]; + buffer certs[MAX_CHAIN_DEPTH]; #ifdef WOLFSSL_SMALL_STACK char* domain = NULL; @@ -4591,10 +4592,6 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, if ((*inOutIdx - begin) + certSz > size) return BUFFER_ERROR; - ret = InitDer(&certs[totalCerts]); - if (ret < 0) { - return 0; - } certs[totalCerts].length = certSz; certs[totalCerts].buffer = input + *inOutIdx; @@ -4628,7 +4625,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* verify up to peer's first */ while (count > 1) { - DerBuffer myCert = certs[count - 1]; + buffer myCert = certs[count - 1]; byte* subjectHash; InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap); @@ -4647,11 +4644,8 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("Chain cert not verified by option, not adding as CA"); } else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) { - DerBuffer add; - ret = InitDer(&add); - if (ret == 0) { - ret = AllocDer(&add, myCert.length, CA_TYPE, ssl->heap); - } + DerBuffer* add = NULL; + ret = AllocDer(&add, myCert.length, CA_TYPE, ssl->heap); if (ret < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -4661,7 +4655,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG("Adding CA from chain"); - XMEMCPY(add.buffer, myCert.buffer, myCert.length); + XMEMCPY(add->buffer, myCert.buffer, myCert.length); /* already verified above */ ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0); @@ -4720,7 +4714,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* peer's, may not have one if blank client cert sent by TLSv1.2 */ if (count) { - DerBuffer myCert = certs[0]; + buffer myCert = certs[0]; int fatal = 0; WOLFSSL_MSG("Verifying Peer's cert"); @@ -8281,15 +8275,19 @@ int SendCertificate(WOLFSSL* ssl) listSz = 0; } else { - certSz = ssl->buffers.certificate.length; + if (!ssl->buffers.certificate) { + WOLFSSL_MSG("Send Cert missing certificate buffer"); + return BUFFER_ERROR; + } + certSz = ssl->buffers.certificate->length; headerSz = 2 * CERT_HEADER_SZ; /* list + cert size */ length = certSz + headerSz; listSz = certSz + CERT_HEADER_SZ; /* may need to send rest of chain, already has leading size(s) */ - if (certSz) { - certChainSz = ssl->buffers.certChain.length; + if (certSz && ssl->buffers.certChain) { + certChainSz = ssl->buffers.certChain->length; length += certChainSz; listSz += certChainSz; } @@ -8399,9 +8397,9 @@ int SendCertificate(WOLFSSL* ssl) fragSz -= CERT_HEADER_SZ; if (!IsEncryptionOn(ssl, 1)) { - HashOutputRaw(ssl, ssl->buffers.certificate.buffer, certSz); + HashOutputRaw(ssl, ssl->buffers.certificate->buffer, certSz); if (certChainSz) - HashOutputRaw(ssl, ssl->buffers.certChain.buffer, + HashOutputRaw(ssl, ssl->buffers.certChain->buffer, certChainSz); } } @@ -8423,7 +8421,7 @@ int SendCertificate(WOLFSSL* ssl) if (certSz && ssl->fragOffset < certSz) { word32 copySz = min(certSz - ssl->fragOffset, fragSz); XMEMCPY(output + i, - ssl->buffers.certificate.buffer + ssl->fragOffset, copySz); + ssl->buffers.certificate->buffer + ssl->fragOffset, copySz); i += copySz; ssl->fragOffset += copySz; length -= copySz; @@ -8432,7 +8430,7 @@ int SendCertificate(WOLFSSL* ssl) if (certChainSz && fragSz) { word32 copySz = min(certChainSz + certSz - ssl->fragOffset, fragSz); XMEMCPY(output + i, - ssl->buffers.certChain.buffer + ssl->fragOffset - certSz, + ssl->buffers.certChain->buffer + ssl->fragOffset - certSz, copySz); i += copySz; ssl->fragOffset += copySz; @@ -8714,7 +8712,7 @@ int SendCertificateStatus(WOLFSSL* ssl) return 0; if (!request || ssl->buffers.weOwnCert) { - DerBuffer der = ssl->buffers.certificate; + DerBuffer* der = ssl->buffers.certificate; #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert = NULL; #else @@ -8722,7 +8720,7 @@ int SendCertificateStatus(WOLFSSL* ssl) #endif /* unable to fetch status. skip. */ - if (der.buffer == NULL || der.length == 0) + if (der->buffer == NULL || der->length == 0) return 0; #ifdef WOLFSSL_SMALL_STACK @@ -8732,7 +8730,7 @@ int SendCertificateStatus(WOLFSSL* ssl) return MEMORY_E; #endif - InitDecodedCert(cert, der.buffer, der.length, NULL); + InitDecodedCert(cert, der->buffer, der->length, NULL); if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, ssl->ctx->cm)) != 0) { @@ -8811,7 +8809,7 @@ int SendCertificateStatus(WOLFSSL* ssl) return 0; if (!request || ssl->buffers.weOwnCert) { - DerBuffer der = ssl->buffers.certificate; + DerBuffer* der = ssl->buffers.certificate; #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert = NULL; #else @@ -8819,7 +8817,7 @@ int SendCertificateStatus(WOLFSSL* ssl) #endif /* unable to fetch status. skip. */ - if (der.buffer == NULL || der.length == 0) + if (der->buffer == NULL || der->length == 0) return 0; #ifdef WOLFSSL_SMALL_STACK @@ -8829,7 +8827,7 @@ int SendCertificateStatus(WOLFSSL* ssl) return MEMORY_E; #endif - InitDecodedCert(cert, der.buffer, der.length, NULL); + InitDecodedCert(cert, der->buffer, der->length, NULL); if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, ssl->ctx->cm)) != 0) { @@ -8884,7 +8882,7 @@ int SendCertificateStatus(WOLFSSL* ssl) if (ret == 0 && (!ssl->ctx->chainOcspRequest[0] || ssl->buffers.weOwnCertChain)) { - DerBuffer der; + DerBuffer* der = NULL; word32 idx = 0; #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert = NULL; @@ -8892,11 +8890,6 @@ int SendCertificateStatus(WOLFSSL* ssl) DecodedCert cert[1]; #endif - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - #ifdef WOLFSSL_SMALL_STACK cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -8904,17 +8897,17 @@ int SendCertificateStatus(WOLFSSL* ssl) return MEMORY_E; #endif - while (idx + OPAQUE24_LEN < ssl->buffers.certChain.length) { - c24to32(ssl->buffers.certChain.buffer + idx, &der.length); + while (idx + OPAQUE24_LEN < ssl->buffers.certChain->length) { + c24to32(ssl->buffers.certChain->buffer + idx, &der->length); idx += OPAQUE24_LEN; - der.buffer = ssl->buffers.certChain.buffer + idx; - idx += der.length; + der->buffer = ssl->buffers.certChain->buffer + idx; + idx += der->length; - if (idx > ssl->buffers.certChain.length) + if (idx > ssl->buffers.certChain->length) break; - InitDecodedCert(cert, der.buffer, der.length, NULL); + InitDecodedCert(cert, der->buffer, der->length, NULL); if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY, ssl->ctx->cm)) != 0) { @@ -11351,7 +11344,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl, /* don't send client cert or cert verify if user hasn't provided cert and private key */ - if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer) + if (ssl->buffers.certificate && ssl->buffers.certificate->buffer && + ssl->buffers.key && ssl->buffers.key->buffer) ssl->options.sendVerify = SEND_CERT; else if (IsTLS(ssl)) ssl->options.sendVerify = SEND_BLANK_CERT; @@ -13433,8 +13427,8 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) ret = wc_InitRsaKey(&key, ssl->heap); if (ret == 0) initRsaKey = 1; if (ret == 0) - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key, - ssl->buffers.key.length); + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &key, + ssl->buffers.key->length); if (ret == 0) sigOutSz = wc_RsaEncryptSize(&key); else @@ -13442,10 +13436,15 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) { #ifdef HAVE_ECC WOLFSSL_MSG("Trying ECC client cert, RSA didn't work"); + + if (ssl->buffers.key == NULL) { + WOLFSSL_MSG("ECC Key missing"); + return NO_PRIVATE_KEY; + } idx = 0; - ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey, - ssl->buffers.key.length); + ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx, &eccKey, + ssl->buffers.key->length); if (ret == 0) { WOLFSSL_MSG("Using ECC client cert"); usingEcc = 1; @@ -14521,7 +14520,7 @@ int DoSessionTicket(WOLFSSL* ssl, /* sig length */ length += LENGTH_SZ; - if (!ssl->buffers.key.buffer) { + if (!ssl->buffers.key || !ssl->buffers.key->buffer) { #ifndef NO_RSA wc_FreeRsaKey(&rsaKey); #endif @@ -14533,8 +14532,8 @@ int DoSessionTicket(WOLFSSL* ssl, if (ssl->specs.sig_algo == rsa_sa_algo) { /* rsa sig size */ word32 i = 0; - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &rsaKey, ssl->buffers.key.length); + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &i, + &rsaKey, ssl->buffers.key->length); if (ret != 0) { goto done_a; } @@ -14545,8 +14544,8 @@ int DoSessionTicket(WOLFSSL* ssl, if (ssl->specs.sig_algo == ecc_dsa_sa_algo) { /* ecdsa sig size */ word32 i = 0; - ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &dsaKey, ssl->buffers.key.length); + ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &i, + &dsaKey, ssl->buffers.key->length); if (ret != 0) { goto done_a; } @@ -15183,12 +15182,12 @@ int DoSessionTicket(WOLFSSL* ssl, /* sig length */ length += LENGTH_SZ; - if (!ssl->buffers.key.buffer) { + if (!ssl->buffers.key || !ssl->buffers.key->buffer) { return NO_PRIVATE_KEY; } - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &rsaKey, ssl->buffers.key.length); + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &i, + &rsaKey, ssl->buffers.key->length); if (ret == 0) { sigSz = wc_RsaEncryptSize(&rsaKey); length += sigSz; @@ -16984,12 +16983,12 @@ int DoSessionTicket(WOLFSSL* ssl, return ret; } - if (!ssl->buffers.key.buffer) { + if (!ssl->buffers.key || !ssl->buffers.key->buffer) { return NO_PRIVATE_KEY; } - ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, - &key, ssl->buffers.key.length); + ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, + &key, ssl->buffers.key->length); if (ret == 0) { length = wc_RsaEncryptSize(&key); @@ -17271,8 +17270,8 @@ int DoSessionTicket(WOLFSSL* ssl, word32 i = 0; wc_ecc_init(&staticKey); - ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &staticKey, ssl->buffers.key.length); + ret = wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &i, + &staticKey, ssl->buffers.key->length); if (ret == 0) { ret = wc_ecc_shared_secret(&staticKey, ssl->peerEccKey, diff --git a/src/ssl.c b/src/ssl.c index 8e788a4bf..1f4aaca08 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1635,21 +1635,12 @@ int wolfSSL_GetHmacSize(WOLFSSL* ssl) #ifndef NO_CERTS -int InitDer(DerBuffer* der) +int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap) { int ret = BAD_FUNC_ARG; - if (der) { - XMEMSET(der, 0, sizeof(DerBuffer)); - ret = 0; - } - return ret; -} - -int AllocDer(DerBuffer* der, word32 length, int type, void* heap) -{ - int ret = BAD_FUNC_ARG; - if (der) { + if (pDer) { int dynType = 0; + DerBuffer* der; /* Determine dynamic type */ switch (type) { @@ -1663,29 +1654,37 @@ int AllocDer(DerBuffer* der, word32 length, int type, void* heap) } /* Setup new buffer */ - der->type = type; - der->dynType = dynType; - der->heap = heap; - der->buffer = (byte*)XMALLOC(length, heap, dynType); - if (!der->buffer) { + *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType); + if (*pDer == NULL) { return MEMORY_ERROR; } + + der = *pDer; + der->type = type; + der->dynType = dynType; /* Cache this for FreeDer */ + der->heap = heap; + der->buffer = (byte*)der + sizeof(DerBuffer); der->length = length; ret = 0; /* Success */ } return ret; } -void FreeDer(DerBuffer* der) +void FreeDer(DerBuffer** pDer) { - if (der && der->buffer) { + if (pDer && *pDer) + { + DerBuffer* der = (DerBuffer*)*pDer; + /* ForceZero private keys */ if (der->type == PRIVATEKEY_TYPE) { ForceZero(der->buffer, der->length); } - XFREE(der->buffer, der->heap, der->dynType); der->buffer = NULL; der->length = 0; + XFREE(der, der->heap, der->dynType); + + *pDer = NULL; } } @@ -1763,7 +1762,7 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, { int eccKey = 0; int ret; - DerBuffer der; + DerBuffer* der = NULL; #ifdef WOLFSSL_SMALL_STACK EncryptedInfo* info = NULL; #else @@ -1782,11 +1781,6 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, return BAD_FUNC_ARG; } - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - #ifdef WOLFSSL_SMALL_STACK info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1808,9 +1802,9 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, WOLFSSL_MSG("Bad Pem To Der"); } else { - if (der.length <= (word32)buffSz) { - XMEMCPY(buff, der.buffer, der.length); - ret = der.length; + if (der->length <= (word32)buffSz) { + XMEMCPY(buff, der->buffer, der->length); + ret = der->length; } else { WOLFSSL_MSG("Bad der length"); @@ -1867,7 +1861,7 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, { int eccKey = 0; int ret; - DerBuffer der; + DerBuffer* der = NULL; #ifdef WOLFSSL_SMALL_STACK EncryptedInfo* info = NULL; #else @@ -1881,11 +1875,6 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, return BAD_FUNC_ARG; } - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - #ifdef WOLFSSL_SMALL_STACK info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1927,9 +1916,9 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz, WOLFSSL_MSG("Bad Pem To Der"); } else { - if (der.length <= (word32)buffSz) { - XMEMCPY(buff, der.buffer, der.length); - ret = der.length; + if (der->length <= (word32)buffSz) { + XMEMCPY(buff, der->buffer, der->length); + ret = der->length; } else { WOLFSSL_MSG("Bad der length"); @@ -2248,7 +2237,7 @@ Signer* GetCAByName(void* vp, byte* hash) /* owns der, internal now uses too */ /* type flag ids from user or from chain received during verify don't allow chain ones to be added w/o isCA extension */ -int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int type, int verify) +int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) { int ret; Signer* signer = 0; @@ -2259,6 +2248,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int type, int verify) #else DecodedCert cert[1]; #endif + DerBuffer* der = *pDer; WOLFSSL_MSG("Adding a CA"); @@ -2354,7 +2344,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer* der, int type, int verify) XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif WOLFSSL_MSG(" Freeing der CA"); - FreeDer(der); + FreeDer(pDer); WOLFSSL_MSG(" OK Freeing der CA"); WOLFSSL_LEAVE("AddCA", ret); @@ -2630,7 +2620,7 @@ static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password, /* Remove PEM header/footer, convert to ASN1, store any encrypted data info->consumed tracks of PEM bytes consumed in case multiple parts */ int PemToDer(const unsigned char* buff, long longSz, int type, - DerBuffer* der, void* heap, EncryptedInfo* info, int* eccKey) + DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey) { const char* header = NULL; const char* footer = NULL; @@ -2642,6 +2632,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, int ret = 0; int sz = (int)longSz; int encrypted_key = 0; + DerBuffer* der; WOLFSSL_ENTER("PemToDer"); @@ -2778,10 +2769,11 @@ int PemToDer(const unsigned char* buff, long longSz, int type, if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE; - ret = AllocDer(der, (word32)neededSz, type, heap); + ret = AllocDer(pDer, (word32)neededSz, type, heap); if (ret < 0) { return ret; } + der = *pDer; if (Base64_Decode((byte*)headerEnd, (word32)neededSz, der->buffer, &der->length) < 0) @@ -2823,7 +2815,6 @@ int PemToDer(const unsigned char* buff, long longSz, int type, XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif if (ret < 0) { - FreeDer(der); return ret; } @@ -2837,7 +2828,6 @@ int PemToDer(const unsigned char* buff, long longSz, int type, XFREE(password, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif if (ret != SSL_SUCCESS) { - FreeDer(der); return ret; } } @@ -2855,7 +2845,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz, int format, int type, WOLFSSL* ssl, long* used, int userChain) { - DerBuffer der; /* holds DER or RAW (for NTRU) */ + DerBuffer* der = NULL; /* holds DER or RAW (for NTRU) */ int ret; int eccKey = 0; int rsaKey = 0; @@ -2878,11 +2868,6 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, if (ctx == NULL && ssl == NULL) return BAD_FUNC_ARG; - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - #ifdef WOLFSSL_SMALL_STACK info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -2939,30 +2924,28 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, WOLFSSL_MSG("Processing Cert Chain"); while (consumed < sz) { - DerBuffer part; + DerBuffer* part = NULL; info->consumed = 0; - ret = InitDer(&part); + + ret = PemToDer(buff + consumed, sz - consumed, type, &part, + heap, info, &eccKey); if (ret == 0) { - ret = PemToDer(buff + consumed, sz - consumed, type, &part, - heap, info, &eccKey); - if (ret == 0) { - gotOne = 1; - if ( (idx + part.length) > bufferSz) { - WOLFSSL_MSG(" Cert Chain bigger than buffer"); - ret = BUFFER_E; - } - else { - c32to24(part.length, &chainBuffer[idx]); - idx += CERT_HEADER_SZ; - XMEMCPY(&chainBuffer[idx], part.buffer,part.length); - idx += part.length; - consumed += info->consumed; - if (used) - *used += info->consumed; - } + gotOne = 1; + if ( (idx + part->length) > bufferSz) { + WOLFSSL_MSG(" Cert Chain bigger than buffer"); + ret = BUFFER_E; + } + else { + c32to24(part->length, &chainBuffer[idx]); + idx += CERT_HEADER_SZ; + XMEMCPY(&chainBuffer[idx], part->buffer, part->length); + idx += part->length; + consumed += info->consumed; + if (used) + *used += info->consumed; } - FreeDer(&part); } + FreeDer(&part); if (ret == SSL_NO_PEM_HEADER && gotOne) { WOLFSSL_MSG("We got one good PEM so stuff at end ok"); @@ -2992,14 +2975,14 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } ret = AllocDer(&ssl->buffers.certChain, idx, type, heap); if (ret == 0) { - XMEMCPY(ssl->buffers.certChain.buffer, chainBuffer, idx); + XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer, idx); ssl->buffers.weOwnCertChain = 1; } } else if (ctx) { FreeDer(&ctx->certChain); ret = AllocDer(&ctx->certChain, idx, type, heap); if (ret == 0) { - XMEMCPY(ctx->certChain.buffer, chainBuffer, idx); + XMEMCPY(ctx->certChain->buffer, chainBuffer, idx); } } } @@ -3025,7 +3008,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, return ret; } - XMEMCPY(der.buffer, buff, sz); + XMEMCPY(der->buffer, buff, sz); } #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) @@ -3053,7 +3036,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, 0, ctx->userdata); /* decrypt the key */ - ret = wolfssl_decrypt_buffer_key(&der, (byte*)password, + ret = wolfssl_decrypt_buffer_key(der, (byte*)password, passwordSz, info); } @@ -3138,7 +3121,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ret = wc_InitRsaKey(key, 0); if (ret == 0) { - if (wc_RsaPrivateKeyDecode(der.buffer, &idx, key, der.length) + if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length) != 0) { #ifdef HAVE_ECC /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ @@ -3169,7 +3152,8 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ecc_key key; wc_ecc_init(&key); - if (wc_EccPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) { + if (wc_EccPrivateKeyDecode(der->buffer, &idx, &key, + der->length) != 0) { wc_ecc_free(&key); return SSL_BAD_FILE; } @@ -3197,7 +3181,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif WOLFSSL_MSG("Checking cert signature type"); - InitDecodedCert(cert, der.buffer, der.length, heap); + InitDecodedCert(cert, der->buffer, der->length, heap); if (DecodeToKey(cert, 0) < 0) { WOLFSSL_MSG("Decode to key failed"); @@ -3422,7 +3406,7 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff, long sz, int format) { int ret = 0; - DerBuffer der; + DerBuffer* der = NULL; #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert = NULL; #else @@ -3431,11 +3415,6 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff, WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer"); - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - #ifdef WOLFSSL_SMALL_STACK cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -3465,7 +3444,7 @@ int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff, info->consumed = 0; ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, info, &eccKey); - InitDecodedCert(cert, der.buffer, der.length, cm->heap); + InitDecodedCert(cert, der->buffer, der->length, cm->heap); #ifdef WOLFSSL_SMALL_STACK XFREE(info, cm->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -4240,7 +4219,7 @@ int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) int ecc = 0; long sz = 0; XFILE file = XFOPEN(fileName, "rb"); - DerBuffer converted; + DerBuffer* converted = NULL; WOLFSSL_ENTER("wolfSSL_PemCertToDer"); @@ -4264,39 +4243,36 @@ int wolfSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) } if (ret == 0) { - ret = InitDer(&converted); - if (ret == 0) { - if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0) { - ret = SSL_BAD_FILE; - } - else { - #ifdef WOLFSSL_SMALL_STACK - info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (info == NULL) - ret = MEMORY_E; - else - #endif - { - ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, - 0, info, &ecc); - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - } - } - - if (ret == 0) { - if (converted.length < (word32)derSz) { - XMEMCPY(derBuf, converted.buffer, converted.length); - ret = converted.length; - } - else - ret = BUFFER_E; - } - - FreeDer(&converted); + if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0) { + ret = SSL_BAD_FILE; } + else { + #ifdef WOLFSSL_SMALL_STACK + info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) + ret = MEMORY_E; + else + #endif + { + ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, + 0, info, &ecc); + #ifdef WOLFSSL_SMALL_STACK + XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } + } + + if (ret == 0) { + if (converted->length < (word32)derSz) { + XMEMCPY(derBuf, converted->buffer, converted->length); + ret = converted->length; + } + else + ret = BUFFER_E; + } + + FreeDer(&converted); } XFCLOSE(file); @@ -4325,7 +4301,7 @@ int wolfSSL_PemPubKeyToDer(const char* fileName, int ret = 0; long sz = 0; XFILE file = XFOPEN(fileName, "rb"); - DerBuffer converted; + DerBuffer* converted = NULL; WOLFSSL_ENTER("wolfSSL_PemPubKeyToDer"); @@ -4348,25 +4324,22 @@ int wolfSSL_PemPubKeyToDer(const char* fileName, dynamic = 1; } if (ret == 0) { - ret = InitDer(&converted); + if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0) + ret = SSL_BAD_FILE; + else + ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted, + 0, NULL, NULL); + if (ret == 0) { - if ( (ret = (int)XFREAD(fileBuf, sz, 1, file)) < 0) - ret = SSL_BAD_FILE; - else - ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted, - 0, NULL, NULL); - - if (ret == 0) { - if (converted.length < (word32)derSz) { - XMEMCPY(derBuf, converted.buffer, converted.length); - ret = converted.length; - } - else - ret = BUFFER_E; + if (converted->length < (word32)derSz) { + XMEMCPY(derBuf, converted->buffer, converted->length); + ret = converted->length; } - - FreeDer(&converted); + else + ret = BUFFER_E; } + + FreeDer(&converted); } XFCLOSE(file); @@ -4382,8 +4355,8 @@ int wolfSSL_PemPubKeyToDer(const char* fileName, int wolfSSL_PubKeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff, int buffSz) { - int ret; - DerBuffer der; + int ret; + DerBuffer* der = NULL; WOLFSSL_ENTER("wolfSSL_PubKeyPemToDer"); @@ -4392,19 +4365,14 @@ int wolfSSL_PubKeyPemToDer(const unsigned char* pem, int pemSz, return BAD_FUNC_ARG; } - ret = InitDer(&der); - if (ret < 0) { - return ret; - } - ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL); if (ret < 0) { WOLFSSL_MSG("Bad Pem To Der"); } else { - if (der.length <= (word32)buffSz) { - XMEMCPY(buff, der.buffer, der.length); - ret = der.length; + if (der->length <= (word32)buffSz) { + XMEMCPY(buff, der->buffer, der->length); + ret = der->length; } else { WOLFSSL_MSG("Bad der length"); @@ -6160,9 +6128,11 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, #ifndef NO_CERTS /* in case used set_accept_state after init */ - if (!havePSK && !haveAnon && - (ssl->buffers.certificate.buffer == NULL || - ssl->buffers.key.buffer == NULL)) { + if (!havePSK && !haveAnon && + (!ssl->buffers.certificate || + !ssl->buffers.certificate->buffer || + !ssl->buffers.key || + !ssl->buffers.key->buffer)) { WOLFSSL_MSG("accept error: don't have server cert and key"); ssl->error = NO_PRIVATE_KEY; WOLFSSL_ERROR(ssl->error); @@ -7414,9 +7384,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const unsigned char* buf, long sz, int format) { - DerBuffer der; + DerBuffer* der = NULL; int ret = 0; - int weOwnDer = 0; word32 pSz = MAX_DH_SIZE; word32 gSz = MAX_DH_SIZE; #ifdef WOLFSSL_SMALL_STACK @@ -7430,8 +7399,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (ctx == NULL || buf == NULL) return BAD_FUNC_ARG; - der.buffer = (byte*)buf; - der.length = (word32)sz; + ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap); + if (ret != 0) { + return ret; + } + der->buffer = (byte*)buf; + der->length = (word32)sz; #ifdef WOLFSSL_SMALL_STACK p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -7448,16 +7421,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = SSL_BAD_FILETYPE; else { if (format == SSL_FILETYPE_PEM) { - ret = InitDer(&der); - if (ret == 0) { - ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, - NULL, NULL); - weOwnDer = 1; - } + FreeDer(&der); + ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap, + NULL, NULL); } if (ret == 0) { - if (wc_DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0) + if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0) ret = SSL_BAD_FILETYPE; else if (ssl) ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz); @@ -7466,8 +7436,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } - if (weOwnDer) - FreeDer(&der); + FreeDer(&der); #ifdef WOLFSSL_SMALL_STACK XFREE(p, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -9796,8 +9765,8 @@ static void ExternalFreeX509(WOLFSSL_X509* x509) if (x509 == NULL || outSz == NULL) return NULL; - *outSz = (int)x509->derCert.length; - return x509->derCert.buffer; + *outSz = (int)x509->derCert->length; + return x509->derCert->buffer; } @@ -10011,7 +9980,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) XFILE file; WOLFSSL_X509* x509 = NULL; - DerBuffer der; + DerBuffer* der = NULL; WOLFSSL_ENTER("wolfSSL_X509_load_certificate"); @@ -10020,11 +9989,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM)) return NULL; - ret = InitDer(&der); - if (ret < 0) { - return NULL; - } - file = XFOPEN(fname, "rb"); if (file == XBADFILE) return NULL; @@ -10090,7 +10054,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) else { ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL); if (ret == 0) { - XMEMCPY(der.buffer, fileBuffer, sz); + XMEMCPY(der->buffer, fileBuffer, sz); } } @@ -10099,7 +10063,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) /* At this point we want `der` to have the certificate in DER format */ /* ready to be decoded. */ - if (der.buffer != NULL) { + if (der->buffer != NULL) { #ifdef WOLFSSL_SMALL_STACK DecodedCert* cert = NULL; #else @@ -10112,7 +10076,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) if (cert != NULL) #endif { - InitDecodedCert(cert, der.buffer, der.length, NULL); + InitDecodedCert(cert, der->buffer, der->length, NULL); if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) { x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL, DYNAMIC_TYPE_X509); @@ -10899,19 +10863,17 @@ int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) int result = SSL_FATAL_ERROR; WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert"); - if (store != NULL && store->cm != NULL && x509 != NULL) { - DerBuffer derCert; + if (store != NULL && store->cm != NULL && x509 != NULL + && x509->derCert != NULL) { + DerBuffer* derCert = NULL; - result = InitDer(&derCert); + result = AllocDer(&derCert, x509->derCert->length, + x509->derCert->type, NULL); if (result == 0) { - result = AllocDer(&derCert, x509->derCert.length, - x509->derCert.type, NULL); - if (result == 0) { - /* AddCA() frees the buffer. */ - XMEMCPY(derCert.buffer, - x509->derCert.buffer, x509->derCert.length); - result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, 1); - } + /* AddCA() frees the buffer. */ + XMEMCPY(derCert->buffer, + x509->derCert->buffer, x509->derCert->length); + result = AddCA(store->cm, &derCert, WOLFSSL_USER_CA, 1); } } @@ -11024,10 +10986,10 @@ void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx) int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) { if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL - && ctx->current_cert != NULL) { + && ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) { return wolfSSL_CertManagerVerifyBuffer(ctx->store->cm, - ctx->current_cert->derCert.buffer, - ctx->current_cert->derCert.length, + ctx->current_cert->derCert->buffer, + ctx->current_cert->derCert->length, SSL_FILETYPE_ASN1); } return SSL_FATAL_ERROR; @@ -11481,12 +11443,7 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) int eccKey = 0; WOLFSSL_CTX* ctx = ssl->ctx; WOLFSSL_X509* peer_cert = &ssl->peerCert; - DerBuffer fileDer; - - ret = InitDer(&fileDer); - if (ret < 0) { - return ret; - } + DerBuffer* fileDer = NULL; file = XFOPEN(fname, "rb"); if (file == XBADFILE) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fb9c40471..afc5dc80d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1818,10 +1818,10 @@ struct WOLFSSL_CTX { buffer serverDH_G; #endif #ifndef NO_CERTS - DerBuffer certificate; - DerBuffer certChain; + DerBuffer* certificate; + DerBuffer* certChain; /* chain after self, in DER, with leading size for each cert */ - DerBuffer privateKey; + DerBuffer* privateKey; WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */ #endif Suites* suites; /* make dynamic, user may not need/set */ @@ -1931,7 +1931,7 @@ int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 inSz, word16 sz); #ifndef NO_CERTS WOLFSSL_LOCAL - int AddCA(WOLFSSL_CERT_MANAGER* ctx, DerBuffer* der, int type, int verify); + int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify); WOLFSSL_LOCAL int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash); #endif @@ -2193,9 +2193,9 @@ typedef struct Buffers { buffer serverDH_Priv; #endif #ifndef NO_CERTS - DerBuffer certificate; /* WOLFSSL_CTX owns, unless we own */ - DerBuffer key; /* WOLFSSL_CTX owns, unless we own */ - DerBuffer certChain; /* WOLFSSL_CTX owns, unless we own */ + DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */ + DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */ + DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ #endif #ifdef WOLFSSL_DTLS @@ -2373,7 +2373,7 @@ struct WOLFSSL_X509 { word32 pkCurveOID; #endif /* HAVE_ECC */ #ifndef NO_CERTS - DerBuffer derCert; /* may need */ + DerBuffer* derCert; /* may need */ #endif DNS_entry* altNames; /* alt names list */ DNS_entry* altNamesNext; /* hint for retrieval */ @@ -2697,12 +2697,11 @@ typedef struct EncryptedInfo { #ifndef NO_CERTS - WOLFSSL_LOCAL int InitDer(DerBuffer* der); - WOLFSSL_LOCAL int AllocDer(DerBuffer* der, word32 length, int type, void* heap); - WOLFSSL_LOCAL void FreeDer(DerBuffer* der); + WOLFSSL_LOCAL int AllocDer(DerBuffer** der, word32 length, int type, void* heap); + WOLFSSL_LOCAL void FreeDer(DerBuffer** der); WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type, - DerBuffer* der, void* heap, EncryptedInfo* info, + DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey); WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,