From 5f4308245c2dc802d9273a70649cbbe64f4b5b8a Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Sun, 29 Sep 2024 01:18:01 +0200 Subject: [PATCH] Close #239: Check existing Name Constraints This check is performed before the certificate is issued and signed. Like all the other checks regarding validity, extensions and other things. Issuing certificates that violate the Name Constraints of any CA in the chain is still be possible. But there will be a warning now with the name of the affected CA-Certificate and the violated constraint. The Issuer can then decide whether to issue the certificate or not. --- lib/pki_x509.cpp | 27 ++++++++++++++++++++++++++- lib/pki_x509.h | 1 + widgets/NewX509.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index 71c48e14..35baedfb 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -18,8 +18,9 @@ #include "pass_info.h" #include -#include #include +#include +#include pki_x509::pki_x509(X509 *c) :pki_x509super(), cert(c) @@ -1242,3 +1243,27 @@ QList pki_x509::purposes() const } return purposes; } + +int pki_x509::name_constraint_check(pki_x509 *issuer) const +{ + int rc = X509_V_OK; + + if (!issuer || issuer == this) + return rc; + + x509v3ext e = issuer->getExtByNid(NID_name_constraints); + if (e.nid() != NID_name_constraints) + return rc; + + NAME_CONSTRAINTS *nc = (NAME_CONSTRAINTS *)e.d2i(); + Q_CHECK_PTR(nc); + rc = NAME_CONSTRAINTS_check(cert, nc); +#ifndef LIBRESSL_VERSION_NUMBER + if (!isCA() && rc == X509_V_OK) + rc = NAME_CONSTRAINTS_check_CN(cert, nc); +#endif + NAME_CONSTRAINTS_free(nc); + pki_openssl_error(); + qDebug() << getIntName() << issuer->getIntName() << get_ossl_verify_error(rc); + return rc; +} diff --git a/lib/pki_x509.h b/lib/pki_x509.h index 1aa8d384..24f35d4b 100644 --- a/lib/pki_x509.h +++ b/lib/pki_x509.h @@ -170,6 +170,7 @@ class pki_x509 : public pki_x509super QList ossl_verify() const; bool check_ca() const; QList purposes() const; + int name_constraint_check(pki_x509 *issuer) const; }; Q_DECLARE_METATYPE(pki_x509 *); diff --git a/widgets/NewX509.cpp b/widgets/NewX509.cpp index e5ffb8fc..c0665f4a 100644 --- a/widgets/NewX509.cpp +++ b/widgets/NewX509.cpp @@ -36,6 +36,7 @@ #include "lib/db_temp.h" #include "lib/oid.h" #include "lib/func.h" +#include "lib/pki_evp.h" void NewX509::setupExplicitDN(NIDlist my_dn_nid = NIDlist()) { @@ -932,6 +933,8 @@ void NewX509::setupTmpCtx() ctx_cert->setIssuer(ctx_cert->getSubject()); } ctx_cert->setSerial(serial); + ctx_cert->setNotBefore(notBefore->getDate()); + ctx_cert->setNotAfter(notAfter->getDate()); initCtx(ctx_cert, signcert, req); } @@ -1476,6 +1479,40 @@ void NewX509::accept() break; } } + if (foreignSignRB->isChecked()) { + setupTmpCtx(); + // Update SAN and BC of ctx_cert + getBasicConstraints(); + getSubAltName(); + for (pki_x509 *crt = getSelectedSigner(), *oldcrt = nullptr; + crt && crt != oldcrt; + oldcrt = crt, crt = crt->getSigner()) + { + int rc = ctx_cert->name_constraint_check(crt); + qDebug() << ctx_cert->getIntName() << "Issuer" + << crt->getIntName()<< get_ossl_verify_error(rc); + if (rc == X509_V_OK) + continue; + gotoTab(2); + xcaWarningBox msg(this, tr("A name constraint of the issuer '%1' is violated: %2") + .arg(crt->getIntName()).arg(get_ossl_verify_error(rc))); + msg.setInformativeText(crt->getExtByNid(NID_name_constraints).getValue()); + msg.addButton(QMessageBox::Ok, tr("Edit extensions")); + msg.addButton(QMessageBox::Close, tr("Abort rollout")); + msg.addButton(QMessageBox::Apply, tr("Continue rollout")); + switch (msg.exec()) + { + case QMessageBox::Ok: + case QMessageBox::Cancel: + return; + case QMessageBox::Close: + reject(); + return; + case QMessageBox::Apply: + break; + } + } + } XcaDetail::accept(); }