Add CSR parsing capabilities to ParseCertRelative and wc_GetPubX509

- wolfSSL_BIO_get_mem_data now returns the last memory BIO in the chain
- Change wolfSSL_BIO_pending calls to wolfSSL_BIO_get_len calls to get accurate length depending on BIO
- Refactor X509 and X509_REQ functions to reuse similar code
- X509 and X509_REQ i2d functions now generate their DER outputs instead of returning the input DER
- Signature generated by wolfSSL_X509_resign_cert is now saved in the x509->sig buffer and added when calling *i2d
- Add test_wolfSSL_d2i_X509_REQ
This commit is contained in:
Juliusz Sosinowicz
2020-07-20 21:23:16 +02:00
parent 1a50d8e028
commit 4aa30d0bde
8 changed files with 326 additions and 106 deletions

BIN
csr.signed.der Normal file

Binary file not shown.

View File

@ -1681,20 +1681,25 @@ int wolfSSL_BIO_meth_set_destroy(WOLFSSL_BIO_METHOD *biom,
/* this compatibility function can be used for multiple BIO types */
int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p)
{
WOLFSSL_BIO* mem_bio;
WOLFSSL_ENTER("wolfSSL_BIO_get_mem_data");
if (bio == NULL)
return WOLFSSL_FATAL_ERROR;
/* Return pointer from last BIO in chain */
while (bio->next)
mem_bio = bio;
/* Return pointer from last memory BIO in chain */
while (bio->next) {
bio = bio->next;
if (p) {
*(byte**)p = (byte*)bio->ptr;
if (bio->type == WOLFSSL_BIO_MEMORY)
mem_bio = bio;
}
return bio->num;
if (p) {
*(byte**)p = (byte*)mem_bio->ptr;
}
return mem_bio->num;
}
int wolfSSL_BIO_pending(WOLFSSL_BIO* bio)

303
src/ssl.c
View File

@ -7507,7 +7507,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
}
(void)out;
memSz = wolfSSL_BIO_pending(bio);
memSz = wolfSSL_BIO_get_len(bio);
if (memSz <= 0) {
return NULL;
}
@ -9450,15 +9450,12 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
}
dns = dns->next;
/* last dns in list add at end of function */
if (dns != NULL) {
if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error pushing ASN1 object onto stack");
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
sk = NULL;
}
if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error pushing ASN1 object onto stack");
wolfSSL_GENERAL_NAME_free(gn);
wolfSSL_sk_free(sk);
sk = NULL;
}
/* null so that it doesn't get pushed again after switch */
gn = NULL;
@ -17938,14 +17935,20 @@ WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
return newX509;
}
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
static WOLFSSL_X509* wolfSSL_X509_X509_REQ_d2i(WOLFSSL_X509** x509,
const byte* in, int len, int req)
{
WOLFSSL_X509 *newX509 = NULL;
WOLFSSL_ENTER("wolfSSL_X509_d2i");
if (in != NULL && len != 0) {
if (in != NULL && len != 0
#ifndef WOLFSSL_CERT_REQ
&& req == 0
#else
&& (req == 0 || req == 1)
#endif
) {
#ifdef WOLFSSL_SMALL_STACK
DecodedCert* cert;
#else
@ -17960,6 +17963,9 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
#endif
InitDecodedCert(cert, (byte*)in, len, NULL);
#ifdef WOLFSSL_CERT_REQ
cert->isCSR = req;
#endif
if (ParseCertRelative(cert, CERT_TYPE, 0, NULL) == 0) {
newX509 = wolfSSL_X509_new();
if (newX509 != NULL) {
@ -17994,6 +18000,19 @@ int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
return isCA;
}
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
{
return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 0);
}
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
const unsigned char* in, int len)
{
return wolfSSL_X509_X509_REQ_d2i(x509, in, len, 1);
}
#endif
#endif /* KEEP_PEER_CERT || SESSION_CERTS || OPENSSL_EXTRA ||
OPENSSL_EXTRA_X509_SMALL */
@ -22763,30 +22782,71 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
*
* bio is the structure to hold output DER
* x509 certificate to create DER from
* req if set then a CSR is generated
*
* returns WOLFSSL_SUCCESS on success
*/
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
static int wolfSSL_i2d_X509_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int req)
{
int ret = WOLFSSL_FAILURE;
/* Get large buffer to hold cert der */
int derSz = 8192;
#ifdef WOLFSSL_SMALL_STACK
byte* der;
#else
byte der[8192];
#endif
WOLFSSL_ENTER("wolfSSL_i2d_X509_bio");
if (bio == NULL || x509 == NULL) {
return WOLFSSL_FAILURE;
}
if (x509->derCert != NULL) {
word32 len = x509->derCert->length;
byte* der = x509->derCert->buffer;
#ifdef WOLFSSL_SMALL_STACK
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (!der) {
WOLFSSL_MSG("malloc failed");
return WOLFSSL_FAILURE;
}
#endif
if (wolfSSL_BIO_write(bio, der, len) == (int)len) {
return WOLFSSL_SUCCESS;
}
if (wolfSSL_X509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
goto cleanup;
}
return WOLFSSL_FAILURE;
if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
goto cleanup;
}
ret = WOLFSSL_SUCCESS;
cleanup:
#ifdef WOLFSSL_SMALL_STACK
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#endif /* !NO_BIO */
/* Converts the X509 to DER format and outputs it into bio.
*
* bio is the structure to hold output DER
* x509 certificate to create DER from
*
* returns WOLFSSL_SUCCESS on success
*/
int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
{
return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 0);
}
#ifdef WOLFSSL_CERT_REQ
int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
{
return wolfSSL_i2d_X509_X509_REQ_bio(bio, x509, 1);
}
#endif /* WOLFSSL_CERT_REQ */
/* Converts an internal structure to a DER buffer
*
@ -22829,16 +22889,16 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out)
return derSz;
}
#ifndef NO_BIO
/* Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
*
* bio is the structure holding DER
* x509 certificate to create from DER. Can be NULL
*
* returns pointer to WOLFSSL_X509 structure on success and NULL on fail
/**
* Converts the DER from bio and creates a WOLFSSL_X509 structure from it.
* @param bio is the structure holding DER
* @param x509 certificate to create from DER. Can be NULL
* @param req 1 for a CSR and 0 for a x509 cert
* @return pointer to WOLFSSL_X509 structure on success and NULL on fail
*/
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
static WOLFSSL_X509* wolfSSL_d2i_X509_X509_REQ_bio(WOLFSSL_BIO* bio,
WOLFSSL_X509** x509, int req)
{
WOLFSSL_X509* localX509 = NULL;
byte* mem = NULL;
@ -22851,9 +22911,9 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
return NULL;
}
size = wolfSSL_BIO_pending(bio);
size = wolfSSL_BIO_get_len(bio);
if (size == 0) {
WOLFSSL_MSG("wolfSSL_BIO_pending error. Possibly no pending data.");
WOLFSSL_MSG("wolfSSL_BIO_get_len error. Possibly no pending data.");
return NULL;
}
@ -22868,7 +22928,16 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
return NULL;
}
localX509 = wolfSSL_X509_d2i(NULL, mem, size);
if (req) {
#ifdef WOLFSSL_CERT_REQ
localX509 = wolfSSL_X509_REQ_d2i(NULL, mem, size);
#else
WOLFSSL_MSG("CSR not compiled in");
#endif
}
else {
localX509 = wolfSSL_X509_d2i(NULL, mem, size);
}
if (localX509 == NULL) {
WOLFSSL_MSG("wolfSSL_X509_d2i error");
XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
@ -22883,6 +22952,17 @@ WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
}
#endif /* !NO_BIO */
WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
{
return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 0);
}
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509** x509)
{
return wolfSSL_d2i_X509_X509_REQ_bio(bio, x509, 1);
}
#endif
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
#ifndef NO_BIO
@ -38295,10 +38375,11 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
* updates derSz with certificate body size on success
* return WOLFSSL_SUCCESS on success
*/
static int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req,
unsigned char* der, int* derSz)
int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req,
unsigned char* der, int* derSz, int includeSig)
{
int ret;
int ret = WOLFSSL_FAILURE;
int totalLen;
Cert cert;
void* key = NULL;
int type = -1;
@ -38385,14 +38466,20 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
ret = wc_MakeCert_ex(&cert, der, *derSz, type, key, &rng);
wc_FreeRng(&rng);
}
if (ret <= 0) {
ret = WOLFSSL_FAILURE;
goto cleanup;
}
if ((ret > 0) && (x509->serialSz == 0) &&
if ((x509->serialSz == 0) &&
(cert.serialSz <= EXTERNAL_SERIAL_SIZE) &&
(cert.serialSz > 0)) {
WOLFSSL_ASN1_INTEGER *i = wolfSSL_ASN1_INTEGER_new();
if (i == NULL) {
ret = MEMORY_E;
WOLFSSL_MSG("wolfSSL_ASN1_INTEGER_new error");
ret = WOLFSSL_FAILURE;
goto cleanup;
}
else {
i->length = cert.serialSz + 2;
@ -38401,12 +38488,34 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
XMEMCPY(i->data + 2, cert.serial, cert.serialSz);
if (wolfSSL_X509_set_serialNumber(x509, i) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Issue setting generated serial number");
ret = EXTENSIONS_E;
wolfSSL_ASN1_INTEGER_free(i);
ret = WOLFSSL_FAILURE;
goto cleanup;
}
wolfSSL_ASN1_INTEGER_free(i);
}
}
if (includeSig) {
if (!x509->sig.buffer) {
WOLFSSL_MSG("No signature buffer");
ret = WOLFSSL_FAILURE;
goto cleanup;
}
totalLen = AddSignature(NULL, ret, NULL, x509->sig.length,
x509->sigOID);
if (totalLen > *derSz) {
WOLFSSL_MSG("Output der buffer too short");
ret = WOLFSSL_FAILURE;
goto cleanup;
}
ret = AddSignature(der, ret, x509->sig.buffer,
x509->sig.length, x509->sigOID);
}
*derSz = ret;
ret = WOLFSSL_SUCCESS;
cleanup:
/* Dispose of the public key object. */
#ifndef NO_RSA
if (x509->pubKeyOID == RSAk)
@ -38417,13 +38526,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
wc_ecc_free(&ecc);
#endif
if (ret > 0) {
*derSz = ret;
return WOLFSSL_SUCCESS;
}
else {
return ret;
}
return ret;
}
@ -38434,7 +38537,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
* WOLFSSL_X509 with the newly signed buffer.
* returns size of signed buffer on success and negative values on fail
*/
static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509, int req,
static int wolfSSL_X509_resign_cert(WOLFSSL_X509* x509,
unsigned char* der, int derSz, int certBodySz, WOLFSSL_EVP_MD* md,
WOLFSSL_EVP_PKEY* pkey)
{
@ -38471,22 +38574,48 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
wc_FreeRng(&rng);
if (ret < 0)
return ret;
derSz = ret;
/* Put in the new certificate encoding into the x509 object. */
FreeDer(&x509->derCert);
type = CERT_TYPE;
#ifdef WOLFSSL_REQ_CERT
if (req) {
type = CERTREQ_TYPE;
/* Extract signature from buffer */
{
word32 idx = 0;
int len = 0;
/* Read top level sequence */
if (GetSequence(der, &idx, &len, derSz) < 0) {
WOLFSSL_MSG("GetSequence error");
return WOLFSSL_FATAL_ERROR;
}
/* Move idx to signature */
idx += certBodySz;
/* Read signature algo sequence */
if (GetSequence(der, &idx, &len, derSz) < 0) {
WOLFSSL_MSG("GetSequence error");
return WOLFSSL_FATAL_ERROR;
}
idx += len;
/* Read signature bit string */
if (CheckBitString(der, &idx, &len, derSz, 0, NULL) != 0) {
WOLFSSL_MSG("CheckBitString error");
return WOLFSSL_FATAL_ERROR;
}
/* Sanity check */
if (idx + len != (word32)derSz) {
WOLFSSL_MSG("unexpected asn1 structure");
return WOLFSSL_FATAL_ERROR;
}
x509->sig.length = 0;
if (x509->sig.buffer)
XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
x509->sig.buffer = (byte*)XMALLOC(len, x509->heap,
DYNAMIC_TYPE_SIGNATURE);
if (!x509->sig.buffer) {
WOLFSSL_MSG("malloc error");
return WOLFSSL_FATAL_ERROR;
}
XMEMCPY(x509->sig.buffer, der + idx, len);
x509->sig.length = len;
}
#endif
if (AllocDer(&x509->derCert, ret, type, NULL) != 0)
return WOLFSSL_FATAL_ERROR;
XMEMCPY(x509->derCert->buffer, der, ret);
x509->derCert->length = ret;
(void)req;
return ret;
}
@ -38502,7 +38631,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
{
int ret;
/* @TODO dynamic set based on expected cert size */
byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
byte *der = (byte *)XMALLOC(WC_MAX_X509_GEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
int derSz = WC_MAX_X509_GEN;
WOLFSSL_ENTER("wolfSSL_X509_sign");
@ -38513,7 +38642,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
}
x509->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz)) !=
if ((ret = wolfSSL_X509_make_der(x509, 0, der, &derSz, 0)) !=
WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Unable to make DER for X509");
WOLFSSL_LEAVE("wolfSSL_X509_sign", ret);
@ -41978,9 +42107,9 @@ WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
}
(void)out;
bioMemSz = wolfSSL_BIO_pending(bio);
bioMemSz = wolfSSL_BIO_get_len(bio);
if (bioMemSz <= 0) {
WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
return NULL;
}
@ -42028,7 +42157,7 @@ WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out)
}
wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
if (wolfSSL_BIO_pending(bio) <= 0) {
if (wolfSSL_BIO_get_len(bio) <= 0) {
WOLFSSL_MSG("Failed to write memory to bio");
XFREE((unsigned char*)extraBioMem, bio->heap,
DYNAMIC_TYPE_TMP_BUFFER);
@ -42135,9 +42264,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
}
(void)out;
memSz = wolfSSL_BIO_pending(bio);
memSz = wolfSSL_BIO_get_len(bio);
if (memSz <= 0) {
WOLFSSL_MSG("wolfSSL_BIO_pending() failure");
WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
return NULL;
}
@ -42175,7 +42304,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
}
wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
if (wolfSSL_BIO_pending(bio) <= 0) {
if (wolfSSL_BIO_get_len(bio) <= 0) {
WOLFSSL_MSG("Failed to write memory to bio");
XFREE((unsigned char*)extraBioMem, bio->heap,
DYNAMIC_TYPE_TMP_BUFFER);
@ -48677,7 +48806,7 @@ PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
return NULL;
pkcs7->len = wolfSSL_BIO_pending(bio);
pkcs7->len = wolfSSL_BIO_get_len(bio);
pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
if (pkcs7->data == NULL) {
wolfSSL_PKCS7_free((PKCS7*)pkcs7);
@ -49592,29 +49721,45 @@ void wolfSSL_X509V3_set_ctx(WOLFSSL_X509V3_CTX* ctx, WOLFSSL_X509* issuer,
int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out)
{
const unsigned char* der;
int derSz = 0;
int ret = WOLFSSL_FAILURE;
WOLFSSL_BIO* bio = NULL;
WOLFSSL_ENTER("wolfSSL_i2d_X509_REQ");
if (req == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
der = wolfSSL_X509_get_der(req, &derSz);
if (der == NULL) {
return MEMORY_E;
if (!(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_i2d_X509_REQ_bio(bio, req) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_i2d_X509_REQ_bio error");
goto cleanup;
}
derSz = wolfSSL_BIO_get_len(bio);
if (*out == NULL) {
*out = (unsigned char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
if (*out == NULL) {
return MEMORY_E;
if (!*out) {
WOLFSSL_MSG("malloc error");
ret = MEMORY_E;
goto cleanup;
}
}
XMEMCPY(*out, der, derSz);
if (wolfSSL_BIO_read(bio, *out, derSz) != derSz) {
WOLFSSL_MSG("wolfSSL_BIO_read error");
goto cleanup;
}
return derSz;
ret = derSz;
cleanup:
wolfSSL_BIO_free(bio);
return ret;
}
WOLFSSL_X509* wolfSSL_X509_REQ_new(void)
@ -49638,11 +49783,11 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
/* Create a Cert that has the certificate request fields. */
req->sigOID = wolfSSL_sigTypeFromPKEY((WOLFSSL_EVP_MD*)md, pkey);
if (wolfSSL_X509_make_der(req, 1, der, &derSz) != WOLFSSL_SUCCESS) {
if (wolfSSL_X509_make_der(req, 1, der, &derSz, 0) != WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_X509_resign_cert(req, 1, der, sizeof(der), derSz,
if (wolfSSL_X509_resign_cert(req, der, sizeof(der), derSz,
(WOLFSSL_EVP_MD*)md, pkey) <= 0) {
return WOLFSSL_FAILURE;
}

View File

@ -27585,8 +27585,7 @@ static void test_wolfSSL_X509_STORE_CTX_get0_current_issuer(void)
cmp = X509_NAME_cmp(caName, issuerName);
AssertIntEQ(cmp, 0);
#else
/* X509_STORE_CTX_get0_current_issuer() returns empty issuer */
AssertNull(issuerName);
AssertNotNull(issuerName);
#endif
X509_free(issuer);
@ -37881,6 +37880,19 @@ static void test_wolfSSL_X509_CRL(void)
return;
}
static void test_wolfSSL_d2i_X509_REQ(void)
{
const char* csrFile = "./csr.signed.der";
BIO* bio = NULL;
X509* x509 = NULL;
AssertNotNull(bio = BIO_new_file(csrFile, "rb"));
AssertNotNull(d2i_X509_REQ_bio(bio, &x509));
X509_free(x509);
BIO_free(bio);
}
static void test_wolfSSL_PEM_read_X509(void)
{
#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
@ -39597,6 +39609,7 @@ void ApiTest(void)
test_wolfSSL_SHA256();
test_wolfSSL_X509_get_serialNumber();
test_wolfSSL_X509_CRL();
test_wolfSSL_d2i_X509_REQ();
test_wolfSSL_PEM_read_X509();
test_wolfSSL_PEM_read();
#ifndef NO_BIO

View File

@ -934,7 +934,7 @@ static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
#endif
#endif
static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
int CheckBitString(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx, int zeroBits, byte* unusedBits)
{
word32 idx = *inOutIdx;
@ -6673,19 +6673,25 @@ int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
WOLFSSL_MSG("Got Cert Header");
/* Using the sigIndex as the upper bound because that's where the
* actual certificate data ends. */
if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
oidSigType, cert->sigIndex)) < 0)
return ret;
#ifdef WOLFSSL_CERT_REQ
if (!cert->isCSR) {
#endif
/* Using the sigIndex as the upper bound because that's where the
* actual certificate data ends. */
if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
oidSigType, cert->sigIndex)) < 0)
return ret;
WOLFSSL_MSG("Got Algo ID");
WOLFSSL_MSG("Got Algo ID");
if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)
return ret;
if ( (ret = GetName(cert, ISSUER, cert->sigIndex)) < 0)
return ret;
if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)
*badDate = ret;
if ( (ret = GetValidity(cert, verify, cert->sigIndex)) < 0)
*badDate = ret;
#ifdef WOLFSSL_CERT_REQ
}
#endif
if ( (ret = GetName(cert, SUBJECT, cert->sigIndex)) < 0)
return ret;
@ -9415,6 +9421,9 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
int idx = 0;
#endif
byte* tsip_encRsaKeyIdx;
#ifdef WOLFSSL_CERT_REQ
int len = 0;
#endif
if (cert == NULL) {
return BAD_FUNC_ARG;
@ -9432,6 +9441,25 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
WOLFSSL_MSG("Parsed Past Key");
#ifdef WOLFSSL_CERT_REQ
/* Read attributes */
if (cert->isCSR) {
if (GetASNHeader_ex(cert->source,
ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED, &cert->srcIdx,
&len, cert->maxIdx, 1) < 0) {
WOLFSSL_MSG("GetASNHeader_ex error");
return ASN_PARSE_E;
}
if (len) {
WOLFSSL_MSG("Non-empty attributes. wolfSSL doesn't support "
"parsing CSR attributes.");
return ASN_VERSION_E;
}
}
#endif
if (cert->srcIdx < cert->sigIndex) {
#ifndef ALLOW_V1_EXTENSIONS
if (cert->version < 2) {
@ -9461,14 +9489,23 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
cert->srcIdx = cert->sigIndex;
}
if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
oidSigType, cert->maxIdx)) < 0)
if ((ret = GetAlgoId(cert->source, &cert->srcIdx,
#ifdef WOLFSSL_CERT_REQ
!cert->isCSR ? &confirmOID : &cert->signatureOID,
#else
&confirmOID,
#endif
oidSigType, cert->maxIdx)) < 0)
return ret;
if ((ret = GetSignature(cert)) < 0)
return ret;
if (confirmOID != cert->signatureOID)
if (confirmOID != cert->signatureOID
#ifdef WOLFSSL_CERT_REQ
&& !cert->isCSR
#endif
)
return ASN_SIG_OID_E;
#ifndef NO_SKID
@ -13703,7 +13740,7 @@ exit_ms:
/* add signature to end of buffer, size of buffer assumed checked, return
new length */
static int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
int sigAlgoType)
{
byte seq[MAX_SEQ_SZ];
@ -13841,7 +13878,7 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
byte erSeq[MAX_SEQ_SZ];
byte erSet[MAX_SET_SZ];
output[0] = 0xa0;
output[0] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
sz++;
if (pw && pw[0]) {

View File

@ -361,9 +361,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define DSA_bits wolfSSL_DSA_bits
#define i2d_X509_bio wolfSSL_i2d_X509_bio
#define i2d_X509_REQ_bio wolfSSL_i2d_X509_bio
#define i2d_X509_REQ_bio wolfSSL_i2d_X509_REQ_bio
#define d2i_X509_bio wolfSSL_d2i_X509_bio
#define d2i_X509_REQ_bio wolfSSL_d2i_X509_bio
#define d2i_X509_REQ_bio wolfSSL_d2i_X509_REQ_bio
#define d2i_X509_fp wolfSSL_d2i_X509_fp
#define i2d_X509 wolfSSL_i2d_X509
#define d2i_X509 wolfSSL_d2i_X509
@ -379,6 +379,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define i2d_PrivateKey wolfSSL_i2d_PrivateKey
#define i2d_X509_REQ wolfSSL_i2d_X509_REQ
#define d2i_X509_REQ wolfSSL_d2i_X509_REQ
#define X509_REQ_new wolfSSL_X509_REQ_new
#define X509_REQ_free wolfSSL_X509_REQ_free
#define X509_REQ_sign wolfSSL_X509_REQ_sign

View File

@ -2186,6 +2186,10 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509,
const unsigned char** in, int len);
WOLFSSL_API WOLFSSL_X509*
wolfSSL_X509_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len);
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_API WOLFSSL_X509*
wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509, const unsigned char* in, int len);
#endif
WOLFSSL_API int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out);
WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL **crl,
const unsigned char *in, int len);
@ -3423,7 +3427,12 @@ WOLFSSL_API int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
unsigned char* out, int outSz);
WOLFSSL_API int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses);
WOLFSSL_LOCAL int wolfSSL_X509_make_der(WOLFSSL_X509* x509, int req,
unsigned char* der, int* derSz, int includeSig);
WOLFSSL_API int wolfSSL_i2d_X509_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509);
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_API int wolfSSL_i2d_X509_REQ_bio(WOLFSSL_BIO* bio, WOLFSSL_X509* x509);
#endif
#if !defined(NO_FILESYSTEM)
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_fp(XFILE fp,
WOLFSSL_X509** x509);
@ -3431,6 +3440,10 @@ WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s
#endif
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_bio(WOLFSSL_BIO* bio,
WOLFSSL_X509** x509);
#ifdef WOLFSSL_CERT_REQ
WOLFSSL_API WOLFSSL_X509* wolfSSL_d2i_X509_REQ_bio(WOLFSSL_BIO* bio,
WOLFSSL_X509** x509);
#endif
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)

View File

@ -944,7 +944,9 @@ struct DecodedCert {
#if defined(WOLFSSL_SEP) || defined(WOLFSSL_QT)
byte extCertPolicyCrit : 1;
#endif
#ifdef WOLFSSL_CERT_REQ
byte isCSR : 1; /* Do we intend on parsing a CSR? */
#endif
};
@ -1041,6 +1043,8 @@ WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz,
WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm);
WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz,
void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID);
WOLFSSL_LOCAL int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
int sigAlgoType);
WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm);
WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify);
WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate);
@ -1113,6 +1117,8 @@ WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx, int check);
WOLFSSL_LOCAL int GetOctetString(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
WOLFSSL_LOCAL int CheckBitString(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx, int zeroBits, byte* unusedBits);
WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
WOLFSSL_LOCAL int GetSet_ex(const byte* input, word32* inOutIdx, int* len,