From b5667920bdb88d160bc719bb1183f8077e5cee97 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Thu, 3 Dec 2009 23:32:23 +0100 Subject: [PATCH] start certificate export to templates --- lib/db_x509.cpp | 22 +++++++++++++++- lib/db_x509.h | 1 + lib/pki_temp.cpp | 44 ++++++++++++++++++++++++++++++-- lib/pki_temp.h | 2 ++ lib/pki_x509.cpp | 20 ++++----------- lib/pki_x509.h | 1 - lib/x509v3ext.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++ lib/x509v3ext.h | 3 +++ 8 files changed, 138 insertions(+), 19 deletions(-) diff --git a/lib/db_x509.cpp b/lib/db_x509.cpp index c98bc995..9680e031 100644 --- a/lib/db_x509.cpp +++ b/lib/db_x509.cpp @@ -581,6 +581,7 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index) this, SLOT(toRequest())); itemScard = subExport->addAction(tr("Smart Card"), this, SLOT(toScard())); + subExport->addAction(tr("Template"), this, SLOT(toTemplate())); menu->addAction(tr("Delete"), this, SLOT(delete_ask())); itemTrust = menu->addAction(tr("Trust"), this, SLOT(setTrust())); @@ -1020,9 +1021,10 @@ void db_x509::toRequest() try { pki_x509req *req = new pki_x509req(); + check_oom(req); req->setIntName(cert->getIntName()); req->createReq(cert->getRefKey(), cert->getSubject(), - cert->getRefKey()->getDefaultMD(), cert->getExt()); + cert->getRefKey()->getDefaultMD(), cert->getV3ext()); mainwin->reqs->insert(req); } catch (errorEx &err) { @@ -1042,6 +1044,24 @@ void db_x509::toScard() } } +void db_x509::toTemplate() +{ + pki_x509 *cert = static_cast(currentIdx.internalPointer()); + if (!cert) + return; + + try { + pki_temp *temp = new pki_temp(); + check_oom(temp); + temp->setIntName(cert->getIntName()); + temp->fromCert(cert); + mainwin->temps->insert(temp); + } + catch (errorEx &err) { + mainwin->Error(err); + } +} + void db_x509::caProperties() { Ui::CaProperties ui; diff --git a/lib/db_x509.h b/lib/db_x509.h index e3dc6ad5..dc920a3c 100644 --- a/lib/db_x509.h +++ b/lib/db_x509.h @@ -67,6 +67,7 @@ class db_x509: public db_x509super void caProperties(); void toRequest(); void toScard(); + void toTemplate(); void newCert(pki_temp *); void newCert(pki_x509req *); void loadPKCS12(); diff --git a/lib/pki_temp.cpp b/lib/pki_temp.cpp index 44fb706e..419d0273 100644 --- a/lib/pki_temp.cpp +++ b/lib/pki_temp.cpp @@ -89,6 +89,48 @@ pki_temp::pki_temp(const QString d) noWellDefined=false; } +static QString extVtoString(extList &el, int nid) +{ + int i = el.idxByNid(nid); + if (i != -1) { + QStringList sl = el[i].i2v(); + printf("extVtoString: %d '%s'\n", nid, CCHAR(sl.join(", "))); + el.removeAt(i); + return sl.join(", "); + } + return QString(); +} + +static QString extToString(extList &el, int nid) +{ + int i = el.idxByNid(nid); + if (i != -1) { + QString s = el[i].i2s(); + printf("extToString: %d '%s'\n", nid, CCHAR(s)); + el.removeAt(i); + return s; + } + return QString(); +} + +void pki_temp::fromCert(pki_x509 *cert) +{ + extList el = cert->getV3ext(); + + xname = cert->getSubject(); + subAltName = extVtoString(el, NID_subject_alt_name); + issAltName = extVtoString(el, NID_issuer_alt_name); + crlDist = extVtoString(el, NID_crl_distribution_points); + authInfAcc = extVtoString(el, NID_info_access); + + nsComment = extToString(el, NID_netscape_comment); + nsBaseUrl = extToString(el, NID_netscape_base_url); + nsRevocationUrl = extToString(el, NID_netscape_revocation_url); + nsCARevocationUrl = extToString(el, NID_netscape_ca_revocation_url); + nsRenewalUrl = extToString(el, NID_netscape_renewal_url); + nsCaPolicyUrl = extToString(el, NID_netscape_ca_policy_url); + nsSslServerName = extToString(el, NID_netscape_ssl_server_name); +} void pki_temp::fromData(const unsigned char *p, db_header_t *head ) { @@ -257,7 +299,6 @@ pki_temp::~pki_temp() } - int pki_temp::dataSize() { int s = 9 * sizeof(int) + 9 * sizeof(char) + @@ -279,7 +320,6 @@ int pki_temp::dataSize() return s; } - bool pki_temp::compare(pki_base *) { // we don't care if templates with identical contents diff --git a/lib/pki_temp.h b/lib/pki_temp.h index 15bd861c..8cfefd32 100644 --- a/lib/pki_temp.h +++ b/lib/pki_temp.h @@ -11,6 +11,7 @@ #include "pki_base.h" #include "x509name.h" #include "asn1time.h" +#include "pki_x509.h" class pki_temp: public pki_base { @@ -29,6 +30,7 @@ class pki_temp: public pki_base int validN, validM; // methods + void fromCert(pki_x509 *cert); pki_temp(const pki_temp *pk); pki_temp(const QString d = QString()); diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index dc71279b..fe7a7f2d 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -558,21 +558,12 @@ extList pki_x509::getV3ext() x509v3ext pki_x509::getExtByNid(int nid) { - extList el = getExt(); - x509v3ext e; + extList el = getV3ext(); + int i = el.idxByNid(nid); - for (int i=0; i< el.count(); i++){ - if (el[i].nid() == nid) return el[i]; - } - return e; -} - -extList pki_x509::getExt() -{ - extList el; - el.setStack(cert->cert_info->extensions); - - return el; + if (i == -1) + return x509v3ext(); + return el[i]; } pki_x509 *pki_x509::getSigner() @@ -606,7 +597,6 @@ void pki_x509::setEffTrust(int t) efftrust = t; } - bool pki_x509::isRevoked() { return isrevoked ; diff --git a/lib/pki_x509.h b/lib/pki_x509.h index 5291073f..5d85c799 100644 --- a/lib/pki_x509.h +++ b/lib/pki_x509.h @@ -103,7 +103,6 @@ class pki_x509 : public pki_x509super QString getSigAlg(); x509v3ext getExtByNid(int nid); const EVP_MD *getDigest(); - extList getExt(); QVariant column_data(int col); QVariant getIcon(int column); }; diff --git a/lib/x509v3ext.cpp b/lib/x509v3ext.cpp index ba11979d..780743a6 100644 --- a/lib/x509v3ext.cpp +++ b/lib/x509v3ext.cpp @@ -111,6 +111,70 @@ QString x509v3ext::getValue() const return text; } +static void *ext_str_new(X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); + const unsigned char *p = ext->value->data; + void *ext_str; + + if(method->it) + ext_str = ASN1_item_d2i(NULL, &p, ext->value->length, ASN1_ITEM_ptr(method->it)); + else + ext_str = method->d2i(NULL, &p, ext->value->length); + return ext_str; +} + +static void ext_str_free(X509_EXTENSION *ext, void *ext_str) +{ + const X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); + + if (method->it) + ASN1_item_free((ASN1_VALUE*)ext_str,ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_str); +} + +QString x509v3ext::i2s() +{ + QString str; + X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); + void *ext_str = ext_str_new(ext); + + if (!ext_str) + return str; + if (method->i2s) + str = QString(method->i2s(method, ext_str)); + + ext_str_free(ext, ext_str); + return str; +} + +QStringList x509v3ext::i2v() +{ + X509V3_EXT_METHOD *method = X509V3_EXT_get(ext); + void *ext_str = ext_str_new(ext); + QStringList sl; + + if (!ext_str) + return sl; + if (method->i2v) { + STACK_OF(CONF_VALUE) *val = method->i2v(method, ext_str, NULL); + for (int i = 0; i < sk_CONF_VALUE_num(val); i++) { + CONF_VALUE *nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + sl << QString(nval->value); + else if (!nval->value) + sl << QString(nval->name); + else + sl << QString("%1:%2").arg(nval->name).arg(nval->value); + } + sk_CONF_VALUE_pop_free(val, X509V3_conf_free); + } + + ext_str_free(ext, ext_str); + return sl; +} + QString x509v3ext::getHtml() const { QString html; diff --git a/lib/x509v3ext.h b/lib/x509v3ext.h index ead319eb..35a90f45 100644 --- a/lib/x509v3ext.h +++ b/lib/x509v3ext.h @@ -11,6 +11,7 @@ #include #include #include +#include class QString; @@ -35,6 +36,8 @@ class x509v3ext bool isValid() const; int nid() const; void *d2i(); + QString i2s(); + QStringList i2v(); }; class extList : public QList