Add wc_SetIssuerRaw and EncodeCert with raw fields (#1798)

* Make cert with raw issuer
* Add wc_SetIssuerRaw
* Use issuer raw in EncodeCert
This commit is contained in:
Eric Blankenhorn 2018-09-07 18:22:23 -05:00 committed by David Garske
parent 7d1ab5e9d2
commit 412eecd51a
6 changed files with 215 additions and 6 deletions

View File

@ -557,6 +557,72 @@ WOLFSSL_API int wc_SetAltNames(Cert*, const char*);
*/
WOLFSSL_API int wc_SetIssuerBuffer(Cert*, const byte*, int);
/*!
\ingroup ASN
\brief This function sets the raw issuer for a certificate from the
issuer in the provided der buffer. This method is used to set the raw
issuer field prior to signing.
\return 0 Returned on successfully setting the issuer for the certificate
\return MEMORY_E Returned if there is an error allocating memory
with XMALLOC
\return ASN_PARSE_E Returned if there is an error parsing the cert
header file
\return ASN_OBJECT_ID_E Returned if there is an error parsing the
encryption type from the cert
\return ASN_EXPECT_0_E Returned if there is a formatting error in the
encryption specification of the cert file
\return ASN_BEFORE_DATE_E Returned if the date is before the certificate
start date
\return ASN_AFTER_DATE_E Returned if the date is after the certificate
expiration date
\return ASN_BITSTR_E Returned if there is an error parsing a bit string
from the certificate
\return ASN_NTRU_KEY_E Returned if there is an error parsing the NTRU key
from the certificate
\return ECC_CURVE_OID_E Returned if there is an error parsing the ECC key
from the certificate
\return ASN_UNKNOWN_OID_E Returned if the certificate is using an unknown
key object id
\return ASN_VERSION_E Returned if the ALLOW_V1_EXTENSIONS option is not
defined and the certificate is a V1 or V2 certificate
\return BAD_FUNC_ARG Returned if there is an error processing the
certificate extension
\return ASN_CRIT_EXT_E Returned if an unfamiliar critical extension is
encountered in processing the certificate
\return ASN_SIG_OID_E Returned if the signature encryption type is not
the same as the encryption type of the certificate in the provided file
\return ASN_SIG_CONFIRM_E Returned if confirming the certification
signature fails
\return ASN_NAME_INVALID_E Returned if the certificates name is not
permitted by the CA name constraints
\return ASN_NO_SIGNER_E Returned if there is no CA signer to verify the
certificates authenticity
\param cert pointer to the cert for which to set the raw issuer
\param der pointer to the buffer containing the der formatted certificate
from which to grab the subject
\param derSz size of the buffer containing the der formatted certificate
from which to grab the subject
_Example_
\code
Cert myCert;
// initialize myCert
byte* der;
der = (byte*)malloc(FOURK_BUF);
// initialize der
if(wc_SetIssuerRaw(&myCert, der, FOURK_BUF) != 0) {
// error setting subject
}
\endcode
\sa wc_InitCert
\sa wc_SetIssuer
*/
WOLFSSL_API int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz);
/*!
\ingroup ASN

View File

@ -8081,6 +8081,10 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
x509->subject.rawLen = min(dCert->subjectRawLen, sizeof(x509->subject.raw));
XMEMCPY(x509->subject.raw, dCert->subjectRaw, x509->subject.rawLen);
#ifdef WOLFSSL_CERT_EXT
x509->issuer.rawLen = min(dCert->issuerRawLen, sizeof(x509->issuer.raw));
XMEMCPY(x509->issuer.raw, dCert->issuerRaw, x509->issuer.rawLen);
#endif
#endif
XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);

View File

@ -19587,6 +19587,32 @@ static void test_wc_GetSubjectRaw(void)
#endif
}
static void test_wc_SetIssuerRaw(void)
{
#if !defined(NO_ASN) && !defined(NO_FILESYSTEM) && \
defined(WOLFSSL_CERT_EXT) && defined(OPENSSL_EXTRA)
char joiCertFile[] = "./certs/test/cert-ext-joi.pem";
WOLFSSL_X509* x509;
int peerCertSz;
const byte* peerCertBuf;
Cert forgedCert;
printf(testingFmt, "test_wc_SetIssuerRaw()");
AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(joiCertFile, WOLFSSL_FILETYPE_PEM));
AssertNotNull(peerCertBuf = wolfSSL_X509_get_der(x509, &peerCertSz));
AssertIntEQ(0, wc_InitCert(&forgedCert));
AssertIntEQ(0, wc_SetIssuerRaw(&forgedCert, peerCertBuf, peerCertSz));
wolfSSL_FreeX509(x509);
printf(resultFmt, passed);
#endif
}
static void test_CheckCertSignature(void)
{
#if !defined(NO_CERTS) && defined(WOLFSSL_SMALL_CERT_VERIFY)
@ -20901,6 +20927,7 @@ void ApiTest(void)
test_wc_GetPkcs8TraditionalOffset();
test_wc_SetSubjectRaw();
test_wc_GetSubjectRaw();
test_wc_SetIssuerRaw();
test_CheckCertSignature();
/* wolfCrypt ECC tests */

View File

@ -4108,7 +4108,7 @@ static int GetName(DecodedCert* cert, int nameType)
length += cert->srcIdx;
idx = 0;
#ifdef HAVE_PKCS7
#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
/* store pointer to raw issuer */
if (nameType == ISSUER) {
cert->issuerRaw = &cert->source[cert->srcIdx];
@ -10581,13 +10581,58 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
}
/* subject name */
der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
#ifdef WOLFSSL_CERT_EXT
if (XSTRLEN((const char*)cert->sbjRaw) > 0) {
/* Use the raw subject */
int idx;
der->subjectSz = min(sizeof(der->subject),
(word32)XSTRLEN((const char*)cert->sbjRaw));
/* header */
idx = SetSequence(der->subjectSz, der->subject);
if (der->subjectSz + idx > (int)sizeof(der->subject)) {
return SUBJECT_E;
}
XMEMCPY((char*)der->subject + idx, (const char*)cert->sbjRaw,
der->subjectSz);
der->subjectSz += idx;
}
else
#endif
{
/* Use the name structure */
der->subjectSz = SetName(der->subject, sizeof(der->subject),
&cert->subject);
}
if (der->subjectSz <= 0)
return SUBJECT_E;
/* issuer name */
der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
&cert->subject : &cert->issuer);
#ifdef WOLFSSL_CERT_EXT
if (XSTRLEN((const char*)cert->issRaw) > 0) {
/* Use the raw issuer */
int idx;
der->issuerSz = min(sizeof(der->issuer),
(word32)XSTRLEN((const char*)cert->issRaw));
/* header */
idx = SetSequence(der->issuerSz, der->issuer);
if (der->issuerSz + idx > (int)sizeof(der->issuer)) {
return ISSUER_E;
}
XMEMCPY((char*)der->issuer + idx, (const char*)cert->issRaw,
der->issuerSz);
der->issuerSz += idx;
}
else
#endif
{
/* Use the name structure */
der->issuerSz = SetName(der->issuer, sizeof(der->issuer),
cert->selfSigned ? &cert->subject : &cert->issuer);
}
if (der->issuerSz <= 0)
return ISSUER_E;
@ -12292,8 +12337,60 @@ static int SetSubjectRawFromCert(byte* sbjRaw, const byte* der, int derSz)
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, (byte*)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
/* Set cert issuer from issuerFile in PEM */
@ -12384,6 +12481,20 @@ int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
}
return ret;
}
/* Set cert raw issuer from DER buffer */
int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
{
int ret;
if (cert == NULL) {
ret = BAD_FUNC_ARG;
}
else {
ret = SetIssuerRawFromCert(cert->issRaw, der, derSz);
}
return ret;
}
#endif
#ifdef WOLFSSL_ALT_NAMES

View File

@ -673,7 +673,7 @@ struct DecodedCert {
int beforeDateLen;
byte* afterDate;
int afterDateLen;
#ifdef HAVE_PKCS7
#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
byte* issuerRaw; /* pointer to issuer inside source */
int issuerRawLen;
#endif

View File

@ -297,7 +297,6 @@ WOLFSSL_API int wc_MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
WC_RNG*);
WOLFSSL_API int wc_SetIssuer(Cert*, const char*);
WOLFSSL_API int wc_SetSubject(Cert*, const char*);
WOLFSSL_API int wc_SetSubjectRaw(Cert*, const byte* der, int derSz);
#ifdef WOLFSSL_ALT_NAMES
WOLFSSL_API int wc_SetAltNames(Cert*, const char*);
#endif
@ -324,6 +323,8 @@ WOLFSSL_API int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey,
ecc_key *eckey);
WOLFSSL_API int wc_SetSubjectKeyId(Cert *cert, const char* file);
WOLFSSL_API int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert);
WOLFSSL_API int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz);
WOLFSSL_API int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz);
#ifdef HAVE_NTRU
WOLFSSL_API int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert, byte *ntruKey,