Skip to content

Commit

Permalink
Various fixes for dual algorithm certificates (#7577)
Browse files Browse the repository at this point in the history
This commit adds varios fixes for the implementation of hybrid
certificates with two algorithms:
* Support for Certificate Signing Requests (both creating hybrid ones
  and also verifying ones)
* Fix for SAN fields in the DecodedCert and PreTBS generation
* Fix related to WOLFSSL_SMALL_STACK

Signed-off-by: Tobias Frauenschläger <t.frauenschlaeger@me.com>
  • Loading branch information
Frauschi authored May 23, 2024
1 parent b98e4e0 commit d28dd60
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
21 changes: 20 additions & 1 deletion src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -7526,11 +7526,24 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
int ret = 0;
WOLFSSL_X509 *x = NULL;
byte certOwnsAltNames = 0;
byte certIsCSR = 0;

if ((cert == NULL) || (der == NULL) || (derSz <= 0)) {
return BAD_FUNC_ARG;
}

/* The call to CopyDecodedToX509() transfers ownership of the altNames in
* the DecodedCert to the temporary X509 object, causing the list to be
* freed in wolfSSL_X509_free(). As this is an unintended side-effect, we
* have to save the ownerFlag here and transfer ownership back to the
* DecodedCert prior to freeing the X509 object. */
certOwnsAltNames = cert->weOwnAltNames;

#ifdef WOLFSSL_CERT_REQ
certIsCSR = cert->isCSR;
#endif

x = wolfSSL_X509_new();
if (x == NULL) {
ret = MEMORY_E;
Expand All @@ -7539,6 +7552,9 @@ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
ret = CopyDecodedToX509(x, cert);
}

/* CopyDecodedToX509() clears cert->weOwnAltNames. Restore it. */
cert->weOwnAltNames = certOwnsAltNames;

if (ret == 0) {
/* Remove the altsigval extension. */
XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
Expand All @@ -7547,13 +7563,16 @@ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
/* Remove sigOID so it won't be encoded. */
x->sigOID = 0;
/* We now have a PreTBS. Encode it. */
ret = wolfssl_x509_make_der(x, 0, der, &derSz, 0);
ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
if (ret == WOLFSSL_SUCCESS) {
ret = derSz;
}
}

if (x != NULL) {
/* Safe the altNames list from being freed unitentionally. */
x->altNames = NULL;

wolfSSL_X509_free(x);
}

Expand Down
44 changes: 41 additions & 3 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -23864,13 +23864,12 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
#ifndef WOLFSSL_SMALL_STACK
byte der[MAX_CERT_VERIFY_SZ];
#else
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap,
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, cert->heap,
DYNAMIC_TYPE_DCERT);
if (der == NULL) {
ret = MEMORY_E;
} else
#endif /* ! WOLFSSL_SMALL_STACK */

{
ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ);

Expand All @@ -23882,7 +23881,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
NULL, 0, NULL);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT);
XFREE(der, cert->heap, DYNAMIC_TYPE_DCERT);
#endif /* WOLFSSL_SMALL_STACK */

if (ret != 0) {
Expand Down Expand Up @@ -23912,6 +23911,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
}
#ifdef WOLFSSL_CERT_REQ
else if (type == CERTREQ_TYPE) {
/* try to confirm/verify signature */
if ((ret = ConfirmSignature(&cert->sigCtx,
cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin,
Expand All @@ -23930,6 +23930,44 @@ 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, cert->heap,
DYNAMIC_TYPE_DCERT);
if (der == NULL) {
ret = MEMORY_E;
} else
#endif /* ! WOLFSSL_SMALL_STACK */
{
ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ);

if (ret > 0) {
ret = ConfirmSignature(&cert->sigCtx, der, ret,
cert->sapkiDer, cert->sapkiLen,
cert->sapkiOID, cert->altSigValDer,
cert->altSigValLen, cert->altSigAlgOID,
NULL, 0, NULL);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(der, cert->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 */
}
#endif
else {
Expand Down

0 comments on commit d28dd60

Please sign in to comment.