forked from wolfSSL/wolfssl
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:
BIN
csr.signed.der
Normal file
BIN
csr.signed.der
Normal file
Binary file not shown.
17
src/bio.c
17
src/bio.c
@ -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)
|
||||
|
287
src/ssl.c
287
src/ssl.c
@ -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,8 +9450,6 @@ 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");
|
||||
@ -9459,7 +9457,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c,
|
||||
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;
|
||||
|
||||
if (wolfSSL_BIO_write(bio, der, len) == (int)len) {
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
#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_X509_make_der(x509, req, der, &derSz, 1) != WOLFSSL_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,14 +38526,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
|
||||
wc_ecc_free(&ecc);
|
||||
#endif
|
||||
|
||||
if (ret > 0) {
|
||||
*derSz = ret;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* signs a der buffer for the WOLFSSL_X509 structure using the PKEY and MD
|
||||
@ -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;
|
||||
}
|
||||
#endif
|
||||
/* Extract signature from buffer */
|
||||
{
|
||||
word32 idx = 0;
|
||||
int len = 0;
|
||||
|
||||
if (AllocDer(&x509->derCert, ret, type, NULL) != 0)
|
||||
/* Read top level sequence */
|
||||
if (GetSequence(der, &idx, &len, derSz) < 0) {
|
||||
WOLFSSL_MSG("GetSequence error");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
XMEMCPY(x509->derCert->buffer, der, ret);
|
||||
x509->derCert->length = ret;
|
||||
|
||||
(void)req;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
17
tests/api.c
17
tests/api.c
@ -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
|
||||
|
@ -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,6 +6673,9 @@ int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
|
||||
|
||||
WOLFSSL_MSG("Got Cert Header");
|
||||
|
||||
#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,
|
||||
@ -6686,6 +6689,9 @@ int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate)
|
||||
|
||||
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,
|
||||
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]) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user