forked from wolfSSL/wolfssl
Ensuring that X509 Basic Constraint is set when CA:FALSE
This commit is contained in:
@ -8148,6 +8148,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
cert->version = req->version;
|
||||
cert->isCA = req->isCa;
|
||||
cert->basicConstSet = req->basicConstSet;
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
if (req->subjKeyIdSz != 0) {
|
||||
XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
|
||||
@ -8239,6 +8240,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(
|
||||
cert->sigType = wolfSSL_X509_get_signature_type(x509);
|
||||
cert->keyType = x509->pubKeyOID;
|
||||
cert->isCA = wolfSSL_X509_get_isCA(x509);
|
||||
cert->basicConstSet = x509->basicConstSet;
|
||||
|
||||
#ifdef WOLFSSL_CERT_EXT
|
||||
if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
|
||||
|
47
tests/api.c
47
tests/api.c
@ -38593,7 +38593,54 @@ static void test_wolfSSL_PEM_write_bio_X509(void)
|
||||
expectedLen = 1688;
|
||||
AssertIntEQ(wolfSSL_BIO_get_len(output), expectedLen);
|
||||
|
||||
/* Reset buffers and x509 */
|
||||
BIO_free(input);
|
||||
BIO_free(output);
|
||||
X509_free(x509a);
|
||||
|
||||
/* test CA and basicConstSet values are encoded when
|
||||
* the cert is a CA */
|
||||
AssertNotNull(input = BIO_new_file(
|
||||
"certs/server-cert.pem", "rb"));
|
||||
|
||||
/* read PEM into X509 struct */
|
||||
AssertNotNull(PEM_read_bio_X509(input, &x509a, NULL, NULL));
|
||||
|
||||
/* write X509 back to PEM BIO */
|
||||
AssertNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));
|
||||
AssertIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);
|
||||
|
||||
/* read exported X509 PEM back into struct, ensure isCa and
|
||||
* basicConstSet values are maintained */
|
||||
AssertNotNull(PEM_read_bio_X509(output, &x509b, NULL, NULL));
|
||||
AssertIntEQ(x509b->isCa, 1);
|
||||
AssertIntEQ(x509b->basicConstSet, 1);
|
||||
|
||||
X509_free(x509a);
|
||||
X509_free(x509b);
|
||||
BIO_free(input);
|
||||
BIO_free(output);
|
||||
|
||||
/* test CA and basicConstSet values are encoded when
|
||||
* the cert is not CA */
|
||||
AssertNotNull(input = BIO_new_file(
|
||||
"certs/client-uri-cert.pem", "rb"));
|
||||
|
||||
/* read PEM into X509 struct */
|
||||
AssertNotNull(PEM_read_bio_X509(input, &x509a, NULL, NULL));
|
||||
|
||||
/* write X509 back to PEM BIO */
|
||||
AssertNotNull(output = BIO_new(wolfSSL_BIO_s_mem()));
|
||||
AssertIntEQ(PEM_write_bio_X509(output, x509a), WOLFSSL_SUCCESS);
|
||||
|
||||
/* read exported X509 PEM back into struct, ensure isCa and
|
||||
* basicConstSet values are maintained */
|
||||
AssertNotNull(PEM_read_bio_X509(output, &x509b, NULL, NULL));
|
||||
AssertIntEQ(x509b->isCa, 0);
|
||||
AssertIntEQ(x509b->basicConstSet, 1);
|
||||
|
||||
X509_free(x509a);
|
||||
X509_free(x509b);
|
||||
BIO_free(input);
|
||||
BIO_free(output);
|
||||
|
||||
|
@ -22041,21 +22041,46 @@ static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
|
||||
}
|
||||
|
||||
|
||||
/* encode CA basic constraint true, return total bytes written */
|
||||
/* encode CA basic constraints true
|
||||
* return total bytes written */
|
||||
static int SetCa(byte* out, word32 outSz)
|
||||
{
|
||||
const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
|
||||
0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
|
||||
/* ASN1->DER sequence for Basic Constraints True */
|
||||
const byte caBasicConstASN1[] = {
|
||||
0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
|
||||
0x05, 0x30, 0x03, 0x01, 0x01, 0xff
|
||||
};
|
||||
|
||||
if (out == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (outSz < sizeof(ca))
|
||||
if (outSz < sizeof(caBasicConstASN1))
|
||||
return BUFFER_E;
|
||||
|
||||
XMEMCPY(out, ca, sizeof(ca));
|
||||
XMEMCPY(out, caBasicConstASN1, sizeof(caBasicConstASN1));
|
||||
|
||||
return (int)sizeof(ca);
|
||||
return (int)sizeof(caBasicConstASN1);
|
||||
}
|
||||
|
||||
/* encode basic constraints without CA Boolean
|
||||
* return total bytes written */
|
||||
static int SetBC(byte* out, word32 outSz)
|
||||
{
|
||||
/* ASN1->DER sequence for Basic Constraint without CA Boolean */
|
||||
const byte BasicConstASN1[] = {
|
||||
0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
|
||||
0x02, 0x30, 0x00
|
||||
};
|
||||
|
||||
if (out == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (outSz < sizeof(BasicConstASN1))
|
||||
return BUFFER_E;
|
||||
|
||||
XMEMCPY(out, BasicConstASN1, sizeof(BasicConstASN1));
|
||||
|
||||
return (int)sizeof(BasicConstASN1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -23589,6 +23614,12 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
||||
/* TODO: consider adding path length field in Cert. */
|
||||
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
|
||||
}
|
||||
else if (cert->basicConstSet) {
|
||||
/* Set Basic Constraints to be a non Certificate Authority. */
|
||||
SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID));
|
||||
dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1;
|
||||
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
|
||||
}
|
||||
else {
|
||||
/* Don't write out Basic Constraints extension items. */
|
||||
SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
|
||||
@ -24172,7 +24203,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
||||
/* set the extensions */
|
||||
der->extensionsSz = 0;
|
||||
|
||||
/* CA */
|
||||
/* Set CA */
|
||||
if (cert->isCA) {
|
||||
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
||||
if (der->caSz <= 0)
|
||||
@ -24180,6 +24211,14 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
||||
|
||||
der->extensionsSz += der->caSz;
|
||||
}
|
||||
/* Set Basic Constraint */
|
||||
else if (cert->basicConstSet) {
|
||||
der->caSz = SetBC(der->ca, sizeof(der->ca));
|
||||
if (der->caSz <= 0)
|
||||
return EXTENSIONS_E;
|
||||
|
||||
der->extensionsSz += der->caSz;
|
||||
}
|
||||
else
|
||||
der->caSz = 0;
|
||||
|
||||
@ -25335,7 +25374,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
||||
/* set the extensions */
|
||||
der->extensionsSz = 0;
|
||||
|
||||
/* CA */
|
||||
/* Set CA */
|
||||
if (cert->isCA) {
|
||||
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
||||
if (der->caSz <= 0)
|
||||
@ -25343,6 +25382,14 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
||||
|
||||
der->extensionsSz += der->caSz;
|
||||
}
|
||||
/* Set Basic Constraint */
|
||||
else if (cert->basicConstSet) {
|
||||
der->caSz = SetBC(der->ca, sizeof(der->ca));
|
||||
if (der->caSz <= 0)
|
||||
return EXTENSIONS_E;
|
||||
|
||||
der->extensionsSz += der->caSz;
|
||||
}
|
||||
else
|
||||
der->caSz = 0;
|
||||
|
||||
|
@ -443,9 +443,10 @@ typedef struct Cert {
|
||||
CertExtension customCertExt[NUM_CUSTOM_EXT];
|
||||
int customCertExtCount;
|
||||
#endif
|
||||
void* decodedCert; /* internal DecodedCert allocated from heap */
|
||||
byte* der; /* Pointer to buffer of current DecodedCert cache */
|
||||
void* heap; /* heap hint */
|
||||
void* decodedCert; /* internal DecodedCert allocated from heap */
|
||||
byte* der; /* Pointer to buffer of current DecodedCert cache */
|
||||
void* heap; /* heap hint */
|
||||
byte basicConstSet:1; /* Indicator for when Basic Constaint is set */
|
||||
} Cert;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user