Browse Source

Add support for more OpenSSL APIs

Add support for PEM_read and PEM_write
Add OpenSSL PKCS#7 signed data support
Add OpenSSL PKCS#8 Private key APIs
Add X509_REQ OpenSSL APIs
Sean Parkinson 5 years ago
parent
commit
95bd340de5

BIN
certs/ecc-keyPkcs8.der


BIN
certs/ecc-keyPkcs8Enc.der


+ 3 - 0
certs/include.am

@@ -14,8 +14,10 @@ EXTRA_DIST += \
 	     certs/ecc-privkey.pem \
 	     certs/ecc-privkeyPkcs8.pem \
 	     certs/ecc-keyPkcs8Enc.pem \
+	     certs/ecc-keyPkcs8Enc.der \
 	     certs/ecc-key-comp.pem \
 	     certs/ecc-keyPkcs8.pem \
+	     certs/ecc-keyPkcs8.der \
 	     certs/ecc-client-key.pem \
 	     certs/ecc-client-keyPub.pem \
 	     certs/client-ecc-cert.pem \
@@ -33,6 +35,7 @@ EXTRA_DIST += \
 	     certs/server-keyPkcs8Enc12.pem \
 	     certs/server-keyPkcs8Enc2.pem \
 	     certs/server-keyPkcs8Enc.pem \
+	     certs/server-keyPkcs8Enc.der \
 	     certs/server-keyPkcs8.pem \
 	     certs/server-revoked-cert.pem \
 	     certs/server-revoked-key.pem \

BIN
certs/server-keyPkcs8Enc.der


+ 1 - 1
examples/client/client.c

@@ -2193,7 +2193,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
     #ifdef HAVE_PK_CALLBACKS
         pkCbInfo.ourKey = ourKey;
     #endif
-    if (!loadCertKeyIntoSSLObj
+    if (useClientCert && !loadCertKeyIntoSSLObj
     #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
         && !pkCallbacks
     #endif

+ 2 - 0
src/internal.c

@@ -2882,6 +2882,7 @@ void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
     if (name != NULL) {
         name->name        = name->staticName;
         name->dynamicName = 0;
+        name->sz = 0;
 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
         XMEMSET(&name->fullName, 0, sizeof(DecodedName));
         XMEMSET(&name->cnEntry,  0, sizeof(WOLFSSL_X509_NAME_ENTRY));
@@ -2912,6 +2913,7 @@ void FreeX509Name(WOLFSSL_X509_NAME* name, void* heap)
                     XFREE(name->extra[i].data.data, heap, DYNAMIC_TYPE_OPENSSL);
                 }
             }
+            wolfSSL_ASN1_OBJECT_free(&name->cnEntry.object);
         }
 #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
     }

File diff suppressed because it is too large
+ 1003 - 441
src/ssl.c


+ 523 - 15
tests/api.c

@@ -316,6 +316,9 @@
 #ifdef HAVE_ECC
     #include <wolfssl/openssl/ecdsa.h>
 #endif
+#ifdef HAVE_PKCS7
+    #include <wolfssl/openssl/pkcs7.h>
+#endif
 #endif /* OPENSSL_EXTRA */
 
 #if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
@@ -450,8 +453,10 @@ static int test_wolfCrypt_Init(void)
 {
 #if defined(WOLFSSL_TEST_PLATFORMDEPEND) && !defined(NO_FILESYSTEM)
     const char *fname[] = {
-    svrCertFile, svrKeyFile, caCertFile, eccCertFile, eccKeyFile, eccRsaCertFile,
-    cliCertFile, cliCertDerFile, cliKeyFile, ntruCertFile, ntruKeyFile, dhParamFile,
+    svrCertFile, svrKeyFile, caCertFile,
+    eccCertFile, eccKeyFile, eccRsaCertFile,
+    cliCertFile, cliCertDerFile, cliKeyFile,
+    ntruCertFile, ntruKeyFile, dhParamFile,
     cliEccKeyFile, cliEccCertFile, caEccCertFile, edCertFile, edKeyFile,
     cliEdCertFile, cliEdKeyFile, caEdCertFile,
     NULL
@@ -1426,6 +1431,8 @@ static void test_wolfSSL_EC(void)
     /* NISTP256R1 Gx/Gy */
     const char* kGx   = "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
     const char* kGy   = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
+    const char* uncompG   = "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5";
+    const char* compG   = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
 
     AssertNotNull(ctx = BN_CTX_new());
     AssertNotNull(group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
@@ -1457,7 +1464,7 @@ static void test_wolfSSL_EC(void)
     /* check if point X coordinate is zero */
     AssertIntEQ(BN_is_zero(X), WOLFSSL_FAILURE);
 
-    /* check bx2hex */
+    /* check bn2hex */
     hexStr = BN_bn2hex(k);
     AssertStrEQ(hexStr, kTest);
 #ifndef NO_FILESYSTEM
@@ -1482,6 +1489,14 @@ static void test_wolfSSL_EC(void)
 #endif
     XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);
 
+    hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_UNCOMPRESSED, ctx);
+    AssertStrEQ(hexStr, uncompG);
+    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);
+
+    hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_COMPRESSED, ctx);
+    AssertStrEQ(hexStr, compG);
+    XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC);
+
     /* cleanup */
     BN_free(X);
     BN_free(Y);
@@ -15391,18 +15406,11 @@ static void test_wc_PKCS7_EncodeSignedData_ex(void)
 } /* END test_wc_PKCS7_EncodeSignedData_ex */
 
 
-/*
- * Testing wc_PKCS_VerifySignedData()
- */
-static void test_wc_PKCS7_VerifySignedData(void)
-{
 #if defined(HAVE_PKCS7)
+static int CreatePKCS7SignedData(unsigned char* output, int outputSz)
+{
     PKCS7*      pkcs7;
     WC_RNG      rng;
-    byte        output[FOURK_BUF];
-    byte        badOut[0];
-    word32      outputSz = (word32)sizeof(output);
-    word32      badOutSz = (word32)sizeof(badOut);
     byte        data[] = "Test data to encode.";
 
 #ifndef NO_RSA
@@ -15493,6 +15501,32 @@ static void test_wc_PKCS7_VerifySignedData(void)
     AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
     AssertIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
 
+    wc_PKCS7_Free(pkcs7);
+    wc_FreeRng(&rng);
+
+    return outputSz;
+}
+#endif
+
+/*
+ * Testing wc_PKCS_VerifySignedData()
+ */
+static void test_wc_PKCS7_VerifySignedData(void)
+{
+#if defined(HAVE_PKCS7)
+    PKCS7* pkcs7;
+    byte   output[FOURK_BUF];
+    word32 outputSz = sizeof(output);
+    byte   badOut[0];
+    word32 badOutSz = (word32)sizeof(badOut);
+
+    AssertIntGT((outputSz = CreatePKCS7SignedData(output, outputSz)), 0);
+
+    AssertNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, devId));
+    AssertIntEQ(wc_PKCS7_Init(pkcs7, HEAP_HINT, INVALID_DEVID), 0);
+    AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
+    AssertIntEQ(wc_PKCS7_VerifySignedData(pkcs7, output, outputSz), 0);
+
     /* Test bad args. */
     AssertIntEQ(wc_PKCS7_VerifySignedData(NULL, output, outputSz), BAD_FUNC_ARG);
     AssertIntEQ(wc_PKCS7_VerifySignedData(pkcs7, NULL, outputSz), BAD_FUNC_ARG);
@@ -15505,10 +15539,9 @@ static void test_wc_PKCS7_VerifySignedData(void)
                                 badOutSz), BAD_FUNC_ARG);
 #endif
 
-    printf(resultFmt, passed);
-
     wc_PKCS7_Free(pkcs7);
-    wc_FreeRng(&rng);
+
+    printf(resultFmt, passed);
 #endif
 } /* END test_wc_PKCS7_VerifySignedData() */
 
@@ -18874,6 +18907,162 @@ static void test_wolfSSL_PKCS8_Compat(void)
     #endif
 }
 
+static void test_wolfSSL_PKCS8_d2i(void)
+{
+#ifdef OPENSSL_ALL
+    WOLFSSL_EVP_PKEY* pkey = NULL;
+#ifndef NO_FILESYSTEM
+    unsigned char pkcs8_buffer[2048];
+    const unsigned char* p;
+    int bytes;
+    XFILE file;
+    BIO* bio;
+    WOLFSSL_EVP_PKEY* evpPkey = NULL;
+#endif
+    #ifndef NO_RSA
+        #ifndef NO_FILESYSTEM
+    const char rsaDerPkcs8File[] = "./certs/server-keyPkcs8.der";
+    const char rsaPemPkcs8File[] = "./certs/server-keyPkcs8.pem";
+#ifndef NO_DES3
+    const char rsaDerPkcs8EncFile[] = "./certs/server-keyPkcs8Enc.der";
+#endif
+        #endif
+        #ifdef USE_CERT_BUFFERS_1024
+    const unsigned char* rsa = (unsigned char*)server_key_der_1024;
+    int rsaSz = sizeof_server_key_der_1024;
+        #else
+    const unsigned char* rsa = (unsigned char*)server_key_der_2048;
+    int rsaSz = sizeof_server_key_der_2048;
+        #endif
+    #endif
+    #ifdef HAVE_ECC
+    const unsigned char* ec = (unsigned char*)ecc_key_der_256;
+    int ecSz = sizeof_ecc_key_der_256;
+        #ifndef NO_FILESYSTEM
+    const char ecDerPkcs8File[] = "certs/ecc-keyPkcs8.der";
+    const char ecPemPkcs8File[] = "certs/ecc-keyPkcs8.pem";
+#ifndef NO_DES3
+    const char ecDerPkcs8EncFile[] = "certs/ecc-keyPkcs8Enc.der";
+#endif
+        #endif
+    #endif
+
+    #ifndef NO_RSA
+    /* Try to auto-detect normal RSA private key */
+    AssertNotNull(pkey = d2i_AutoPrivateKey(NULL, &rsa, rsaSz));
+    wolfSSL_EVP_PKEY_free(pkey);
+    #endif
+    #ifdef HAVE_ECC
+    /* Try to auto-detect normal EC private key */
+    AssertNotNull(pkey = d2i_AutoPrivateKey(NULL, &ec, ecSz));
+    wolfSSL_EVP_PKEY_free(pkey);
+    #endif
+    #ifndef NO_FILESYSTEM
+        #ifndef NO_RSA
+    /* Get DER encoded RSA PKCS#8 data. */
+    file = XFOPEN(rsaDerPkcs8File, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    p = pkcs8_buffer;
+    /* Try to decode - auto-detect key type. */
+    AssertNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
+    /* Get PEM encoded RSA PKCS#8 data. */
+    file = XFOPEN(rsaPemPkcs8File, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    AssertNotNull(bio = BIO_new(BIO_s_mem()));
+    /* Write PKCS#8 PEM to BIO. */
+    AssertIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
+                                                                  NULL), bytes);
+    /* Compare file and written data */
+    AssertIntEQ(wolfSSL_BIO_get_mem_data(bio, &p), bytes);
+    AssertIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
+    BIO_free(bio);
+#ifndef NO_DES3
+    AssertNotNull(bio = BIO_new(BIO_s_mem()));
+    /* Write Encrypted PKCS#8 PEM to BIO. */
+    bytes = 1834;
+    AssertIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_des_ede3_cbc(),
+                          NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
+    AssertNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
+                                                            (void*)"yassl123"));
+    wolfSSL_EVP_PKEY_free(evpPkey);
+    BIO_free(bio);
+#endif
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    /* PKCS#8 encrypted RSA key */
+#ifndef NO_DES3
+    file = XFOPEN(rsaDerPkcs8EncFile, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    AssertNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
+    AssertNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
+                                                            (void*)"yassl123"));
+    wolfSSL_EVP_PKEY_free(pkey);
+    BIO_free(bio);
+#endif
+        #endif
+        #ifdef HAVE_ECC
+    /* PKCS#8 encode EC key */
+    file = XFOPEN(ecDerPkcs8File, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    p = pkcs8_buffer;
+    /* Try to decode - auto-detect key type. */
+    AssertNotNull(pkey = d2i_AutoPrivateKey(NULL, &p, bytes));
+    /* Get PEM encoded RSA PKCS#8 data. */
+    file = XFOPEN(ecPemPkcs8File, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    AssertNotNull(bio = BIO_new(BIO_s_mem()));
+    /* Write PKCS#8 PEM to BIO. */
+    AssertIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, NULL, NULL, 0, NULL,
+                                                                  NULL), bytes);
+    /* Compare file and written data */
+    AssertIntEQ(wolfSSL_BIO_get_mem_data(bio, &p), bytes);
+    AssertIntEQ(XMEMCMP(p, pkcs8_buffer, bytes), 0);
+    BIO_free(bio);
+    AssertNotNull(bio = BIO_new(BIO_s_mem()));
+    /* Write Encrypted PKCS#8 PEM to BIO. */
+    bytes = 379;
+    AssertIntEQ(PEM_write_bio_PKCS8PrivateKey(bio, pkey, EVP_aes_256_cbc(),
+                          NULL, 0, PasswordCallBack, (void*)"yassl123"), bytes);
+    AssertNotNull(evpPkey = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallBack,
+                                                            (void*)"yassl123"));
+    wolfSSL_EVP_PKEY_free(evpPkey);
+    BIO_free(bio);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    /* PKCS#8 encrypted EC key */
+#ifndef NO_DES3
+    file = XFOPEN(ecDerPkcs8EncFile, "rb");
+    AssertTrue(file != XBADFILE);
+    AssertIntGT((bytes = (int)XFREAD(pkcs8_buffer, 1, sizeof(pkcs8_buffer),
+                                                                     file)), 0);
+    XFCLOSE(file);
+    AssertNotNull(bio = BIO_new_mem_buf((void*)pkcs8_buffer, bytes));
+    AssertNotNull(pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, PasswordCallBack,
+                                                            (void*)"yassl123"));
+    wolfSSL_EVP_PKEY_free(pkey);
+    BIO_free(bio);
+#endif
+        #endif
+    #endif
+
+    printf(resultFmt, passed);
+#endif
+}
 
 static void test_wolfSSL_ERR_put_error(void)
 {
@@ -19121,6 +19310,9 @@ static void test_wolfSSL_X509_NAME_ENTRY(void)
                 0x0c, cn, (int)sizeof(cn)));
     AssertIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS);
 
+    AssertIntEQ(X509_NAME_add_entry_by_txt(nm, "emailAddress", MBSTRING_UTF8,
+                                           (byte*)"support@wolfssl.com", 19, -1,
+                                           1), WOLFSSL_SUCCESS);
 
     X509_NAME_ENTRY_free(entry);
     BIO_free(bio);
@@ -21038,6 +21230,196 @@ static void test_wc_ecc_get_curve_id_from_params(void)
 #endif
 }
 
+static void test_EVP_PKEY_rsa(void)
+{
+#if defined(OPENSSL_ALL) && !defined(NO_RSA)
+    WOLFSSL_RSA* rsa;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    AssertNotNull(rsa = wolfSSL_RSA_new());
+    AssertNotNull(pkey = wolfSSL_PKEY_new());
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_RSA(NULL, rsa), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_RSA(pkey, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    printf(resultFmt, passed);
+#endif
+}
+
+static void test_EVP_PKEY_ec(void)
+{
+#if defined(OPENSSL_ALL) && defined(HAVE_ECC)
+    WOLFSSL_EC_KEY* ecKey;
+    WOLFSSL_EVP_PKEY* pkey;
+
+    AssertNotNull(ecKey = wolfSSL_EC_KEY_new());
+    AssertNotNull(pkey = wolfSSL_PKEY_new());
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_EC_KEY(NULL, ecKey), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, ecKey), WOLFSSL_SUCCESS);
+    wolfSSL_EVP_PKEY_free(pkey);
+
+    printf(resultFmt, passed);
+#endif
+}
+
+#if defined(OPENSSL_ALL) && !defined(NO_CERT)
+static void free_x509(X509* x)
+{
+    AssertIntEQ((x == (X509*)1 || x == (X509*)2), 1);
+}
+#endif
+
+static void test_sk_X509(void)
+{
+#if defined(OPENSSL_ALL) && !defined(NO_CERT)
+    STACK_OF(X509)* s;
+
+    AssertNotNull(s = sk_X509_new());
+    AssertIntEQ(sk_X509_num(s), 0);
+    sk_X509_free(s);
+
+    AssertNotNull(s = sk_X509_new());
+    sk_X509_push(s, (X509*)1);
+    AssertIntEQ(sk_X509_num(s), 1);
+    AssertIntEQ((sk_X509_value(s, 0) == (X509*)1), 1);
+    sk_X509_push(s, (X509*)2);
+    AssertIntEQ(sk_X509_num(s), 2);
+    AssertIntEQ((sk_X509_value(s, 0) == (X509*)2), 1);
+    AssertIntEQ((sk_X509_value(s, 1) == (X509*)1), 1);
+    sk_X509_push(s, (X509*)2);
+    sk_X509_pop_free(s, free_x509);
+
+    printf(resultFmt, passed);
+#endif
+}
+
+static void test_X509_get_signature_nid(void)
+{
+#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
+    X509*   x509;
+
+    AssertIntEQ(X509_get_signature_nid(NULL), 0);
+    AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile,
+                                                             SSL_FILETYPE_PEM));
+    AssertIntEQ(X509_get_signature_nid(x509), CTC_SHA256wRSA);
+    X509_free(x509);
+
+    printf(resultFmt, passed);
+#endif
+}
+
+static void test_X509_REQ(void)
+{
+#if defined(OPENSSL_ALL) && !defined(NO_CERT) && defined(WOLFSSL_CERT_GEN) && \
+                                                       defined(WOLFSSL_CERT_REQ)
+    X509_NAME* name;
+#if !defined(NO_RSA) || defined(HAVE_ECC)
+    X509_REQ* req;
+    EVP_PKEY* priv;
+    EVP_PKEY* pub;
+    unsigned char* der = NULL;
+#endif
+#ifndef NO_RSA
+    #ifdef USE_CERT_BUFFERS_1024
+    const unsigned char* rsaPriv = (const unsigned char*)client_key_der_1024;
+    unsigned char* rsaPub = (unsigned char*)client_keypub_der_1024;
+    #elif defined(USE_CERT_BUFFERS_2048)
+    const unsigned char* rsaPriv = (const unsigned char*)client_key_der_2048;
+    unsigned char* rsaPub = (unsigned char*)client_keypub_der_2048;
+    #endif
+#endif
+#ifdef HAVE_ECC
+    const unsigned char* ecPriv = (const unsigned char*)ecc_clikey_der_256;
+    unsigned char* ecPub = (unsigned char*)ecc_clikeypub_der_256;
+    int len;
+#endif
+
+    AssertNotNull(name = X509_NAME_new());
+    AssertIntEQ(X509_NAME_add_entry_by_txt(name, "commonName", MBSTRING_UTF8,
+                                           (byte*)"wolfssl.com", 11, 0, 1),
+                WOLFSSL_SUCCESS);
+    AssertIntEQ(X509_NAME_add_entry_by_txt(name, "emailAddress", MBSTRING_UTF8,
+                                           (byte*)"support@wolfssl.com", 19, -1,
+                                           1), WOLFSSL_SUCCESS);
+
+#ifndef NO_RSA
+    AssertNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &rsaPriv,
+                                             (long)sizeof_client_key_der_2048));
+    AssertNotNull(pub = wolfSSL_d2i_PUBKEY(NULL, &rsaPub,
+                                          (long)sizeof_client_keypub_der_2048));
+    AssertNotNull(req = X509_REQ_new());
+    AssertIntEQ(X509_REQ_set_subject_name(NULL, name), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_set_subject_name(req, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
+    AssertIntEQ(X509_REQ_set_pubkey(NULL, pub), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_set_pubkey(req, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
+    AssertIntEQ(X509_REQ_sign(NULL, priv, EVP_sha256()), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_sign(req, NULL, EVP_sha256()), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_sign(req, priv, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
+    AssertIntEQ(i2d_X509_REQ(req, &der), 643);
+    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
+    der = NULL;
+    X509_REQ_free(NULL);
+    X509_REQ_free(req);
+    EVP_PKEY_free(pub);
+    EVP_PKEY_free(priv);
+#endif
+#ifdef HAVE_ECC
+    AssertNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &ecPriv,
+                                                    sizeof_ecc_clikey_der_256));
+    AssertNotNull(pub = wolfSSL_d2i_PUBKEY(NULL, &ecPub,
+                                                 sizeof_ecc_clikeypub_der_256));
+    AssertNotNull(req = X509_REQ_new());
+    AssertIntEQ(X509_REQ_set_subject_name(req, name), WOLFSSL_SUCCESS);
+    AssertIntEQ(X509_REQ_set_pubkey(req, pub), WOLFSSL_SUCCESS);
+    AssertIntEQ(X509_REQ_sign(req, priv, EVP_sha256()), WOLFSSL_SUCCESS);
+    /* Signature is random and may be shorter or longer. */
+    AssertIntGE((len = i2d_X509_REQ(req, &der)), 245);
+    AssertIntLE(len, 253);
+    XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
+    X509_REQ_free(req);
+    EVP_PKEY_free(pub);
+    EVP_PKEY_free(priv);
+
+    wc_ecc_fp_free();
+#endif
+
+    X509_NAME_free(name);
+
+    printf(resultFmt, passed);
+#endif
+}
+
+static void test_wolfssl_PKCS7(void)
+{
+#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
+    PKCS7* pkcs7;
+    byte   data[FOURK_BUF];
+    word32 len = sizeof(data);
+    const byte*  p = data;
+
+    AssertIntGT((len = CreatePKCS7SignedData(data, len)), 0);
+
+    AssertNull(pkcs7 = d2i_PKCS7(NULL, NULL, len));
+    AssertNull(pkcs7 = d2i_PKCS7(NULL, &p, 0));
+    AssertNotNull(pkcs7 = d2i_PKCS7(NULL, &p, len));
+    AssertIntEQ(wolfSSL_PKCS7_verify(NULL, NULL, NULL, NULL, NULL,
+                                              PKCS7_NOVERIFY), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL,
+                                                           0), WOLFSSL_FAILURE);
+    AssertIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL,
+                                              PKCS7_NOVERIFY), WOLFSSL_SUCCESS);
+
+    PKCS7_free(NULL);
+    PKCS7_free(pkcs7);
+
+    printf(resultFmt, passed);
+#endif
+}
 
 /*----------------------------------------------------------------------------*
  | Certficate Failure Checks
@@ -21885,6 +22267,118 @@ static void test_wolfSSL_PEM_read_X509(void)
 #endif
 }
 
+static void test_wolfSSL_PEM_read(void)
+{
+#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
+    const char* filename = "./certs/server-keyEnc.pem";
+    XFILE fp;
+    char* name = NULL;
+    char* header = NULL;
+    byte* data = NULL;
+    long len;
+    EVP_CIPHER_INFO cipher;
+    WOLFSSL_BIO* bio;
+    byte* fileData;
+    size_t fileDataSz;
+    byte* out;
+
+    printf(testingFmt, "wolfSSL_PEM_read");
+    fp = XFOPEN(filename, "rb");
+    AssertTrue((fp != XBADFILE));
+
+    /* Fail cases. */
+    AssertIntEQ(PEM_read(fp, NULL, &header, &data, &len), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_read(fp, &name, NULL, &data, &len), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_read(fp, &name, &header, NULL, &len), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_read(fp, &name, &header, &data, NULL), WOLFSSL_FAILURE);
+
+    AssertIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);
+
+    AssertIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
+    AssertIntGT(XSTRLEN(header), 0);
+    AssertIntGT(len, 0);
+
+    AssertIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
+    AssertIntGT((fileDataSz = XFTELL(fp)), 0);
+    AssertIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
+    AssertNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
+                                                      DYNAMIC_TYPE_TMP_BUFFER));
+    AssertIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
+    XFCLOSE(fp);
+
+    AssertNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
+
+    /* Fail cases. */
+    AssertIntEQ(PEM_write_bio(NULL, name, header, data, len), 0);
+    AssertIntEQ(PEM_write_bio(bio, NULL, header, data, len), 0);
+    AssertIntEQ(PEM_write_bio(bio, name, NULL, data, len), 0);
+    AssertIntEQ(PEM_write_bio(bio, name, header, NULL, len), 0);
+
+    AssertIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
+    AssertIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
+    AssertIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);
+
+    /* Fail cases. */
+    AssertIntEQ(PEM_get_EVP_CIPHER_INFO(NULL, &cipher), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_get_EVP_CIPHER_INFO(header, NULL), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_get_EVP_CIPHER_INFO((char*)"", &cipher), WOLFSSL_FAILURE);
+
+#ifndef NO_DES3
+    AssertIntEQ(PEM_get_EVP_CIPHER_INFO(header, &cipher), WOLFSSL_SUCCESS);
+#endif
+
+    /* Fail cases. */
+    AssertIntEQ(PEM_do_header(&cipher, NULL, &len, PasswordCallBack,
+                              (void*)"yassl123"), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_do_header(&cipher, data, NULL, PasswordCallBack,
+                              (void*)"yassl123"), WOLFSSL_FAILURE);
+    AssertIntEQ(PEM_do_header(&cipher, data, &len, NULL,
+                              (void*)"yassl123"), WOLFSSL_FAILURE);
+
+#ifndef NO_DES3
+    AssertIntEQ(PEM_do_header(&cipher, data, &len, PasswordCallBack,
+                              (void*)"yassl123"), WOLFSSL_SUCCESS);
+#endif
+
+    BIO_free(bio);
+    XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    name = NULL;
+    header = NULL;
+    data = NULL;
+    fp = XFOPEN(svrKeyFile, "rb");
+    AssertTrue((fp != XBADFILE));
+    AssertIntEQ(PEM_read(fp, &name, &header, &data, &len), WOLFSSL_SUCCESS);
+    AssertIntEQ(XSTRNCMP(name, "RSA PRIVATE KEY", 15), 0);
+    AssertIntEQ(XSTRLEN(header), 0);
+    AssertIntGT(len, 0);
+
+    AssertIntEQ(XFSEEK(fp, 0, SEEK_END), 0);
+    AssertIntGT((fileDataSz = XFTELL(fp)), 0);
+    AssertIntEQ(XFSEEK(fp, 0, SEEK_SET), 0);
+    AssertNotNull(fileData = (unsigned char*)XMALLOC(fileDataSz, NULL,
+                                                      DYNAMIC_TYPE_TMP_BUFFER));
+    AssertIntEQ(XFREAD(fileData, 1, fileDataSz, fp), fileDataSz);
+    XFCLOSE(fp);
+
+    AssertNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()));
+    AssertIntEQ(PEM_write_bio(bio, name, header, data, len), fileDataSz);
+    AssertIntEQ(wolfSSL_BIO_get_mem_data(bio, &out), fileDataSz);
+    AssertIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);
+
+    BIO_free(bio);
+    XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+    printf(resultFmt, passed);
+#endif
+}
+
 static void test_wolfSSL_X509_NAME_ENTRY_get_object()
 {
 #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA)
@@ -22330,6 +22824,7 @@ void ApiTest(void)
     test_wolfSSL_CTX_set_srp_password();
     test_wolfSSL_pseudo_rand();
     test_wolfSSL_PKCS8_Compat();
+    test_wolfSSL_PKCS8_d2i();
     test_wolfSSL_ERR_put_error();
     test_wolfSSL_HMAC();
     test_wolfSSL_OBJ();
@@ -22353,6 +22848,7 @@ void ApiTest(void)
     test_wolfSSL_X509_get_serialNumber();
     test_wolfSSL_X509_CRL();
     test_wolfSSL_PEM_read_X509();
+    test_wolfSSL_PEM_read();
     test_wolfSSL_X509_NAME_ENTRY_get_object();
     test_wolfSSL_OpenSSL_add_all_algorithms();
     test_wolfSSL_ASN1_STRING_print_ex();
@@ -22374,6 +22870,18 @@ void ApiTest(void)
     /* test the no op functions for compatibility */
     test_no_op_functions();
 
+    /* OpenSSL EVP_PKEY API tests */
+    test_EVP_PKEY_rsa();
+    test_EVP_PKEY_ec();
+    /* OpenSSL sk_X509 API test */
+    test_sk_X509();
+    /* OpenSSL X509 API test */
+    test_X509_get_signature_nid();
+    /* OpenSSL X509 REQ API test */
+    test_X509_REQ();
+    /* OpenSSL PKCS7 API test */
+    test_wolfssl_PKCS7();
+
     /* wolfCrypt ASN tests */
     test_wc_GetPkcs8TraditionalOffset();
     test_wc_SetSubjectRaw();

+ 266 - 22
wolfcrypt/src/asn.c

@@ -1360,6 +1360,7 @@ static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
 #if !defined(NO_DES3) && !defined(NO_SHA)
 static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
 #endif
+static const byte pbes2[] = {42, 134, 72, 134, 247, 13, 1, 5, 13};
 
 /* PKCS12 */
 #if !defined(NO_RC4) && !defined(NO_SHA)
@@ -1808,6 +1809,10 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
                     *oidSz = sizeof(pbeSha1Des3);
                     break;
         #endif
+                case PBES2:
+                    oid = pbes2;
+                    *oidSz = sizeof(pbes2);
+                    break;
             }
             break;
 
@@ -2262,9 +2267,10 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
 
 /* Remove PKCS8 header, place inOutIdx at beginning of traditional,
  * return traditional length on success, negative on error */
-int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
+int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz,
+                        word32* algId)
 {
-    word32 idx, oid;
+    word32 idx;
     int    version, length;
     int    ret;
 
@@ -2279,7 +2285,7 @@ int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
     if (GetMyVersion(input, &idx, &version, sz) < 0)
         return ASN_PARSE_E;
 
-    if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
+    if (GetAlgoId(input, &idx, algId, oidKeyType, sz) < 0)
         return ASN_PARSE_E;
 
     if (input[idx] == ASN_OBJECT_ID) {
@@ -2297,7 +2303,7 @@ int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
 }
 
 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
-int ToTraditional(byte* input, word32 sz)
+int ToTraditional(byte* input, word32 sz, word32* algId)
 {
     word32 inOutIdx = 0;
     int    length;
@@ -2305,7 +2311,7 @@ int ToTraditional(byte* input, word32 sz)
     if (input == NULL)
         return BAD_FUNC_ARG;
 
-    length = ToTraditionalInline(input, &inOutIdx, sz);
+    length = ToTraditionalInline(input, &inOutIdx, sz, algId);
     if (length < 0)
         return length;
 
@@ -2322,11 +2328,12 @@ int ToTraditional(byte* input, word32 sz)
 int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
 {
     int length;
+    word32 algId;
 
     if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
         return BAD_FUNC_ARG;
 
-    length = ToTraditionalInline(input, inOutIdx, sz);
+    length = ToTraditionalInline(input, inOutIdx, sz, &algId);
 
     return length;
 }
@@ -2849,7 +2856,7 @@ static int Pkcs8Pad(byte* buf, int sz, int blockSz)
  * returns the size of encrypted data on success
  */
 int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
-        const char* password,int passwordSz, int vPKCS, int vAlgo,
+        const char* password, int passwordSz, int vPKCS, int vAlgo,
         byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
 {
     int algoID = 0;
@@ -3058,10 +3065,231 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
     return totalSz + sz;
 }
 
+static int GetAlgoV2(int encAlgId, const byte** oid, int *len, int* id,
+                     int *blkSz)
+{
+    int ret = 0;
+
+    switch (encAlgId) {
+#if !defined(NO_DES3) && !defined(NO_SHA)
+    case DESb:
+        *len = sizeof(blkDesCbcOid);
+        *oid = blkDesCbcOid;
+        *id = PBE_SHA1_DES;
+        *blkSz = 8;
+        break;
+    case DES3b:
+        *len = sizeof(blkDes3CbcOid);
+        *oid = blkDes3CbcOid;
+        *id = PBE_SHA1_DES3;
+        *blkSz = 8;
+        break;
+#endif
+#if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC)
+    case AES256CBCb:
+        *len = sizeof(blkAes256CbcOid);
+        *oid = blkAes256CbcOid;
+        *id = PBE_AES256_CBC;
+        *blkSz = 16;
+        break;
+#endif
+    default:
+        (void)len;
+        (void)oid;
+        (void)id;
+        (void)blkSz;
+        ret = ALGO_ID_E;
+    }
+
+    return ret;
+}
+
+/* Converts Encrypted PKCS#8 to 'traditional' (i.e. PKCS#8 removed from
+ * decrypted key.)
+ */
+int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
+        const char* password, int passwordSz, int vPKCS, int vAlgo,
+        int encAlgId, byte* salt, word32 saltSz, int itt, WC_RNG* rng,
+        void* heap)
+{
+    int ret = 0;
+    int version, blockSz, id;
+    word32 idx = 0, encIdx;
+#ifdef WOLFSSL_SMALL_STACK
+    byte* saltTmp = NULL;
+#else
+    byte saltTmp[MAX_SALT_SIZE];
+#endif
+    byte cbcIv[MAX_IV_SIZE];
+    byte *pkcs8Key = NULL;
+    word32 pkcs8KeySz, padSz;
+    int algId;
+    const byte* curveOid = NULL;
+    word32 curveOidSz = 0;
+    const byte* pbeOid;
+    word32 pbeOidSz;
+    const byte* encOid = NULL;
+    int encOidSz = 0;
+    word32 pbeLen, kdfLen = 0, encLen = 0;
+    word32 innerLen, outerLen;
+
+    ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz);
+    /* create random salt if one not provided */
+    if (ret == 0 && (salt == NULL || saltSz <= 0)) {
+        saltSz = 8;
+    #ifdef WOLFSSL_SMALL_STACK
+        saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        if (saltTmp == NULL)
+            return MEMORY_E;
+    #endif
+        salt = saltTmp;
+
+        if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
+            WOLFSSL_MSG("Error generating random salt");
+        #ifdef WOLFSSL_SMALL_STACK
+            XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+        #endif
+            return ret;
+        }
+    }
+
+    if (ret == 0) {
+        /* check key type and get OID if ECC */
+        ret = wc_GetKeyOID(key, keySz, &curveOid, &curveOidSz, &algId, heap);
+        if (ret == 1)
+            ret = 0;
+    }
+    if (ret == 0) {
+        ret = wc_CreatePKCS8Key(NULL, &pkcs8KeySz, key, keySz, algId, curveOid,
+                                                                    curveOidSz);
+        if (ret == LENGTH_ONLY_E)
+            ret = 0;
+    }
+    if (ret == 0) {
+        pkcs8Key = (byte*)XMALLOC(pkcs8KeySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+        if (pkcs8Key == NULL)
+            ret = MEMORY_E;
+    }
+    if (ret == 0) {
+        ret = wc_CreatePKCS8Key(pkcs8Key, &pkcs8KeySz, key, keySz, algId,
+                                                          curveOid, curveOidSz);
+        if (ret >= 0) {
+            pkcs8KeySz = ret;
+            ret = 0;
+        }
+    }
+
+    if (ret == 0 && version == PKCS5v2)
+        ret = GetAlgoV2(encAlgId, &encOid, &encOidSz, &id, &blockSz);
+
+    if (ret == 0) {
+        padSz = (blockSz - (pkcs8KeySz & (blockSz - 1))) & (blockSz - 1);
+        /* inner = OCT salt INT itt */
+        innerLen = 2 + saltSz + 2 + (itt < 256 ? 1 : 2);
+
+        if (version != PKCS5v2) {
+            pbeOid = OidFromId(id, oidPBEType, &pbeOidSz);
+            /* pbe = OBJ pbse1 SEQ [ inner ] */
+            pbeLen = 2 + pbeOidSz + 2 + innerLen;
+        }
+        else {
+            pbeOid = pbes2;
+            pbeOidSz = sizeof(pbes2);
+            /* kdf = OBJ pbkdf2 [ SEQ innerLen ] */
+            kdfLen = 2 + sizeof(pbkdf2Oid) + 2 + innerLen;
+            /* enc = OBJ enc_alg OCT iv */
+            encLen = 2 + encOidSz + 2 + blockSz;
+            /* pbe = OBJ pbse2 SEQ [ SEQ [ kdf ] SEQ [ enc ] ] */
+            pbeLen = 2 + sizeof(pbes2) + 2 + 2 + kdfLen + 2 + encLen;
+
+            ret = wc_RNG_GenerateBlock(rng, cbcIv, blockSz);
+        }
+    }
+    if (ret == 0) {
+        /* outer = SEQ [ pbe ] OCT encrypted_PKCS#8_key */
+        outerLen = 2 + pbeLen;
+        outerLen += SetOctetString(pkcs8KeySz + padSz, out);
+        outerLen += pkcs8KeySz + padSz;
+
+        idx += SetSequence(outerLen, out + idx);
+
+        encIdx = idx + outerLen - pkcs8KeySz - padSz;
+        /* Put Encrypted content in place. */
+        XMEMCPY(out + encIdx, pkcs8Key, pkcs8KeySz);
+        if (padSz > 0) {
+            XMEMSET(out + encIdx + pkcs8KeySz, padSz, padSz);
+            pkcs8KeySz += padSz;
+        }
+        ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
+                                   out + encIdx, pkcs8KeySz, version, cbcIv, 1);
+    }
+    if (ret == 0) {
+        if (version != PKCS5v2) {
+            /* PBE algorithm */
+            idx += SetSequence(pbeLen, out + idx);
+            idx += SetObjectId(pbeOidSz, out + idx);
+            XMEMCPY(out + idx, pbeOid, pbeOidSz);
+            idx += pbeOidSz;
+        }
+        else {
+            /* PBES2 algorithm identifier */
+            idx += SetSequence(pbeLen, out + idx);
+            idx += SetObjectId(pbeOidSz, out + idx);
+            XMEMCPY(out + idx, pbeOid, pbeOidSz);
+            idx += pbeOidSz;
+            /* PBES2 Parameters: SEQ [ kdf ] SEQ [ enc ] */
+            idx += SetSequence(2 + kdfLen + 2 + encLen, out + idx);
+            /* KDF Algorithm Identifier */
+            idx += SetSequence(kdfLen, out + idx);
+            idx += SetObjectId(sizeof(pbkdf2Oid), out + idx);
+            XMEMCPY(out + idx, pbkdf2Oid, sizeof(pbkdf2Oid));
+            idx += sizeof(pbkdf2Oid);
+        }
+        idx += SetSequence(innerLen, out + idx);
+        idx += SetOctetString(saltSz, out + idx);
+        XMEMCPY(out + idx, salt, saltSz); idx += saltSz;
+        ret = SetShortInt(out, &idx, itt, *outSz);
+        if (ret > 0)
+            ret = 0;
+    }
+    if (ret == 0) {
+        if (version == PKCS5v2) {
+            /* Encryption Algorithm Identifier */
+            idx += SetSequence(encLen, out + idx);
+            idx += SetObjectId(encOidSz, out + idx);
+            XMEMCPY(out + idx, encOid, encOidSz);
+            idx += encOidSz;
+            /* Encryption Algorithm Parameter: CBC IV */
+            idx += SetOctetString(blockSz, out + idx);
+            XMEMCPY(out + idx, cbcIv, blockSz);
+            idx += blockSz;
+        }
+        idx += SetOctetString(pkcs8KeySz, out + idx);
+        /* Default PRF - no need to write out OID */
+        idx += pkcs8KeySz;
+
+        ret = idx;
+    }
+
+    if (pkcs8Key != NULL) {
+        ForceZero(pkcs8Key, pkcs8KeySz);
+        XFREE(pkcs8Key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#ifdef WOLFSSL_SMALL_STACK
+    if (saltTmp != NULL) {
+        XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
+    }
+#endif
+
+    (void)rng;
+
+    return ret;
+}
 
 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
    of input */
-int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
+int ToTraditionalEnc(byte* input, word32 sz,const char* password,
+                     int passwordSz, word32* algId)
 {
     word32 inOutIdx = 0, seqEnd, oid;
     int    ret = 0, first, second, length = 0, version, saltSz, id;
@@ -3195,7 +3423,7 @@ exit_tte:
 
     if (ret == 0) {
         XMEMMOVE(input, input + inOutIdx, length);
-        ret = ToTraditional(input, length);
+        ret = ToTraditional(input, length, algId);
     }
 
     return ret;
@@ -3373,7 +3601,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
     if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)
         return BUFFER_E;
 
-    out[inOutIdx++] = ASN_LONG_LENGTH; totalSz++;
+    out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; totalSz++;
     sz = SetLength(inputSz, out + inOutIdx);
     inOutIdx += sz; totalSz += sz;
 
@@ -3420,7 +3648,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
  *
  * returns the total size of decrypted content on success.
  */
-int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
+int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz)
 {
     word32 inOutIdx = 0, seqEnd, oid;
     int    ret = 0;
@@ -8275,6 +8503,16 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
             if (footer) *footer = END_PUB_KEY;
             ret = 0;
             break;
+        case PKCS8_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_PRIV_KEY;
+            if (footer) *footer = END_PRIV_KEY;
+            ret = 0;
+            break;
+        case PKCS8_ENC_PRIVATEKEY_TYPE:
+            if (header) *header = BEGIN_ENC_PRIV_KEY;
+            if (footer) *footer = END_ENC_PRIV_KEY;
+            ret = 0;
+            break;
         default:
             break;
     }
@@ -8352,8 +8590,7 @@ int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
     return ret;
 }
 
-static int wc_EncryptedInfoParse(EncryptedInfo* info,
-    char** pBuffer, size_t bufSz)
+int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz)
 {
     int err = 0;
     char*  bufferStart;
@@ -8419,17 +8656,23 @@ static int wc_EncryptedInfoParse(EncryptedInfo* info,
                 return BUFFER_E;
             info->name[finish - start] = '\0'; /* null term */
 
+            /* populate info */
+            err = wc_EncryptedInfoGet(info, info->name);
+            if (err != 0)
+                return err;
+
             /* get IV */
-            if (finishSz < sizeof(info->iv) + 1)
-                return BUFFER_E;
-            if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
+            if (finishSz < info->ivSz + 1)
                 return BUFFER_E;
 
-            if (newline == NULL)
+            if (newline == NULL) {
                 newline = XSTRNSTR(finish, "\n", min(finishSz,
                                                      PEM_LINE_LEN));
+            }
             if ((newline != NULL) && (newline > finish)) {
                 info->ivSz = (word32)(newline - (finish + 1));
+                if (XMEMCPY(info->iv, finish + 1, info->ivSz) == NULL)
+                    return BUFFER_E;
                 info->set = 1;
             }
             else
@@ -8444,9 +8687,6 @@ static int wc_EncryptedInfoParse(EncryptedInfo* info,
         /* return new headerEnd */
         if (pBuffer)
             *pBuffer = newline;
-
-        /* populate info */
-        err = wc_EncryptedInfoGet(info, info->name);
     }
 
     return err;
@@ -8636,6 +8876,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
     int         sz          = (int)longSz;
     int         encrypted_key = 0;
     DerBuffer*  der;
+    word32      algId = 0;
 
     WOLFSSL_ENTER("PemToDer");
 
@@ -8758,7 +8999,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
         ) && !encrypted_key)
     {
         /* pkcs8 key, convert and adjust length */
-        if ((ret = ToTraditional(der->buffer, der->length)) > 0) {
+        if ((ret = ToTraditional(der->buffer, der->length, &algId)) > 0) {
             der->length = ret;
         }
         else {
@@ -8798,10 +9039,13 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
             if (header == BEGIN_ENC_PRIV_KEY) {
             #ifndef NO_PWDBASED
                 ret = ToTraditionalEnc(der->buffer, der->length,
-                                       password, passwordSz);
+                                       password, passwordSz, &algId);
 
                 if (ret >= 0) {
                     der->length = ret;
+                    if (algId == ECDSAk)
+                        *eccKey = 1;
+                    ret = 0;
                 }
             #else
                 ret = NOT_COMPILED_IN;

+ 4 - 2
wolfcrypt/src/pkcs12.c

@@ -751,6 +751,7 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
     byte* buf             = NULL;
     word32 i, oid;
     int ret, pswSz;
+    word32 algId;
 
     WOLFSSL_ENTER("wc_PKCS12_parse");
 
@@ -900,7 +901,7 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                             ERROR_OUT(MEMORY_E, exit_pk12par);
                         }
                         XMEMCPY(*pkey, data + idx, size);
-                        *pkeySz =  ToTraditional(*pkey, size);
+                        *pkeySz =  ToTraditional(*pkey, size, &algId);
                     }
 
                 #ifdef WOLFSSL_DEBUG_PKCS12
@@ -937,7 +938,8 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
                         XMEMCPY(k, data + idx, size);
 
                         /* overwrites input, be warned */
-                        if ((ret = ToTraditionalEnc(k, size, psw, pswSz)) < 0) {
+                        if ((ret = ToTraditionalEnc(k, size, psw, pswSz,
+                                                                 &algId)) < 0) {
                             XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
                             goto exit_pk12par;
                         }

+ 2 - 1
wolfcrypt/src/pkcs7.c

@@ -905,9 +905,11 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
 
     heap = pkcs7->heap;
     devId = pkcs7->devId;
+    cert = pkcs7->certList;
     ret = wc_PKCS7_Init(pkcs7, heap, devId);
     if (ret != 0)
         return ret;
+    pkcs7->certList = cert;
 
     if (derCert != NULL && derCertSz > 0) {
 #ifdef WOLFSSL_SMALL_STACK
@@ -3462,7 +3464,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
             wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
             pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
         #endif
-
             /* Get the inner ContentInfo sequence */
             if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
                         NO_USER_CHECK) < 0)

+ 21 - 10
wolfcrypt/src/wc_encrypt.c

@@ -347,7 +347,7 @@ int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz,
     if (info->cipherType == WC_CIPHER_AES_CBC)
         ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz,
             info->iv);
-#endif /* NO_AES */
+#endif /* !NO_AES && HAVE_AES_CBC */
 
 #ifdef WOLFSSL_SMALL_STACK
     XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY);
@@ -568,24 +568,35 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt,
     #ifdef WOLFSSL_AES_256
         case PBE_AES256_CBC:
         {
-            Aes dec;
-            ret = wc_AesInit(&dec, NULL, INVALID_DEVID);
-            if (ret == 0)
-                ret = wc_AesSetKey(&dec, key, derivedLen,
-                                   cbcIv, AES_DECRYPTION);
-            if (ret == 0)
-                ret = wc_AesCbcDecrypt(&dec, input, input, length);
+            Aes aes;
+            ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
+            if (ret == 0) {
+                if (enc) {
+                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
+                                                                AES_ENCRYPTION);
+                }
+                else {
+                    ret = wc_AesSetKey(&aes, key, derivedLen, cbcIv,
+                                                                AES_DECRYPTION);
+                }
+            }
+            if (ret == 0) {
+                if (enc)
+                    ret = wc_AesCbcEncrypt(&aes, input, input, length);
+                else
+                    ret = wc_AesCbcDecrypt(&aes, input, input, length);
+            }
             if (ret != 0) {
 #ifdef WOLFSSL_SMALL_STACK
                 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 #endif
                 return ret;
             }
-            ForceZero(&dec, sizeof(Aes));
+            ForceZero(&aes, sizeof(Aes));
             break;
         }
     #endif /* WOLFSSL_AES_256 */
-#endif
+#endif /* !NO_AES && HAVE_AES_CBC */
 
         default:
 #ifdef WOLFSSL_SMALL_STACK

+ 2 - 2
wolfcrypt/test/test.c

@@ -13124,7 +13124,7 @@ int openssl_test(void)
             return -7424;
 
     }  /* end evp_cipher test: EVP_aes_128_cbc*/
-#endif /* WOLFSSL_AES_128 */
+#endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */
 
 #if defined(HAVE_AES_ECB) && defined(WOLFSSL_AES_256)
     {  /* evp_cipher test: EVP_aes_256_ecb*/
@@ -13641,7 +13641,7 @@ int openssl_test(void)
 
 
     }
-#endif /* WOLFSSL_AES_128 */
+#endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */
 #endif /* ifndef NO_AES */
     return 0;
 }

+ 3 - 0
wolfssl/openssl/asn1.h

@@ -53,4 +53,7 @@
                                           ASN1_STRFLGS_UTF8_CONVERT | \
                                           ASN1_STRFLGS_DUMP_UNKNOWN | \
                                           ASN1_STRFLGS_DUMP_DER)
+
+#define MBSTRING_UTF8                    0x1000
+
 #endif /* WOLFSSL_ASN1_H_ */

+ 37 - 29
wolfssl/openssl/ec.h

@@ -33,6 +33,7 @@ extern "C" {
 
 /* Map OpenSSL NID value */
 enum {
+    POINT_CONVERSION_COMPRESSED = 2,
     POINT_CONVERSION_UNCOMPRESSED = 4,
 
 #ifdef HAVE_ECC
@@ -101,6 +102,7 @@ struct WOLFSSL_EC_KEY {
     char           exSet;        /* external set from internal ? */
 };
 
+
 #define WOLFSSL_EC_KEY_LOAD_PRIVATE 1
 #define WOLFSSL_EC_KEY_LOAD_PUBLIC  2
 
@@ -182,36 +184,42 @@ WOLFSSL_API
 int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group,
                                     const WOLFSSL_EC_POINT *a);
 
-#define EC_KEY_free wolfSSL_EC_KEY_free
-#define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key
-#define EC_KEY_get0_group wolfSSL_EC_KEY_get0_group
-#define EC_KEY_set_private_key wolfSSL_EC_KEY_set_private_key
-#define EC_KEY_get0_private_key wolfSSL_EC_KEY_get0_private_key
-#define EC_KEY_new_by_curve_name wolfSSL_EC_KEY_new_by_curve_name
-#define EC_KEY_set_group wolfSSL_EC_KEY_set_group
-#define EC_KEY_generate_key wolfSSL_EC_KEY_generate_key
-#define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag
-#define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key
-#define EC_KEY_new wolfSSL_EC_KEY_new
-
-#define EC_GROUP_set_asn1_flag wolfSSL_EC_GROUP_set_asn1_flag
-#define EC_GROUP_new_by_curve_name wolfSSL_EC_GROUP_new_by_curve_name
-#define EC_GROUP_cmp wolfSSL_EC_GROUP_cmp
-#define EC_GROUP_get_curve_name wolfSSL_EC_GROUP_get_curve_name
-#define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree
-#define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order
-#define EC_GROUP_free wolfSSL_EC_GROUP_free
-
-#define EC_POINT_new wolfSSL_EC_POINT_new
+WOLFSSL_API
+char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group,
+                                 const WOLFSSL_EC_POINT* point, int form,
+                                 WOLFSSL_BN_CTX* ctx);
+
+#define EC_KEY_new                      wolfSSL_EC_KEY_new
+#define EC_KEY_free                     wolfSSL_EC_KEY_free
+#define EC_KEY_get0_public_key          wolfSSL_EC_KEY_get0_public_key
+#define EC_KEY_get0_group               wolfSSL_EC_KEY_get0_group
+#define EC_KEY_set_private_key          wolfSSL_EC_KEY_set_private_key
+#define EC_KEY_get0_private_key         wolfSSL_EC_KEY_get0_private_key
+#define EC_KEY_new_by_curve_name        wolfSSL_EC_KEY_new_by_curve_name
+#define EC_KEY_set_group                wolfSSL_EC_KEY_set_group
+#define EC_KEY_generate_key             wolfSSL_EC_KEY_generate_key
+#define EC_KEY_set_asn1_flag            wolfSSL_EC_KEY_set_asn1_flag
+#define EC_KEY_set_public_key           wolfSSL_EC_KEY_set_public_key
+
+#define EC_GROUP_free                   wolfSSL_EC_GROUP_free
+#define EC_GROUP_set_asn1_flag          wolfSSL_EC_GROUP_set_asn1_flag
+#define EC_GROUP_new_by_curve_name      wolfSSL_EC_GROUP_new_by_curve_name
+#define EC_GROUP_cmp                    wolfSSL_EC_GROUP_cmp
+#define EC_GROUP_get_curve_name         wolfSSL_EC_GROUP_get_curve_name
+#define EC_GROUP_get_degree             wolfSSL_EC_GROUP_get_degree
+#define EC_GROUP_get_order              wolfSSL_EC_GROUP_get_order
+
+#define EC_POINT_new                    wolfSSL_EC_POINT_new
+#define EC_POINT_free                   wolfSSL_EC_POINT_free
 #define EC_POINT_get_affine_coordinates_GFp \
-            wolfSSL_EC_POINT_get_affine_coordinates_GFp
-#define EC_POINT_mul wolfSSL_EC_POINT_mul
-#define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free
-#define EC_POINT_cmp wolfSSL_EC_POINT_cmp
-#define EC_POINT_free wolfSSL_EC_POINT_free
-#define EC_POINT_is_at_infinity wolfSSL_EC_POINT_is_at_infinity
-
-#define EC_POINT_dump wolfSSL_EC_POINT_dump
+                                     wolfSSL_EC_POINT_get_affine_coordinates_GFp
+#define EC_POINT_mul                    wolfSSL_EC_POINT_mul
+#define EC_POINT_clear_free             wolfSSL_EC_POINT_clear_free
+#define EC_POINT_cmp                    wolfSSL_EC_POINT_cmp
+#define EC_POINT_is_at_infinity         wolfSSL_EC_POINT_is_at_infinity
+
+#define EC_POINT_point2hex              wolfSSL_EC_POINT_point2hex
+#define EC_POINT_dump                   wolfSSL_EC_POINT_dump
 
 #ifdef __cplusplus
 }  /* extern "C" */

+ 35 - 28
wolfssl/openssl/evp.h

@@ -355,6 +355,10 @@ WOLFSSL_API int  wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx,
 WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_get_cipherbynid(int);
 WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int);
 
+WOLFSSL_API int wolfSSL_EVP_PKEY_assign_RSA(WOLFSSL_EVP_PKEY* pkey,
+                                            WOLFSSL_RSA* key);
+WOLFSSL_API int wolfSSL_EVP_PKEY_assign_EC_KEY(WOLFSSL_EVP_PKEY* pkey,
+                                               WOLFSSL_EC_KEY* key);
 WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY*);
 WOLFSSL_API WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY*);
 WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *key);
@@ -545,34 +549,37 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX;
 #define EVP_get_cipherbyname          wolfSSL_EVP_get_cipherbyname
 #define EVP_get_digestbyname          wolfSSL_EVP_get_digestbyname
 
-#define EVP_PKEY_get1_RSA   wolfSSL_EVP_PKEY_get1_RSA
-#define EVP_PKEY_get1_DSA   wolfSSL_EVP_PKEY_get1_DSA
-#define EVP_PKEY_set1_RSA   wolfSSL_EVP_PKEY_set1_RSA
-#define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY
-#define EVP_PKEY_get0_hmac   wolfSSL_EVP_PKEY_get0_hmac
-#define EVP_PKEY_new_mac_key wolfSSL_EVP_PKEY_new_mac_key
-#define EVP_MD_CTX_copy     wolfSSL_EVP_MD_CTX_copy
-#define EVP_MD_CTX_copy_ex  wolfSSL_EVP_MD_CTX_copy_ex
-#define EVP_PKEY_bits       wolfSSL_EVP_PKEY_bits
-#define EVP_PKEY_CTX_free   wolfSSL_EVP_PKEY_CTX_free
-#define EVP_PKEY_CTX_new    wolfSSL_EVP_PKEY_CTX_new
-#define EVP_PKEY_CTX_set_rsa_padding wolfSSL_EVP_PKEY_CTX_set_rsa_padding
-#define EVP_PKEY_decrypt    wolfSSL_EVP_PKEY_decrypt
-#define EVP_PKEY_decrypt_init wolfSSL_EVP_PKEY_decrypt_init
-#define EVP_PKEY_encrypt    wolfSSL_EVP_PKEY_encrypt
-#define EVP_PKEY_encrypt_init wolfSSL_EVP_PKEY_encrypt_init
-#define EVP_PKEY_new        wolfSSL_PKEY_new
-#define EVP_PKEY_free       wolfSSL_EVP_PKEY_free
-#define EVP_PKEY_size       wolfSSL_EVP_PKEY_size
-#define EVP_PKEY_type       wolfSSL_EVP_PKEY_type
-#define EVP_PKEY_base_id    wolfSSL_EVP_PKEY_base_id
-#define EVP_PKEY_id         wolfSSL_EVP_PKEY_id
-#define EVP_SignFinal       wolfSSL_EVP_SignFinal
-#define EVP_SignInit        wolfSSL_EVP_SignInit
-#define EVP_SignUpdate      wolfSSL_EVP_SignUpdate
-#define EVP_VerifyFinal     wolfSSL_EVP_VerifyFinal
-#define EVP_VerifyInit      wolfSSL_EVP_VerifyInit
-#define EVP_VerifyUpdate    wolfSSL_EVP_VerifyUpdate
+#define EVP_PKEY_asign_RSA             wolfSSL_EVP_PKEY_assign_RSA
+#define EVP_PKEY_asign_EC_KEY          wolfSSL_EVP_PKEY_assign_EC_KEY
+#define EVP_PKEY_get1_DSA              wolfSSL_EVP_PKEY_get1_DSA
+#define EVP_PKEY_get1_RSA              wolfSSL_EVP_PKEY_get1_RSA
+#define EVP_PKEY_get1_DSA              wolfSSL_EVP_PKEY_get1_DSA
+#define EVP_PKEY_set1_RSA              wolfSSL_EVP_PKEY_set1_RSA
+#define EVP_PKEY_get1_EC_KEY           wolfSSL_EVP_PKEY_get1_EC_KEY
+#define EVP_PKEY_get0_hmac             wolfSSL_EVP_PKEY_get0_hmac
+#define EVP_PKEY_new_mac_key           wolfSSL_EVP_PKEY_new_mac_key
+#define EVP_MD_CTX_copy                wolfSSL_EVP_MD_CTX_copy
+#define EVP_MD_CTX_copy_ex             wolfSSL_EVP_MD_CTX_copy_ex
+#define EVP_PKEY_bits                  wolfSSL_EVP_PKEY_bits
+#define EVP_PKEY_CTX_free              wolfSSL_EVP_PKEY_CTX_free
+#define EVP_PKEY_CTX_new               wolfSSL_EVP_PKEY_CTX_new
+#define EVP_PKEY_CTX_set_rsa_padding   wolfSSL_EVP_PKEY_CTX_set_rsa_padding
+#define EVP_PKEY_decrypt               wolfSSL_EVP_PKEY_decrypt
+#define EVP_PKEY_decrypt_init          wolfSSL_EVP_PKEY_decrypt_init
+#define EVP_PKEY_encrypt               wolfSSL_EVP_PKEY_encrypt
+#define EVP_PKEY_encrypt_init          wolfSSL_EVP_PKEY_encrypt_init
+#define EVP_PKEY_new                   wolfSSL_PKEY_new
+#define EVP_PKEY_free                  wolfSSL_EVP_PKEY_free
+#define EVP_PKEY_size                  wolfSSL_EVP_PKEY_size
+#define EVP_PKEY_type                  wolfSSL_EVP_PKEY_type
+#define EVP_PKEY_base_id               wolfSSL_EVP_PKEY_base_id
+#define EVP_PKEY_id                    wolfSSL_EVP_PKEY_id
+#define EVP_SignFinal                  wolfSSL_EVP_SignFinal
+#define EVP_SignInit                   wolfSSL_EVP_SignInit
+#define EVP_SignUpdate                 wolfSSL_EVP_SignUpdate
+#define EVP_VerifyFinal                wolfSSL_EVP_VerifyFinal
+#define EVP_VerifyInit                 wolfSSL_EVP_VerifyInit
+#define EVP_VerifyUpdate               wolfSSL_EVP_VerifyUpdate
 
 #define EVP_CIPHER_CTX_block_size  wolfSSL_EVP_CIPHER_CTX_block_size
 #define EVP_CIPHER_block_size      wolfSSL_EVP_CIPHER_block_size

+ 1 - 0
wolfssl/openssl/include.am

@@ -32,6 +32,7 @@ nobase_include_HEADERS+= \
                          wolfssl/openssl/ossl_typ.h \
                          wolfssl/openssl/pem.h \
                          wolfssl/openssl/pkcs12.h \
+                         wolfssl/openssl/pkcs7.h \
                          wolfssl/openssl/rand.h \
                          wolfssl/openssl/rsa.h \
                          wolfssl/openssl/sha.h \

+ 45 - 18
wolfssl/openssl/pem.h

@@ -128,6 +128,23 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
                                         unsigned char* passwd, int len,
                                         pem_password_cb* cb, void* arg);
 
+
+WOLFSSL_API
+int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
+                         unsigned char **data, long *len);
+WOLFSSL_API
+int wolfSSL_PEM_write_bio(WOLFSSL_BIO *bio, const char *name,
+                          const char *header, const unsigned char *data,
+                          long len);
+#if !defined(NO_FILESYSTEM)
+WOLFSSL_API
+int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
+                     long *len);
+WOLFSSL_API
+int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
+                      const unsigned char *data, long len);
+#endif
+
 #if !defined(NO_FILESYSTEM)
 WOLFSSL_API
 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x,
@@ -138,30 +155,40 @@ WOLFSSL_X509 *wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
 WOLFSSL_API
 WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **x,
                                           pem_password_cb *cb, void *u);
+
+WOLFSSL_API
+int wolfSSL_PEM_write_X509(XFILE fp, WOLFSSL_X509 *x);
 #endif /* NO_FILESYSTEM */
 
-#define PEM_read_X509               wolfSSL_PEM_read_X509
-#define PEM_read_PrivateKey         wolfSSL_PEM_read_PrivateKey
-#define PEM_write_bio_PrivateKey    wolfSSL_PEM_write_bio_PrivateKey
+#define PEM_read                        wolfSSL_PEM_read
+#define PEM_read_bio                    wolfSSL_PEM_read_bio
+#define PEM_write                       wolfSSL_PEM_write
+#define PEM_write_bio                   wolfSSL_PEM_write_bio
+
+#define PEM_read_X509                   wolfSSL_PEM_read_X509
+#define PEM_read_PrivateKey             wolfSSL_PEM_read_PrivateKey
+#define PEM_write_X509                  wolfSSL_PEM_write_X509
+#define PEM_write_bio_PrivateKey        wolfSSL_PEM_write_bio_PrivateKey
+#define PEM_write_bio_PKCS8PrivateKey   wolfSSL_PEM_write_bio_PKCS8PrivateKey
 /* RSA */
-#define PEM_write_bio_RSAPrivateKey wolfSSL_PEM_write_bio_RSAPrivateKey
-#define PEM_read_bio_RSAPrivateKey  wolfSSL_PEM_read_bio_RSAPrivateKey
-#define PEM_write_RSAPrivateKey     wolfSSL_PEM_write_RSAPrivateKey
-#define PEM_write_RSA_PUBKEY        wolfSSL_PEM_write_RSA_PUBKEY
-#define PEM_write_RSAPublicKey      wolfSSL_PEM_write_RSAPublicKey
-#define PEM_read_RSAPublicKey       wolfSSL_PEM_read_RSAPublicKey
+#define PEM_write_bio_RSAPrivateKey     wolfSSL_PEM_write_bio_RSAPrivateKey
+#define PEM_read_bio_RSAPrivateKey      wolfSSL_PEM_read_bio_RSAPrivateKey
+#define PEM_write_RSAPrivateKey         wolfSSL_PEM_write_RSAPrivateKey
+#define PEM_write_RSA_PUBKEY            wolfSSL_PEM_write_RSA_PUBKEY
+#define PEM_write_RSAPublicKey          wolfSSL_PEM_write_RSAPublicKey
+#define PEM_read_RSAPublicKey           wolfSSL_PEM_read_RSAPublicKey
 /* DSA */
-#define PEM_write_bio_DSAPrivateKey wolfSSL_PEM_write_bio_DSAPrivateKey
-#define PEM_write_DSAPrivateKey     wolfSSL_PEM_write_DSAPrivateKey
-#define PEM_write_DSA_PUBKEY        wolfSSL_PEM_write_DSA_PUBKEY
+#define PEM_write_bio_DSAPrivateKey     wolfSSL_PEM_write_bio_DSAPrivateKey
+#define PEM_write_DSAPrivateKey         wolfSSL_PEM_write_DSAPrivateKey
+#define PEM_write_DSA_PUBKEY            wolfSSL_PEM_write_DSA_PUBKEY
 /* ECC */
-#define PEM_write_bio_ECPrivateKey wolfSSL_PEM_write_bio_ECPrivateKey
-#define PEM_write_EC_PUBKEY        wolfSSL_PEM_write_EC_PUBKEY
-#define PEM_write_ECPrivateKey     wolfSSL_PEM_write_ECPrivateKey
+#define PEM_write_bio_ECPrivateKey      wolfSSL_PEM_write_bio_ECPrivateKey
+#define PEM_write_EC_PUBKEY             wolfSSL_PEM_write_EC_PUBKEY
+#define PEM_write_ECPrivateKey          wolfSSL_PEM_write_ECPrivateKey
 /* EVP_KEY */
-#define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey
-#define PEM_read_PUBKEY         wolfSSL_PEM_read_PUBKEY
-#define PEM_read_bio_PUBKEY     wolfSSL_PEM_read_bio_PUBKEY
+#define PEM_read_bio_PrivateKey         wolfSSL_PEM_read_bio_PrivateKey
+#define PEM_read_PUBKEY                 wolfSSL_PEM_read_PUBKEY
+#define PEM_read_bio_PUBKEY             wolfSSL_PEM_read_bio_PUBKEY
 
 #ifdef __cplusplus
     }  /* extern "C" */ 

+ 74 - 0
wolfssl/openssl/pkcs7.h

@@ -0,0 +1,74 @@
+/* pkcs7.h
+ *
+ * Copyright (C) 2006-2018 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+/* pkcs7.h for openSSL */
+
+
+#ifndef WOLFSSL_PKCS7_H_
+#define WOLFSSL_PKCS7_H_
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/wolfcrypt/pkcs7.h>
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
+
+#define PKCS7_NOINTERN         0x0010
+#define PKCS7_NOVERIFY         0x0020
+
+
+typedef struct WOLFSSL_PKCS7
+{
+    PKCS7 pkcs7;
+    unsigned char* data;
+    int len;
+} WOLFSSL_PKCS7;
+
+
+WOLFSSL_API PKCS7* wolfSSL_PKCS7_new(void);
+WOLFSSL_API void wolfSSL_PKCS7_free(PKCS7* p7);
+
+WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in,
+    int len);
+WOLFSSL_API PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7);
+WOLFSSL_API int wolfSSL_PKCS7_verify(PKCS7* p7, WOLFSSL_STACK* certs,
+    WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags);
+WOLFSSL_API WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* p7,
+    WOLFSSL_STACK* certs, int flags);
+
+#define PKCS7_new                      wolfSSL_PKCS7_new 
+#define PKCS7_free                     wolfSSL_PKCS7_free
+#define d2i_PKCS7                      wolfSSL_d2i_PKCS7
+#define d2i_PKCS7_bio                  wolfSSL_d2i_PKCS7_bio
+#define PKCS7_verify                   wolfSSL_PKCS7_verify
+#define PKCS7_get0_signers             wolfSSL_PKCS7_get0_signers
+
+#endif /* OPENSSL_ALL && HAVE_PKCS7 */
+
+#ifdef __cplusplus
+    }  /* extern "C" */
+#endif
+
+#endif /* WOLFSSL_PKCS7_H_ */
+

File diff suppressed because it is too large
+ 538 - 466
wolfssl/openssl/ssl.h


+ 39 - 2
wolfssl/ssl.h

@@ -922,12 +922,18 @@ WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID(
                                             WOLFSSL_X509*, unsigned char*, int*);
 WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID(
                                             WOLFSSL_X509*, unsigned char*, int*);
+
+WOLFSSL_API int wolfSSL_X509_set_subject_name(WOLFSSL_X509*,
+                                              WOLFSSL_X509_NAME*);
+WOLFSSL_API int wolfSSL_X509_set_pubkey(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*);
+
 WOLFSSL_API int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*);
 WOLFSSL_API int wolfSSL_X509_NAME_get_text_by_NID(
                                             WOLFSSL_X509_NAME*, int, char*, int);
 WOLFSSL_API int wolfSSL_X509_NAME_get_index_by_NID(
                                            WOLFSSL_X509_NAME*, int, int);
 WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_X509_NAME_ENTRY_get_data(WOLFSSL_X509_NAME_ENTRY*);
+
 WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void);
 WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type);
 WOLFSSL_API void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1);
@@ -2614,6 +2620,9 @@ WOLFSSL_API WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID(
             unsigned char* data, int dataSz);
 WOLFSSL_API int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name,
                               WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set);
+WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name,
+    const char *field, int type, const unsigned char *bytes, int len, int loc,
+    int set);
 WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x,
             const WOLFSSL_X509_NAME* y);
 WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void);
@@ -2661,9 +2670,14 @@ WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X50
 WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX
         (WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u);
 #ifndef NO_FILESYSTEM
-WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(XFILE fp, WOLFSSL_X509_CRL **x,
-                                                    pem_password_cb *cb, void *u);
+WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(XFILE fp,
+        WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u);
 #endif
+WOLFSSL_API int wolfSSL_PEM_get_EVP_CIPHER_INFO(char* header,
+                                                EncryptedInfo* cipher);
+WOLFSSL_API int wolfSSL_PEM_do_header(EncryptedInfo* cipher,
+                                      unsigned char* data, long* len,
+                                      pem_password_cb* callback, void* ctx);
 
 /*lighttp compatibility */
 
@@ -2731,6 +2745,18 @@ WOLFSSL_API int wolfSSL_PEM_write_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x);
 
 #endif /* HAVE_STUNNEL || HAVE_LIGHTY */
 
+#ifdef OPENSSL_ALL
+WOLFSSL_API int wolfSSL_i2d_X509_REQ(WOLFSSL_X509* req, unsigned char** out);
+WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_REQ_new(void);
+WOLFSSL_API void wolfSSL_X509_REQ_free(WOLFSSL_X509* req);
+WOLFSSL_API int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey,
+                                      const WOLFSSL_EVP_MD *md);
+WOLFSSL_API int wolfSSL_X509_REQ_set_subject_name(WOLFSSL_X509 *req,
+                                                  WOLFSSL_X509_NAME *name);
+WOLFSSL_API int wolfSSL_X509_REQ_set_pubkey(WOLFSSL_X509 *req,
+                                            WOLFSSL_EVP_PKEY *pkey);
+#endif
+
 
 #if defined(OPENSSL_ALL) \
     || defined(HAVE_STUNNEL) \
@@ -2770,6 +2796,7 @@ WOLFSSL_API int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits);
 
 WOLFSSL_API int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *s);
 
+WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_new(void);
 WOLFSSL_API int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s);
 
 WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int,
@@ -3021,6 +3048,16 @@ WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1
 WOLFSSL_API int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp);
 WOLFSSL_API int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE *store);
 WOLFSSL_API long wolfSSL_X509_get_version(const WOLFSSL_X509 *x);
+WOLFSSL_API int wolfSSL_X509_get_signature_nid(const WOLFSSL_X509* x);
+
+WOLFSSL_API int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
+    WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
+    int passwdSz, pem_password_cb* cb, void* ctx);
+WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio,
+    WOLFSSL_EVP_PKEY** pkey, pem_password_cb* cb, void* u);
+WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(
+    WOLFSSL_EVP_PKEY** pkey, const unsigned char** data, long length);
+
 #endif /* OPENSSL_EXTRA */
 
 #ifdef HAVE_PK_CALLBACKS

+ 12 - 3
wolfssl/wolfcrypt/asn.h

@@ -335,6 +335,7 @@ enum Oid_Types {
     oidPBEType          = 14,
     oidHmacType         = 15,
     oidCompressType     = 16,
+    oidCertNameType     = 17,
     oidIgnoreType
 };
 
@@ -981,13 +982,18 @@ WOLFSSL_LOCAL void    FreeTrustedPeer(TrustedPeerCert*, void*);
 WOLFSSL_LOCAL void    FreeTrustedPeerTable(TrustedPeerCert**, int, void*);
 #endif /* WOLFSSL_TRUST_PEER_CERT */
 
-WOLFSSL_ASN_API int ToTraditional(byte* buffer, word32 length);
+WOLFSSL_ASN_API int ToTraditional(byte* buffer, word32 length, word32* algId);
 WOLFSSL_LOCAL int ToTraditionalInline(const byte* input, word32* inOutIdx,
-                                      word32 length);
-WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int);
+                                      word32 length, word32* algId);
+WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int,
+                                   word32* algId);
 WOLFSSL_ASN_API int UnTraditionalEnc(byte* key, word32 keySz, byte* out,
         word32* outSz, const char* password, int passwordSz, int vPKCS,
         int vAlgo, byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap);
+WOLFSSL_ASN_API int TraditionalEnc(byte* key, word32 keySz, byte* out,
+        word32* outSz, const char* password, int passwordSz, int vPKCS,
+        int vAlgo, int encAlgId, byte* salt, word32 saltSz, int itt,
+        WC_RNG* rng, void* heap);
 WOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz);
 WOLFSSL_LOCAL int EncryptContent(byte* input, word32 sz, byte* out, word32* outSz,
         const char* password,int passwordSz, int vPKCS, int vAlgo,
@@ -1074,6 +1080,9 @@ WOLFSSL_LOCAL void FreeSignatureCtx(SignatureCtx* sigCtx);
 
 #ifndef NO_CERTS
 
+WOLFSSL_LOCAL int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer,
+                                        size_t bufSz);
+
 WOLFSSL_LOCAL int PemToDer(const unsigned char* buff, long sz, int type,
                           DerBuffer** pDer, void* heap, EncryptedInfo* info,
                           int* eccKey);

+ 3 - 1
wolfssl/wolfcrypt/asn_public.h

@@ -71,7 +71,9 @@ enum CertType {
     TRUSTED_PEER_TYPE,
     EDDSA_PRIVATEKEY_TYPE,
     ED25519_TYPE,
-    PKCS12_TYPE
+    PKCS12_TYPE,
+    PKCS8_PRIVATEKEY_TYPE,
+    PKCS8_ENC_PRIVATEKEY_TYPE
 };
 
 

Some files were not shown because too many files changed in this diff