add support for PKCS8 decryption to OPENSSL_EXTRA_X509_SMALL build

This commit is contained in:
Jacob Barthelmeh 2018-03-20 15:06:35 -06:00
parent bba0a3e88c
commit df6ea54cd5
5 changed files with 177 additions and 83 deletions

167
src/ssl.c
View File

@ -50,8 +50,8 @@
#endif
#endif
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
defined(WOLFSSL_KEY_GEN)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN)
#include <wolfssl/openssl/evp.h>
/* openssl headers end, wolfssl internal headers next */
#include <wolfssl/wolfcrypt/wc_encrypt.h>
@ -3189,7 +3189,8 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz,
#endif /* NO_CERTS */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
static struct cipher{
unsigned char type;
@ -3527,7 +3528,7 @@ static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
return min((word32)sz, (word32)XSTRLEN((char*)userdata));
}
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
#ifndef NO_CERTS
@ -3562,7 +3563,8 @@ int wolfSSL_KeyPemToDer(const unsigned char* pem, int pemSz,
info->ctx = NULL;
info->consumed = 0;
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
if (pass) {
info->ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
if (info->ctx == NULL) {
@ -4469,7 +4471,8 @@ int wolfSSL_Init(void)
}
#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_CERTS)
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)) && !defined(NO_CERTS)
/* WOLFSSL_SUCCESS if ok, <= 0 else */
static int wolfssl_decrypt_buffer_key(DerBuffer* der, byte* password,
@ -4559,7 +4562,8 @@ static int wolfssl_decrypt_buffer_key(DerBuffer* der, byte* password,
return WOLFSSL_FATAL_ERROR;
}
#endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */
#endif /* defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) ||
defined(HAVE_WEBSERVER) */
#if defined(WOLFSSL_KEY_GEN) && defined(OPENSSL_EXTRA)
@ -4909,7 +4913,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
return 0;
}
#if (defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)) && !defined(NO_PWDBASED)
if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
int passwordSz;
#ifdef WOLFSSL_SMALL_STACK
@ -4953,7 +4958,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
}
}
}
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || NO_PWDBASED */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER ||
NO_PWDBASED */
return 0;
}
@ -5183,7 +5189,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
return ret;
}
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
/* for WOLFSSL_FILETYPE_PEM, PemToDer manage the decryption if required */
if (info->set && (format != WOLFSSL_FILETYPE_PEM)) {
/* decrypt */
@ -5224,7 +5231,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
return ret;
}
}
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
#ifdef WOLFSSL_SMALL_STACK
XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
@ -12478,7 +12485,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
void* userdata)
@ -12496,72 +12504,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
}
int wolfSSL_num_locks(void)
{
return 0;
}
void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
{
WOLFSSL_ENTER("wolfSSL_set_locking_callback");
if (wc_SetMutexCb(f) != 0) {
WOLFSSL_MSG("Error when setting mutex call back");
}
}
typedef unsigned long (idCb)(void);
static idCb* inner_idCb = NULL;
unsigned long wolfSSL_thread_id(void)
{
if (inner_idCb != NULL) {
return inner_idCb();
}
else {
return 0;
}
}
void wolfSSL_set_id_callback(unsigned long (*f)(void))
{
inner_idCb = f;
}
unsigned long wolfSSL_ERR_get_error(void)
{
WOLFSSL_ENTER("wolfSSL_ERR_get_error");
#if defined(WOLFSSL_NGINX)
{
unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
NULL, NULL);
wc_RemoveErrorNode(-1);
return ret;
}
#elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
{
int ret = wc_PullErrorNode(NULL, NULL, NULL);
if (ret < 0) {
if (ret == BAD_STATE_E) return 0; /* no errors in queue */
WOLFSSL_MSG("Error with pulling error node!");
WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
ret = 0 - ret; /* return absolute value of error */
/* panic and try to clear out nodes */
wc_ClearErrorNodes();
}
return (unsigned long)ret;
}
#else
return (unsigned long)(0 - NOT_COMPILED_IN);
#endif
}
#ifndef NO_MD5
int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type,
@ -12697,6 +12639,75 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
}
#endif /* NO_MD5 */
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || HAVE_WEBSERVER */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
int wolfSSL_num_locks(void)
{
return 0;
}
void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
{
WOLFSSL_ENTER("wolfSSL_set_locking_callback");
if (wc_SetMutexCb(f) != 0) {
WOLFSSL_MSG("Error when setting mutex call back");
}
}
typedef unsigned long (idCb)(void);
static idCb* inner_idCb = NULL;
unsigned long wolfSSL_thread_id(void)
{
if (inner_idCb != NULL) {
return inner_idCb();
}
else {
return 0;
}
}
void wolfSSL_set_id_callback(unsigned long (*f)(void))
{
inner_idCb = f;
}
unsigned long wolfSSL_ERR_get_error(void)
{
WOLFSSL_ENTER("wolfSSL_ERR_get_error");
#if defined(WOLFSSL_NGINX)
{
unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
NULL, NULL);
wc_RemoveErrorNode(-1);
return ret;
}
#elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
{
int ret = wc_PullErrorNode(NULL, NULL, NULL);
if (ret < 0) {
if (ret == BAD_STATE_E) return 0; /* no errors in queue */
WOLFSSL_MSG("Error with pulling error node!");
WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
ret = 0 - ret; /* return absolute value of error */
/* panic and try to clear out nodes */
wc_ClearErrorNodes();
}
return (unsigned long)ret;
}
#else
return (unsigned long)(0 - NOT_COMPILED_IN);
#endif
}
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */

View File

@ -2811,6 +2811,83 @@ static void test_wolfSSL_PKCS12(void)
#endif /* OPENSSL_EXTRA */
}
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
!defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
!defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA)
/* for PKCS8 test case */
static INLINE int PKCS8TestCallBack(char* passwd, int sz, int rw, void* userdata)
{
int flag = 0;
(void)rw;
if (userdata != NULL) {
flag = *((int*)userdata); /* user set data */
}
switch (flag) {
case 1: /* flag set for specific WOLFSSL_CTX structure, note userdata
* can be anything the user wishes to be passed to the callback
* associated with the WOLFSSL_CTX */
strncpy(passwd, "yassl123", sz);
return 8;
default:
return BAD_FUNC_ARG;
}
}
#endif
/* Testing functions dealing with PKCS8 */
static void test_wolfSSL_PKCS8(void)
{
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
!defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
!defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA)
byte buffer[FOURK_BUF];
byte der[FOURK_BUF];
char file[] = "./certs/server-keyPkcs8Enc.pem";
FILE *f;
int flag = 1;
int bytes;
WOLFSSL_CTX* ctx;
printf(testingFmt, "wolfSSL_PKCS8()");
f = fopen(file, "rb");
AssertNotNull(f);
bytes = (int)fread(buffer, 1, sizeof(buffer), f);
fclose(f);
/* Note that wolfSSL_Init() or wolfCrypt_Init() has been called before these
* function calls */
AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()));
wolfSSL_CTX_set_default_passwd_cb(ctx, &PKCS8TestCallBack);
wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)&flag);
AssertIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buffer, bytes,
SSL_FILETYPE_PEM), SSL_SUCCESS);
/* this next case should fail if setting the user flag to a value other
* than 1 due to the password callback functions return value */
flag = 0;
wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)&flag);
AssertIntNE(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buffer, bytes,
SSL_FILETYPE_PEM), SSL_SUCCESS);
wolfSSL_CTX_free(ctx);
/* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */
AssertIntGT(wolfSSL_KeyPemToDer(buffer, bytes, der, FOURK_BUF, "yassl123"),
0);
/* test that error value is returned with a bad password */
AssertIntLT(wolfSSL_KeyPemToDer(buffer, bytes, der, FOURK_BUF, "bad"), 0);
printf(resultFmt, passed);
#endif /* OPENSSL_EXTRA */
}
/* Testing functions dealing with PKCS5 */
static void test_wolfSSL_PKCS5(void)
{
@ -17546,6 +17623,7 @@ void ApiTest(void)
/* X509 tests */
test_wolfSSL_X509_NAME_get_entry();
test_wolfSSL_PKCS12();
test_wolfSSL_PKCS8();
test_wolfSSL_PKCS5();
/*OCSP Stapling. */

View File

@ -347,8 +347,9 @@ int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)
#endif /* defined(WOLFSSL_BASE64_ENCODE) */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) \
|| defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) || \
defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST)
static
const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

View File

@ -2436,9 +2436,12 @@ struct WOLFSSL_CTX {
#ifdef HAVE_ANON
byte haveAnon; /* User wants to allow Anon suites */
#endif /* HAVE_ANON */
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER)
pem_password_cb* passwd_cb;
void* userdata;
#endif
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
WOLFSSL_X509_STORE x509_store; /* points to ctx->cm */
WOLFSSL_X509_STORE* x509_store_pt; /* take ownership of external store */
byte readAhead;

View File

@ -63,8 +63,9 @@ WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out,
word32* outLen);
#endif
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) \
|| defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) || \
defined(HAVE_ECC_CDH) || defined(HAVE_SELFTEST)
WOLFSSL_API
int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen);
WOLFSSL_API