Support importing existing OpenVPN TLS Auth keys

The TA-Key is the property of a CA.
This commit is contained in:
Christian Hohnstaedt 2024-04-10 20:41:09 +02:00
parent 68b14617cc
commit e3c2c40f1e
6 changed files with 99 additions and 7 deletions

View File

@ -152,6 +152,14 @@ load_db::load_db()
caption = QObject::tr("Open XCA Database");
}
/* OpenVPN TA key */
load_takey::load_takey()
:load_base()
{
filter = QObject::tr("OpenVPN tls-auth key ( *.key );;") + filter;
caption = QObject::tr("Import OpenVPN tls-auth key");
}
/* Shared library */
load_pkcs11::load_pkcs11()
:load_base()

View File

@ -79,6 +79,12 @@ class load_db: public load_base
load_db();
};
class load_takey: public load_base
{
public:
load_takey();
};
class load_pkcs11: public load_base
{
public:

View File

@ -276,6 +276,9 @@ pki_x509 *pki_x509::getBySerial(const a1int &a) const
return NULL;
}
#define D5 "-----"
#define OVPN_TA_KEY "OpenVPN Static key V1"
QString pki_x509::getTaKey()
{
XSqlQuery q;
@ -304,14 +307,69 @@ QString pki_x509::getTaKey()
qDebug() << "Generated TA key" << this << b.size() << QString::fromLatin1(b.toHex()).left(6);
}
TransCommit();
QString takey("-----BEGIN OpenVPN Static key V1-----\n");
QString takey(D5 "BEGIN " OVPN_TA_KEY D5 "\n");
QString hex(QString::fromLatin1(b.toHex()));
for (int i=0; i<16; i++)
takey += hex.mid(32*i, 32) + "\n";
takey += "-----END OpenVPN Static key V1-----\n";
takey += D5 "END " OVPN_TA_KEY D5 "\n";
return takey;
}
bool pki_x509::importTaKey(const QByteArray &takey)
{
int start = takey.indexOf(D5 "BEGIN " OVPN_TA_KEY D5);
int end = takey.indexOf(D5 "END " OVPN_TA_KEY D5);
QByteArray data, existing_takey;
bool existed= false;
if (start >= 0 && end > 0 && start < end) {
start += sizeof D5 "BEGIN " OVPN_TA_KEY D5;
data = QByteArray::fromHex(takey.mid(start, end-start));
qDebug() << "TAKEY content" << start << end << data.size();
}
if (data.size() != 2048/8) {
XCA_ERROR(tr("Invalid OpenVPN tls-auth key"));
return false;
}
XSqlQuery q;
Transaction;
if (!TransBegin())
return false;
SQL_PREPARE(q, "SELECT value FROM takeys WHERE item = ?");
q.bindValue(0, sqlItemId);
q.exec();
if (q.next()) {
existed = true;
existing_takey = QByteArray::fromBase64(q.value(0).toByteArray());
qDebug() << "Existing TA key" << this << existing_takey.size()
<< QString::fromLatin1(existing_takey.toHex()).left(6);
}
if (existing_takey != data) {
if (existed)
SQL_PREPARE(q, "UPDATE takeys SET value = ? WHERE item = ?");
else
SQL_PREPARE(q, "INSERT INTO takeys (item, value) VALUES ( ?, ? )");
q.bindValue(0, sqlItemId);
q.bindValue(1, data.toBase64());
q.exec();
}
TransCommit();
QSqlError e = q.lastError();
if (e.isValid()) {
XCA_ERROR(tr("Failed to import tls-auth key"));
return false;
} else if (existing_takey == data) {
XCA_INFO(tr("Same tls-auth key already stored for this CA"));
} else if (existing_takey.isEmpty()) {
XCA_INFO(tr("New tls-auth key successfully imported"));
} else {
XCA_INFO(tr("Existing tls-auth key successfully replaced"));
}
return true;
}
a1int pki_x509::hashInfo(const EVP_MD *md) const
{
unsigned char digest[EVP_MAX_MD_SIZE];

View File

@ -164,6 +164,7 @@ class pki_x509 : public pki_x509super
QStringList icsVEVENT() const;
QStringList icsVEVENT_ca() const;
QString getTaKey();
bool importTaKey(const QByteArray &takey);
};
Q_DECLARE_METATYPE(pki_x509 *);

View File

@ -19,6 +19,7 @@
#include <QAbstractItemModel>
#include <QAbstractItemView>
#include <QFileDialog>
#include <QMenu>
void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
@ -27,7 +28,6 @@ void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
QMenu *subCa;
bool parentCanSign, multi, hasScard, sameParent,
allRevoked, allUnrevoked;
pki_key *privkey;
X509SuperTreeView::fillContextMenu(menu, subExport, index, indexes);
@ -35,13 +35,12 @@ void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
menu->addAction(tr("Import from PKCS#7"), this, SLOT(loadPKCS7()));
pki_x509 *cert = db_base::fromIndex<pki_x509>(index);
pki_x509 *parent;
if (indexes.size() == 0 || !cert)
return;
privkey = cert->getRefKey();
parent = cert->getSigner();
pki_key *privkey = cert->getRefKey();
pki_x509 *parent = cert->getSigner();
parentCanSign = parent && parent->canSign() && (parent != cert);
hasScard = pkcs11::libraries.loaded();
@ -79,8 +78,11 @@ void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
subCa->addAction(tr("Properties"), this, SLOT(caProperties()));
subCa->addAction(tr("Generate CRL"), this, SLOT(genCrl()));
subCa->addAction(tr("Manage revocations"), this,
SLOT(manageRevocations()));
SLOT(manageRevocations()));
subCa->setEnabled(cert->canSign());
menu->addAction(tr("Import OpenVPN tls-auth key"), this,
SLOT(loadTaKey()))->setEnabled(cert->isCA());
}
if (parent == cert && parent->canSign())
menu->addAction(tr("Renewal"), this, SLOT(certRenewal()));
@ -125,6 +127,22 @@ void CertTreeView::loadPKCS7()
load_default(&l);
}
void CertTreeView::loadTaKey()
{
pki_x509 *ca = db_base::fromIndex<pki_x509>(currentIndex());
if (!ca || !ca->isCA())
return;
load_takey l;
QString fname = QFileDialog::getOpenFileName(this, l.caption,
getHomeDir(), l.filter);
if (fname.isEmpty())
return;
XFile f(fname);
f.open_read();
ca->importTaKey(f.read(4096));
}
void CertTreeView::genCrl()
{
pki_x509 *ca = db_base::fromIndex<pki_x509>(currentIndex());

View File

@ -42,5 +42,6 @@ class CertTreeView: public X509SuperTreeView
void revoke();
void unRevoke();
void load();
void loadTaKey();
};
#endif