Refactor of the DER buffer handling. Added new DerBuffer struct that includes the type and heap ptr. Added new InitDer, AllocDer and FreeDer functions. Cleanup of some missing "heap" args on XMALLOC/XFREE. In FreeDer uses ForceZero if type is private key.

This commit is contained in:
David Garske
2016-02-18 22:42:15 -08:00
parent b72c83e191
commit 3fe5ee1a7c
5 changed files with 414 additions and 365 deletions

View File

@@ -263,20 +263,23 @@ 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 */
buffer der;
DerBuffer der;
#ifdef WOLFSSL_SMALL_STACK
DecodedCRL* dcrl;
#else
DecodedCRL dcrl[1];
#endif
der.buffer = NULL;
WOLFSSL_ENTER("BufferLoadCRL");
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;
@@ -289,6 +292,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type)
}
else {
WOLFSSL_MSG("Pem to Der failed");
FreeDer(&der);
return -1;
}
}
@@ -296,9 +300,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type)
#ifdef WOLFSSL_SMALL_STACK
dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (dcrl == NULL) {
if (der.buffer)
XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
FreeDer(&der);
return MEMORY_E;
}
#endif
@@ -321,8 +323,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type)
XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (der.buffer)
XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
FreeDer(&der);
return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */
}

View File

@@ -566,9 +566,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
#endif
#ifndef NO_CERTS
XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
FreeDer(&ctx->privateKey);
FreeDer(&ctx->certificate);
FreeDer(&ctx->certChain);
wolfSSL_CertManagerFree(ctx->cm);
#endif
@@ -1643,7 +1643,7 @@ void InitX509(WOLFSSL_X509* x509, int dynamicFlag)
x509->version = 0;
x509->pubKey.buffer = NULL;
x509->sig.buffer = NULL;
x509->derCert.buffer = NULL;
InitDer(&x509->derCert);
x509->altNames = NULL;
x509->altNamesNext = NULL;
x509->dynamicMemory = (byte)dynamicFlag;
@@ -1687,7 +1687,7 @@ void FreeX509(WOLFSSL_X509* x509)
FreeX509Name(&x509->subject);
if (x509->pubKey.buffer)
XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
FreeDer(&x509->derCert);
XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
#ifdef OPENSSL_EXTRA
XFREE(x509->authKeyId, NULL, DYNAMIC_TYPE_X509_EXT);
@@ -1859,9 +1859,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#ifndef NO_CERTS
/* ctx still owns certificate, certChain, key, dh, and cm */
ssl->buffers.certificate = ctx->certificate;
ssl->buffers.certChain = ctx->certChain;
ssl->buffers.key = ctx->privateKey;
XMEMCPY(&ssl->buffers.certificate, &ctx->certificate, sizeof(DerBuffer));
XMEMCPY(&ssl->buffers.certChain, &ctx->certChain, sizeof(DerBuffer));
XMEMCPY(&ssl->buffers.key, &ctx->privateKey, sizeof(DerBuffer));
#endif
#ifdef HAVE_CAVIUM
@@ -2129,17 +2129,7 @@ void SSL_ResourceFree(WOLFSSL* ssl)
}
#endif
#ifndef NO_CERTS
if (ssl->buffers.weOwnCert)
XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
if (ssl->buffers.weOwnCertChain)
XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
if (ssl->buffers.weOwnKey) {
if (ssl->buffers.key.buffer) {
ForceZero(ssl->buffers.key.buffer, ssl->buffers.key.length);
}
XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
ssl->buffers.key.buffer = NULL;
}
wolfSSL_UnloadCertsKeys(ssl);
#endif
#ifndef NO_RSA
if (ssl->peerRsaKey) {
@@ -2335,21 +2325,7 @@ void FreeHandshakeResources(WOLFSSL* ssl)
}
#endif
#ifndef NO_CERTS
if (ssl->buffers.weOwnCert) {
XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
ssl->buffers.certificate.buffer = NULL;
}
if (ssl->buffers.weOwnCertChain) {
XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
ssl->buffers.certChain.buffer = NULL;
}
if (ssl->buffers.weOwnKey) {
if (ssl->buffers.key.buffer) {
ForceZero(ssl->buffers.key.buffer, ssl->buffers.key.length);
}
XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
ssl->buffers.key.buffer = NULL;
}
wolfSSL_UnloadCertsKeys(ssl);
#endif
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
@@ -4493,14 +4469,8 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
}
/* store cert for potential retrieval */
x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
DYNAMIC_TYPE_CERT);
if (x509->derCert.buffer == NULL) {
ret = MEMORY_E;
}
else {
if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, NULL) == 0) {
XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
x509->derCert.length = dCert->maxIdx;
}
x509->altNames = dCert->altNames;
@@ -4561,7 +4531,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
word32 size)
word32 size)
{
word32 listSz;
word32 begin = *inOutIdx;
@@ -4569,7 +4539,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
int anyError = 0;
int totalCerts = 0; /* number of certs in certs buffer */
int count;
buffer certs[MAX_CHAIN_DEPTH];
DerBuffer certs[MAX_CHAIN_DEPTH];
#ifdef WOLFSSL_SMALL_STACK
char* domain = NULL;
@@ -4616,6 +4586,10 @@ 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;
@@ -4649,7 +4623,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
/* verify up to peer's first */
while (count > 1) {
buffer myCert = certs[count - 1];
DerBuffer myCert = certs[count - 1];
byte* subjectHash;
InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
@@ -4668,18 +4642,24 @@ 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)) {
buffer add;
add.length = myCert.length;
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
DYNAMIC_TYPE_CA);
DerBuffer add;
ret = InitDer(&add);
if (ret == 0) {
ret = AllocDer(&add, myCert.length, CA_TYPE, ssl->heap);
}
if (ret < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
WOLFSSL_MSG("Adding CA from chain");
if (add.buffer == NULL)
return MEMORY_E;
XMEMCPY(add.buffer, myCert.buffer, myCert.length);
/* already verified above */
ret = AddCA(ssl->ctx->cm, add, WOLFSSL_CHAIN_CA, 0);
ret = AddCA(ssl->ctx->cm, &add, WOLFSSL_CHAIN_CA, 0);
if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
}
else if (ret != 0) {
@@ -4735,7 +4715,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) {
buffer myCert = certs[0];
DerBuffer myCert = certs[0];
int fatal = 0;
WOLFSSL_MSG("Verifying Peer's cert");
@@ -4833,10 +4813,10 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#ifdef KEEP_PEER_CERT
if (fatal == 0) {
/* set X509 format for peer cert even if fatal */
int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
if (copyRet == MEMORY_E)
fatal = 1;
/* set X509 format for peer cert even if fatal */
int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
if (copyRet == MEMORY_E)
fatal = 1;
}
#endif
@@ -8717,7 +8697,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
return 0;
if (!request || ssl->buffers.weOwnCert) {
buffer der = ssl->buffers.certificate;
DerBuffer der = ssl->buffers.certificate;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert = NULL;
#else
@@ -8814,7 +8794,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
return 0;
if (!request || ssl->buffers.weOwnCert) {
buffer der = ssl->buffers.certificate;
DerBuffer der = ssl->buffers.certificate;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert = NULL;
#else
@@ -8887,7 +8867,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
if (ret == 0 && (!ssl->ctx->chainOcspRequest[0]
|| ssl->buffers.weOwnCertChain)) {
buffer der = {NULL, 0};
DerBuffer der;
word32 idx = 0;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert = NULL;
@@ -8895,6 +8875,11 @@ 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);

603
src/ssl.c

File diff suppressed because it is too large Load Diff

View File

@@ -7668,7 +7668,7 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
if (cert == NULL || file == NULL)
return BAD_FUNC_ARG;
der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, NULL, DYNAMIC_TYPE_CERT);
if (der == NULL) {
WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
return MEMORY_E;
@@ -7684,14 +7684,14 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
/* Load PubKey in internal structure */
rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
if (rsakey == NULL) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
return MEMORY_E;
}
if (wc_InitRsaKey(rsakey, NULL) != 0) {
WOLFSSL_MSG("wc_InitRsaKey failure");
XFREE(rsakey, NULL, DYNAMIC_TYPE_RSA);
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
return MEMORY_E;
}
@@ -7706,7 +7706,7 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
/* Check to load ecc public key */
eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
if (eckey == NULL) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
return MEMORY_E;
}
@@ -7714,7 +7714,7 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
WOLFSSL_MSG("wc_ecc_init failure");
wc_ecc_free(eckey);
XFREE(eckey, NULL, DYNAMIC_TYPE_ECC);
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
return MEMORY_E;
}
@@ -7722,17 +7722,17 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
if (ret != 0) {
WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
wc_ecc_free(eckey);
return PUBLIC_KEY_E;
}
#else
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
return PUBLIC_KEY_E;
#endif /* HAVE_ECC */
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(der, NULL, DYNAMIC_TYPE_CERT);
ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);

View File

@@ -1211,6 +1211,17 @@ typedef struct buffer {
word32 length;
} buffer;
#ifndef NO_CERTS
/* wolfSSL DER buffer */
typedef struct DerBuffer {
byte* buffer;
void* heap;
word32 length;
int type; /* enum CertType */
int dynType; /* DYNAMIC_TYPE_* */
} DerBuffer;
#endif /* !NO_CERTS */
enum {
FORCED_FREE = 1,
@@ -1807,10 +1818,10 @@ struct WOLFSSL_CTX {
buffer serverDH_G;
#endif
#ifndef NO_CERTS
buffer certificate;
buffer certChain;
DerBuffer certificate;
DerBuffer certChain;
/* chain after self, in DER, with leading size for each cert */
buffer 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 */
@@ -1920,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, buffer der, int type, int verify);
int AddCA(WOLFSSL_CERT_MANAGER* ctx, DerBuffer* der, int type, int verify);
WOLFSSL_LOCAL
int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash);
#endif
@@ -2182,9 +2193,9 @@ typedef struct Buffers {
buffer serverDH_Priv;
#endif
#ifndef NO_CERTS
buffer certificate; /* WOLFSSL_CTX owns, unless we own */
buffer key; /* WOLFSSL_CTX owns, unless we own */
buffer 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
@@ -2358,7 +2369,7 @@ struct WOLFSSL_X509 {
#ifdef HAVE_ECC
word32 pkCurveOID;
#endif /* HAVE_ECC */
buffer derCert; /* may need */
DerBuffer derCert; /* may need */
DNS_entry* altNames; /* alt names list */
DNS_entry* altNamesNext; /* hint for retrieval */
byte dynamicMemory; /* dynamic memory flag */
@@ -2680,8 +2691,13 @@ 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 PemToDer(const unsigned char* buff, long sz, int type,
buffer* der, void* heap, EncryptedInfo* info,
DerBuffer* der, void* heap, EncryptedInfo* info,
int* eccKey);
WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,
@@ -2784,9 +2800,9 @@ WOLFSSL_LOCAL int ProcessReply(WOLFSSL*);
WOLFSSL_LOCAL int SetCipherSpecs(WOLFSSL*);
WOLFSSL_LOCAL int MakeMasterSecret(WOLFSSL*);
WOLFSSL_LOCAL int AddSession(WOLFSSL*);
WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData);
WOLFSSL_LOCAL int AddSession(WOLFSSL*);
WOLFSSL_LOCAL int DeriveKeys(WOLFSSL* ssl);
WOLFSSL_LOCAL int StoreKeys(WOLFSSL* ssl, const byte* keyData);
WOLFSSL_LOCAL int IsTLS(const WOLFSSL* ssl);
WOLFSSL_LOCAL int IsAtLeastTLSv1_2(const WOLFSSL* ssl);