mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
QRegExp is deprecated and needs special library in Qt6: core5compat Replace by QRegularExpression which has been introduced by Qt5
225 lines
5.4 KiB
C++
225 lines
5.4 KiB
C++
/* vi: set sw=4 ts=4:
|
|
*
|
|
* Copyright (C) 2001 - 2020 Christian Hohnstaedt.
|
|
*
|
|
* All rights reserved.
|
|
*/
|
|
|
|
|
|
#include "NewKey.h"
|
|
#include "MainWindow.h"
|
|
#include "Help.h"
|
|
#include "lib/pki_evp.h"
|
|
#include "lib/pkcs11.h"
|
|
#include "distname.h"
|
|
#include "clicklabel.h"
|
|
#include "ItemCombo.h"
|
|
#include <QLabel>
|
|
#include <QPushButton>
|
|
#include <QLineEdit>
|
|
#include <QStringList>
|
|
|
|
class keyListItem
|
|
{
|
|
public:
|
|
bool card;
|
|
keytype ktype;
|
|
QString printname;
|
|
slotid slot;
|
|
unsigned minKeySize;
|
|
unsigned maxKeySize;
|
|
unsigned long ec_flags;
|
|
|
|
keyListItem(pkcs11 *p11, slotid nslot, CK_MECHANISM_TYPE m)
|
|
{
|
|
slot = nslot;
|
|
CK_MECHANISM_INFO mechinfo;
|
|
p11->mechanismInfo(slot, m, &mechinfo);
|
|
|
|
minKeySize = mechinfo.ulMinKeySize;
|
|
maxKeySize = mechinfo.ulMaxKeySize;
|
|
if (maxKeySize == 0) {
|
|
/* Fallback for libraries not
|
|
* filling in the maxKeySize */
|
|
maxKeySize = INT_MAX;
|
|
}
|
|
ktype = keytype::byMech(m);
|
|
tkInfo ti = p11->tokenInfo(slot);
|
|
#ifndef OPENSSL_NO_EC
|
|
if (m == CKM_EC_KEY_PAIR_GEN) {
|
|
CK_MECHANISM_INFO info;
|
|
p11->mechanismInfo(slot, m, &info);
|
|
ec_flags = info.flags & (CKF_EC_F_P | CKF_EC_F_2M);
|
|
if (!ec_flags) {
|
|
/* Fallback: Assume to support both for
|
|
* libraries leaving this flag empty
|
|
*/
|
|
ec_flags = CKF_EC_F_P | CKF_EC_F_2M;
|
|
}
|
|
}
|
|
#endif
|
|
printname = QString("%1 #%2 (%3 Key of %4 - %5 bits)").
|
|
arg(ti.label()).arg(ti.serial()).
|
|
arg(ktype.name).
|
|
arg(minKeySize).
|
|
arg(maxKeySize);
|
|
card = true;
|
|
}
|
|
keyListItem(const keytype &t = keytype())
|
|
: ktype(t)
|
|
{
|
|
printname = ktype.name;
|
|
card = false;
|
|
slot = slotid();
|
|
minKeySize = 0;
|
|
maxKeySize = INT_MAX;
|
|
ec_flags = 0;
|
|
}
|
|
int type() const
|
|
{
|
|
return ktype.type;
|
|
}
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(keyListItem);
|
|
|
|
NewKey::NewKey(QWidget *parent, const QString &name)
|
|
:QDialog(parent ? parent : mainwin)
|
|
{
|
|
static const QList<int> sizeList = { 1024, 2048, 4096, 8192 };
|
|
slotidList p11_slots;
|
|
QList<keyListItem> keytypes;
|
|
|
|
setupUi(this);
|
|
setWindowTitle(XCA_TITLE);
|
|
image->setPixmap(QPixmap(":keyImg"));
|
|
mainwin->helpdlg->register_ctxhelp_button(this, "keygen");
|
|
|
|
if (!name.isEmpty())
|
|
keyDesc->setText(name);
|
|
|
|
keyLength->setEditable(true);
|
|
foreach (int size, sizeList)
|
|
keyLength->addItem(QString("%1 bit").arg(size));
|
|
|
|
foreach (const keytype t, keytype::types())
|
|
keytypes << keyListItem(t);
|
|
|
|
updateCurves();
|
|
keyLength->setEditText(QString("%1 bit").arg(keyjob::defaultjob.size));
|
|
keyDesc->setFocus();
|
|
if (pkcs11::libraries.loaded()) try {
|
|
pkcs11 p11;
|
|
p11_slots = p11.getSlotList();
|
|
|
|
foreach(slotid slot, p11_slots) {
|
|
QList<CK_MECHANISM_TYPE> ml = p11.mechanismList(slot);
|
|
foreach(keytype t, keytype::types())
|
|
if (ml.contains(t.mech))
|
|
keytypes << keyListItem(&p11, slot,
|
|
t.mech);
|
|
}
|
|
} catch (errorEx &) {
|
|
p11_slots.clear();
|
|
}
|
|
for (int i=0; i<keytypes.count(); i++) {
|
|
QVariant q;
|
|
q.setValue(keytypes[i]);
|
|
keyType->addItem(keytypes[i].printname, q);
|
|
if (!keytypes[i].card &&
|
|
keytypes[i].type() == keyjob::defaultjob.ktype.type)
|
|
{
|
|
keyType->setCurrentIndex(i);
|
|
}
|
|
}
|
|
buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
|
|
}
|
|
|
|
void NewKey::addCurveBoxCurves(const QList<builtin_curve> &curves)
|
|
{
|
|
foreach(builtin_curve curve, curves) {
|
|
QString sn(OBJ_nid2sn(curve.nid));
|
|
QString p, comment = curve.comment;
|
|
|
|
if (comment.isEmpty())
|
|
comment = "---";
|
|
p = sn + ": " + comment;
|
|
curveBox->addItem(sn + ": " + comment, curve.nid);
|
|
}
|
|
}
|
|
|
|
void NewKey::updateCurves(unsigned min, unsigned max, unsigned long ec_flags)
|
|
{
|
|
#ifndef OPENSSL_NO_EC
|
|
QList<builtin_curve> curve_rfc5480, curve_x962, curve_other;
|
|
|
|
foreach(builtin_curve curve, builtinCurves) {
|
|
const char *sn = OBJ_nid2sn(curve.nid);
|
|
|
|
if (!sn || curve.order_size < min || curve.order_size > max)
|
|
continue;
|
|
if (ec_flags && (curve.type & ec_flags) == 0)
|
|
continue;
|
|
switch (curve.flags) {
|
|
case CURVE_RFC5480: curve_rfc5480 << curve; break;
|
|
case CURVE_X962: curve_x962 << curve; break;
|
|
case CURVE_OTHER: curve_other << curve; break;
|
|
}
|
|
}
|
|
curveBox->clear();
|
|
addCurveBoxCurves(curve_rfc5480);
|
|
curveBox->insertSeparator(curveBox->count());
|
|
addCurveBoxCurves(curve_x962);
|
|
curveBox->insertSeparator(curveBox->count());
|
|
addCurveBoxCurves(curve_other);
|
|
|
|
int default_index = curveBox->findData(
|
|
QVariant(keyjob::defaultjob.ec_nid));
|
|
curveBox->setCurrentIndex(default_index == -1 ? 0 : default_index);
|
|
#else
|
|
(void)min; (void)max; (void)ec_flags;
|
|
#endif
|
|
}
|
|
|
|
void NewKey::on_keyType_currentIndexChanged(int idx)
|
|
{
|
|
keyListItem ki = keyType->itemData(idx).value<keyListItem>();
|
|
|
|
curveBox->setVisible(ki.ktype.curve);
|
|
curveLabel->setVisible(ki.ktype.curve);
|
|
keySizeLabel->setVisible(ki.ktype.length);
|
|
keyLength->setVisible(ki.ktype.length);
|
|
|
|
rememberDefault->setEnabled(!ki.card);
|
|
if (ki.ktype.curve && ki.card) {
|
|
updateCurves(ki.minKeySize, ki.maxKeySize, ki.ec_flags);
|
|
}
|
|
}
|
|
|
|
keyjob NewKey::getKeyJob() const
|
|
{
|
|
keyjob job;
|
|
keyListItem selected = keyType->itemData(keyType->currentIndex())
|
|
.value<keyListItem>();
|
|
job.ktype = selected.ktype;
|
|
if (job.isEC()) {
|
|
int idx = curveBox->currentIndex();
|
|
job.ec_nid = curveBox->itemData(idx).toInt();
|
|
} else {
|
|
QString size = keyLength->currentText();
|
|
size.replace(QRegularExpression("[^0-9]"), "");
|
|
job.size = size.toInt();
|
|
}
|
|
job.slot = selected.slot;
|
|
return job;
|
|
}
|
|
|
|
void NewKey::accept()
|
|
{
|
|
if (rememberDefault->isChecked()) {
|
|
keyjob::defaultjob = getKeyJob();
|
|
Settings["defaultkey"] = keyjob::defaultjob.toString();
|
|
}
|
|
QDialog::accept();
|
|
}
|