Merge pull request #317 from dgarske/DerBufferRefactor

Refactor of the DER buffer handling
This commit is contained in:
toddouska
2016-02-25 09:35:50 -08:00
5 changed files with 416 additions and 364 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,11 @@ 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;
if (AllocDer(&x509->derCert, dCert->maxIdx, CERT_TYPE, NULL) == 0) {
XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
}
else {
XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
x509->derCert.length = dCert->maxIdx;
ret = MEMORY_E;
}
x509->altNames = dCert->altNames;
@@ -4561,7 +4534,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 +4542,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 +4589,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 +4626,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 +4645,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 +4718,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 +4816,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 +8700,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 +8797,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 +8870,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 +8878,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

@@ -7667,7 +7667,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;
@@ -7683,14 +7683,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;
}
@@ -7705,7 +7705,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;
}
@@ -7713,7 +7713,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;
}
@@ -7721,17 +7721,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);