Close #45: Unable to view Public Key

Allow displaying the public key of a certificate
or request without importing it.

When importing certificates or CRLs,
display the issuer if it exists in the database.
This commit is contained in:
Christian Hohnstaedt 2018-07-01 09:55:16 +02:00
parent d32d14ee98
commit bdfa10d4d5
16 changed files with 129 additions and 35 deletions

View File

@ -36,6 +36,12 @@ QString pki_base::comboText() const
{
return desc;
}
void pki_base::autoIntName()
{
setIntName("");
}
void pki_base::deleteFromToken() { };
void pki_base::deleteFromToken(slotid) { };
void pki_base::writeDefault(const QString) { }
@ -121,6 +127,9 @@ void pki_base::fromPEMbyteArray(QByteArray &ba, QString name)
BIO *bio = BIO_new_mem_buf(ba.data(), ba.length());
fromPEM_BIO(bio, name);
BIO_free(bio);
autoIntName();
if (getIntName().isEmpty())
setIntName(rmslashdot(name));
}
QString pki_base::rmslashdot(const QString &s)

View File

@ -88,6 +88,7 @@ class pki_base : public QObject
{
desc = d;
}
virtual void autoIntName();
QString getComment() const
{
return comment;

View File

@ -32,7 +32,6 @@ void pki_crl::fromPEM_BIO(BIO *bio, QString name)
openssl_error(name);
X509_CRL_free(crl);
crl = _crl;
setIntName(rmslashdot(name));
}
QString pki_crl::getMsg(msg_type msg) const
@ -53,7 +52,7 @@ QString pki_crl::getMsg(msg_type msg) const
return pki_base::getMsg(msg);
}
QSqlError pki_crl::insertSqlData()
QSqlError pki_crl::lookupIssuer()
{
XSqlQuery q;
unsigned name_hash = getSubject().hashNum();
@ -74,12 +73,23 @@ QSqlError pki_crl::insertSqlData()
}
verify(x);
}
return q.lastError();
}
QSqlError pki_crl::insertSqlData()
{
QSqlError e = lookupIssuer();
if (e.isValid())
return e;
XSqlQuery q;
SQL_PREPARE(q, "INSERT INTO crls (item, hash, num, iss_hash, issuer, crl) "
"VALUES (?, ?, ?, ?, ?, ?)");
q.bindValue(0, sqlItemId);
q.bindValue(1, hash());
q.bindValue(2, numRev());
q.bindValue(3, name_hash);
q.bindValue(3, (uint)getSubject().hashNum());
q.bindValue(4, issuer ? issuer->getSqlItemId() : QVariant());
q.bindValue(5, i2d_b64());
q.exec();

View File

@ -78,6 +78,7 @@ class pki_crl: public pki_x509name
a1int getCrlNumber() const;
BIO *pem(BIO *, int);
bool visible() const;
QSqlError lookupIssuer();
QSqlError insertSqlData();
QSqlError deleteSqlData();
void restoreSql(const QSqlRecord &rec);

View File

@ -274,6 +274,9 @@ void pki_evp::fromPEMbyteArray(QByteArray &ba, QString name)
setIntName(rmslashdot(name));
set_EVP_PKEY(pkey);
autoIntName();
if (getIntName().isEmpty())
setIntName(rmslashdot(name));
}
static void search_ec_oid(EVP_PKEY *pkey)

View File

@ -50,6 +50,12 @@ pki_key::~pki_key()
EVP_PKEY_free(key);
}
void pki_key::autoIntName()
{
setIntName(QString("%1 %2%3").arg(length(), getTypeString(),
isPubKey() ? QString(" ") + tr("Public key") : QString("")));
}
void pki_key::d2i(QByteArray &ba)
{
EVP_PKEY *k = (EVP_PKEY*)d2i_bytearray(D2I_VOID(d2i_PUBKEY), ba);

View File

@ -47,6 +47,7 @@ class pki_key: public pki_base
pki_key(const pki_key *pk);
virtual ~pki_key();
static builtin_curves builtinCurves;
void autoIntName();
QString length() const;
QString comboText() const;
QString getKeyTypeString(void) const;

View File

@ -435,6 +435,7 @@ void pki_temp::try_fload(QString fname, const char *mode)
try {
fromPEM_BIO(b, fname);
BIO_free(b);
setIntName(rmslashdot(fname));
return;
} catch (errorEx &err) {
BIO_free(b);

View File

@ -206,16 +206,13 @@ pki_x509 *pki_x509::findIssuer()
return NULL;
}
void pki_x509::fromPEM_BIO(BIO *bio, QString name)
void pki_x509::fromPEM_BIO(BIO *bio, QString)
{
X509 *_cert;
_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
pki_openssl_error();
X509_free(cert);
cert = _cert;
autoIntName();
if (getIntName().isEmpty())
setIntName(rmslashdot(name));
}
void pki_x509::fload(const QString fname)
@ -738,7 +735,9 @@ bool pki_x509::verify(pki_x509 *signer)
return true;
if ((psigner != NULL) || (signer == NULL))
return false;
if (signer == this && signerSqlId == sqlItemId)
if (signer == this &&
signerSqlId == sqlItemId &&
signerSqlId != QVariant())
return true;
if (verify_only(signer)) {
@ -894,7 +893,7 @@ int pki_x509::sigAlg() const
pki_x509 *pki_x509::getSigner()
{
return static_cast<pki_x509 *>(psigner);
return psigner;
}
bool pki_x509::isRevoked() const

View File

@ -138,9 +138,6 @@ void pki_x509req::fromPEM_BIO(BIO *bio, QString name)
openssl_error(name);
X509_REQ_free(request);
request = req;
autoIntName();
if (getIntName().isEmpty())
setIntName(rmslashdot(name));
}
void pki_x509req::fload(const QString fname)

View File

@ -20,7 +20,7 @@ pki_x509super::~pki_x509super()
{
}
QSqlError pki_x509super::insertSqlData()
QSqlError pki_x509super::lookupKey()
{
XSqlQuery q;
unsigned hash = pubHash();
@ -43,13 +43,22 @@ QSqlError pki_x509super::insertSqlData()
break;
}
}
return q.lastError();
}
QSqlError pki_x509super::insertSqlData()
{
QSqlError e = lookupKey();
if (e.isValid())
return e;
XSqlQuery q;
SQL_PREPARE(q, "INSERT INTO x509super (item, subj_hash, pkey, key_hash) "
"VALUES (?, ?, ?, ?)");
q.bindValue(0, sqlItemId);
q.bindValue(1, (uint)getSubject().hashNum());
q.bindValue(2, privkey ? privkey->getSqlItemId() : QVariant());
q.bindValue(3, hash);
q.bindValue(3, pubHash());
q.exec();
return q.lastError();
}

View File

@ -52,6 +52,7 @@ class pki_x509super : public pki_x509name
QVariant column_data(const dbheader *hd) const;
void opensslConf(QString fname);
bool visible() const;
QSqlError lookupKey();
QSqlError insertSqlData();
QSqlError deleteSqlData();
void restoreSql(const QSqlRecord &rec);

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>532</width>
<width>572</width>
<height>403</height>
</rect>
</property>

View File

@ -7,6 +7,7 @@
#include "CertDetail.h"
#include "KeyDetail.h"
#include "MainWindow.h"
#include "distname.h"
#include "clicklabel.h"
@ -24,6 +25,7 @@ CertDetail::CertDetail(QWidget *parent)
showConf = false;
keySqlId = QVariant();
issuerSqlId = QVariant();
myPubKey = NULL;
}
void CertDetail::on_showExt_clicked()
@ -46,6 +48,7 @@ void CertDetail::setX509super(pki_x509super *x)
// examine the key
pki_key *key= x->getRefKey();
myPubKey = x->getPubKey();
if (key) {
privKey->setText(key->getIntName());
privKey->setClickText(key->getSqlItemId().toString());
@ -55,6 +58,13 @@ void CertDetail::setX509super(pki_x509super *x)
privKey->setRed();
}
keySqlId = key->getSqlItemId();
} else if (myPubKey) {
privKey->setText(tr("Show public key"));
privKey->setRed();
connect(privKey, SIGNAL(doubleClicked(QString)),
this, SLOT(showPubKey()));
myPubKey->setIntName(x->getIntName());
myPubKey->setComment(tr("This key is not in the database."));
} else {
privKey->setText(tr("Not available"));
privKey->setDisabled(true);
@ -94,11 +104,11 @@ void CertDetail::setCert(pki_x509 *cert)
tabwidget->removeTab(3);
// examine the signature
if ( cert->getSigner() == NULL) {
if (cert->getSigner() == NULL) {
signature->setText(tr("Signer unknown"));
signature->setDisabled(true);
signature->disableToolTip();
} else if ( cert == cert->getSigner()) {
} else if (cert == cert->getSigner()) {
signature->setText(tr("Self signed"));
signature->setGreen();
signature->disableToolTip();
@ -243,3 +253,23 @@ void CertDetail::itemChanged(pki_base *pki)
if (pki->getSqlItemId() == issuerSqlId)
signature->setText(pki->getIntName());
}
void CertDetail::showPubKey()
{
if (!myPubKey)
return;
KeyDetail *dlg = new KeyDetail(this);
if (!dlg)
return;
dlg->setKey(myPubKey);
dlg->keyDesc->setReadOnly(true);
dlg->comment->setReadOnly(true);
dlg->exec();
delete dlg;
}
CertDetail::~CertDetail()
{
if (myPubKey)
delete myPubKey;
}

View File

@ -23,15 +23,18 @@ class CertDetail: public QDialog, public Ui::CertDetail
QString conf, exts;
QLabel *labelFromAsn1String(ASN1_STRING *s);
void setX509super(pki_x509super *x);
pki_key *myPubKey;
public:
CertDetail( QWidget *parent);
CertDetail(QWidget *parent);
~CertDetail();
void setCert(pki_x509 *cert);
void setReq(pki_x509req *req);
private slots:
void on_showExt_clicked();
void itemChanged(pki_base *pki);
void showPubKey();
};
#endif

View File

@ -77,10 +77,24 @@ void ImportMulti::addItem(pki_base *pki)
pki->pkiSource = imported;
const std::type_info &t = typeid(*pki);
if (t == typeid(pki_x509) || t == typeid(pki_evp) ||
t == typeid(pki_x509req) || t == typeid(pki_crl) ||
t == typeid(pki_temp) || t == typeid(pki_scard))
if (t == typeid(pki_x509)) {
pki_x509 *x = static_cast<pki_x509 *>(pki);
x->setSigner(x->findIssuer());
x->lookupKey();
mcont->inToCont(pki);
}
else if (t == typeid(pki_x509req)) {
pki_x509req *x = static_cast<pki_x509req *>(pki);
x->lookupKey();
mcont->inToCont(pki);
}
else if (t == typeid(pki_crl)) {
pki_crl *x = static_cast<pki_crl *>(pki);
x->lookupIssuer();
mcont->inToCont(pki);
}
else if (t == typeid(pki_evp) || t == typeid(pki_temp) ||
t == typeid(pki_scard))
{
mcont->inToCont(pki);
}
@ -287,28 +301,38 @@ void ImportMulti::on_butDetails_clicked()
const std::type_info &t = typeid(*pki);
try {
if (t == typeid(pki_x509)){
CertDetail *dlg;
dlg = new CertDetail(mainwin);
CertDetail *dlg = new CertDetail(mainwin);
dlg->setCert(static_cast<pki_x509 *>(pki));
dlg->exec();
connect(dlg->privKey, SIGNAL(doubleClicked(QString)),
mainwin->keys, SLOT(showItem(QString)));
connect(dlg->signature,
SIGNAL(doubleClicked(QString)),
mainwin->certs, SLOT(showItem(QString)));
if (dlg->exec())
pki->setIntName(dlg->descr->text());
delete dlg;
} else if (t == typeid(pki_evp) || t == typeid(pki_scard)) {
KeyDetail *dlg;
dlg = new KeyDetail(mainwin);
KeyDetail *dlg = new KeyDetail(mainwin);
dlg->setKey(static_cast<pki_key *>(pki));
dlg->exec();
if (dlg->exec())
pki->setIntName(dlg->keyDesc->text());
delete dlg;
} else if (t == typeid(pki_x509req)) {
CertDetail *dlg;
dlg = new CertDetail(mainwin);
CertDetail *dlg = new CertDetail(mainwin);
dlg->setReq(static_cast<pki_x509req *>(pki));
dlg->exec();
connect(dlg->privKey, SIGNAL(doubleClicked(QString)),
mainwin->keys, SLOT(showItem(QString)));
if (dlg->exec())
pki->setIntName(dlg->descr->text());
delete dlg;
} else if (t == typeid(pki_crl)) {
CrlDetail *dlg;
dlg = new CrlDetail(mainwin);
CrlDetail *dlg = new CrlDetail(mainwin);
dlg->setCrl(static_cast<pki_crl *>(pki));
dlg->exec();
connect(dlg->issuerIntName,
SIGNAL(doubleClicked(QString)),
mainwin->certs, SLOT(showItem(QString)));
if (dlg->exec())
pki->setIntName(dlg->descr->text());
delete dlg;
} else if (t == typeid(pki_temp)) {
XCA_WARN(tr("Details of the item '%1' cannot be shown")
@ -319,7 +343,6 @@ void ImportMulti::on_butDetails_clicked()
catch (errorEx &err) {
mainwin->Error(err);
}
}
ImportMulti::~ImportMulti()