diff --git a/src/ssl.c b/src/ssl.c index d6f9d75a8..8cd25ee6f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -6836,6 +6836,51 @@ int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format) #ifdef OPENSSL_EXTRA /* put SSL type in extra for now, not very common */ +WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio, + WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey) +{ + const unsigned char* mem; + int memSz; + int keySz; + + WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8; + + WOLFSSL_MSG("wolfSSL_d2i_PKCS8_PKEY_bio()"); + + if (bio == NULL) { + return NULL; + } + + if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) { + return NULL; + } + + if ((keySz = wolfSSL_KeyPemToDer(mem, memSz, (unsigned char*)mem, memSz, + NULL)) < 0) { + WOLFSSL_MSG("Not PEM format"); + keySz = memSz; + if ((keySz = ToTraditional((byte*)mem, (word32)keySz)) < 0) { + return NULL; + } + } + + pkcs8 = wolfSSL_PKEY_new(); + pkcs8->pkey.ptr = (char*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_PUBLIC_KEY); + if (pkcs8->pkey.ptr == NULL) { + wolfSSL_EVP_PKEY_free(pkcs8); + return NULL; + } + XMEMCPY(pkcs8->pkey.ptr, mem, keySz); + pkcs8->pkey_sz = keySz; + + if (pkey != NULL) { + *pkey = pkcs8; + } + + return pkcs8; +} + + WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz) { diff --git a/tests/api.c b/tests/api.c index f89d3601a..fc0153ab7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -14792,6 +14792,29 @@ static void test_wolfSSL_pseudo_rand(void) #endif } +static void test_wolfSSL_pkcs8(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC) + PKCS8_PRIV_KEY_INFO* pt; + BIO* bio; + FILE* f; + int bytes; + char buffer[512]; + + printf(testingFmt, "wolfSSL_pkcs8()"); + + /* file from wolfssl/certs/ directory */ + AssertNotNull(f = fopen("./certs/ecc-keyPkcs8.pem", "rb")); + AssertIntGT((bytes = (int)fread(buffer, 1, sizeof(buffer), f)), 0); + AssertNotNull(bio = BIO_new_mem_buf((void*)buffer, bytes)); + AssertNotNull(pt = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL)); + BIO_free(bio); + PKCS8_PRIV_KEY_INFO_free(pt); + + printf(resultFmt, passed); + #endif +} + static void test_no_op_functions(void) { @@ -15591,7 +15614,7 @@ void ApiTest(void) test_wolfSSL_CTX_set_srp_username(); test_wolfSSL_CTX_set_srp_password(); test_wolfSSL_pseudo_rand(); - AssertIntEQ(test_wolfSSL_Cleanup(), WOLFSSL_SUCCESS); + test_wolfSSL_pkcs8(); /* test the no op functions for compatibility */ test_no_op_functions(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index ec6cd1a69..e68250e4c 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -67,6 +67,7 @@ typedef WOLFSSL_X509_CHAIN X509_CHAIN; typedef WOLFSSL_EVP_PKEY EVP_PKEY; +typedef WOLFSSL_EVP_PKEY PKCS8_PRIV_KEY_INFO; typedef WOLFSSL_RSA RSA; typedef WOLFSSL_DSA DSA; typedef WOLFSSL_EC_KEY EC_KEY; @@ -123,6 +124,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_get_certificate wolfSSL_get_certificate #define SSL_use_certificate wolfSSL_use_certificate #define SSL_use_certificate_ASN1 wolfSSL_use_certificate_ASN1 +#define d2i_PKCS8_PRIV_KEY_INFO_bio wolfSSL_d2i_PKCS8_PKEY_bio +#define PKCS8_PRIV_KEY_INFO_free wolfSSL_EVP_PKEY_free #define d2i_PrivateKey wolfSSL_d2i_PrivateKey #define SSL_use_PrivateKey wolfSSL_use_PrivateKey diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 4a4fbe55a..6e1da80ab 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -193,6 +193,20 @@ struct WOLFSSL_ASN1_TIME { /* ASN_TIME | LENGTH | date bytes */ }; +typedef char WOLFSSL_EVP_MD; +typedef struct WOLFSSL_EVP_PKEY { + int type; /* openssh dereference */ + int save_type; /* openssh dereference */ + int pkey_sz; + union { + char* ptr; /* der format of key / or raw for NTRU */ + } pkey; + #ifdef HAVE_ECC + int pkey_curve; + #endif +} WOLFSSL_EVP_PKEY; +typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO; + #ifndef WOLFSSL_EVP_PKEY_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; #define WOLFSSL_EVP_PKEY_TYPE_DEFINED @@ -816,6 +830,8 @@ WOLFSSL_API int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL*, WOLFSSL_EVP_PKE WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX*, int); WOLFSSL_API void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT*); +WOLFSSL_API WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio( + WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new(void);