Skip to content

Commit d28dd60

Browse files
authored
Various fixes for dual algorithm certificates (#7577)
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>
1 parent b98e4e0 commit d28dd60

2 files changed

Lines changed: 61 additions & 4 deletions

File tree

src/x509.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7526,11 +7526,24 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
75267526
int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
75277527
int ret = 0;
75287528
WOLFSSL_X509 *x = NULL;
7529+
byte certOwnsAltNames = 0;
7530+
byte certIsCSR = 0;
75297531

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

7536+
/* The call to CopyDecodedToX509() transfers ownership of the altNames in
7537+
* the DecodedCert to the temporary X509 object, causing the list to be
7538+
* freed in wolfSSL_X509_free(). As this is an unintended side-effect, we
7539+
* have to save the ownerFlag here and transfer ownership back to the
7540+
* DecodedCert prior to freeing the X509 object. */
7541+
certOwnsAltNames = cert->weOwnAltNames;
7542+
7543+
#ifdef WOLFSSL_CERT_REQ
7544+
certIsCSR = cert->isCSR;
7545+
#endif
7546+
75347547
x = wolfSSL_X509_new();
75357548
if (x == NULL) {
75367549
ret = MEMORY_E;
@@ -7539,6 +7552,9 @@ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
75397552
ret = CopyDecodedToX509(x, cert);
75407553
}
75417554

7555+
/* CopyDecodedToX509() clears cert->weOwnAltNames. Restore it. */
7556+
cert->weOwnAltNames = certOwnsAltNames;
7557+
75427558
if (ret == 0) {
75437559
/* Remove the altsigval extension. */
75447560
XFREE(x->altSigValDer, x->heap, DYNAMIC_TYPE_X509_EXT);
@@ -7547,13 +7563,16 @@ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) {
75477563
/* Remove sigOID so it won't be encoded. */
75487564
x->sigOID = 0;
75497565
/* We now have a PreTBS. Encode it. */
7550-
ret = wolfssl_x509_make_der(x, 0, der, &derSz, 0);
7566+
ret = wolfssl_x509_make_der(x, certIsCSR, der, &derSz, 0);
75517567
if (ret == WOLFSSL_SUCCESS) {
75527568
ret = derSz;
75537569
}
75547570
}
75557571

75567572
if (x != NULL) {
7573+
/* Safe the altNames list from being freed unitentionally. */
7574+
x->altNames = NULL;
7575+
75577576
wolfSSL_X509_free(x);
75587577
}
75597578

wolfcrypt/src/asn.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23864,13 +23864,12 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
2386423864
#ifndef WOLFSSL_SMALL_STACK
2386523865
byte der[MAX_CERT_VERIFY_SZ];
2386623866
#else
23867-
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap,
23867+
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, cert->heap,
2386823868
DYNAMIC_TYPE_DCERT);
2386923869
if (der == NULL) {
2387023870
ret = MEMORY_E;
2387123871
} else
2387223872
#endif /* ! WOLFSSL_SMALL_STACK */
23873-
2387423873
{
2387523874
ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ);
2387623875

@@ -23882,7 +23881,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
2388223881
NULL, 0, NULL);
2388323882
}
2388423883
#ifdef WOLFSSL_SMALL_STACK
23885-
XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT);
23884+
XFREE(der, cert->heap, DYNAMIC_TYPE_DCERT);
2388623885
#endif /* WOLFSSL_SMALL_STACK */
2388723886

2388823887
if (ret != 0) {
@@ -23912,6 +23911,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
2391223911
}
2391323912
#ifdef WOLFSSL_CERT_REQ
2391423913
else if (type == CERTREQ_TYPE) {
23914+
/* try to confirm/verify signature */
2391523915
if ((ret = ConfirmSignature(&cert->sigCtx,
2391623916
cert->source + cert->certBegin,
2391723917
cert->sigIndex - cert->certBegin,
@@ -23930,6 +23930,44 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
2393023930
WOLFSSL_ERROR_VERBOSE(ret);
2393123931
return ret;
2393223932
}
23933+
23934+
#ifdef WOLFSSL_DUAL_ALG_CERTS
23935+
if ((ret == 0) && cert->extAltSigAlgSet &&
23936+
cert->extAltSigValSet) {
23937+
#ifndef WOLFSSL_SMALL_STACK
23938+
byte der[MAX_CERT_VERIFY_SZ];
23939+
#else
23940+
byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, cert->heap,
23941+
DYNAMIC_TYPE_DCERT);
23942+
if (der == NULL) {
23943+
ret = MEMORY_E;
23944+
} else
23945+
#endif /* ! WOLFSSL_SMALL_STACK */
23946+
{
23947+
ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ);
23948+
23949+
if (ret > 0) {
23950+
ret = ConfirmSignature(&cert->sigCtx, der, ret,
23951+
cert->sapkiDer, cert->sapkiLen,
23952+
cert->sapkiOID, cert->altSigValDer,
23953+
cert->altSigValLen, cert->altSigAlgOID,
23954+
NULL, 0, NULL);
23955+
}
23956+
#ifdef WOLFSSL_SMALL_STACK
23957+
XFREE(der, cert->heap, DYNAMIC_TYPE_DCERT);
23958+
#endif /* WOLFSSL_SMALL_STACK */
23959+
23960+
if (ret != 0) {
23961+
WOLFSSL_MSG("Confirm alternative signature failed");
23962+
WOLFSSL_ERROR_VERBOSE(ret);
23963+
return ret;
23964+
}
23965+
else {
23966+
WOLFSSL_MSG("Alt signature has been verified!");
23967+
}
23968+
}
23969+
}
23970+
#endif /* WOLFSSL_DUAL_ALG_CERTS */
2393323971
}
2393423972
#endif
2393523973
else {

0 commit comments

Comments
 (0)