mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 19:24:42 +02:00
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) {
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
cert->version = req->version;
|
cert->version = req->version;
|
||||||
cert->isCA = req->isCa;
|
cert->isCA = req->isCa;
|
||||||
|
cert->basicConstSet = req->basicConstSet;
|
||||||
#ifdef WOLFSSL_CERT_EXT
|
#ifdef WOLFSSL_CERT_EXT
|
||||||
if (req->subjKeyIdSz != 0) {
|
if (req->subjKeyIdSz != 0) {
|
||||||
XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
|
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->sigType = wolfSSL_X509_get_signature_type(x509);
|
||||||
cert->keyType = x509->pubKeyOID;
|
cert->keyType = x509->pubKeyOID;
|
||||||
cert->isCA = wolfSSL_X509_get_isCA(x509);
|
cert->isCA = wolfSSL_X509_get_isCA(x509);
|
||||||
|
cert->basicConstSet = x509->basicConstSet;
|
||||||
|
|
||||||
#ifdef WOLFSSL_CERT_EXT
|
#ifdef WOLFSSL_CERT_EXT
|
||||||
if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) {
|
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;
|
expectedLen = 1688;
|
||||||
AssertIntEQ(wolfSSL_BIO_get_len(output), expectedLen);
|
AssertIntEQ(wolfSSL_BIO_get_len(output), expectedLen);
|
||||||
|
|
||||||
|
/* Reset buffers and x509 */
|
||||||
|
BIO_free(input);
|
||||||
|
BIO_free(output);
|
||||||
X509_free(x509a);
|
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(input);
|
||||||
BIO_free(output);
|
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)
|
static int SetCa(byte* out, word32 outSz)
|
||||||
{
|
{
|
||||||
const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
|
/* ASN1->DER sequence for Basic Constraints True */
|
||||||
0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
|
const byte caBasicConstASN1[] = {
|
||||||
|
0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
|
||||||
|
0x05, 0x30, 0x03, 0x01, 0x01, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (outSz < sizeof(ca))
|
if (outSz < sizeof(caBasicConstASN1))
|
||||||
return BUFFER_E;
|
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
|
#endif
|
||||||
|
|
||||||
@@ -23589,6 +23614,12 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz,
|
|||||||
/* TODO: consider adding path length field in Cert. */
|
/* TODO: consider adding path length field in Cert. */
|
||||||
dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1;
|
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 {
|
else {
|
||||||
/* Don't write out Basic Constraints extension items. */
|
/* Don't write out Basic Constraints extension items. */
|
||||||
SetASNItem_NoOut(dataASN, CERTEXTSASN_IDX_BC_SEQ,
|
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 */
|
/* set the extensions */
|
||||||
der->extensionsSz = 0;
|
der->extensionsSz = 0;
|
||||||
|
|
||||||
/* CA */
|
/* Set CA */
|
||||||
if (cert->isCA) {
|
if (cert->isCA) {
|
||||||
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
||||||
if (der->caSz <= 0)
|
if (der->caSz <= 0)
|
||||||
@@ -24180,6 +24211,14 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
|
|||||||
|
|
||||||
der->extensionsSz += der->caSz;
|
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
|
else
|
||||||
der->caSz = 0;
|
der->caSz = 0;
|
||||||
|
|
||||||
@@ -25335,7 +25374,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
|||||||
/* set the extensions */
|
/* set the extensions */
|
||||||
der->extensionsSz = 0;
|
der->extensionsSz = 0;
|
||||||
|
|
||||||
/* CA */
|
/* Set CA */
|
||||||
if (cert->isCA) {
|
if (cert->isCA) {
|
||||||
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
der->caSz = SetCa(der->ca, sizeof(der->ca));
|
||||||
if (der->caSz <= 0)
|
if (der->caSz <= 0)
|
||||||
@@ -25343,6 +25382,14 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
|
|||||||
|
|
||||||
der->extensionsSz += der->caSz;
|
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
|
else
|
||||||
der->caSz = 0;
|
der->caSz = 0;
|
||||||
|
|
||||||
|
@@ -446,6 +446,7 @@ typedef struct Cert {
|
|||||||
void* decodedCert; /* internal DecodedCert allocated from heap */
|
void* decodedCert; /* internal DecodedCert allocated from heap */
|
||||||
byte* der; /* Pointer to buffer of current DecodedCert cache */
|
byte* der; /* Pointer to buffer of current DecodedCert cache */
|
||||||
void* heap; /* heap hint */
|
void* heap; /* heap hint */
|
||||||
|
byte basicConstSet:1; /* Indicator for when Basic Constaint is set */
|
||||||
} Cert;
|
} Cert;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user