Skip to content

Commit 538ce14

Browse files
Merge pull request #6953 from SKlimaRA/SKlimaRA/enable-ca-false
Enable encoding CA:FALSE with build flag
2 parents 14906df + 308346a commit 538ce14

3 files changed

Lines changed: 105 additions & 4 deletions

File tree

tests/api.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50676,6 +50676,62 @@ static int test_MakeCertWithPathLen(void)
5067650676
return EXPECT_RESULT();
5067750677
}
5067850678

50679+
static int test_MakeCertWithCaFalse(void)
50680+
{
50681+
EXPECT_DECLS;
50682+
#if defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE) && defined(WOLFSSL_CERT_REQ) && \
50683+
!defined(NO_ASN_TIME) && defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
50684+
const byte expectedIsCa = 0;
50685+
Cert cert;
50686+
DecodedCert decodedCert;
50687+
byte der[FOURK_BUF];
50688+
int derSize = 0;
50689+
WC_RNG rng;
50690+
ecc_key key;
50691+
int ret;
50692+
50693+
XMEMSET(&rng, 0, sizeof(WC_RNG));
50694+
XMEMSET(&key, 0, sizeof(ecc_key));
50695+
XMEMSET(&cert, 0, sizeof(Cert));
50696+
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
50697+
50698+
ExpectIntEQ(wc_InitRng(&rng), 0);
50699+
ExpectIntEQ(wc_ecc_init(&key), 0);
50700+
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
50701+
ExpectIntEQ(wc_InitCert(&cert), 0);
50702+
50703+
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
50704+
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
50705+
(void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
50706+
(void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
50707+
(void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
50708+
(void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com",
50709+
CTC_NAME_SIZE);
50710+
(void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com",
50711+
CTC_NAME_SIZE);
50712+
50713+
cert.selfSigned = 1;
50714+
cert.isCA = expectedIsCa;
50715+
cert.isCaSet = 1;
50716+
cert.sigType = CTC_SHA256wECDSA;
50717+
50718+
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
50719+
ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
50720+
FOURK_BUF, NULL, &key, &rng), 0);
50721+
50722+
wc_InitDecodedCert(&decodedCert, der, derSize, NULL);
50723+
ExpectIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
50724+
ExpectIntEQ(decodedCert.isCA, expectedIsCa);
50725+
50726+
wc_FreeDecodedCert(&decodedCert);
50727+
ret = wc_ecc_free(&key);
50728+
ExpectIntEQ(ret, 0);
50729+
ret = wc_FreeRng(&rng);
50730+
ExpectIntEQ(ret, 0);
50731+
#endif
50732+
return EXPECT_RESULT();
50733+
}
50734+
5067950735
/*----------------------------------------------------------------------------*
5068050736
| wolfCrypt ECC
5068150737
*----------------------------------------------------------------------------*/
@@ -68515,6 +68571,7 @@ TEST_CASE testCases[] = {
6851568571
TEST_DECL(test_wc_ParseCert),
6851668572
TEST_DECL(test_wc_ParseCert_Error),
6851768573
TEST_DECL(test_MakeCertWithPathLen),
68574+
TEST_DECL(test_MakeCertWithCaFalse),
6851868575
TEST_DECL(test_wc_SetKeyUsage),
6851968576
TEST_DECL(test_wc_SetAuthKeyIdFromPublicKey_ex),
6852068577
TEST_DECL(test_wc_SetSubjectBuffer),

wolfcrypt/src/asn.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ ASN Options:
9696
cost of taking up more memory. Adds initials, givenname, dnQualifer for
9797
example.
9898
* WC_ASN_HASH_SHA256: Force use of SHA2-256 for the internal hash ID calcs.
99+
* WOLFSSL_ALLOW_ENCODING_CA_FALSE: Allow encoding BasicConstraints CA:FALSE
100+
* which is discouraged by X.690 specification - default values shall not
101+
* be encoded.
99102
*/
100103

101104
#include <wolfssl/wolfcrypt/error-crypt.h>
@@ -18622,7 +18625,8 @@ static int DecodeBasicCaConstraint(const byte* input, int sz, DecodedCert* cert)
1862218625
if ((ret == 0) && (dataASN[BASICCONSASN_IDX_SEQ].length != 0)) {
1862318626
/* Bad encoding when CA Boolean is false
1862418627
* (default when not present). */
18625-
#ifndef ASN_TEMPLATE_SKIP_ISCA_CHECK
18628+
#if !defined(ASN_TEMPLATE_SKIP_ISCA_CHECK) && \
18629+
!defined(WOLFSSL_ALLOW_ENCODING_CA_FALSE)
1862618630
if ((dataASN[BASICCONSASN_IDX_CA].length != 0) && (!isCA)) {
1862718631
WOLFSSL_ERROR_VERBOSE(ASN_PARSE_E);
1862818632
ret = ASN_PARSE_E;
@@ -26055,10 +26059,9 @@ static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
2605526059
return (int)sizeof(caPathLenBasicConstASN1);
2605626060
}
2605726061

26058-
26059-
/* encode CA basic constraints true
26062+
/* encode CA basic constraints
2606026063
* return total bytes written */
26061-
static int SetCa(byte* out, word32 outSz)
26064+
static int SetCaEx(byte* out, word32 outSz, byte isCa)
2606226065
{
2606326066
/* ASN1->DER sequence for Basic Constraints True */
2606426067
const byte caBasicConstASN1[] = {
@@ -26074,9 +26077,20 @@ static int SetCa(byte* out, word32 outSz)
2607426077

2607526078
XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
2607626079

26080+
if (!isCa) {
26081+
out[sizeof(caBasicConstASN1)-1] = isCa;
26082+
}
26083+
2607726084
return (int)sizeof(caBasicConstASN1);
2607826085
}
2607926086

26087+
/* encode CA basic constraints true
26088+
* return total bytes written */
26089+
static int SetCa(byte* out, word32 outSz)
26090+
{
26091+
return SetCaEx(out, outSz, 1);
26092+
}
26093+
2608026094
/* encode basic constraints without CA Boolean
2608126095
* return total bytes written */
2608226096
static int SetBC(byte* out, word32 outSz)
@@ -27827,6 +27841,13 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
2782727841
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
2782827842
}
2782927843
}
27844+
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
27845+
else if (cert->isCaSet) {
27846+
SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 0);
27847+
SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
27848+
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
27849+
}
27850+
#endif
2783027851
else if (cert->basicConstSet) {
2783127852
/* Set Basic Constraints to be a non Certificate Authority. */
2783227853
SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
@@ -28475,7 +28496,17 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
2847528496

2847628497
der->extensionsSz += der->caSz;
2847728498
}
28499+
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
2847828500
/* Set CA */
28501+
else if (cert->isCaSet) {
28502+
der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
28503+
if (der->caSz <= 0)
28504+
return EXTENSIONS_E;
28505+
28506+
der->extensionsSz += der->caSz;
28507+
}
28508+
#endif
28509+
/* Set CA true */
2847928510
else if (cert->isCA) {
2848028511
der->caSz = SetCa(der->ca, sizeof(der->ca));
2848128512
if (der->caSz <= 0)
@@ -29873,7 +29904,17 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
2987329904

2987429905
der->extensionsSz += der->caSz;
2987529906
}
29907+
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
2987629908
/* Set CA */
29909+
else if (cert->isCaSet) {
29910+
der->caSz = SetCaEx(der->ca, sizeof(der->ca), cert->isCA);
29911+
if (der->caSz <= 0)
29912+
return EXTENSIONS_E;
29913+
29914+
der->extensionsSz += der->caSz;
29915+
}
29916+
#endif
29917+
/* Set CA true */
2987729918
else if (cert->isCA) {
2987829919
der->caSz = SetCa(der->ca, sizeof(der->ca));
2987929920
if (der->caSz <= 0)

wolfssl/wolfcrypt/asn_public.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ typedef struct Cert {
530530
byte* der; /* Pointer to buffer of current DecodedCert cache */
531531
void* heap; /* heap hint */
532532
byte basicConstSet:1; /* Indicator for when Basic Constraint is set */
533+
#ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE
534+
byte isCaSet:1; /* Indicator for when isCA is set */
535+
#endif
533536
byte pathLenSet:1; /* Indicator for when path length is set */
534537
#ifdef WOLFSSL_ALT_NAMES
535538
byte altNamesCrit:1; /* Indicator of criticality of SAN extension */

0 commit comments

Comments
 (0)