Merge pull request #2125 from embhorn/zd4297

Decoded cert cache feature
This commit is contained in:
toddouska
2019-03-12 14:02:47 -07:00
committed by GitHub
5 changed files with 526 additions and 313 deletions

View File

@ -1377,6 +1377,19 @@ then
fi fi
# DECODED CERT CACHE
AC_ARG_ENABLE([certgencache],
[AS_HELP_STRING([--enable-certgencache],[Enable decoded cert caching (default: disabled)])],
[ ENABLED_certgencache=$enableval ],
[ ENABLED_certgencache=no ]
)
if test "$ENABLED_certgencache" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_GEN_CACHE"
fi
# SEP # SEP
AC_ARG_ENABLE([sep], AC_ARG_ENABLE([sep],
[AS_HELP_STRING([--enable-sep],[Enable sep extensions (default: disabled)])], [AS_HELP_STRING([--enable-sep],[Enable sep extensions (default: disabled)])],
@ -4874,6 +4887,7 @@ echo " * keygen: $ENABLED_KEYGEN"
echo " * certgen: $ENABLED_CERTGEN" echo " * certgen: $ENABLED_CERTGEN"
echo " * certreq: $ENABLED_CERTREQ" echo " * certreq: $ENABLED_CERTREQ"
echo " * certext: $ENABLED_CERTEXT" echo " * certext: $ENABLED_CERTEXT"
echo " * certgencache: $ENABLED_certgencache"
echo " * HC-128: $ENABLED_HC128" echo " * HC-128: $ENABLED_HC128"
echo " * RABBIT: $ENABLED_RABBIT" echo " * RABBIT: $ENABLED_RABBIT"
echo " * CHACHA: $ENABLED_CHACHA" echo " * CHACHA: $ENABLED_CHACHA"

View File

@ -1597,3 +1597,35 @@ WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,
\sa none \sa none
*/ */
WOLFSSL_API int wc_GetCTC_HashOID(int type); WOLFSSL_API int wc_GetCTC_HashOID(int type);
/*!
\ingroup ASN
\brief This function cleans up memory and resources used by the certificate
structure's decoded cert cache. When WOLFSSL_CERT_GEN_CACHE is defined the
decoded cert structure is cached in the certificate structure. This allows
subsequent calls to certificate set functions to avoid parsing the decoded
cert on each call.
\return 0 on success.
\return BAD_FUNC_ARG Returned if invalid pointer is passed in as argument.
\param cert pointer to an uninitialized certificate information structure.
_Example_
\code
Cert cert; // Initialized certificate structure
wc_SetCert_Free(&cert);
\endcode
\sa wc_SetAuthKeyIdFromCert
\sa wc_SetIssuerBuffer
\sa wc_SetSubjectBuffer
\sa wc_SetSubjectRaw
\sa wc_SetIssuerRaw
\sa wc_SetAltNamesBuffer
\sa wc_SetDatesBuffer
*/
WOLFSSL_API void wc_SetCert_Free(Cert* cert);

View File

@ -9933,6 +9933,62 @@ static word32 SetUTF8String(word32 len, byte* output)
#endif /* WOLFSSL_CERT_REQ */ #endif /* WOLFSSL_CERT_REQ */
#ifndef WOLFSSL_CERT_GEN_CACHE
/* wc_SetCert_Free is only public when WOLFSSL_CERT_GEN_CACHE is not defined */
static
#endif
void wc_SetCert_Free(Cert* cert)
{
if (cert != NULL) {
if (cert->der != NULL) {
cert->der = NULL;
}
if (cert->decodedCert) {
FreeDecodedCert((DecodedCert*)cert->decodedCert);
XFREE(cert->decodedCert, cert->heap, DYNAMIC_TYPE_DCERT);
cert->decodedCert = NULL;
}
}
}
static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz)
{
int ret;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Allocate DecodedCert struct and Zero */
cert->decodedCert = (void*)XMALLOC(sizeof(DecodedCert), cert->heap,
DYNAMIC_TYPE_DCERT);
if (cert->decodedCert == NULL) {
ret = MEMORY_E;
}
else {
XMEMSET(cert->decodedCert, 0, sizeof(DecodedCert));
InitDecodedCert((DecodedCert*)cert->decodedCert, der, derSz,
cert->heap);
ret = ParseCertRelative((DecodedCert*)cert->decodedCert,
CERT_TYPE, 0, NULL);
if (ret >= 0) {
cert->der = (byte*)der;
}
else {
wc_SetCert_Free(cert);
}
}
}
return ret;
}
#endif /* WOLFSSL_CERT_GEN */ #endif /* WOLFSSL_CERT_GEN */
@ -12462,66 +12518,53 @@ int wc_SetSubjectKeyId(Cert *cert, const char* file)
#endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */ #endif /* !NO_FILESYSTEM && !NO_ASN_CRYPT */
/* Set AKID from certificate contains in buffer (DER encoded) */ static int SetAuthKeyIdFromDcert(Cert* cert, DecodedCert* decoded)
int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
{ {
int ret; int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* decoded;
#else
DecodedCert decoded[1];
#endif
if (cert == NULL || der == NULL || derSz <= 0)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_SMALL_STACK
decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (decoded == NULL)
return MEMORY_E;
#endif
/* decode certificate and get SKID that will be AKID of current cert */
InitDecodedCert(decoded, der, derSz, NULL);
ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
if (ret != 0) {
FreeDecodedCert(decoded);
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
/* Subject Key Id not found !! */ /* Subject Key Id not found !! */
if (decoded->extSubjKeyIdSet == 0) { if (decoded->extSubjKeyIdSet == 0) {
FreeDecodedCert(decoded); ret = ASN_NO_SKID;
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ASN_NO_SKID;
} }
/* SKID invalid size */ /* SKID invalid size */
if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) { else if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
FreeDecodedCert(decoded); ret = MEMORY_E;
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
} }
/* Put the SKID of CA to AKID of certificate */ else {
XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE); /* Put the SKID of CA to AKID of certificate */
cert->akidSz = KEYID_SIZE; XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
cert->akidSz = KEYID_SIZE;
}
FreeDecodedCert(decoded); return ret;
#ifdef WOLFSSL_SMALL_STACK }
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return 0; /* Set AKID from certificate contains in buffer (DER encoded) */
int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
{
int ret = 0;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
ret = SetAuthKeyIdFromDcert(cert, cert->decodedCert);
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
}
return ret;
} }
@ -12708,33 +12751,11 @@ int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
#ifdef WOLFSSL_ALT_NAMES #ifdef WOLFSSL_ALT_NAMES
/* Set Alt Names from der cert, return 0 on success */ static int SetAltNamesFromDcert(Cert* cert, DecodedCert* decoded)
static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
{ {
int ret; int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* decoded;
#else
DecodedCert decoded[1];
#endif
if (derSz < 0) if (decoded->extensions) {
return derSz;
#ifdef WOLFSSL_SMALL_STACK
decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (decoded == NULL)
return MEMORY_E;
#endif
InitDecodedCert(decoded, der, derSz, NULL);
ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
if (ret < 0) {
WOLFSSL_MSG("ParseCertRelative error");
}
else if (decoded->extensions) {
byte b; byte b;
int length; int length;
word32 maxExtensionsIdx; word32 maxExtensionsIdx;
@ -12794,17 +12815,11 @@ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
} }
} }
FreeDecodedCert(decoded); return ret;
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret < 0 ? ret : 0;
} }
/* Set Alt Names from der cert, return 0 on success */
/* Set Dates from der cert, return 0 on success */ static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
{ {
int ret; int ret;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@ -12813,7 +12828,6 @@ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
DecodedCert decoded[1]; DecodedCert decoded[1];
#endif #endif
WOLFSSL_ENTER("SetDatesFromCert");
if (derSz < 0) if (derSz < 0)
return derSz; return derSz;
@ -12830,7 +12844,23 @@ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
if (ret < 0) { if (ret < 0) {
WOLFSSL_MSG("ParseCertRelative error"); WOLFSSL_MSG("ParseCertRelative error");
} }
else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) { else {
ret = SetAltNamesFromDcert(cert, decoded);
}
FreeDecodedCert(decoded);
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret < 0 ? ret : 0;
}
static int SetDatesFromDcert(Cert* cert, DecodedCert* decoded)
{
int ret = 0;
if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
WOLFSSL_MSG("Couldn't extract dates"); WOLFSSL_MSG("Couldn't extract dates");
ret = -1; ret = -1;
} }
@ -12847,21 +12877,106 @@ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
cert->afterDateSz = decoded->afterDateLen; cert->afterDateSz = decoded->afterDateLen;
} }
FreeDecodedCert(decoded); return ret;
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret < 0 ? ret : 0;
} }
#endif /* WOLFSSL_ALT_NAMES */ #endif /* WOLFSSL_ALT_NAMES */
static void SetNameFromDcert(CertName* cn, DecodedCert* decoded)
{
int sz;
if (decoded->subjectCN) {
sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
cn->commonName[sz] = '\0';
cn->commonNameEnc = decoded->subjectCNEnc;
}
if (decoded->subjectC) {
sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
cn->country[sz] = '\0';
cn->countryEnc = decoded->subjectCEnc;
}
if (decoded->subjectST) {
sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
cn->state[sz] = '\0';
cn->stateEnc = decoded->subjectSTEnc;
}
if (decoded->subjectL) {
sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
cn->locality[sz] = '\0';
cn->localityEnc = decoded->subjectLEnc;
}
if (decoded->subjectO) {
sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
cn->org[sz] = '\0';
cn->orgEnc = decoded->subjectOEnc;
}
if (decoded->subjectOU) {
sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
cn->unit[sz] = '\0';
cn->unitEnc = decoded->subjectOUEnc;
}
if (decoded->subjectSN) {
sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
cn->sur[sz] = '\0';
cn->surEnc = decoded->subjectSNEnc;
}
if (decoded->subjectSND) {
sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->serialDev, decoded->subjectSND, CTC_NAME_SIZE);
cn->serialDev[sz] = '\0';
cn->serialDevEnc = decoded->subjectSNDEnc;
}
#ifdef WOLFSSL_CERT_EXT
if (decoded->subjectBC) {
sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->busCat, decoded->subjectBC, CTC_NAME_SIZE);
cn->busCat[sz] = '\0';
cn->busCatEnc = decoded->subjectBCEnc;
}
if (decoded->subjectJC) {
sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->joiC, decoded->subjectJC, CTC_NAME_SIZE);
cn->joiC[sz] = '\0';
cn->joiCEnc = decoded->subjectJCEnc;
}
if (decoded->subjectJS) {
sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->joiSt, decoded->subjectJS, CTC_NAME_SIZE);
cn->joiSt[sz] = '\0';
cn->joiStEnc = decoded->subjectJSEnc;
}
#endif
if (decoded->subjectEmail) {
sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
? decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
cn->email[sz] = '\0';
}
}
/* Set cn name from der buffer, return 0 on success */ /* Set cn name from der buffer, return 0 on success */
static int SetNameFromCert(CertName* cn, const byte* der, int derSz) static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
{ {
int ret, sz; int ret;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
DecodedCert* decoded; DecodedCert* decoded;
#else #else
@ -12885,91 +13000,7 @@ static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
WOLFSSL_MSG("ParseCertRelative error"); WOLFSSL_MSG("ParseCertRelative error");
} }
else { else {
if (decoded->subjectCN) { SetNameFromDcert(cn, decoded);
sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
cn->commonName[sz] = '\0';
cn->commonNameEnc = decoded->subjectCNEnc;
}
if (decoded->subjectC) {
sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
cn->country[sz] = '\0';
cn->countryEnc = decoded->subjectCEnc;
}
if (decoded->subjectST) {
sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
cn->state[sz] = '\0';
cn->stateEnc = decoded->subjectSTEnc;
}
if (decoded->subjectL) {
sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
cn->locality[sz] = '\0';
cn->localityEnc = decoded->subjectLEnc;
}
if (decoded->subjectO) {
sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
cn->org[sz] = '\0';
cn->orgEnc = decoded->subjectOEnc;
}
if (decoded->subjectOU) {
sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
cn->unit[sz] = '\0';
cn->unitEnc = decoded->subjectOUEnc;
}
if (decoded->subjectSN) {
sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
cn->sur[sz] = '\0';
cn->surEnc = decoded->subjectSNEnc;
}
if (decoded->subjectSND) {
sz = (decoded->subjectSNDLen < CTC_NAME_SIZE) ? decoded->subjectSNDLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->serialDev, decoded->subjectSND, CTC_NAME_SIZE);
cn->serialDev[sz] = '\0';
cn->serialDevEnc = decoded->subjectSNDEnc;
}
#ifdef WOLFSSL_CERT_EXT
if (decoded->subjectBC) {
sz = (decoded->subjectBCLen < CTC_NAME_SIZE) ? decoded->subjectBCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->busCat, decoded->subjectBC, CTC_NAME_SIZE);
cn->busCat[sz] = '\0';
cn->busCatEnc = decoded->subjectBCEnc;
}
if (decoded->subjectJC) {
sz = (decoded->subjectJCLen < CTC_NAME_SIZE) ? decoded->subjectJCLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->joiC, decoded->subjectJC, CTC_NAME_SIZE);
cn->joiC[sz] = '\0';
cn->joiCEnc = decoded->subjectJCEnc;
}
if (decoded->subjectJS) {
sz = (decoded->subjectJSLen < CTC_NAME_SIZE) ? decoded->subjectJSLen
: CTC_NAME_SIZE - 1;
XSTRNCPY(cn->joiSt, decoded->subjectJS, CTC_NAME_SIZE);
cn->joiSt[sz] = '\0';
cn->joiStEnc = decoded->subjectJSEnc;
}
#endif
if (decoded->subjectEmail) {
sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
? decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
cn->email[sz] = '\0';
}
} }
FreeDecodedCert(decoded); FreeDecodedCert(decoded);
@ -12981,112 +13012,6 @@ static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
#ifdef WOLFSSL_CERT_EXT
/* Set raw subject from der buffer, return 0 on success */
static int SetSubjectRawFromCert(byte* sbjRaw, const byte* der, int derSz)
{
int ret;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* decoded;
#else
DecodedCert decoded[1];
#endif
if ((derSz < 0) || (sbjRaw == NULL)) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_SMALL_STACK
decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (decoded == NULL) {
return MEMORY_E;
}
#endif
InitDecodedCert(decoded, der, derSz, NULL);
ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
if (ret < 0) {
WOLFSSL_MSG("ParseCertRelative error");
}
#ifndef IGNORE_NAME_CONSTRAINT
else {
if ((decoded->subjectRaw) &&
(decoded->subjectRawLen <= (int)sizeof(CertName))) {
XMEMCPY(sbjRaw, decoded->subjectRaw, decoded->subjectRawLen);
}
}
#else
else {
/* Fields are not accessible */
ret = -1;
WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw subject");
}
#endif
FreeDecodedCert(decoded);
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret < 0 ? ret : 0;
}
/* Set raw issuer from der buffer, return 0 on success */
static int SetIssuerRawFromCert(byte* issuerRaw, const byte* der, int derSz)
{
int ret;
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* decoded;
#else
DecodedCert decoded[1];
#endif
if ((derSz < 0) || (issuerRaw == NULL)) {
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_SMALL_STACK
decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (decoded == NULL) {
return MEMORY_E;
}
#endif
InitDecodedCert(decoded, der, derSz, NULL);
ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
if (ret < 0) {
WOLFSSL_MSG("ParseCertRelative error");
}
#ifndef IGNORE_NAME_CONSTRAINT
else {
if ((decoded->issuerRaw) &&
(decoded->issuerRawLen <= (int)sizeof(CertName))) {
XMEMCPY(issuerRaw, decoded->issuerRaw, decoded->issuerRawLen);
}
}
#else
else {
/* Fields are not accessible */
ret = -1;
WOLFSSL_MSG("IGNORE_NAME_CONSTRAINT excludes raw issuer");
}
#endif
FreeDecodedCert(decoded);
#ifdef WOLFSSL_SMALL_STACK
XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret < 0 ? ret : 0;
}
#endif /* WOLFSSL_CERT_EXT */
#ifndef NO_FILESYSTEM #ifndef NO_FILESYSTEM
/* Set cert issuer from issuerFile in PEM */ /* Set cert issuer from issuerFile in PEM */
@ -13170,48 +13095,116 @@ int wc_SetAltNames(Cert* cert, const char* file)
/* Set cert issuer from DER buffer */ /* Set cert issuer from DER buffer */
int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz) int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
{ {
if (cert == NULL) { int ret = 0;
return BAD_FUNC_ARG;
}
cert->selfSigned = 0;
return SetNameFromCert(&cert->issuer, der, derSz);
}
/* Set cert subject from DER buffer */
int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
{
if (cert == NULL) {
return BAD_FUNC_ARG;
}
return SetNameFromCert(&cert->subject, der, derSz);
}
#ifdef WOLFSSL_CERT_EXT
/* Set cert raw subject from DER buffer */
int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
{
int ret;
if (cert == NULL) { if (cert == NULL) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
else { else {
ret = SetSubjectRawFromCert(cert->sbjRaw, der, derSz); cert->selfSigned = 0;
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
SetNameFromDcert(&cert->issuer, cert->decodedCert);
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
} }
return ret;
}
/* Set cert subject from DER buffer */
int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
{
int ret = 0;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
SetNameFromDcert(&cert->subject, cert->decodedCert);
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
}
return ret;
}
#ifdef WOLFSSL_CERT_EXT
/* Set cert raw subject from DER buffer */
int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
{
int ret = 0;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
if ((((DecodedCert*)cert->decodedCert)->subjectRaw) &&
(((DecodedCert*)cert->decodedCert)->subjectRawLen <=
(int)sizeof(CertName))) {
XMEMCPY(cert->sbjRaw,
((DecodedCert*)cert->decodedCert)->subjectRaw,
((DecodedCert*)cert->decodedCert)->subjectRawLen);
}
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
}
return ret; return ret;
} }
/* Set cert raw issuer from DER buffer */ /* Set cert raw issuer from DER buffer */
int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz) int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
{ {
int ret; int ret = 0;
if (cert == NULL) { if (cert == NULL) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
else { else {
ret = SetIssuerRawFromCert(cert->issRaw, der, derSz); /* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
if ((((DecodedCert*)cert->decodedCert)->issuerRaw) &&
(((DecodedCert*)cert->decodedCert)->issuerRawLen <=
(int)sizeof(CertName))) {
XMEMCPY(cert->issRaw,
((DecodedCert*)cert->decodedCert)->issuerRaw,
((DecodedCert*)cert->decodedCert)->issuerRawLen);
}
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
} }
return ret; return ret;
} }
@ -13222,13 +13215,53 @@ int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
/* Set cert alt names from DER buffer */ /* Set cert alt names from DER buffer */
int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
{ {
return SetAltNamesFromCert(cert, der, derSz); int ret = 0;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
ret = SetAltNamesFromDcert(cert, cert->decodedCert);
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
}
return(ret);
} }
/* Set cert dates from DER buffer */ /* Set cert dates from DER buffer */
int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz) int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
{ {
return SetDatesFromCert(cert, der, derSz); int ret = 0;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
/* Check if decodedCert is cached */
if (cert->der != der) {
/* Allocate cache for the decoded cert */
ret = wc_SetCert_LoadDer(cert, der, derSz);
}
if (ret >= 0) {
ret = SetDatesFromDcert(cert, cert->decodedCert);
#ifndef WOLFSSL_CERT_GEN_CACHE
wc_SetCert_Free(cert);
#endif
}
}
return(ret);
} }
#endif /* WOLFSSL_ALT_NAMES */ #endif /* WOLFSSL_ALT_NAMES */

View File

@ -357,6 +357,10 @@ int cert_test(void);
!defined(NO_FILESYSTEM) !defined(NO_FILESYSTEM)
int certext_test(void); int certext_test(void);
#endif #endif
#if defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
int decodedCertCache_test(void);
#endif
#ifdef HAVE_IDEA #ifdef HAVE_IDEA
int idea_test(void); int idea_test(void);
#endif #endif
@ -945,6 +949,14 @@ initDefaultName();
printf( "CERT EXT test passed!\n"); printf( "CERT EXT test passed!\n");
#endif #endif
#if defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
if ( (ret = decodedCertCache_test()) != 0)
return err_sys("DECODED CERT CACHE test failed!\n", ret);
else
printf( "DECODED CERT CACHE test passed!\n");
#endif
#ifdef HAVE_CURVE25519 #ifdef HAVE_CURVE25519
if ( (ret = curve25519_test()) != 0) if ( (ret = curve25519_test()) != 0)
return err_sys("CURVE25519 test failed!\n", ret); return err_sys("CURVE25519 test failed!\n", ret);
@ -9077,6 +9089,122 @@ int certext_test(void)
} }
#endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */ #endif /* WOLFSSL_CERT_EXT && WOLFSSL_TEST_CERT */
#if defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
int decodedCertCache_test(void)
{
int ret = 0;
Cert cert;
FILE* file;
byte* der;
word32 derSz;
derSz = FOURK_BUF;
der = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL)
ret = -1;
if (ret == 0) {
/* load cert.der */
file = XFOPEN(certDerFile, "rb");
if (file != NULL) {
derSz = XFREAD(der, 1, FOURK_BUF, file);
XFCLOSE(file);
}
else
ret = -1;
}
if (ret == 0) {
if (wc_InitCert(&cert)) {
ret = -1;
}
}
if (ret == 0) {
ret = wc_SetSubjectBuffer(&cert, der, derSz);
}
if (ret == 0) {
if(wc_SetSubjectBuffer(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
if (ret == 0) {
if (wc_SetSubjectRaw(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetSubjectRaw(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
if (ret == 0) {
if(wc_SetIssuerBuffer(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetIssuerBuffer(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
if (ret == 0) {
if(wc_SetIssuerRaw(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetIssuerRaw(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
#ifdef WOLFSSL_ALT_NAMES
if (ret == 0) {
if(wc_SetAltNamesBuffer(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetAltNamesBuffer(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
if (ret == 0) {
if(wc_SetDatesBuffer(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetDatesBuffer(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
#endif
if (ret == 0) {
if(wc_SetAuthKeyIdFromCert(&cert, der, derSz) != 0)
ret = -1;
}
if (ret == 0) {
if(wc_SetAuthKeyIdFromCert(NULL, der, derSz) != BAD_FUNC_ARG)
ret = -1;
}
wc_SetCert_Free(&cert);
if (ret == 0) {
if(cert.decodedCert != NULL)
ret = -1;
}
XFREE(der, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
#endif /* defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) &&
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) */
#if !defined(NO_ASN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) #if !defined(NO_ASN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
static int rsa_flatten_test(RsaKey* key) static int rsa_flatten_test(RsaKey* key)
{ {

View File

@ -297,7 +297,9 @@ typedef struct Cert {
#ifdef WOLFSSL_CERT_REQ #ifdef WOLFSSL_CERT_REQ
char challengePw[CTC_NAME_SIZE]; char challengePw[CTC_NAME_SIZE];
#endif #endif
void* heap; /* heap hint */ void* decodedCert; /* internal DecodedCert allocated from heap */
byte* der; /* Pointer to buffer of current DecodedCert cache */
void* heap; /* heap hint */
} Cert; } Cert;
@ -336,6 +338,11 @@ WOLFSSL_API int wc_SetSubject(Cert*, const char*);
#ifdef WOLFSSL_ALT_NAMES #ifdef WOLFSSL_ALT_NAMES
WOLFSSL_API int wc_SetAltNames(Cert*, const char*); WOLFSSL_API int wc_SetAltNames(Cert*, const char*);
#endif #endif
#ifdef WOLFSSL_CERT_GEN_CACHE
WOLFSSL_API void wc_SetCert_Free(Cert* cert);
#endif
WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int); WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int);
WOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int); WOLFSSL_API int wc_SetSubjectBuffer(Cert*, const byte*, int);
WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int); WOLFSSL_API int wc_SetAltNamesBuffer(Cert*, const byte*, int);
@ -545,4 +552,3 @@ WOLFSSL_API int wc_ParseCertPIV(wc_CertPIV* cert, const byte* buf, word32 totalS
#endif #endif
#endif /* WOLF_CRYPT_ASN_PUBLIC_H */ #endif /* WOLF_CRYPT_ASN_PUBLIC_H */