Merge pull request #5304 from SKlimaRA/SKlimaRA/cert-pathlen

drafted pathlen for cert struct
This commit is contained in:
David Garske
2022-07-20 07:54:13 -07:00
committed by GitHub
3 changed files with 125 additions and 4 deletions

View File

@@ -47194,6 +47194,58 @@ static void test_wc_ParseCert(void)
#endif
}
static void test_MakeCertWithPathLen(void)
{
#if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC)
const byte expectedPathLen = 7;
Cert cert;
DecodedCert decodedCert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
printf(testingFmt, "test_MakeCertWithPathLen");
AssertIntEQ(wc_InitRng(&rng), 0);
AssertIntEQ(wc_ecc_init(&key), 0);
AssertIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
AssertIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.state, "state", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.locality, "Bozeman", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.commonName, "www.yourDomain.com", CTC_NAME_SIZE);
(void)XSTRNCPY(cert.subject.email, "yourEmail@yourDomain.com", CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = 1;
cert.pathLen = expectedPathLen;
cert.sigType = CTC_SHA256wECDSA;
#ifdef WOLFSSL_CERT_EXT
cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif
AssertIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
derSize = wc_SignCert(cert.bodySz, cert.sigType, der, FOURK_BUF, NULL,
&key, &rng);
AssertIntGE(derSize, 0);
wc_InitDecodedCert(&decodedCert, der, derSize, NULL);
AssertIntEQ(wc_ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL), 0);
AssertIntEQ(decodedCert.pathLength, expectedPathLen);
wc_FreeDecodedCert(&decodedCert);
AssertIntEQ(wc_ecc_free(&key), 0);
AssertIntEQ(wc_FreeRng(&rng), 0);
printf(resultFmt, passed);
#endif
}
/*----------------------------------------------------------------------------*
| wolfCrypt ECC
*----------------------------------------------------------------------------*/
@@ -56291,6 +56343,7 @@ void ApiTest(void)
test_wc_SetSubject();
test_CheckCertSignature();
test_wc_ParseCert();
test_MakeCertWithPathLen();
/* wolfCrypt ECC tests */
test_wc_ecc_get_curve_size_from_name();

View File

@@ -22854,6 +22854,31 @@ static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
}
/* encode CA basic constraints true with path length
* return total bytes written */
static int SetCaWithPathLen(byte* out, word32 outSz, byte pathLen)
{
/* ASN1->DER sequence for Basic Constraints True and path length */
const byte caPathLenBasicConstASN1[] = {
0x30, 0x0F, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04,
0x08, 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01,
0x00
};
if (out == NULL)
return BAD_FUNC_ARG;
if (outSz < sizeof(caPathLenBasicConstASN1))
return BUFFER_E;
XMEMCPY(out, caPathLenBasicConstASN1, sizeof(caPathLenBasicConstASN1));
out[sizeof(caPathLenBasicConstASN1)-1] = pathLen;
return (int)sizeof(caPathLenBasicConstASN1);
}
/* encode CA basic constraints true
* return total bytes written */
static int SetCa(byte* out, word32 outSz)
@@ -24424,8 +24449,17 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
/* Set Basic Constraints to be a Certificate Authority. */
SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1);
SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
/* TODO: consider adding path length field in Cert. */
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
if (cert->pathLen
#ifdef WOLFSSL_CERT_EXT
&& ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
#endif
) {
SetASN_Int8Bit(&dataASN[CERTEXTSASN_IDX_BC_PATHLEN],
cert->pathLen);
}
else {
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
}
}
else if (cert->basicConstSet) {
/* Set Basic Constraints to be a non Certificate Authority. */
@@ -25016,8 +25050,24 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
/* set the extensions */
der->extensionsSz = 0;
/* RFC 5280 : 4.2.1.9. Basic Constraints
* The pathLenConstraint field is meaningful only if the CA boolean is
* asserted and the key usage extension, if present, asserts the
* keyCertSign bit */
/* Set CA and path length */
if ((cert->isCA) && (cert->pathLen)
#ifdef WOLFSSL_CERT_EXT
&& ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
#endif
) {
der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
if (der->caSz <= 0)
return CA_TRUE_E;
der->extensionsSz += der->caSz;
}
/* Set CA */
if (cert->isCA) {
else if (cert->isCA) {
der->caSz = SetCa(der->ca, sizeof(der->ca));
if (der->caSz <= 0)
return CA_TRUE_E;
@@ -26187,8 +26237,24 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
/* set the extensions */
der->extensionsSz = 0;
/* RFC 5280 : 4.2.1.9. Basic Constraints
* The pathLenConstraint field is meaningful only if the CA boolean is
* asserted and the key usage extension, if present, asserts the
* keyCertSign bit */
/* Set CA and path length */
if ((cert->isCA) && (cert->pathLen)
#ifdef WOLFSSL_CERT_EXT
&& ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage))
#endif
) {
der->caSz = SetCaWithPathLen(der->ca, sizeof(der->ca), cert->pathLen);
if (der->caSz <= 0)
return CA_TRUE_E;
der->extensionsSz += der->caSz;
}
/* Set CA */
if (cert->isCA) {
else if (cert->isCA) {
der->caSz = SetCa(der->ca, sizeof(der->ca));
if (der->caSz <= 0)
return CA_TRUE_E;

View File

@@ -384,6 +384,8 @@ typedef struct Cert {
int selfSigned; /* self signed flag */
CertName subject; /* subject info */
int isCA; /* is this going to be a CA */
byte pathLen; /* max depth of valid certification
* paths that include this cert */
/* internal use only */
int bodySz; /* pre sign total size */
int keyType; /* public key type of subject */