mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 20:24:39 +02:00
Added processing of user cert chain in DER format. Added arg check on "wolfSSL_get_certificate" to fix NULL dereference if certificate not yet set via "wolfSSL_use_certificate_buffer" or "wolfSSL_use_certificate_file". Added "wolfSSL_CTX_use_certificate_chain_buffer_format" to expose way to import certificate chain buffer as ASN1 (since "wolfSSL_CTX_use_certificate_chain_buffer" assumes PEM) . Changed ProcessFile from static and added as local in internal.h.
This commit is contained in:
211
src/ssl.c
211
src/ssl.c
@@ -3783,63 +3783,17 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* process the buffer buff, length sz, into ctx of format and type
|
|
||||||
used tracks bytes consumed, userChain specifies a user cert chain
|
/* process user cert chain to pass during the handshake */
|
||||||
to pass during the handshake */
|
static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||||
static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|
||||||
long sz, int format, int type, WOLFSSL* ssl,
|
long sz, int format, int type, WOLFSSL* ssl,
|
||||||
long* used, int userChain)
|
long* used, EncryptedInfo* info)
|
||||||
{
|
{
|
||||||
DerBuffer* der = NULL; /* holds DER or RAW (for NTRU) */
|
int ret = 0;
|
||||||
int ret;
|
|
||||||
int eccKey = 0;
|
|
||||||
int rsaKey = 0;
|
|
||||||
void* heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
|
void* heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
EncryptedInfo* info = NULL;
|
|
||||||
#else
|
|
||||||
EncryptedInfo info[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
(void)rsaKey;
|
|
||||||
|
|
||||||
if (used)
|
|
||||||
*used = sz; /* used bytes default to sz, PEM chain may shorten*/
|
|
||||||
|
|
||||||
if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
|
|
||||||
&& format != SSL_FILETYPE_RAW)
|
|
||||||
return SSL_BAD_FILETYPE;
|
|
||||||
|
|
||||||
if (ctx == NULL && ssl == NULL)
|
|
||||||
return BAD_FUNC_ARG;
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
|
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
if (info == NULL)
|
|
||||||
return MEMORY_E;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info->set = 0;
|
|
||||||
info->ctx = ctx;
|
|
||||||
info->consumed = 0;
|
|
||||||
|
|
||||||
if (format == SSL_FILETYPE_PEM) {
|
|
||||||
ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
|
|
||||||
|
|
||||||
if (used)
|
|
||||||
*used = info->consumed;
|
|
||||||
|
|
||||||
if (ret < 0) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
FreeDer(&der);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we may have a user cert chain, try to consume */
|
/* we may have a user cert chain, try to consume */
|
||||||
if (userChain && type == CERT_TYPE && info->consumed < sz) {
|
if (type == CERT_TYPE && info->consumed < sz) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte staticBuffer[1]; /* force heap usage */
|
byte staticBuffer[1]; /* force heap usage */
|
||||||
#else
|
#else
|
||||||
@@ -3847,7 +3801,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
#endif
|
#endif
|
||||||
byte* chainBuffer = staticBuffer;
|
byte* chainBuffer = staticBuffer;
|
||||||
int dynamicBuffer = 0;
|
int dynamicBuffer = 0;
|
||||||
word32 bufferSz = sizeof(staticBuffer);
|
word32 bufferSz = FILE_BUFFER_SIZE;
|
||||||
long consumed = info->consumed;
|
long consumed = info->consumed;
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
int gotOne = 0;
|
int gotOne = 0;
|
||||||
@@ -3858,10 +3812,6 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
/* will shrink to actual size */
|
/* will shrink to actual size */
|
||||||
chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
|
chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
|
||||||
if (chainBuffer == NULL) {
|
if (chainBuffer == NULL) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
FreeDer(&der);
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
dynamicBuffer = 1;
|
dynamicBuffer = 1;
|
||||||
@@ -3869,11 +3819,33 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
|
|
||||||
WOLFSSL_MSG("Processing Cert Chain");
|
WOLFSSL_MSG("Processing Cert Chain");
|
||||||
while (consumed < sz) {
|
while (consumed < sz) {
|
||||||
|
int eccKey = 0;
|
||||||
DerBuffer* part = NULL;
|
DerBuffer* part = NULL;
|
||||||
|
word32 remain = (word32)(sz - consumed);
|
||||||
info->consumed = 0;
|
info->consumed = 0;
|
||||||
|
|
||||||
ret = PemToDer(buff + consumed, sz - consumed, type, &part,
|
if (format == SSL_FILETYPE_PEM) {
|
||||||
|
ret = PemToDer(buff + consumed, remain, type, &part,
|
||||||
heap, info, &eccKey);
|
heap, info, &eccKey);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int length = remain;
|
||||||
|
if (format == SSL_FILETYPE_ASN1) {
|
||||||
|
/* get length of der (read sequence) */
|
||||||
|
word32 inOutIdx = 0;
|
||||||
|
if (GetSequence(buff + consumed, &inOutIdx, &length, remain) < 0) {
|
||||||
|
ret = SSL_NO_PEM_HEADER;
|
||||||
|
}
|
||||||
|
length += inOutIdx; /* include leading squence */
|
||||||
|
}
|
||||||
|
info->consumed = length;
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = AllocDer(&part, length, type, heap);
|
||||||
|
if (ret == 0) {
|
||||||
|
XMEMCPY(part->buffer, buff + consumed, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
gotOne = 1;
|
gotOne = 1;
|
||||||
if ((idx + part->length) > bufferSz) {
|
if ((idx + part->length) > bufferSz) {
|
||||||
@@ -3893,7 +3865,7 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
FreeDer(&part);
|
FreeDer(&part);
|
||||||
|
|
||||||
if (ret == SSL_NO_PEM_HEADER && gotOne) {
|
if (ret == SSL_NO_PEM_HEADER && gotOne) {
|
||||||
WOLFSSL_MSG("We got one good PEM so stuff at end ok");
|
WOLFSSL_MSG("We got one good cert, so stuff at end ok");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3901,10 +3873,6 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
WOLFSSL_MSG(" Error in Cert in Chain");
|
WOLFSSL_MSG(" Error in Cert in Chain");
|
||||||
if (dynamicBuffer)
|
if (dynamicBuffer)
|
||||||
XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
|
XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
FreeDer(&der);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
WOLFSSL_MSG(" Consumed another Cert in Chain");
|
WOLFSSL_MSG(" Consumed another Cert in Chain");
|
||||||
@@ -3934,7 +3902,86 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
|
|
||||||
if (dynamicBuffer)
|
if (dynamicBuffer)
|
||||||
XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
|
XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* process the buffer buff, length sz, into ctx of format and type
|
||||||
|
used tracks bytes consumed, userChain specifies a user cert chain
|
||||||
|
to pass during the handshake */
|
||||||
|
int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||||
|
long sz, int format, int type, WOLFSSL* ssl,
|
||||||
|
long* used, int userChain)
|
||||||
|
{
|
||||||
|
DerBuffer* der = NULL; /* holds DER or RAW (for NTRU) */
|
||||||
|
int ret = 0;
|
||||||
|
int eccKey = 0;
|
||||||
|
int rsaKey = 0;
|
||||||
|
void* heap = ctx ? ctx->heap : ((ssl) ? ssl->heap : NULL);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
EncryptedInfo* info = NULL;
|
||||||
|
#else
|
||||||
|
EncryptedInfo info[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void)rsaKey;
|
||||||
|
|
||||||
|
if (used)
|
||||||
|
*used = sz; /* used bytes default to sz, PEM chain may shorten*/
|
||||||
|
|
||||||
|
/* check args */
|
||||||
|
if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
|
||||||
|
&& format != SSL_FILETYPE_RAW)
|
||||||
|
return SSL_BAD_FILETYPE;
|
||||||
|
|
||||||
|
if (ctx == NULL && ssl == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (info == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
info->set = 0;
|
||||||
|
info->ctx = ctx;
|
||||||
|
info->consumed = 0;
|
||||||
|
|
||||||
|
if (format == SSL_FILETYPE_PEM) {
|
||||||
|
ret = PemToDer(buff, sz, type, &der, heap, info, &eccKey);
|
||||||
|
}
|
||||||
|
else { /* ASN1 (DER) or RAW (NTRU) */
|
||||||
|
int length = (int)sz;
|
||||||
|
if (format == SSL_FILETYPE_ASN1) {
|
||||||
|
/* get length of der (read sequence) */
|
||||||
|
word32 inOutIdx = 0;
|
||||||
|
if (GetSequence(buff, &inOutIdx, &length, (word32)sz) < 0) {
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
length += inOutIdx; /* include leading squence */
|
||||||
|
}
|
||||||
|
info->consumed = length;
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = AllocDer(&der, (word32)length, type, heap);
|
||||||
|
if (ret == 0) {
|
||||||
|
XMEMCPY(der->buffer, buff, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (used) {
|
||||||
|
*used = info->consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process user chain */
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (userChain) {
|
||||||
|
ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for error */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
@@ -3942,19 +3989,6 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
FreeDer(&der);
|
FreeDer(&der);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* ASN1 (DER) or RAW (NTRU) */
|
|
||||||
ret = AllocDer(&der, (word32)sz, type, heap);
|
|
||||||
if (ret < 0) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
XMEMCPY(der->buffer, buff, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
|
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
|
||||||
/* for SSL_FILETYPE_PEM, PemToDer manage the decryption if required */
|
/* for SSL_FILETYPE_PEM, PemToDer manage the decryption if required */
|
||||||
@@ -8775,12 +8809,18 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
|
||||||
|
const unsigned char* in, long sz, int format)
|
||||||
|
{
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
|
||||||
|
return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
|
int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
|
||||||
const unsigned char* in, long sz)
|
const unsigned char* in, long sz)
|
||||||
{
|
{
|
||||||
WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer");
|
return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
|
||||||
return ProcessBuffer(ctx, in, sz, SSL_FILETYPE_PEM, CERT_TYPE, NULL,
|
SSL_FILETYPE_PEM);
|
||||||
NULL, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -11833,6 +11873,10 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
|
|||||||
|
|
||||||
if (ssl->buffers.weOwnCert) {
|
if (ssl->buffers.weOwnCert) {
|
||||||
if (ssl->ourCert == NULL) {
|
if (ssl->ourCert == NULL) {
|
||||||
|
if (ssl->buffers.certificate == NULL) {
|
||||||
|
WOLFSSL_MSG("Certificate buffer not set!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
ssl->ourCert = wolfSSL_X509_d2i(NULL,
|
ssl->ourCert = wolfSSL_X509_d2i(NULL,
|
||||||
ssl->buffers.certificate->buffer,
|
ssl->buffers.certificate->buffer,
|
||||||
ssl->buffers.certificate->length);
|
ssl->buffers.certificate->length);
|
||||||
@@ -11842,17 +11886,20 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
|
|||||||
else { /* if cert not owned get parent ctx cert or return null */
|
else { /* if cert not owned get parent ctx cert or return null */
|
||||||
if (ssl->ctx) {
|
if (ssl->ctx) {
|
||||||
if (ssl->ctx->ourCert == NULL) {
|
if (ssl->ctx->ourCert == NULL) {
|
||||||
|
if (ssl->ctx->certificate == NULL) {
|
||||||
|
WOLFSSL_MSG("Ctx Certificate buffer not set!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
|
ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
|
||||||
ssl->ctx->certificate->buffer,
|
ssl->ctx->certificate->buffer,
|
||||||
ssl->ctx->certificate->length);
|
ssl->ctx->certificate->length);
|
||||||
}
|
}
|
||||||
return ssl->ctx->ourCert;
|
return ssl->ctx->ourCert;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
|
#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
|
||||||
#endif /* NO_CERTS */
|
#endif /* NO_CERTS */
|
||||||
|
|
||||||
|
@@ -2905,6 +2905,9 @@ typedef struct EncryptedInfo {
|
|||||||
DerBuffer** pDer, void* heap, EncryptedInfo* info,
|
DerBuffer** pDer, void* heap, EncryptedInfo* info,
|
||||||
int* eccKey);
|
int* eccKey);
|
||||||
|
|
||||||
|
WOLFSSL_LOCAL int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||||
|
long sz, int format, int type, WOLFSSL* ssl,
|
||||||
|
long* used, int userChain);
|
||||||
WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,
|
WOLFSSL_LOCAL int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format,
|
||||||
int type, WOLFSSL* ssl, int userChain,
|
int type, WOLFSSL* ssl, int userChain,
|
||||||
WOLFSSL_CRL* crl);
|
WOLFSSL_CRL* crl);
|
||||||
|
@@ -1090,6 +1090,8 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
|
|||||||
const unsigned char*, long, int);
|
const unsigned char*, long, int);
|
||||||
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*,
|
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*,
|
||||||
const unsigned char*, long, int);
|
const unsigned char*, long, int);
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX*,
|
||||||
|
const unsigned char*, long, int);
|
||||||
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*,
|
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*,
|
||||||
const unsigned char*, long);
|
const unsigned char*, long);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user