Also change File loading from FILE* to QFile

This commit is contained in:
Christian Hohnstaedt 2019-03-18 06:15:21 +01:00
parent 026d8f8e6d
commit fa704001ca
10 changed files with 160 additions and 179 deletions

View File

@ -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());

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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()

View File

@ -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();
}

View File

@ -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);

View File

@ -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)

View File

@ -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);