Improvements to dual alg certificates

* Support for external keys (CryptoCb interface)
* Support for usage in mutual authentication
* better entity cert parsing
* Fix for Zephyr port to support the feature
* Check key support
* Proper validation of signatures in certificate chains
* Proper validation of peer cert with local issuer signature
	(alt pub key is cached now)
* Support for ECC & RSA as alt keys with PQC as primary
* Support for PQC certificate generation
* Better support for hybrid signatures with variable length signatures
* Support for primary and alternative private keys in a single
  file/buffer
* More API support for alternative private keys

Signed-off-by: Tobias Frauenschläger <t.frauenschlaeger@me.com>
This commit is contained in:
Tobias Frauenschläger
2024-02-07 07:13:14 +01:00
committed by Anthony Hu
parent d930825a92
commit 136eaae4f1
14 changed files with 2396 additions and 686 deletions

View File

@@ -2251,6 +2251,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
#ifndef NO_CERTS
ctx->privateKeyDevId = INVALID_DEVID;
#ifdef WOLFSSL_DUAL_ALG_CERTS
ctx->altPrivateKeyDevId = INVALID_DEVID;
#endif
#endif
#ifndef NO_DH
@@ -4333,11 +4336,15 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
#endif
#ifdef HAVE_PQC
case PQC_SA_MAJOR:
/* Hash performed as part of sign/verify operation. */
/* Hash performed as part of sign/verify operation.
* However, if we want a dual alg signature with a
* classic algorithm as alternative, we need an explicit
* hash algo here.
*/
#ifdef HAVE_FALCON
if (input[1] == FALCON_LEVEL1_SA_MINOR) {
*hsType = falcon_level1_sa_algo;
*hashAlgo = sha512_mac;
*hashAlgo = sha256_mac;
}
else if (input[1] == FALCON_LEVEL5_SA_MINOR) {
*hsType = falcon_level5_sa_algo;
@@ -4347,11 +4354,11 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType)
#ifdef HAVE_DILITHIUM
if (input[1] == DILITHIUM_LEVEL2_SA_MINOR) {
*hsType = dilithium_level2_sa_algo;
*hashAlgo = sha512_mac;
*hashAlgo = sha256_mac;
}
else if (input[1] == DILITHIUM_LEVEL3_SA_MINOR) {
*hsType = dilithium_level3_sa_algo;
*hashAlgo = sha512_mac;
*hashAlgo = sha384_mac;
}
else if (input[1] == DILITHIUM_LEVEL5_SA_MINOR) {
*hsType = dilithium_level5_sa_algo;
@@ -6761,9 +6768,12 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->buffers.keySz = ctx->privateKeySz;
ssl->buffers.keyDevId = ctx->privateKeyDevId;
#ifdef WOLFSSL_DUAL_ALG_CERTS
ssl->buffers.altKey = ctx->altPrivateKey;
ssl->buffers.altKeySz = ctx->altPrivateKeySz;
ssl->buffers.altKeyType = ctx->altPrivateKeyType;
ssl->buffers.altKey = ctx->altPrivateKey;
ssl->buffers.altKeyType = ctx->altPrivateKeyType;
ssl->buffers.altKeyId = ctx->altPrivateKeyId;
ssl->buffers.altKeyLabel = ctx->altPrivateKeyLabel;
ssl->buffers.altKeySz = ctx->altPrivateKeySz;
ssl->buffers.altKeyDevId = ctx->altPrivateKeyDevId;
#endif /* WOLFSSL_DUAL_ALG_CERTS */
#endif
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
@@ -12975,23 +12985,40 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
/* Copy over alternative sig and pubkey. In this case we will allocate new
* buffers for them as we have no knowledge of when the DecodedCert is
* freed. */
x509->sapkiDer = (byte*)XMALLOC(dCert->sapkiLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
x509->altSigAlgDer = (byte*)XMALLOC(dCert->altSigAlgLen, x509->heap,
if (dCert->extSapkiSet) {
x509->sapkiDer = (byte*)XMALLOC(dCert->sapkiLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
x509->altSigValDer = (byte*)XMALLOC(dCert->altSigValLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if ((x509->sapkiDer != NULL) && (x509->altSigAlgDer != NULL) &&
(x509->altSigValDer != NULL)) {
XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen);
XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer, dCert->altSigAlgLen);
XMEMCPY(x509->altSigValDer, dCert->altSigValDer, dCert->altSigValLen);
x509->sapkiLen = dCert->sapkiLen;
x509->altSigAlgLen = dCert->altSigAlgLen;
x509->altSigValLen = dCert->altSigValLen;
if (x509->sapkiDer != NULL) {
XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen);
x509->sapkiLen = dCert->sapkiLen;
}
else {
ret = MEMORY_E;
}
}
else {
ret = MEMORY_E;
if (dCert->extAltSigAlgSet) {
x509->altSigAlgDer = (byte*)XMALLOC(dCert->altSigAlgLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->altSigAlgDer != NULL) {
XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer,
dCert->altSigAlgLen);
x509->altSigAlgLen = dCert->altSigAlgLen;
}
else {
ret = MEMORY_E;
}
}
if (dCert->extAltSigValSet) {
x509->altSigValDer = (byte*)XMALLOC(dCert->altSigValLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->altSigValDer != NULL) {
XMEMCPY(x509->altSigValDer, dCert->altSigValDer,
dCert->altSigValLen);
x509->altSigValLen = dCert->altSigValLen;
}
else {
ret = MEMORY_E;
}
}
#endif /* WOLFSSL_DUAL_ALG_CERTS */
@@ -13942,39 +13969,6 @@ PRAGMA_GCC_DIAG_POP
alreadySigner = AlreadySigner(SSL_CM(ssl), subjectHash);
}
#ifdef WOLFSSL_DUAL_ALG_CERTS
if ((ret == 0) && (args->dCert->sapkiDer != NULL)) {
#ifndef WOLFSSL_SMALL_STACK
byte der[MAX_CERT_VERIFY_SZ];
#else
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap,
DYNAMIC_TYPE_DCERT);
if (der == NULL) {
ret = MEMORY_E;
}
#endif /* ! WOLFSSL_SMALL_STACK */
if (ret == 0) {
ret = wc_GeneratePreTBS(args->dCert, der, MAX_CERT_VERIFY_SZ);
if (ret > 0) {
ret = wc_ConfirmAltSignature(der, ret,
args->dCert->sapkiDer, args->dCert->sapkiLen,
args->dCert->sapkiOID,
args->dCert->altSigValDer, args->dCert->altSigValLen,
args->dCert->altSigAlgOID, ssl->heap);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT);
#endif /* WOLFSSL_SMALL_STACK */
if (ret == 0) {
WOLFSSL_MSG("Alternative signature has been verified!");
}
}
}
#endif /* WOLFSSL_DUAL_ALG_CERTS */
#ifdef WOLFSSL_SMALL_CERT_VERIFY
/* get signature check failures from above */
if (ret == 0)
@@ -27721,9 +27715,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ssl->hsType = DYNAMIC_TYPE_RSA;
else if (ssl->buffers.keyType == ecc_dsa_sa_algo)
ssl->hsType = DYNAMIC_TYPE_ECC;
else if (ssl->buffers.keyType == falcon_level5_sa_algo)
else if ((ssl->buffers.keyType == falcon_level1_sa_algo) ||
(ssl->buffers.keyType == falcon_level5_sa_algo))
ssl->hsType = DYNAMIC_TYPE_FALCON;
else if (ssl->buffers.keyType == dilithium_level5_sa_algo)
else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) ||
(ssl->buffers.keyType == dilithium_level3_sa_algo) ||
(ssl->buffers.keyType == dilithium_level5_sa_algo))
ssl->hsType = DYNAMIC_TYPE_DILITHIUM;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
@@ -27782,7 +27779,8 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ret = NOT_COMPILED_IN;
#endif
}
else if (ssl->buffers.keyType == falcon_level5_sa_algo) {
else if ((ssl->buffers.keyType == falcon_level1_sa_algo) ||
(ssl->buffers.keyType == falcon_level5_sa_algo)) {
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
if (ssl->buffers.keyLabel) {
ret = wc_falcon_init_label((falcon_key*)ssl->hsKey,
@@ -27795,6 +27793,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ssl->buffers.key->length, ssl->heap,
ssl->buffers.keyDevId);
}
if (ret == 0) {
if (ssl->buffers.keyType == falcon_level1_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 1);
}
else if (ssl->buffers.keyType == falcon_level5_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 5);
}
}
if (ret == 0) {
if (ssl->buffers.keySz < ssl->options.minFalconKeySz) {
WOLFSSL_MSG("Falcon key size too small");
@@ -27808,7 +27814,9 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ret = NOT_COMPILED_IN;
#endif
}
else if (ssl->buffers.keyType == dilithium_level5_sa_algo) {
else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) ||
(ssl->buffers.keyType == dilithium_level3_sa_algo) ||
(ssl->buffers.keyType == dilithium_level5_sa_algo)) {
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
if (ssl->buffers.keyLabel) {
ret = wc_dilithium_init_label((dilithium_key*)ssl->hsKey,
@@ -27821,6 +27829,17 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ssl->buffers.key->length, ssl->heap,
ssl->buffers.keyDevId);
}
if (ret == 0) {
if (ssl->buffers.keyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 2);
}
else if (ssl->buffers.keyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 3);
}
else if (ssl->buffers.keyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 5);
}
}
if (ret == 0) {
if (ssl->buffers.keySz < ssl->options.minDilithiumKeySz) {
WOLFSSL_MSG("Dilithium key size too small");
@@ -28116,13 +28135,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
WOLFSSL_MSG("Using Falcon private key");
/* Check it meets the minimum Falcon key size requirements. */
if (FALCON_MAX_KEY_SIZE < ssl->options.minFalconKeySz) {
keySz = wc_falcon_size((falcon_key*)ssl->hsKey);
if (keySz < ssl->options.minFalconKeySz) {
WOLFSSL_MSG("Falcon key size too small");
ERROR_OUT(FALCON_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = FALCON_MAX_SIG_SIZE;
*length = wc_falcon_sig_size((falcon_key*)ssl->hsKey);
goto exit_dpk;
}
@@ -28187,13 +28207,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
WOLFSSL_MSG("Using Dilithium private key");
/* Check it meets the minimum Dilithium key size requirements. */
if (DILITHIUM_MAX_KEY_SIZE < ssl->options.minDilithiumKeySz) {
keySz = wc_dilithium_size((dilithium_key*)ssl->hsKey);
if (keySz < ssl->options.minDilithiumKeySz) {
WOLFSSL_MSG("Dilithium key size too small");
ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = DILITHIUM_MAX_SIG_SIZE;
*length = wc_dilithium_sig_size((dilithium_key*)ssl->hsKey);
goto exit_dpk;
}
@@ -28213,12 +28234,15 @@ exit_dpk:
return ret;
}
#if defined(HAVE_PQC) && defined(WOLFSSL_DUAL_ALG_CERTS)
/* This is just like the above, but only consider Falcon and Dilthium and
* only for the alternative key; not the native key. */
#if defined(WOLFSSL_DUAL_ALG_CERTS)
/* This is just like the above, but only consider RSA, ECC, Falcon and
* Dilthium; Furthermore, use the alternative key, not the native key.
*/
int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
{
int ret = BAD_FUNC_ARG;
int keySz;
word32 idx;
/* make sure alt private key exists */
if (ssl->buffers.altKey == NULL || ssl->buffers.altKey->buffer == NULL) {
@@ -28226,8 +28250,280 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
ERROR_OUT(NO_PRIVATE_KEY, exit_dapk);
}
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->buffers.altKeyDevId != INVALID_DEVID &&
(ssl->buffers.altKeyId || ssl->buffers.altKeyLabel)) {
if (ssl->buffers.altKeyType == rsa_sa_algo)
ssl->hsAltType = DYNAMIC_TYPE_RSA;
else if (ssl->buffers.altKeyType == ecc_dsa_sa_algo)
ssl->hsAltType = DYNAMIC_TYPE_ECC;
else if ((ssl->buffers.altKeyType == falcon_level1_sa_algo) ||
(ssl->buffers.altKeyType == falcon_level5_sa_algo))
ssl->hsAltType = DYNAMIC_TYPE_FALCON;
else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level3_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level5_sa_algo))
ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
if (ret != 0) {
goto exit_dapk;
}
if (ssl->buffers.altKeyType == rsa_sa_algo) {
#ifndef NO_RSA
if (ssl->buffers.altKeyLabel) {
ret = wc_InitRsaKey_Label((RsaKey*)ssl->hsAltKey,
(char*)ssl->buffers.altKey->buffer,
ssl->heap, ssl->buffers.altKeyDevId);
}
else if (ssl->buffers.altKeyId) {
ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsAltKey,
ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length, ssl->heap,
ssl->buffers.altKeyDevId);
}
if (ret == 0) {
if (ssl->buffers.altKeySz < ssl->options.minRsaKeySz) {
WOLFSSL_MSG("RSA key size too small");
ERROR_OUT(RSA_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)ssl->buffers.altKeySz;
}
#else
ret = NOT_COMPILED_IN;
#endif
}
else if (ssl->buffers.altKeyType == ecc_dsa_sa_algo) {
#ifdef HAVE_ECC
if (ssl->buffers.altKeyLabel) {
ret = wc_ecc_init_label((ecc_key*)ssl->hsAltKey,
(char*)ssl->buffers.altKey->buffer,
ssl->heap, ssl->buffers.altKeyDevId);
}
else if (ssl->buffers.altKeyId) {
ret = wc_ecc_init_id((ecc_key*)ssl->hsAltKey,
ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length, ssl->heap,
ssl->buffers.altKeyDevId);
}
if (ret == 0) {
if (ssl->buffers.altKeySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)wc_ecc_sig_size_calc(ssl->buffers.altKeySz);
}
#else
ret = NOT_COMPILED_IN;
#endif
}
else if ((ssl->buffers.altKeyType == falcon_level1_sa_algo) ||
(ssl->buffers.altKeyType == falcon_level5_sa_algo)) {
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
if (ssl->buffers.altKeyLabel) {
ret = wc_falcon_init_label((falcon_key*)ssl->hsAltKey,
(char*)ssl->buffers.altKey->buffer,
ssl->heap, ssl->buffers.altKeyDevId);
}
else if (ssl->buffers.altKeyId) {
ret = wc_falcon_init_id((falcon_key*)ssl->hsAltKey,
ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length, ssl->heap,
ssl->buffers.altKeyDevId);
}
if (ret == 0) {
if (ssl->buffers.altKeyType == falcon_level1_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 1);
}
else if (ssl->buffers.altKeyType == falcon_level5_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 5);
}
}
if (ret == 0) {
if (ssl->buffers.altKeySz < ssl->options.minFalconKeySz) {
WOLFSSL_MSG("Falcon key size too small");
ERROR_OUT(FALCON_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)
wc_falcon_sig_size((falcon_key*)ssl->hsAltKey);
}
#else
ret = NOT_COMPILED_IN;
#endif
}
else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level3_sa_algo) ||
(ssl->buffers.altKeyType == dilithium_level5_sa_algo)) {
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
if (ssl->buffers.altKeyLabel) {
ret = wc_dilithium_init_label((dilithium_key*)ssl->hsAltKey,
(char*)ssl->buffers.altKey->buffer,
ssl->heap, ssl->buffers.altKeyDevId);
}
else if (ssl->buffers.altKeyId) {
ret = wc_dilithium_init_id((dilithium_key*)ssl->hsAltKey,
ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length, ssl->heap,
ssl->buffers.altKeyDevId);
}
if (ret == 0) {
if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, 2);
}
else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, 3);
}
else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) {
ret = wc_dilithium_set_level(
(dilithium_key*)ssl->hsAltKey, 5);
}
}
if (ret == 0) {
if (ssl->buffers.altKeySz < ssl->options.minDilithiumKeySz) {
WOLFSSL_MSG("Dilithium key size too small");
ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)wc_dilithium_sig_size(
(dilithium_key*)ssl->hsAltKey);
}
#else
ret = NOT_COMPILED_IN;
#endif
}
goto exit_dapk;
}
#endif /* WOLF_PRIVATE_KEY_ID */
#ifndef NO_RSA
if (ssl->buffers.altKeyType == rsa_sa_algo ||
ssl->buffers.altKeyType == 0) {
ssl->hsAltType = DYNAMIC_TYPE_RSA;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
if (ret != 0) {
goto exit_dapk;
}
WOLFSSL_MSG("Trying RSA private key");
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is an RSA private key. */
ret = wc_RsaPrivateKeyDecode(ssl->buffers.altKey->buffer, &idx,
(RsaKey*)ssl->hsAltKey, ssl->buffers.altKey->length);
#ifdef WOLF_PRIVATE_KEY_ID
/* if using external key then allow using a public key */
if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying RSA public key with crypto callbacks");
idx = 0;
ret = wc_RsaPublicKeyDecode(ssl->buffers.altKey->buffer, &idx,
(RsaKey*)ssl->hsAltKey, ssl->buffers.altKey->length);
}
#endif
if (ret == 0) {
WOLFSSL_MSG("Using RSA private key");
/* It worked so check it meets minimum key size requirements. */
keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsAltKey);
if (keySz < 0) { /* check if keySz has error case */
ERROR_OUT(keySz, exit_dapk);
}
if (keySz < ssl->options.minRsaKeySz) {
WOLFSSL_MSG("RSA key size too small");
ERROR_OUT(RSA_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)keySz;
goto exit_dapk;
}
}
#endif /* !NO_RSA */
#ifdef HAVE_ECC
#ifndef NO_RSA
FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey);
#endif /* !NO_RSA */
if (ssl->buffers.altKeyType == ecc_dsa_sa_algo ||
ssl->buffers.altKeyType == 0
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
|| ssl->buffers.altKeyType == sm2_sa_algo
#endif
) {
ssl->hsAltType = DYNAMIC_TYPE_ECC;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
if (ret != 0) {
goto exit_dapk;
}
#ifndef NO_RSA
WOLFSSL_MSG("Trying ECC private key, RSA didn't work");
#else
WOLFSSL_MSG("Trying ECC private key");
#endif
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is an ECC private key. */
ret = wc_EccPrivateKeyDecode(ssl->buffers.altKey->buffer, &idx,
(ecc_key*)ssl->hsAltKey,
ssl->buffers.altKey->length);
#ifdef WOLF_PRIVATE_KEY_ID
/* if using external key then allow using a public key */
if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying ECC public key with crypto callbacks");
idx = 0;
ret = wc_EccPublicKeyDecode(ssl->buffers.altKey->buffer, &idx,
(ecc_key*)ssl->hsAltKey,
ssl->buffers.altKey->length);
}
#endif
if (ret == 0) {
WOLFSSL_MSG("Using ECC private key");
/* Check it meets the minimum ECC key size requirements. */
keySz = wc_ecc_size((ecc_key*)ssl->hsAltKey);
if (keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = (word16)wc_ecc_sig_size((ecc_key*)ssl->hsAltKey);
goto exit_dapk;
}
}
#endif
#if defined(HAVE_PQC)
#if defined(HAVE_FALCON)
#if !defined(NO_RSA) || defined(HAVE_ECC)
FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey);
#endif
if (ssl->buffers.altKeyType == falcon_level1_sa_algo ||
ssl->buffers.altKeyType == falcon_level5_sa_algo) {
ssl->buffers.altKeyType == falcon_level5_sa_algo ||
ssl->buffers.altKeyType == 0) {
ssl->hsAltType = DYNAMIC_TYPE_FALCON;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
@@ -28242,14 +28538,25 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 5);
}
else {
/* What if ssl->buffers.keyType is 0? We might want to do something
* more graceful here. */
ret = ALGO_ID_E;
}
if (ret != 0) {
goto exit_dapk;
}
WOLFSSL_MSG("Trying Falcon private key");
#if defined(HAVE_ECC)
WOLFSSL_MSG("Trying Falcon private key, ECC didn't work");
#elif !defined(NO_RSA)
WOLFSSL_MSG("Trying Falcon private key, RSA didn't work");
#else
WOLFSSL_MSG("Trying Falcon private key");
#endif
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is a Falcon private key. */
ret = wc_falcon_import_private_only(ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length,
@@ -28258,21 +28565,28 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
WOLFSSL_MSG("Using Falcon private key");
/* Check it meets the minimum Falcon key size requirements. */
if (FALCON_MAX_KEY_SIZE < ssl->options.minFalconKeySz) {
keySz = wc_falcon_size((falcon_key*)ssl->hsAltKey);
if (keySz < ssl->options.minFalconKeySz) {
WOLFSSL_MSG("Falcon key size too small");
ERROR_OUT(FALCON_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = wc_falcon_sig_size((falcon_key*)ssl->hsAltKey);
goto exit_dapk;
}
}
FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey);
#endif /* HAVE_FALCON */
#if defined(HAVE_DILITHIUM)
#if !defined(NO_RSA) || defined(HAVE_ECC)
FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey);
#endif
if (ssl->buffers.altKeyType == dilithium_level2_sa_algo ||
ssl->buffers.altKeyType == dilithium_level3_sa_algo ||
ssl->buffers.altKeyType == dilithium_level5_sa_algo) {
ssl->buffers.altKeyType == dilithium_level5_sa_algo ||
ssl->buffers.altKeyType == 0) {
ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM;
ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey);
@@ -28290,6 +28604,8 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, 5);
}
else {
/* What if ssl->buffers.keyType is 0? We might want to do something
* more graceful here. */
ret = ALGO_ID_E;
}
@@ -28297,8 +28613,18 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
goto exit_dapk;
}
WOLFSSL_MSG("Trying Dilithium private key");
#if defined(HAVE_FALCON)
WOLFSSL_MSG("Trying Dilithium private key, Falcon didn't work");
#elif defined(HAVE_ECC)
WOLFSSL_MSG("Trying Dilithium private key, ECC didn't work");
#elif !defined(NO_RSA)
WOLFSSL_MSG("Trying Dilithium private key, RSA didn't work");
#else
WOLFSSL_MSG("Trying Dilithium private key");
#endif
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is a Dilithium private key. */
ret = wc_dilithium_import_private_only(ssl->buffers.altKey->buffer,
ssl->buffers.altKey->length,
@@ -28307,16 +28633,24 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length)
WOLFSSL_MSG("Using Dilithium private key");
/* Check it meets the minimum Dilithium key size requirements. */
if (DILITHIUM_MAX_KEY_SIZE < ssl->options.minDilithiumKeySz) {
keySz = wc_dilithium_size((dilithium_key*)ssl->hsAltKey);
if (keySz < ssl->options.minDilithiumKeySz) {
WOLFSSL_MSG("Dilithium key size too small");
ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dapk);
}
/* Return the maximum signature length. */
*length = wc_dilithium_sig_size((dilithium_key*)ssl->hsAltKey);
goto exit_dapk;
}
}
#endif /* HAVE_DILITHIUM */
#endif /* HAVE_PQC */
(void)idx;
(void)keySz;
(void)length;
exit_dapk:
if (ret != 0) {
@@ -28325,7 +28659,7 @@ exit_dapk:
return ret;
}
#endif /* HAVE_PQC && WOLFSSL_DUAL_ALG_CERTS */
#endif /* WOLFSSL_DUAL_ALG_CERTS */
#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12)

1086
src/ssl.c

File diff suppressed because it is too large Load Diff

View File

@@ -9583,7 +9583,7 @@ int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length,
case WOLFSSL_CKS_SIGSPEC_EXTERNAL:
default:
/* All other values (including external) are not. */
return WOLFSSL_NOT_IMPLEMENTED;
return BAD_FUNC_ARG;
}
}
@@ -9618,7 +9618,7 @@ int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length,
for (j = 0; j < length; j++) {
if (ssl->sigSpec[i] == input[j]) {
/* Got the match, set to this one. */
ret = wolfSSL_UseCKS(ssl, &ssl->peerSigSpec[i], 1);
ret = wolfSSL_UseCKS(ssl, &ssl->sigSpec[i], 1);
if (ret == WOLFSSL_SUCCESS) {
ret = TLSX_UseCKS(&ssl->extensions, ssl, ssl->heap);
TLSX_SetResponse(ssl, TLSX_CKS);

File diff suppressed because it is too large Load Diff

View File

@@ -10171,6 +10171,15 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
#endif
#ifndef NO_DSA
DsaKey* dsa = NULL;
#endif
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
falcon_key* falcon = NULL;
#endif
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
dilithium_key* dilithium = NULL;
#endif
#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
sphincs_key* sphincs = NULL;
#endif
WC_RNG rng;
word32 idx = 0;
@@ -10297,6 +10306,148 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
}
key = (void*)dsa;
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
(x509->pubKeyOID == FALCON_LEVEL5k)) {
falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
DYNAMIC_TYPE_FALCON);
if (falcon == NULL) {
WOLFSSL_MSG("Failed to allocate memory for falcon_key");
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return WOLFSSL_FAILURE;
}
ret = wc_falcon_init(falcon);
if (ret != 0) {
XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
if (x509->pubKeyOID == FALCON_LEVEL1k) {
type = FALCON_LEVEL1_TYPE;
wc_falcon_set_level(falcon, 1);
}
else if (x509->pubKeyOID == FALCON_LEVEL5k) {
type = FALCON_LEVEL5_TYPE;
wc_falcon_set_level(falcon, 5);
}
ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx, falcon,
x509->pubKey.length);
if (ret != 0) {
WOLFSSL_ERROR_VERBOSE(ret);
wc_falcon_free(falcon);
XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
key = (void*)falcon;
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) ||
(x509->pubKeyOID == DILITHIUM_LEVEL3k) ||
(x509->pubKeyOID == DILITHIUM_LEVEL5k)) {
dilithium = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL,
DYNAMIC_TYPE_DILITHIUM);
if (dilithium == NULL) {
WOLFSSL_MSG("Failed to allocate memory for dilithium_key");
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return WOLFSSL_FAILURE;
}
ret = wc_dilithium_init(dilithium);
if (ret != 0) {
XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
if (x509->pubKeyOID == DILITHIUM_LEVEL2k) {
type = DILITHIUM_LEVEL2_TYPE;
wc_dilithium_set_level(dilithium, 2);
}
else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) {
type = DILITHIUM_LEVEL3_TYPE;
wc_dilithium_set_level(dilithium, 3);
}
else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) {
type = DILITHIUM_LEVEL5_TYPE;
wc_dilithium_set_level(dilithium, 5);
}
ret = wc_Dilithium_PublicKeyDecode(x509->pubKey.buffer, &idx,
dilithium, x509->pubKey.length);
if (ret != 0) {
WOLFSSL_ERROR_VERBOSE(ret);
wc_dilithium_free(dilithium);
XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
key = (void*)dilithium;
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) ||
(x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) ||
(x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) {
sphincs = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL,
DYNAMIC_TYPE_SPHINCS);
if (sphincs == NULL) {
WOLFSSL_MSG("Failed to allocate memory for sphincs_key");
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return WOLFSSL_FAILURE;
}
ret = wc_sphincs_init(sphincs);
if (ret != 0) {
XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
if (x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) {
type = SPHINCS_FAST_LEVEL1_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT);
}
else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) {
type = SPHINCS_FAST_LEVEL3_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT);
}
else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) {
type = SPHINCS_FAST_LEVEL5_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT);
}
else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) {
type = SPHINCS_SMALL_LEVEL1_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT);
}
else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) {
type = SPHINCS_SMALL_LEVEL3_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT);
}
else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) {
type = SPHINCS_SMALL_LEVEL5_TYPE;
wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT);
}
ret = wc_Sphincs_PublicKeyDecode(x509->pubKey.buffer, &idx, sphincs,
x509->pubKey.length);
if (ret != 0) {
WOLFSSL_ERROR_VERBOSE(ret);
wc_sphincs_free(sphincs);
XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
return ret;
}
key = (void*)sphincs;
}
#endif
if (key == NULL) {
WOLFSSL_MSG("No public key found for certificate");
@@ -10397,6 +10548,32 @@ cleanup:
wc_FreeDsaKey(dsa);
XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
(x509->pubKeyOID == FALCON_LEVEL5k)) {
wc_falcon_free(falcon);
XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) ||
(x509->pubKeyOID == DILITHIUM_LEVEL3k) ||
(x509->pubKeyOID == DILITHIUM_LEVEL5k)) {
wc_dilithium_free(dilithium);
XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
}
#endif
#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) ||
(x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) ||
(x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) ||
(x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) {
wc_sphincs_free(sphincs);
XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS);
}
#endif
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);

View File

@@ -7770,17 +7770,59 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
* return 1 (true) on match
* return 0 or negative value on failure/error
*
* key : buffer holding DER format key
* keySz : size of key buffer
* der : a initialized and parsed DecodedCert holding a certificate */
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der)
* key : buffer holding DER format key
* keySz : size of key buffer
* der : a initialized and parsed DecodedCert holding a certificate
* checkAlt : indicate if we check primary or alternative key
*/
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der,
int checkAlt)
{
int ret = 0;
if (key == NULL || der == NULL) {
return BAD_FUNC_ARG;
}
return wc_CheckPrivateKey(key, keySz, der->publicKey,
der->pubKeySize, (enum Key_Sum) der->keyOID);
#ifdef WOLFSSL_DUAL_ALG_CERTS
if (checkAlt && der->sapkiDer != NULL) {
/* We have to decode the public key first */
word32 idx = 0;
/* Dilithium has the largest public key at the moment */
word32 pubKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE;
byte* decodedPubKey = (byte*)XMALLOC(pubKeyLen, NULL,
DYNAMIC_TYPE_PUBLIC_KEY);
if (decodedPubKey == NULL) {
ret = MEMORY_E;
}
if (ret == 0) {
if (der->sapkiOID == RSAk || der->sapkiOID == ECDSAk) {
/* Simply copy the data */
XMEMCPY(decodedPubKey, der->sapkiDer, der->sapkiLen);
pubKeyLen = der->sapkiLen;
}
else {
ret = DecodeAsymKeyPublic(der->sapkiDer, &idx, der->sapkiLen,
decodedPubKey, &pubKeyLen,
der->sapkiOID);
}
}
if (ret == 0) {
ret = wc_CheckPrivateKey(key, keySz, decodedPubKey, pubKeyLen,
(enum Key_Sum) der->sapkiOID);
}
XFREE(decodedPubKey, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
}
else
#endif
{
ret = wc_CheckPrivateKey(key, keySz, der->publicKey,
der->pubKeySize, (enum Key_Sum) der->keyOID);
}
(void)checkAlt;
return ret;
}
#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
@@ -15585,8 +15627,15 @@ int DecodeToKey(DecodedCert* cert, int verify)
int ret;
int badDate = 0;
#ifdef WOLFSSL_DUAL_ALG_CERTS
/* Call internal version and decode completely to also handle extensions.
* This is required to parse a potential alternative public key in the
* SubjectAlternativeKey extension. */
ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 0);
#else
/* Call internal version and stop after public key. */
ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1);
#endif
/* Always return date errors. */
if (ret == 0) {
ret = badDate;
@@ -23753,6 +23802,45 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
WOLFSSL_ERROR_VERBOSE(ret);
return ret;
}
#ifdef WOLFSSL_DUAL_ALG_CERTS
if ((ret == 0) && cert->extAltSigAlgSet &&
cert->extAltSigValSet) {
#ifndef WOLFSSL_SMALL_STACK
byte der[MAX_CERT_VERIFY_SZ];
#else
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap,
DYNAMIC_TYPE_DCERT);
if (der == NULL) {
ret = MEMORY_E;
}
#endif /* ! WOLFSSL_SMALL_STACK */
if (ret == 0) {
ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ);
if (ret > 0) {
ret = ConfirmSignature(&cert->sigCtx, der, ret,
cert->ca->sapkiDer, cert->ca->sapkiLen,
cert->ca->sapkiOID, cert->altSigValDer,
cert->altSigValLen, cert->altSigAlgOID,
NULL, 0, NULL);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT);
#endif /* WOLFSSL_SMALL_STACK */
if (ret != 0) {
WOLFSSL_MSG("Confirm alternative signature failed");
WOLFSSL_ERROR_VERBOSE(ret);
return ret;
}
else {
WOLFSSL_MSG("Alt signature has been verified!");
}
}
}
#endif /* WOLFSSL_DUAL_ALG_CERTS */
}
#ifndef IGNORE_NAME_CONSTRAINTS
if (verify == VERIFY || verify == VERIFY_OCSP ||
@@ -23852,6 +23940,9 @@ void FreeSigner(Signer* signer, void* heap)
(void)heap;
XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
#ifdef WOLFSSL_DUAL_ALG_CERTS
XFREE(signer->sapkiDer, heap, DYNAMIC_TYPE_PUBLIC_KEY);
#endif
#ifndef IGNORE_NAME_CONSTRAINTS
if (signer->permittedNames)
FreeNameSubtrees(signer->permittedNames, heap);
@@ -28190,7 +28281,8 @@ int SetName(byte* output, word32 outputSz, CertName* name)
static int EncodePublicKey(int keyType, byte* output, int outLen,
RsaKey* rsaKey, ecc_key* eccKey,
ed25519_key* ed25519Key, ed448_key* ed448Key,
DsaKey* dsaKey)
DsaKey* dsaKey, falcon_key* falconKey,
dilithium_key* dilithiumKey, sphincs_key* sphincsKey)
{
int ret = 0;
@@ -28200,6 +28292,9 @@ static int EncodePublicKey(int keyType, byte* output, int outLen,
(void)ed25519Key;
(void)ed448Key;
(void)dsaKey;
(void)falconKey;
(void)dilithiumKey;
(void)sphincsKey;
switch (keyType) {
#ifndef NO_RSA
@@ -28235,6 +28330,41 @@ static int EncodePublicKey(int keyType, byte* output, int outLen,
}
break;
#endif
#if defined(HAVE_PQC) && defined(HAVE_FALCON)
case FALCON_LEVEL1_KEY:
case FALCON_LEVEL5_KEY:
ret = wc_Falcon_PublicKeyToDer(falconKey, output,
(word32)outLen, 1);
if (ret <= 0) {
ret = PUBLIC_KEY_E;
}
break;
#endif /* HAVE_PQC && HAVE_FALCON */
#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM)
case DILITHIUM_LEVEL2_KEY:
case DILITHIUM_LEVEL3_KEY:
case DILITHIUM_LEVEL5_KEY:
ret = wc_Dilithium_PublicKeyToDer(dilithiumKey, output,
(word32)outLen, 1);
if (ret <= 0) {
ret = PUBLIC_KEY_E;
}
break;
#endif /* HAVE_PQC && HAVE_DILITHIUM */
#if defined(HAVE_PQC) && defined(HAVE_SPHINCS)
case SPHINCS_FAST_LEVEL1_KEY:
case SPHINCS_FAST_LEVEL3_KEY:
case SPHINCS_FAST_LEVEL5_KEY:
case SPHINCS_SMALL_LEVEL1_KEY:
case SPHINCS_SMALL_LEVEL3_KEY:
case SPHINCS_SMALL_LEVEL5_KEY:
ret = wc_Sphincs_PublicKeyToDer(sphincsKey, output,
(word32)outLen, 1);
if (ret <= 0) {
ret = PUBLIC_KEY_E;
}
break;
#endif /* HAVE_PQC && HAVE_SPHINCS */
default:
ret = PUBLIC_KEY_E;
break;
@@ -30001,7 +30131,8 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
if (ret >= 0) {
/* Calculate public key encoding size. */
ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
eccKey, ed25519Key, ed448Key, dsaKey);
eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
dilithiumKey, sphincsKey);
publicKeySz = (word32)ret;
}
if (ret >= 0) {
@@ -30181,7 +30312,8 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
.data.buffer.data,
(int)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ]
.data.buffer.length,
rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
rsaKey, eccKey, ed25519Key, ed448Key, dsaKey,
falconKey, dilithiumKey, sphincsKey);
}
if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) {
/* Encode extensions into buffer. */
@@ -30262,6 +30394,7 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
NULL, NULL, NULL, NULL);
}
#ifdef WOLFSSL_CERT_REQ
#ifndef WOLFSSL_ASN_TEMPLATE
@@ -31048,7 +31181,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
if (ret >= 0) {
/* Determine encode public key size. */
ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey,
eccKey, ed25519Key, ed448Key, dsaKey);
eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
dilithiumKey, sphincsKey);
publicKeySz = (word32)ret;
}
if (ret >= 0) {
@@ -31162,7 +31296,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
ret = EncodePublicKey(cert->keyType,
(byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data,
(int)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length,
rsaKey, eccKey, ed25519Key, ed448Key, dsaKey);
rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey,
dilithiumKey, sphincsKey);
}
if ((ret >= 0 && derBuffer != NULL) &&
(!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) {
@@ -31486,6 +31621,7 @@ int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
NULL, NULL, NULL, rng);
}
WOLFSSL_ABI
int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
RsaKey* key, WC_RNG* rng)

View File

@@ -395,7 +395,7 @@ int wc_dilithium_export_public(dilithium_key* key,
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
if ((key->level != 2) && (key->level != 3) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
@@ -914,11 +914,11 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx,
pubKey, &pubKeyLen, keytype);
if (ret == 0) {
if (pubKeyLen == 0) {
ret = wc_dilithium_import_private_only(input, inSz, key);
ret = wc_dilithium_import_private_key(input, inSz, NULL, 0, key);
}
else {
ret = wc_dilithium_import_private_key(privKey, privKeyLen,
pubKey, pubKeyLen, key);
ret = wc_dilithium_import_private_key(input, inSz, pubKey,
pubKeyLen, key);
}
}
return ret;
@@ -983,7 +983,7 @@ int wc_Dilithium_PublicKeyToDer(dilithium_key* key, byte* output, word32 inLen,
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (key == NULL || output == NULL) {
if (key == NULL) {
return BAD_FUNC_ARG;
}

View File

@@ -846,11 +846,11 @@ int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
pubKey, &pubKeyLen, keytype);
if (ret == 0) {
if (pubKeyLen == 0) {
ret = wc_falcon_import_private_only(input, inSz, key);
ret = wc_falcon_import_private_key(input, inSz, NULL, 0, key);
}
else {
ret = wc_falcon_import_private_key(privKey, privKeyLen,
pubKey, pubKeyLen, key);
ret = wc_falcon_import_private_key(input, inSz, pubKey,
pubKeyLen, key);
}
}
return ret;
@@ -912,7 +912,7 @@ int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output, word32 inLen,
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (key == NULL || output == NULL) {
if (key == NULL) {
return BAD_FUNC_ARG;
}

View File

@@ -1120,7 +1120,7 @@ static WARN_UNUSED_RESULT int freeDecCertList(WC_DerCertList** list,
InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert) == 1) {
if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert, 0) == 1) {
WOLFSSL_MSG("Key Pair found");
*cert = current->buffer;
*certSz = current->bufferSz;

View File

@@ -952,7 +952,7 @@ int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output, word32 inLen,
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (key == NULL || output == NULL) {
if (key == NULL) {
return BAD_FUNC_ARG;
}

View File

@@ -1915,10 +1915,10 @@ enum Misc {
#ifdef HAVE_PQC
#ifndef MIN_FALCONKEY_SZ
#define MIN_FALCONKEY_SZ 897
#define MIN_FALCONKEY_SZ 1281
#endif
#ifndef MIN_DILITHIUMKEY_SZ
#define MIN_DILITHIUMKEY_SZ 1312
#define MIN_DILITHIUMKEY_SZ 2528
#endif
#endif
@@ -3583,8 +3583,11 @@ struct WOLFSSL_CTX {
#ifdef WOLFSSL_DUAL_ALG_CERTS
DerBuffer* altPrivateKey;
byte altPrivateKeyType;
byte altPrivateKeyType:6;
byte altPrivateKeyId:1;
byte altPrivateKeyLabel:1;
int altPrivateKeySz;
int altPrivateKeyDevId;
#endif /* WOLFSSL_DUAL_ALG_CERTS */
#ifdef OPENSSL_ALL
WOLFSSL_EVP_PKEY* privateKeyPKey;
@@ -4548,15 +4551,18 @@ typedef struct Buffers {
#ifndef NO_CERTS
DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */
DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */
byte keyType:6; /* Type of key: RSA, ECC, Ed25519 */
byte keyType:6; /* Type of key */
byte keyId:1; /* Key data is an id not data */
byte keyLabel:1; /* Key data is a label not data */
int keySz; /* Size of RSA key */
int keyDevId; /* Device Id for key */
#ifdef WOLFSSL_DUAL_ALG_CERTS
DerBuffer* altKey; /* WOLFSSL_CTX owns, unless we own */
byte altKeyType; /* Type of key: dilithium, falcon */
int altKeySz; /* Size of key */
byte altKeyType:6; /* Type of alt key */
byte altKeyId:1; /* Key data is an id not data */
byte altKeyLabel:1; /* Key data is a label not data */
int altKeySz; /* Size of alt key */
int altKeyDevId; /* Device Id for alt key */
#endif
DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */
/* chain after self, in DER, with leading size for each cert */

View File

@@ -3096,6 +3096,17 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
const unsigned char* in, long sz, int format);
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
const unsigned char* in, long sz);
#ifdef WOLFSSL_DUAL_ALG_CERTS
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx,
const unsigned char* in, long sz, int format);
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_id(WOLFSSL_CTX* ctx,
const unsigned char* id, long sz,
int devId, long keySz);
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx,
const unsigned char* id, long sz, int devId);
WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx,
const char* label, int devId);
#endif
/* SSL versions */
WOLFSSL_API int wolfSSL_use_certificate_buffer(WOLFSSL* ssl, const unsigned char* in,
@@ -3114,6 +3125,17 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
const unsigned char* in, long sz);
WOLFSSL_API int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl);
#ifdef WOLFSSL_DUAL_ALG_CERTS
WOLFSSL_API int wolfSSL_use_AltPrivateKey_buffer(WOLFSSL* ssl,
const unsigned char* in, long sz, int format);
WOLFSSL_API int wolfSSL_use_AltPrivateKey_id(WOLFSSL* ssl,
const unsigned char* id, long sz,
int devId, long keySz);
WOLFSSL_API int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl,
const unsigned char* id, long sz, int devId);
WOLFSSL_API int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl,
const char* label, int devId);
#endif
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
defined(KEEP_OUR_CERT)

View File

@@ -969,6 +969,9 @@ enum Misc_ASN {
MAX_DSA_PRIVKEY_SZ = (DSA_INTS * MAX_DSA_INT_SZ) + MAX_SEQ_SZ +
MAX_VERSION_SZ, /* Maximum size of a DSA Private
key taken from DsaKeyIntsToDer. */
#if defined(HAVE_PQC)
MAX_PQC_PUBLIC_KEY_SZ = 2592, /* Maximum size of a Dilithium public key. */
#endif
MAX_RSA_E_SZ = 16, /* Max RSA public e size */
MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */
MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */
@@ -1015,7 +1018,11 @@ enum Misc_ASN {
OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */
#if defined(HAVE_PQC)
MAX_PUBLIC_KEY_SZ = MAX_PQC_PUBLIC_KEY_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,
#else
MAX_PUBLIC_KEY_SZ = MAX_DSA_PUBKEY_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,
#endif
#ifdef WOLFSSL_ENCRYPTED_KEYS
HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */
#else
@@ -2017,10 +2024,9 @@ struct Signer {
word32 cm_idx;
#endif
#ifdef WOLFSSL_DUAL_ALG_CERTS
/* The Subject Alternative Public Key Info (SAPKI) will NOT be cached.
* Caching of it is NOT SUPPORTED yet. */
byte *sapkiDer;
int sapkiLen;
word32 sapkiOID; /* key type */
byte* sapkiDer;
int sapkiLen;
#endif /* WOLFSSL_DUAL_ALG_CERTS */
byte type;
@@ -2308,7 +2314,8 @@ WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
int maxIdx);
WOLFSSL_LOCAL int GetNameHash_ex(const byte* source, word32* idx, byte* hash,
int maxIdx, word32 sigOID);
WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der);
WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz,
DecodedCert* der, int checkAlt);
WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
const byte* pubKey, word32 pubKeySz, enum Key_Sum ks);
WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g);

View File

@@ -2008,6 +2008,7 @@ extern void uITRON4_free(void *p) ;
#define WOLFSSL_DH_CONST
#define WOLFSSL_HAVE_MAX
#define NO_WRITEV
#define NO_STDLIB_ISASCII
#define USE_FLAT_BENCHMARK_H
#define USE_FLAT_TEST_H