From 80ac2306df141da07f3e1dac65ca7526a0ea1780 Mon Sep 17 00:00:00 2001 From: Justin Karneges <justin@affinix.com> Date: Sat, 9 Apr 2005 22:46:24 +0000 Subject: [PATCH] handle input of both encrypted and non-encrypted DER private keys svn path=/trunk/kdesupport/qca/; revision=404478 --- plugins/qca-openssl/qca-openssl.cpp | 62 ++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/plugins/qca-openssl/qca-openssl.cpp b/plugins/qca-openssl/qca-openssl.cpp index cc52f86e..988903d6 100644 --- a/plugins/qca-openssl/qca-openssl.cpp +++ b/plugins/qca-openssl/qca-openssl.cpp @@ -32,6 +32,7 @@ #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/x509v3.h> +#include <openssl/pkcs12.h> // comment this out if you'd rather use openssl 0.9.6 //#define OSSL_097 @@ -874,6 +875,60 @@ static QCA::Validity convert_verify_error(int err) return rc; } +EVP_PKEY *qca_d2i_PKCS8PrivateKey(const QSecureArray &in, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + + // first try unencrypted form + BIO *bi = BIO_new(BIO_s_mem()); + BIO_write(bi, in.data(), in.size()); + p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(bi, NULL); + BIO_free(bi); + if(!p8inf) + { + X509_SIG *p8; + + // now try encrypted form + bi = BIO_new(BIO_s_mem()); + BIO_write(bi, in.data(), in.size()); + p8 = d2i_PKCS8_bio(bi, NULL); + BIO_free(bi); + if(!p8) + return NULL; + + // get passphrase + char psbuf[PEM_BUFSIZE]; + int klen; + if(cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if(klen <= 0) + { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + + // decrypt it + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if(!p8inf) + return NULL; + } + + EVP_PKEY *ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if(!ret) + return NULL; + if(x) + { + if(*x) + EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} class opensslHashContext : public QCA::HashContext { @@ -2423,14 +2478,11 @@ public: delete k; k = 0; - BIO *bi = BIO_new(BIO_s_mem()); - BIO_write(bi, in.data(), in.size()); EVP_PKEY *pkey; if(!passphrase.isEmpty()) - pkey = d2i_PKCS8PrivateKey_bio(bi, NULL, NULL, (void *)passphrase.data()); + pkey = qca_d2i_PKCS8PrivateKey(in, NULL, NULL, (void *)passphrase.data()); else - pkey = d2i_PKCS8PrivateKey_bio(bi, NULL, &passphrase_cb, NULL); - BIO_free(bi); + pkey = qca_d2i_PKCS8PrivateKey(in, NULL, &passphrase_cb, NULL); if(!pkey) return QCA::ErrorDecode;