Merge pull request #7789 from SparkiDev/test_ssl_load

SSL loading of keys/certs: testing and fixes
This commit is contained in:
David Garske
2024-07-26 11:48:13 -07:00
committed by GitHub
3 changed files with 740 additions and 89 deletions

View File

@@ -7283,7 +7283,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
#ifndef NO_CERTS #ifndef NO_CERTS
/* Load the DER encoded DH parameters/key into DH key. /* Load the DER encoded DH parameters into DH key.
* *
* @param [in, out] dh DH key to load parameters into. * @param [in, out] dh DH key to load parameters into.
* @param [in] der Buffer holding DER encoded parameters data. * @param [in] der Buffer holding DER encoded parameters data.
@@ -7294,7 +7294,7 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
* @return 0 on success. * @return 0 on success.
* @return 1 when decoding DER or setting the external key fails. * @return 1 when decoding DER or setting the external key fails.
*/ */
static int wolfssl_dh_load_key(WOLFSSL_DH* dh, const unsigned char* der, static int wolfssl_dh_load_params(WOLFSSL_DH* dh, const unsigned char* der,
word32* idx, word32 derSz) word32* idx, word32 derSz)
{ {
int err = 0; int err = 0;
@@ -7407,7 +7407,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH** dh, const unsigned char** pp,
WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed"); WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed");
err = 1; err = 1;
} }
if ((!err) && (wolfssl_dh_load_key(newDh, *pp, &idx, if ((!err) && (wolfssl_dh_load_params(newDh, *pp, &idx,
(word32)length) != 0)) { (word32)length) != 0)) {
WOLFSSL_ERROR_MSG("Loading DH parameters failed"); WOLFSSL_ERROR_MSG("Loading DH parameters failed");
err = 1; err = 1;
@@ -7567,7 +7567,7 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
ret = -1; ret = -1;
} }
if ((ret == 1) && (wolfssl_dh_load_key(dh, derBuf, &idx, if ((ret == 1) && (wolfssl_dh_load_params(dh, derBuf, &idx,
(word32)derSz) != 0)) { (word32)derSz) != 0)) {
WOLFSSL_ERROR_MSG("DH key decode failed"); WOLFSSL_ERROR_MSG("DH key decode failed");
ret = -1; ret = -1;

View File

@@ -142,21 +142,10 @@ static int DataToDerBuffer(const unsigned char* buff, word32 len, int format,
} }
/* Data in buffer is ASN.1 format - get first SEQ or OCT into der. */ /* Data in buffer is ASN.1 format - get first SEQ or OCT into der. */
else { else {
int length;
word32 inOutIdx = 0;
/* Get length of SEQ including header. */ /* Get length of SEQ including header. */
if ((info->consumed = wolfssl_der_length(buff, (int)len)) > 0) { if ((info->consumed = wolfssl_der_length(buff, (int)len)) > 0) {
ret = 0; ret = 0;
} }
/* Private keys may be wrapped in OCT when PKCS#8 wrapper removed.
* TODO: is this really needed? */
else if ((type == PRIVATEKEY_TYPE) &&
(GetOctetString(buff, &inOutIdx, &length, len) >= 0)) {
/* Include octet string DER header. */
info->consumed = length + inOutIdx;
ret = 0;
}
else { else {
ret = ASN_PARSE_E; ret = ASN_PARSE_E;
} }
@@ -302,22 +291,11 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
WOLFSSL_ENTER("ProcessUserChain"); WOLFSSL_ENTER("ProcessUserChain");
/* Validate parameters. */
if ((type == CA_TYPE) && (ctx == NULL)) {
WOLFSSL_MSG("Need context for CA load");
ret = BAD_FUNC_ARG;
}
/* Ignore non-certificate types. */
if ((ret == 0) && (type != CERT_TYPE) && (type != CHAIN_CERT_TYPE) &&
(type != CA_TYPE)) {
WOLFSSL_MSG("File type not a certificate");
}
/* Check we haven't consumed all the data. */ /* Check we haven't consumed all the data. */
else if ((ret == 0) && (info->consumed >= sz)) { if (info->consumed >= sz) {
WOLFSSL_MSG("Already consumed data"); WOLFSSL_MSG("Already consumed data");
} }
else if (ret == 0) { else {
#ifndef WOLFSSL_SMALL_STACK #ifndef WOLFSSL_SMALL_STACK
byte stackBuffer[FILE_BUFFER_SIZE]; byte stackBuffer[FILE_BUFFER_SIZE];
#endif #endif
@@ -884,17 +862,17 @@ static int ProcessBufferTryDecodeFalcon(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
ret = wc_falcon_init(key); ret = wc_falcon_init(key);
if (ret == 0) { if (ret == 0) {
/* Set up key to parse the format specified. */ /* Set up key to parse the format specified. */
if (*keyFormat == FALCON_LEVEL1k) { if ((*keyFormat == FALCON_LEVEL1k) || ((*keyFormat == 0) &&
((der->length == FALCON_LEVEL1_KEY_SIZE) ||
(der->length == FALCON_LEVEL1_PRV_KEY_SIZE)))) {
ret = wc_falcon_set_level(key, 1); ret = wc_falcon_set_level(key, 1);
} }
else if (*keyFormat == FALCON_LEVEL5k) { else if ((*keyFormat == FALCON_LEVEL5k) || ((*keyFormat == 0) &&
((der->length == FALCON_LEVEL5_KEY_SIZE) ||
(der->length == FALCON_LEVEL5_PRV_KEY_SIZE)))) {
ret = wc_falcon_set_level(key, 5); ret = wc_falcon_set_level(key, 5);
} }
else { else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
/* TODO: get the size of the private key for different formats and
* compare with DER length. */
wc_falcon_free(key); wc_falcon_free(key);
ret = ALGO_ID_E; ret = ALGO_ID_E;
} }
@@ -935,6 +913,11 @@ static int ProcessBufferTryDecodeFalcon(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
/* Free dynamically allocated data in key. */ /* Free dynamically allocated data in key. */
wc_falcon_free(key); wc_falcon_free(key);
} }
else if ((ret == ALGO_ID_E) && (*keyFormat == 0)) {
WOLFSSL_MSG("Not a Falcon key");
/* Format unknown so keep trying. */
ret = 0;
}
/* Dispose of allocated key. */ /* Dispose of allocated key. */
XFREE(key, heap, DYNAMIC_TYPE_FALCON); XFREE(key, heap, DYNAMIC_TYPE_FALCON);
@@ -977,20 +960,22 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
ret = wc_dilithium_init(key); ret = wc_dilithium_init(key);
if (ret == 0) { if (ret == 0) {
/* Set up key to parse the format specified. */ /* Set up key to parse the format specified. */
if (*keyFormat == DILITHIUM_LEVEL2k) { if ((*keyFormat == DILITHIUM_LEVEL2k) || ((*keyFormat == 0) &&
((der->length == DILITHIUM_LEVEL2_KEY_SIZE) ||
(der->length == DILITHIUM_LEVEL2_PRV_KEY_SIZE)))) {
ret = wc_dilithium_set_level(key, 2); ret = wc_dilithium_set_level(key, 2);
} }
else if (*keyFormat == DILITHIUM_LEVEL3k) { else if ((*keyFormat == DILITHIUM_LEVEL3k) || ((*keyFormat == 0) &&
((der->length == DILITHIUM_LEVEL3_KEY_SIZE) ||
(der->length == DILITHIUM_LEVEL3_PRV_KEY_SIZE)))) {
ret = wc_dilithium_set_level(key, 3); ret = wc_dilithium_set_level(key, 3);
} }
else if (*keyFormat == DILITHIUM_LEVEL5k) { else if ((*keyFormat == DILITHIUM_LEVEL5k) || ((*keyFormat == 0) &&
((der->length == DILITHIUM_LEVEL5_KEY_SIZE) ||
(der->length == DILITHIUM_LEVEL5_PRV_KEY_SIZE)))) {
ret = wc_dilithium_set_level(key, 5); ret = wc_dilithium_set_level(key, 5);
} }
else { else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
/* TODO: get the size of the private key for different formats and
* compare with DER length. */
wc_dilithium_free(key); wc_dilithium_free(key);
ret = ALGO_ID_E; ret = ALGO_ID_E;
} }
@@ -1036,6 +1021,11 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
/* Free dynamically allocated data in key. */ /* Free dynamically allocated data in key. */
wc_dilithium_free(key); wc_dilithium_free(key);
} }
else if ((ret == ALGO_ID_E) && (*keyFormat == 0)) {
WOLFSSL_MSG("Not a Dilithium key");
/* Format unknown so keep trying. */
ret = 0;
}
/* Dispose of allocated key. */ /* Dispose of allocated key. */
XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM); XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
@@ -4846,8 +4836,7 @@ int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
WOLFSSL_ENTER("wolfSSL_add0_chain_cert"); WOLFSSL_ENTER("wolfSSL_add0_chain_cert");
/* Validate parameters. */ /* Validate parameters. */
if ((ssl == NULL) || (ssl->ctx == NULL) || (x509 == NULL) || if ((ssl == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
(x509->derCert == NULL)) {
ret = 0; ret = 0;
} }
@@ -4910,8 +4899,7 @@ int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
WOLFSSL_ENTER("wolfSSL_add1_chain_cert"); WOLFSSL_ENTER("wolfSSL_add1_chain_cert");
/* Validate parameters. */ /* Validate parameters. */
if ((ssl == NULL) || (ssl->ctx == NULL) || (x509 == NULL) || if ((ssl == NULL) || (x509 == NULL) || (x509->derCert == NULL)) {
(x509->derCert == NULL)) {
ret = 0; ret = 0;
} }
@@ -5437,10 +5425,6 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
pAlloc = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); pAlloc = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); gAlloc = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if ((pAlloc == NULL) || (gAlloc == NULL)) { if ((pAlloc == NULL) || (gAlloc == NULL)) {
XFREE(pAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
pAlloc = NULL;
XFREE(gAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
gAlloc = NULL;
ret = MEMORY_E; ret = MEMORY_E;
} }
} }
@@ -5453,11 +5437,9 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
ret = wolfssl_ctx_set_tmp_dh(ctx, pAlloc, pSz, gAlloc, gSz); ret = wolfssl_ctx_set_tmp_dh(ctx, pAlloc, pSz, gAlloc, gSz);
} }
if (ret != 1) { if ((ret != 1) && (ctx != NULL)) {
/* Free the allocated buffers if not assigned into SSL context. */ /* Free the allocated buffers if not assigned into SSL context. */
if (pAlloc)
XFREE(pAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(pAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (gAlloc)
XFREE(gAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(gAlloc, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
} }
return ret; return ret;
@@ -5491,7 +5473,7 @@ long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
} }
if (ret == 1) { if (ret == 1) {
/* Get needed size for p and g. */ /* Get sizes of p and g. */
pSz = wolfSSL_BN_bn2bin(dh->p, NULL); pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
gSz = wolfSSL_BN_bn2bin(dh->g, NULL); gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
/* Validate p and g size. */ /* Validate p and g size. */
@@ -5522,7 +5504,7 @@ long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
ret = wolfssl_set_tmp_dh(ssl, p, pSz, g, gSz); ret = wolfssl_set_tmp_dh(ssl, p, pSz, g, gSz);
} }
if (ret != 1 && ssl != NULL) { if ((ret != 1) && (ssl != NULL)) {
/* Free the allocated buffers if not assigned into SSL. */ /* Free the allocated buffers if not assigned into SSL. */
XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
@@ -5557,7 +5539,7 @@ long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
} }
if (ret == 1) { if (ret == 1) {
/* Get needed size for p and g. */ /* Get sizes of p and g. */
pSz = wolfSSL_BN_bn2bin(dh->p, NULL); pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
gSz = wolfSSL_BN_bn2bin(dh->g, NULL); gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
/* Validate p and g size. */ /* Validate p and g size. */

File diff suppressed because it is too large Load Diff