Logo Search packages:      
Sourcecode: xca version File versions  Download package

NewX509_ext.cpp

/* vi: set sw=4 ts=4:
 *
 * Copyright (C) 2001 - 2007 Christian Hohnstaedt.
 *
 * All rights reserved.
 */


#include "NewX509.h"
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qradiobutton.h>
#include <qlineedit.h>
#include <qlistwidget.h>
#include <qmessagebox.h>
#include "MainWindow.h"
#include "lib/x509v3ext.h"


x509v3ext NewX509::getBasicConstraints()
{
      QStringList cont;
      x509v3ext ext;
      QString ca[] = { "", "CA:TRUE", "CA:FALSE" };
      if (basicCA->currentIndex() > 0) {
            if (bcCritical->isChecked())
                  cont << "critical";
            cont << ca[basicCA->currentIndex()];
            if (!basicPath->text().isEmpty())
                  cont << (QString)"pathlen:" + basicPath->text();
            ext.create(NID_basic_constraints, cont.join(", "), &ext_ctx);
      }
      return ext;
}

void NewX509::setBasicConstraints(const x509v3ext &e)
{
      if (e.nid() != NID_basic_constraints) return;
      BASIC_CONSTRAINTS *bc;
      x509v3ext ex = e;
      bc = (BASIC_CONSTRAINTS *)ex.d2i();
      if (bc) {
            bcCritical->setChecked(bc->ca);
            a1int pl(bc->pathlen);
            basicPath->setText(QString::number(pl.getLong()));
      }
}

x509v3ext NewX509::getSubKeyIdent()
{
      x509v3ext ext;
      if (subKey->isChecked())
            ext.create(NID_subject_key_identifier, "hash", &ext_ctx);
      return ext;
}


x509v3ext NewX509::getAuthKeyIdent()
{
      x509v3ext ext;
      if (authKey->isChecked() && authKey->isEnabled()) {
            if (foreignSignRB->isChecked())
                  ext.create(NID_authority_key_identifier,
                        "keyid,issuer:always", &ext_ctx);
            else
                  ext.create(NID_authority_key_identifier,
                        "keyid,issuer", &ext_ctx);
      }
      return ext;
}

x509v3ext NewX509::getKeyUsage()
{
      QString keyusage[] = {
            "digitalSignature", "nonRepudiation", "keyEncipherment",
            "dataEncipherment", "keyAgreement", "keyCertSign",
            "cRLSign", "encipherOnly", "decipherOnly"
      };

      QStringList cont;
      x509v3ext ext;

      int rows = keyUsage->count();
      for (int i=0; i<rows; i++) {
            if (keyUsage->isItemSelected(keyUsage->item(i))) {
                  cont << keyusage[i];
            }
      }
      if (kuCritical->isChecked() && cont.count() > 0)
            cont.prepend("critical");
      ext.create(NID_key_usage, cont.join(", "), &ext_ctx);
      return ext;
}

x509v3ext NewX509::getEkeyUsage()
{
      QStringList cont;
      x509v3ext ext;

      int rows = ekeyUsage->count();
      for (int i=0; i<rows; i++) {
            //QListWidgetItem *li = ekeyUsage->item(i);
            //printf("rows = %d, ekeyUsage = %d, %p\n", rows, i, li);
            if (ekeyUsage->isItemSelected(ekeyUsage->item(i))) {
                  cont << (QString)OBJ_nid2sn(eku_nid[i]);
            }
      }
      if (ekuCritical->isChecked() && cont.count() > 0)
            cont.prepend("critical");
      ext.create(NID_ext_key_usage, cont.join(", "), &ext_ctx);
      return ext;
}

x509v3ext NewX509::getSubAltName()
{
      x509v3ext ext;
      QString s = subAltName->text();
      if (pt == x509_req) {
            QStringList sn, sl = s.split(',');
            foreach (QString str, sl) {
                  if (str != "email:copy")
                        sn += str;
            }
            s = sn.join(",");
      }
      ext.create(NID_subject_alt_name, s, &ext_ctx);
      return ext;
}

x509v3ext NewX509::getIssAltName()
{
      x509v3ext ext;
      QString s = issAltName->text();
      if (pt == x509_req) {
            QStringList sn, sl = s.split(',');
            foreach (QString str, sl) {
                  if (str != "issuer:copy")
                        sn += str;
            }
            s = sn.join(",");
      }
      ext.create(NID_issuer_alt_name, s, &ext_ctx);
      return ext;
}

x509v3ext NewX509::getCrlDist()
{
      x509v3ext ext;
      if (!crlDist->text().isEmpty()) {
            ext.create(NID_crl_distribution_points, crlDist->text(), &ext_ctx);
      }
      return ext;
}

QString NewX509::getAuthInfAcc_string()
{
      QString rval="";
      QString aia_txt   = authInfAcc->text();
      aia_txt = aia_txt.trimmed();

      if (!aia_txt.isEmpty()) {
            rval = OBJ_nid2sn(aia_nid[aiaOid->currentIndex()]);
            rval += ";" + aia_txt;
      }
      return rval;
}

void NewX509::setAuthInfAcc_string(QString aia_txt)
{
      QStringList aia;
      int nid;

      aia = aia_txt.split(';');

      if (aia.count() != 2)
            return;

      nid = OBJ_sn2nid(CCHAR(aia[0]));

      for (int i=0; i < aia_nid.count(); i++) {
            if (aia_nid[i] == nid) {
                  aiaOid->setCurrentIndex(i);
            }
      }
      authInfAcc->setText(aia[1]);
}

x509v3ext NewX509::getAuthInfAcc()
{
      x509v3ext ext;
      QString aia_txt = getAuthInfAcc_string();

      if (!aia_txt.isEmpty()) {
            ext.create(NID_info_access, aia_txt, &ext_ctx);
      }
      return ext;
}

extList NewX509::getAdvanced()
{
      QString conf_str;
      CONF *conf;
      BIO *bio;
      extList elist;
      long err_line=0;
      STACK_OF(X509_EXTENSION) **sk, *sk_tmp = NULL;
      char ext_name[] = "ext";
      int ret, i, start;

      if (nconf_data->isReadOnly()) {
            on_adv_validate_clicked();
      }
      conf_str = nconf_data->toPlainText();
      if (conf_str.isEmpty())
            return elist;
      conf_str += "\n";
      QStringList list = conf_str.split("\n", QString::SkipEmptyParts);

      conf_str = QString("[") + ext_name + "]\n";
      for (i=0; i< list.count(); i++) {
            QString s = list[i].trimmed();
            if (!s.isEmpty()){
                  conf_str += s + "\n";
            }
      }
      bio = BIO_new_mem_buf((void*)CCHAR(conf_str), conf_str.length());
      if (!bio)
            return elist;
      conf = NCONF_new(NULL);
      ret = NCONF_load_bio(conf, bio, &err_line);
      if (ret != 1) {
            int i = ERR_get_error();
            printf("Ret: %d, ERRLINE=%ld: %s\n", ret, err_line,
                  ERR_error_string(i ,NULL));

            QMessageBox::warning(this, XCA_TITLE,
                  tr("Advanced Settings Error: ") +
                  ERR_error_string(i ,NULL), tr("OK"));
            BIO_free(bio);
            return elist;
      }

      if (ext_ctx.subject_cert) {
            sk = &ext_ctx.subject_cert->cert_info->extensions;
            start = *sk ? sk_X509_EXTENSION_num(*sk) : 0;
      } else {
            sk = &sk_tmp;
            start = 0;
      }

      X509V3_set_nconf(&ext_ctx, conf);
      X509V3_EXT_add_nconf_sk(conf, &ext_ctx, ext_name, sk);
      elist.setStack(*sk, start);
      if (sk == &sk_tmp)
            sk_X509_EXTENSION_pop_free(sk_tmp, X509_EXTENSION_free);
      X509V3_set_nconf(&ext_ctx, NULL);
      NCONF_free(conf);
      BIO_free(bio);
      return elist;
}

extList NewX509::getGuiExt()
{
      extList ne;

      ne << getBasicConstraints();
      ne << getSubKeyIdent();
      ne << getAuthKeyIdent();
      ne << getKeyUsage();
      ne << getEkeyUsage();
      ne << getSubAltName();
      ne << getIssAltName();
      ne << getCrlDist();
      ne << getAuthInfAcc();
      return ne;
}

extList NewX509::getAllExt()
{
      extList ne;
      ne = getGuiExt();
      ne += getAdvanced();
      ne += getNetscapeExt();
      return ne;
}

extList NewX509::getNetscapeExt()
{
      QString certTypeList[] = {
            "client", "server",  "email", "objsign",
            "sslCA",  "emailCA", "objCA" };


      QStringList cont;
      x509v3ext ext;
      extList el;

      int rows = nsCertType->count();
      for (int i=0; i<rows; i++) {
            if (nsCertType->isItemSelected(nsCertType->item(i))) {
                  cont <<  certTypeList[i];
            }
      }

      el << ext.create(NID_netscape_cert_type, cont.join(", "), &ext_ctx);
      el << ext.create(NID_netscape_base_url, nsBaseUrl->text(), &ext_ctx);
      el << ext.create(NID_netscape_revocation_url, nsRevocationUrl->text(), &ext_ctx);
      el << ext.create(NID_netscape_ca_revocation_url, nsCARevocationUrl->text(), &ext_ctx);
      el << ext.create(NID_netscape_renewal_url, nsRenewalUrl->text(), &ext_ctx);
      el << ext.create(NID_netscape_ca_policy_url, nsCaPolicyUrl->text(), &ext_ctx);
      el << ext.create(NID_netscape_ssl_server_name, nsSslServerName->text(), &ext_ctx);
      el << ext.create(NID_netscape_comment, nsComment->text(), &ext_ctx);
      return el;
}

void NewX509::initCtx(pki_x509 *subj, pki_x509 *iss, pki_x509req *req)
{
      X509 *s = NULL, *s1 = NULL;
      X509_REQ *r = NULL;

      if (subj) s1 = subj->getCert();
      if (iss) s = iss->getCert();
      if (req) r = req->getReq();

      X509V3_set_ctx(&ext_ctx, s, s1, r, NULL, 0);
}

int NewX509::checkExtDuplicates()
{
      int i, start, cnt, n1, n;
      x509v3ext e;
      STACK_OF(X509_EXTENSION) *sk;
      extList el_dup, el;
      QString olist;

      if (ext_ctx.subject_cert) {
            sk = ext_ctx.subject_cert->cert_info->extensions;
      } else
            return 0;

      el.setStack(sk, 0);
      if (fromReqCB->isChecked() && copyReqExtCB->isChecked()) {
            el += getSelectedReq()->getV3ext();
      }

      cnt = el.size();
      for (start=0; start < cnt; start++) {
            n1 = el[start].nid();
            for (i = start+1; i<cnt; i++) {
                  e = el[i];
                  n = e.nid();
                  if (n1 == n) {
                        // DUPLICATE
                        if (el_dup.idxByNid(n1) ==-1)
                              el_dup << e;

                  }
            }
        }
      if (el_dup.size() <= 0)
            return 0;

      tabWidget->setCurrentIndex(tabWidget->count() -1);
      if (!nconf_data->isReadOnly()) {
            on_adv_validate_clicked();
      }

      olist = "<h2><center><font color=\"red\">Error:</font> "
            "duplicate extensions:</center></h2><p><ul>\n";
      for(int i = 0; i< el_dup.size(); i++) {
            olist += "<li>" + el_dup[i].getObject() + "</li>\n";
      }
      olist += "</ul>\n<hr>\n";
      olist += valid_htmltext;
      nconf_data->document()->setHtml(olist);
      return el_dup.size();
}

void NewX509::setExt(const x509v3ext &ext)
{
      switch (ext.nid()) {
            case NID_basic_constraints:
                  bcCritical->setChecked(ext.getCritical());
      }
}


Generated by  Doxygen 1.6.0   Back to index