diff --git a/csr.signed.der b/csr.signed.der new file mode 100644 index 000000000..7ae007f52 Binary files /dev/null and b/csr.signed.der differ diff --git a/src/bio.c b/src/bio.c index 9c1e0c712..dbf29bcbe 100644 --- a/src/bio.c +++ b/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) diff --git a/src/ssl.c b/src/ssl.c index 434612ec4..689e4579b 100644 --- a/src/ssl.c +++ b/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,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; } diff --git a/tests/api.c b/tests/api.c index 675251fb7..c4e0a07a7 100644 --- a/tests/api.c +++ b/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 diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ff33fed3a..c09ceb269 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -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]) { diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index c98f12b21..33a65fc89 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -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 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a08a79644..bcfadaa7b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -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) diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 3210f9b19..ebb953f05 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -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,