From fa704001ca9074b31d9542e47eabd7b74aaa2b3f Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Mon, 18 Mar 2019 06:15:21 +0100 Subject: [PATCH] Also change File loading from FILE* to QFile --- lib/func.h | 5 --- lib/pki_crl.cpp | 36 ++++++++---------- lib/pki_evp.cpp | 51 +++++++++---------------- lib/pki_key.cpp | 8 +--- lib/pki_key.h | 2 +- lib/pki_pkcs12.cpp | 90 ++++++++++++++++++++++----------------------- lib/pki_pkcs7.cpp | 89 +++++++++++++++++++++++--------------------- lib/pki_x509.cpp | 14 +++---- lib/pki_x509req.cpp | 32 +++++++--------- lib/xfile.h | 12 ++++++ 10 files changed, 160 insertions(+), 179 deletions(-) diff --git a/lib/func.h b/lib/func.h index fccc63a1..03df8ca1 100644 --- a/lib/func.h +++ b/lib/func.h @@ -66,11 +66,6 @@ void *d2i_bytearray(void *(*d2i)(void*, unsigned char**, long), #define QString2filename(str) filename2bytearray(str).constData() -static inline FILE *fopen_read(QString s) -{ - return fopen(QString2filename(s), "rb"); -} - static inline BIO *BIO_from_QByteArray(QByteArray &ba) { return BIO_new_mem_buf(ba.data(), ba.length()); diff --git a/lib/pki_crl.cpp b/lib/pki_crl.cpp index c47a79c9..70a72263 100644 --- a/lib/pki_crl.cpp +++ b/lib/pki_crl.cpp @@ -118,27 +118,23 @@ QSqlError pki_crl::deleteSqlData() void pki_crl::fload(const QString fname) { - FILE *fp = fopen_read(fname); X509_CRL *_crl; - if (fp != NULL) { - _crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); - if (!_crl) { - pki_ign_openssl_error(); - rewind(fp); - _crl = d2i_X509_CRL_fp(fp, NULL); - } - fclose(fp); - if (pki_ign_openssl_error()) { - if (_crl) - X509_CRL_free(_crl); - throw errorEx(tr("Unable to load the revocation list in file %1. Tried PEM and DER formatted CRL.").arg(fname)); - } - X509_CRL_free(crl); - crl = _crl; - setIntName(rmslashdot(fname)); - pki_openssl_error(); - } else - fopen_error(fname); + XFile file(fname); + file.open_read(); + _crl = PEM_read_X509_CRL(file.fp(), NULL, NULL, NULL); + if (!_crl) { + pki_ign_openssl_error(); + file.retry_read(); + _crl = d2i_X509_CRL_fp(file.fp(), NULL); + } + if (pki_ign_openssl_error()) { + if (_crl) + X509_CRL_free(_crl); + throw errorEx(tr("Unable to load the revocation list in file %1. Tried PEM and DER formatted CRL.").arg(fname)); + } + X509_CRL_free(crl); + crl = _crl; + setIntName(rmslashdot(fname)); } QString pki_crl::getSigAlg() const diff --git a/lib/pki_evp.cpp b/lib/pki_evp.cpp index 95220847..87fb7fb0 100644 --- a/lib/pki_evp.cpp +++ b/lib/pki_evp.cpp @@ -322,36 +322,27 @@ void pki_evp::fload(const QString fname) pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the private key from file:\n%1"). arg(compressFilename(fname))); pem_password_cb *cb = PwDialog::pwCallback; - FILE *fp = fopen_read(fname); - EVP_PKEY *pkey; pki_ign_openssl_error(); - if (!fp) { - fopen_error(fname); - return; - } - pkey = PEM_read_PrivateKey(fp, NULL, cb, &p); - try { - openssl_pw_error(fname); - } catch (errorEx &err) { - fclose(fp); - throw err; + XFile file(fname); + file.open_read(); + EVP_PKEY *pkey = PEM_read_PrivateKey(file.fp(), NULL, cb, &p); + openssl_pw_error(fname); + if (!pkey) { + pki_ign_openssl_error(); + file.retry_read(); + pkey = d2i_PrivateKey_fp(file.fp(), NULL); } if (!pkey) { pki_ign_openssl_error(); - rewind(fp); - pkey = d2i_PrivateKey_fp(fp, NULL); - } - if (!pkey) { - pki_ign_openssl_error(); - rewind(fp); - pkey = d2i_PKCS8PrivateKey_fp(fp, NULL, cb, &p); + file.retry_read(); + pkey = d2i_PKCS8PrivateKey_fp(file.fp(), NULL, cb, &p); } if (!pkey) { PKCS8_PRIV_KEY_INFO *p8inf; pki_ign_openssl_error(); - rewind(fp); - p8inf = d2i_PKCS8_PRIV_KEY_INFO_fp(fp, NULL); + file.retry_read(); + p8inf = d2i_PKCS8_PRIV_KEY_INFO_fp(file.fp(), NULL); if (p8inf) { pkey = EVP_PKCS82PKEY(p8inf); PKCS8_PRIV_KEY_INFO_free(p8inf); @@ -359,25 +350,19 @@ void pki_evp::fload(const QString fname) } if (!pkey) { pki_ign_openssl_error(); - rewind(fp); - pkey = PEM_read_PUBKEY(fp, NULL, cb, &p); + file.retry_read(); + pkey = PEM_read_PUBKEY(file.fp(), NULL, cb, &p); } if (!pkey) { pki_ign_openssl_error(); - rewind(fp); - pkey = d2i_PUBKEY_fp(fp, NULL); + file.retry_read(); + pkey = d2i_PUBKEY_fp(file.fp(), NULL); } if (!pkey) { pki_ign_openssl_error(); - rewind(fp); - try { - pkey = load_ssh2_key(fp); - } catch (errorEx &err) { - fclose(fp); - throw err; - } + file.retry_read(); + pkey = load_ssh2_key(file); } - fclose(fp); if (!pkey || pki_ign_openssl_error()) { if (pkey) EVP_PKEY_free(pkey); diff --git a/lib/pki_key.cpp b/lib/pki_key.cpp index 50761d7c..6889e978 100644 --- a/lib/pki_key.cpp +++ b/lib/pki_key.cpp @@ -559,18 +559,14 @@ QByteArray pki_key::ssh_key_next_chunk(QByteArray *ba) const return chunk; } -EVP_PKEY *pki_key::load_ssh2_key(FILE *fp) +EVP_PKEY *pki_key::load_ssh2_key(XFile &file) { /* See RFC 4253 Section 6.6 */ QByteArray ba; QStringList sl; EVP_PKEY *pk = NULL; - ba.resize(4096); - - if (!fgets(ba.data(), ba.size(), fp)) { - return NULL; - } + ba = file.read(4096); sl = QString(ba).split(" ", QString::SkipEmptyParts); if (sl.size() < 2) return NULL; diff --git a/lib/pki_key.h b/lib/pki_key.h index 659118ba..5c9dd76d 100644 --- a/lib/pki_key.h +++ b/lib/pki_key.h @@ -97,7 +97,7 @@ class pki_key: public pki_base void d2i(QByteArray &ba); void d2i_old(QByteArray &ba, int type); QByteArray i2d() const; - EVP_PKEY *load_ssh2_key(FILE *fp); + EVP_PKEY *load_ssh2_key(XFile &file); void writeSSH2public(XFile &file) const; QString fingerprint(const QString &format) const; bool SSH2_compatible() const; diff --git a/lib/pki_pkcs12.cpp b/lib/pki_pkcs12.cpp index fd19b4b5..ce2a448a 100644 --- a/lib/pki_pkcs12.cpp +++ b/lib/pki_pkcs12.cpp @@ -28,59 +28,59 @@ pki_pkcs12::pki_pkcs12(const QString d, pki_x509 *acert, pki_evp *akey) pki_pkcs12::pki_pkcs12(const QString fname) :pki_base(fname) { - FILE *fp; Passwd pass; EVP_PKEY *mykey = NULL; X509 *mycert = NULL; + key=NULL; cert=NULL; certstack = sk_X509_new_null(); pass_info p(XCA_TITLE, tr("Please enter the password to decrypt the PKCS#12 file:\n%1").arg(compressFilename(fname))); - fp = fopen_read(fname); - if (fp) { - PKCS12 *pkcs12 = d2i_PKCS12_fp(fp, NULL); - fclose(fp); - if (pki_ign_openssl_error()) { - if (pkcs12) - PKCS12_free(pkcs12); - throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname)); - } - if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0)) - pass.clear(); - else if (PwDialog::execute(&p, &pass) != 1) { - /* cancel pressed */ + + XFile file(fname); + file.open_read(); + PKCS12 *pkcs12 = d2i_PKCS12_fp(file.fp(), NULL); + if (pki_ign_openssl_error()) { + if (pkcs12) PKCS12_free(pkcs12); - throw errorEx("","", E_PASSWD); - } - PKCS12_parse(pkcs12, pass.constData(), &mykey, &mycert, &certstack); - int error = ERR_peek_error(); - if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) { - pki_ign_openssl_error(); - PKCS12_free(pkcs12); - throw errorEx(getClassName(), tr("The supplied password was wrong (%1)").arg(ERR_reason_error_string(error)), E_PASSWD); - } - pki_ign_openssl_error(); - if (mycert) { - unsigned char *str = X509_alias_get0(mycert, NULL); - if (str) - alias = QString::fromUtf8((const char *)str); - alias = QString::fromUtf8(alias.toLatin1()); - cert = new pki_x509(mycert); - if (alias.isEmpty()) { - cert->autoIntName(); - } else { - cert->setIntName(alias); - } - alias = cert->getIntName(); - cert->pkiSource = imported; - } - if (mykey) { - key = new pki_evp(mykey); - key->setIntName(alias + "_key"); - key->pkiSource = imported; - } + throw errorEx(tr("Unable to load the PKCS#12 (pfx) file %1.").arg(fname)); + } + if (PKCS12_verify_mac(pkcs12, "", 0) || PKCS12_verify_mac(pkcs12, NULL, 0)) + pass.clear(); + else if (PwDialog::execute(&p, &pass) != 1) { + /* cancel pressed */ PKCS12_free(pkcs12); - } else - fopen_error(fname); + throw errorEx("","", E_PASSWD); + } + PKCS12_parse(pkcs12, pass.constData(), &mykey, &mycert, &certstack); + int error = ERR_peek_error(); + if (ERR_GET_REASON(error) == PKCS12_R_MAC_VERIFY_FAILURE) { + pki_ign_openssl_error(); + PKCS12_free(pkcs12); + throw errorEx(getClassName(), + tr("The supplied password was wrong (%1)") + .arg(ERR_reason_error_string(error)), E_PASSWD); + } + pki_ign_openssl_error(); + if (mycert) { + unsigned char *str = X509_alias_get0(mycert, NULL); + if (str) + alias = QString::fromUtf8((const char *)str); + alias = QString::fromUtf8(alias.toLatin1()); + cert = new pki_x509(mycert); + if (alias.isEmpty()) { + cert->autoIntName(); + } else { + cert->setIntName(alias); + } + alias = cert->getIntName(); + cert->pkiSource = imported; + } + if (mykey) { + key = new pki_evp(mykey); + key->setIntName(alias + "_key"); + key->pkiSource = imported; + } + PKCS12_free(pkcs12); } pki_pkcs12::~pki_pkcs12() diff --git a/lib/pki_pkcs7.cpp b/lib/pki_pkcs7.cpp index efa478ed..f9c987d3 100644 --- a/lib/pki_pkcs7.cpp +++ b/lib/pki_pkcs7.cpp @@ -37,11 +37,13 @@ void pki_pkcs7::encryptFile(pki_x509 *crt, QString filename) void pki_pkcs7::encryptBio(pki_x509 *crt, BIO *bio) { STACK_OF(X509) *certstack; - if (!crt) return; + if (!crt) + return; certstack = sk_X509_new_null(); sk_X509_push(certstack, crt->getCert()); openssl_error(); - if (p7) PKCS7_free(p7); + if (p7) + PKCS7_free(p7); p7 = PKCS7_encrypt(certstack, bio, EVP_des_ede3_cbc(), PKCS7_BINARY); openssl_error(); sk_X509_free(certstack); @@ -52,21 +54,26 @@ void pki_pkcs7::signBio(pki_x509 *crt, BIO *bio) pki_key *privkey; EVP_PKEY *pk; STACK_OF(X509) *certstack; - if (!crt) return; + if (!crt) + return; privkey = crt->getRefKey(); - if (!privkey) throw errorEx("No private key for signing found", - getClassName()); + if (!privkey) + throw errorEx("No private key for signing found", getClassName()); certstack = sk_X509_new_null(); pki_x509 *signer = crt->getSigner(); - if (signer == crt) signer = NULL; + if (signer == crt) + signer = NULL; while (signer != NULL ) { sk_X509_push(certstack, signer->getCert()); openssl_error(); - if (signer == signer->getSigner() ) signer = NULL; - else signer = signer->getSigner(); + if (signer == signer->getSigner() ) + signer = NULL; + else + signer = signer->getSigner(); } - if (p7) PKCS7_free(p7); + if (p7) + PKCS7_free(p7); pk = privkey->decryptKey(); p7 = PKCS7_sign(crt->getCert(), pk, certstack, bio, PKCS7_BINARY); EVP_PKEY_free(pk); @@ -74,11 +81,11 @@ void pki_pkcs7::signBio(pki_x509 *crt, BIO *bio) sk_X509_free(certstack); } - void pki_pkcs7::signFile(pki_x509 *crt, QString filename) { - BIO *bio = NULL; - if (!crt) return; + BIO *bio; + if (!crt) + return; bio = BIO_new_file(QString2filename(filename), "r"); openssl_error(); signBio(crt, bio); @@ -87,8 +94,9 @@ void pki_pkcs7::signFile(pki_x509 *crt, QString filename) void pki_pkcs7::signCert(pki_x509 *crt, pki_x509 *contCert) { - BIO *bio = NULL; - if (!crt) return; + BIO *bio; + if (!crt) + return; bio = BIO_new(BIO_s_mem()); openssl_error(); i2d_X509_bio(bio, contCert->getCert()); @@ -127,45 +135,42 @@ int pki_pkcs7::numCert() void pki_pkcs7::fromPEM_BIO(BIO *bio, QString name) { - PKCS7 *_p7; - _p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL); + PKCS7 *_p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL); openssl_error(name); - PKCS7_free(p7); + if (p7) + PKCS7_free(p7); p7 = _p7; setIntName(rmslashdot(name)); } void pki_pkcs7::fload(const QString fname) { - FILE *fp; PKCS7 *_p7; - fp = fopen_read(fname); - if (fp) { - _p7 = PEM_read_PKCS7(fp, NULL, NULL, NULL); - if (!_p7) { - ign_openssl_error(); - rewind(fp); - _p7 = d2i_PKCS7_fp(fp, NULL); - } - fclose(fp); - if (ign_openssl_error()) { - if (_p7) - PKCS7_free(_p7); - throw errorEx(tr("Unable to load the PKCS#7 file %1. Tried PEM and DER format.").arg(fname)); - } - if (p7) - PKCS7_free(p7); - p7 = _p7; - } else - fopen_error(fname); + XFile file(fname); + file.open_read(); + _p7 = PEM_read_PKCS7(file.fp(), NULL, NULL, NULL); + if (!_p7) { + ign_openssl_error(); + file.retry_read(); + _p7 = d2i_PKCS7_fp(file.fp(), NULL); + } + if (ign_openssl_error()) { + if (_p7) + PKCS7_free(_p7); + throw errorEx(tr("Unable to load the PKCS#7 file %1. Tried PEM and DER format.").arg(fname)); + } + if (p7) + PKCS7_free(p7); + p7 = _p7; } STACK_OF(X509) *pki_pkcs7::getCertStack() { - STACK_OF(X509) *certstack = NULL; int i; - if (p7 == NULL) return NULL; + STACK_OF(X509) *certstack = NULL; + if (p7 == NULL) + return NULL; i = OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: @@ -181,8 +186,10 @@ STACK_OF(X509) *pki_pkcs7::getCertStack() return certstack; } -void pki_pkcs7::addCert(pki_x509 *crt) { - if (p7 == NULL || crt == NULL) return; +void pki_pkcs7::addCert(pki_x509 *crt) +{ + if (p7 == NULL || crt == NULL) + return; PKCS7_add_certificate(p7, crt->getCert()); openssl_error(); } diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index 89e784db..c332e870 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -219,19 +219,15 @@ void pki_x509::fromPEM_BIO(BIO *bio, QString) void pki_x509::fload(const QString fname) { - FILE *fp = fopen_read(fname); X509 *_cert; - if (!fp) { - fopen_error(fname); - return; - } - _cert = PEM_read_X509(fp, NULL, NULL, NULL); + XFile file(fname); + file.open_read(); + _cert = PEM_read_X509(file.fp(), NULL, NULL, NULL); if (!_cert) { pki_ign_openssl_error(); - rewind(fp); - _cert = d2i_X509_fp(fp, NULL); + file.retry_read(); + _cert = d2i_X509_fp(file.fp(), NULL); } - fclose(fp); if (pki_ign_openssl_error() ) { if (_cert) X509_free(_cert); diff --git a/lib/pki_x509req.cpp b/lib/pki_x509req.cpp index 1a9bcbfb..9bd84efb 100644 --- a/lib/pki_x509req.cpp +++ b/lib/pki_x509req.cpp @@ -164,26 +164,20 @@ void pki_x509req::fromPEM_BIO(BIO *bio, QString name) void pki_x509req::fload(const QString fname) { - FILE *fp = fopen_read(fname); X509_REQ *_req; int ret = 0; - - if (fp != NULL) { - _req = PEM_read_X509_REQ(fp, NULL, NULL, NULL); - if (!_req) { - pki_ign_openssl_error(); - rewind(fp); - _req = d2i_X509_REQ_fp(fp, NULL); - } - fclose(fp); - if (ret || pki_ign_openssl_error()) { - if (_req) - X509_REQ_free(_req); - throw errorEx(tr("Unable to load the certificate request in file %1. Tried PEM, DER and SPKAC format.").arg(fname)); - } - } else { - fopen_error(fname); - return; + XFile file(fname); + file.open_read(); + _req = PEM_read_X509_REQ(file.fp(), NULL, NULL, NULL); + if (!_req) { + pki_ign_openssl_error(); + file.retry_read(); + _req = d2i_X509_REQ_fp(file.fp(), NULL); + } + if (ret || pki_ign_openssl_error()) { + if (_req) + X509_REQ_free(_req); + throw errorEx(tr("Unable to load the certificate request in file %1. Tried PEM, DER and SPKAC format.").arg(fname)); } if (_req) { @@ -193,7 +187,7 @@ void pki_x509req::fload(const QString fname) autoIntName(); if (getIntName().isEmpty()) setIntName(rmslashdot(fname)); - openssl_error(fname); + pki_openssl_error(); } void pki_x509req::d2i(QByteArray &ba) diff --git a/lib/xfile.h b/lib/xfile.h index b345a594..94fdc84d 100644 --- a/lib/xfile.h +++ b/lib/xfile.h @@ -54,6 +54,18 @@ class XFile : public QFile flush(); return r; } + void retry_read() + { + seek(0); + if (filp) + fseek(filp, 0, SEEK_SET); + if (error()) { + throw errorEx( + tr("Error rewinding file: '%1': %2") + .arg(fileName()) + .arg(strerror(errno))); + } + } bool open_key() { mode_t m = umask(077);