diff --git a/lib/db_base.cpp b/lib/db_base.cpp index 9e3bb598..d79b7450 100644 --- a/lib/db_base.cpp +++ b/lib/db_base.cpp @@ -302,7 +302,8 @@ void db_base::delete_ask() void db_base::pem2clipboard() { long l; - const char *p; + const char *p; + exportType::etype format; QString msg; QClipboard *cb = QApplication::clipboard(); @@ -310,7 +311,8 @@ void db_base::pem2clipboard() if (!currentIdx.isValid()) return; pki_base *pki = static_cast(currentIdx.internalPointer()); - pki->pem(bio); + format = clipboardFormat(); + pki->pem(bio, format); openssl_error(); l = BIO_get_mem_data(bio, &p); msg = QString::fromUtf8(p, l); diff --git a/lib/db_base.h b/lib/db_base.h index 64d9d626..486653f7 100644 --- a/lib/db_base.h +++ b/lib/db_base.h @@ -16,6 +16,7 @@ #include #include #include +#include "widgets/ExportDialog.h" #include "pki_base.h" #include "headerlist.h" @@ -44,6 +45,9 @@ class db_base: public QAbstractItemModel virtual dbheaderList getHeaders(); int colResizing; int handleBadEntry(unsigned char *p, db_header_t *head); + virtual exportType::etype clipboardFormat() { + return exportType::Separator; + } public: pki_base *rootItem; diff --git a/lib/db_key.cpp b/lib/db_key.cpp index 71ee1478..1bea204b 100644 --- a/lib/db_key.cpp +++ b/lib/db_key.cpp @@ -276,6 +276,38 @@ void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index) return; } +exportType::etype db_key::clipboardFormat() +{ + QString title = tr("Export public key [%1]"); + QList types; + + pki_key *key =static_cast(currentIdx.internalPointer()); + + types << exportType(exportType::PEM_key, "pem", tr("PEM public")); + if (key->getKeyType() == EVP_PKEY_RSA || + key->getKeyType() == EVP_PKEY_DSA) + types << exportType(exportType::SSH2_public, + "pub", tr("SSH2 public")); + if (!key->isPubKey() && !key->isToken()) { + types << exportType(exportType::PEM_private, "pem", + tr("PEM private")); + title = tr("Export private key [%1]"); + } + ExportDialog *dlg = new ExportDialog(mainwin, + title.arg(key->getTypeString()), QString(), key, + key->isToken() ? MainWindow::scardImg : MainWindow::keyImg, + types); + + dlg->filename->setText(tr("Clipboard")); + dlg->filename->setEnabled(false); + dlg->fileBut->setEnabled(false); + if (!dlg->exec()) { + delete dlg; + return exportType::Separator; + } + return dlg->type(); +} + void db_key::store() { const EVP_CIPHER *enc = NULL; diff --git a/lib/db_key.h b/lib/db_key.h index f0521d65..2b904054 100644 --- a/lib/db_key.h +++ b/lib/db_key.h @@ -22,6 +22,7 @@ class db_key: public db_base Q_OBJECT protected: virtual dbheaderList getHeaders(); + exportType::etype clipboardFormat(); private: void __setOwnPass(enum pki_key::passType); public: diff --git a/lib/pki_base.h b/lib/pki_base.h index c6170a94..e4fb58b2 100644 --- a/lib/pki_base.h +++ b/lib/pki_base.h @@ -98,7 +98,7 @@ class pki_base : public QObject { return QByteArray(); } - virtual BIO *pem(BIO *) + virtual BIO *pem(BIO *, int format=0) { return NULL; } diff --git a/lib/pki_crl.cpp b/lib/pki_crl.cpp index 2ff415c3..ca81d594 100644 --- a/lib/pki_crl.cpp +++ b/lib/pki_crl.cpp @@ -212,7 +212,7 @@ void pki_crl::writeCrl(const QString fname, bool pem) fopen_error(fname); } -BIO *pki_crl::pem(BIO *b) +BIO *pki_crl::pem(BIO *b, int format) { if (!b) b = BIO_new(BIO_s_mem()); diff --git a/lib/pki_crl.h b/lib/pki_crl.h index 31f9d777..4992d727 100644 --- a/lib/pki_crl.h +++ b/lib/pki_crl.h @@ -68,7 +68,7 @@ class pki_crl: public pki_x509name QByteArray i2d(); void setCrlNumber(a1int num); bool getCrlNumber(a1int *num); - BIO *pem(BIO *); + BIO *pem(BIO *, int); bool visible(); }; diff --git a/lib/pki_key.cpp b/lib/pki_key.cpp index 71a3951e..c5815df1 100644 --- a/lib/pki_key.cpp +++ b/lib/pki_key.cpp @@ -75,31 +75,26 @@ QByteArray pki_key::i2d() return i2d_bytearray(I2D_VOID(i2d_PUBKEY), key); } -BIO *pki_key::pem(BIO *b) +BIO *pki_key::pem(BIO *b, int format) { EVP_PKEY *pkey; + QByteArray ba; if (!b) b = BIO_new(BIO_s_mem()); - if (isPubKey() || isToken()) { - PEM_write_bio_PUBKEY(b, key); - return b; - } - - QString text = tr("Do you really want to export the private key unencrypted to the clipboard ?"); - xcaWarning msg(NULL, text); - msg.addButton(QMessageBox::Ok)->setText(tr("Only export the public key")); - msg.addButton(QMessageBox::Apply)->setText(tr("Export the private key unencrypted")); - - switch (msg.exec()) { - case QMessageBox::Apply: + switch (format) { + case exportType::SSH2_public: + ba = SSH2publicQByteArray(); + BIO_write(b, ba.data(), ba.size()); + break; + case exportType::PEM_private: pkey = decryptKey(); PEM_write_bio_PrivateKey(b, pkey, NULL, NULL, 0, NULL, NULL); EVP_PKEY_free(pkey); - return b; - case QMessageBox::Ok: + break; + case exportType::PEM_key: PEM_write_bio_PUBKEY(b, key); - return b; + break; } return b; } @@ -474,7 +469,7 @@ void pki_key::ssh_key_bn2data(BIGNUM *bn, QByteArray *data) ssh_key_QBA2data(big, data); } -void pki_key::writeSSH2public(QString fname) +QByteArray pki_key::SSH2publicQByteArray() { QByteArray txt, data; @@ -494,14 +489,19 @@ void pki_key::writeSSH2public(QString fname) ssh_key_bn2data(key->pkey.dsa->pub_key, &data); break; default: - return; + return QByteArray(); } - txt += " " + data.toBase64() + "\n"; + return txt + " " + data.toBase64() + "\n"; +} +void pki_key::writeSSH2public(QString fname) +{ QFile f(fname); + if (!f.open(QIODevice::ReadWrite)) fopen_error(fname); else { + QByteArray txt = SSH2publicQByteArray(); if (f.write(txt) != txt.size()) throw errorEx(tr("Failed writing to %1").arg(fname)); f.close(); diff --git a/lib/pki_key.h b/lib/pki_key.h index 07c060fb..03cfb666 100644 --- a/lib/pki_key.h +++ b/lib/pki_key.h @@ -26,6 +26,7 @@ class pki_key: public pki_base EVP_PKEY *key; QString BN2QString(BIGNUM *bn) const; QString BNoneLine(BIGNUM *bn) const; + QByteArray SSH2publicQByteArray(); private: BIGNUM *ssh_key_data2bn(QByteArray *ba, bool skip = false); @@ -78,7 +79,7 @@ class pki_key: public pki_base { return key; } - BIO *pem(BIO *); + BIO *pem(BIO *, int); QVariant column_data(dbheader *hd); QString modulus(); QString pubEx(); diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index ffae7ff1..d8e05a63 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -572,7 +572,7 @@ void pki_x509::writeCert(const QString fname, bool PEM, bool append) fopen_error(fname); } -BIO *pki_x509::pem(BIO *b) +BIO *pki_x509::pem(BIO *b, int format) { if (!b) b = BIO_new(BIO_s_mem()); diff --git a/lib/pki_x509.h b/lib/pki_x509.h index f7ea6396..c07bdaf1 100644 --- a/lib/pki_x509.h +++ b/lib/pki_x509.h @@ -151,7 +151,7 @@ class pki_x509 : public pki_x509super void deleteFromToken(slotid slot); virtual QString getMsg(msg_type msg); virtual int renameOnToken(slotid slot, QString name); - BIO *pem(BIO *); + BIO *pem(BIO *, int); virtual QVariant bg_color(dbheader *hd); }; diff --git a/lib/pki_x509req.cpp b/lib/pki_x509req.cpp index 8a8b9b67..6f4be2e8 100644 --- a/lib/pki_x509req.cpp +++ b/lib/pki_x509req.cpp @@ -255,7 +255,7 @@ void pki_x509req::writeReq(const QString fname, bool pem) fopen_error(fname); } -BIO *pki_x509req::pem(BIO *b) +BIO *pki_x509req::pem(BIO *b, int format) { if (!b) b = BIO_new(BIO_s_mem()); diff --git a/lib/pki_x509req.h b/lib/pki_x509req.h index 311b8c4e..6651a6e5 100644 --- a/lib/pki_x509req.h +++ b/lib/pki_x509req.h @@ -77,7 +77,7 @@ class pki_x509req : public pki_x509super void d2i_spki(QByteArray &ba); QByteArray i2d(); QByteArray i2d_spki(); - BIO *pem(BIO *); + BIO *pem(BIO *, int); bool visible(); }; diff --git a/widgets/ExportDialog.cpp b/widgets/ExportDialog.cpp index 00da6bc8..0ea5f36f 100644 --- a/widgets/ExportDialog.cpp +++ b/widgets/ExportDialog.cpp @@ -107,7 +107,8 @@ void ExportDialog::on_exportFormat_activated(int selected) break; } } - filename->setText(fn); + if (filename->isEnabled()) + filename->setText(fn); on_exportFormat_highlighted(selected); } @@ -132,8 +133,14 @@ void ExportDialog::accept() { QString fn = filename->text(); - if (fn.isEmpty()) + if (!filename->isEnabled()) { + QDialog::accept(); + return; + } + if (fn.isEmpty()) { reject(); + return; + } if (mayWriteFile(fn)) { mainwin->setPath(fn.mid(0, fn.lastIndexOf(QRegExp("[/\\\\]")))); QDialog::accept();