/* vi: set sw=4 ts=4: * * Copyright (C) 2001 - 2010 Christian Hohnstaedt. * * All rights reserved. */ #include "NewKey.h" #include "MainWindow.h" #include "lib/pki_evp.h" #include "widgets/distname.h" #include "widgets/clicklabel.h" #include "lib/pkcs11.h" #include #include #include #include struct typelist { const char *name; int type; }; static const struct typelist typeList[] = { { "RSA", EVP_PKEY_RSA }, { "DSA", EVP_PKEY_DSA }, #ifndef OPENSSL_NO_EC { "EC", EVP_PKEY_EC }, #endif }; int NewKey::defaultType = EVP_PKEY_RSA; int NewKey::defaultEcNid = NID_undef; int NewKey::defaultSize = 2048; class keyListItem { protected: const struct typelist *tl; public: bool card; QString printname; slotid slot; keyListItem(pkcs11 *p11, slotid nslot, CK_MECHANISM_TYPE m) { // assert(m == CKM_RSA_PKCS_KEY_PAIR_GEN); slot = nslot; CK_MECHANISM_INFO mechinfo; p11->mechanismInfo(slot, m, &mechinfo); tkInfo ti = p11->tokenInfo(slot); tl = typeList; //idx of EVP_PKEY_RSA printname = QString("%1 #%2 (%3 Key of %4 - %5 bits)"). arg(ti.label()).arg(ti.serial()). arg(tl->name). arg(mechinfo.ulMinKeySize). arg(mechinfo.ulMaxKeySize); card = true; } keyListItem(const struct typelist *t=typeList) { tl = t; printname = QString(tl->name); card = false; slot = slotid(); } keyListItem(const keyListItem &k) { tl = k.tl; printname = k.printname; card = k.card; slot = k.slot; } int type() { return tl->type; } QString typeName() { return QString(tl->name); } }; Q_DECLARE_METATYPE(keyListItem); NewKey::NewKey(QWidget *parent, QString name) :QDialog(parent) { static const char* const sizeList[] = { "1024", "2048", "4096" }; size_t i; QStringList curve_x962, curve_other; slotidList p11_slots; QList keytypes; setupUi(this); setWindowTitle(tr(XCA_TITLE)); image->setPixmap(*MainWindow::keyImg); if (!name.isEmpty()) keyDesc->setText(name); keyLength->setEditable(true); for (i=0; i < ARRAY_SIZE(sizeList); i++ ) { keyLength->addItem(QString(sizeList[i]) + " bit"); } for (i=0; i < ARRAY_SIZE(typeList); i++ ) { keyListItem gk(typeList +i); keytypes << gk; } #ifndef OPENSSL_NO_EC QString ec_default; for (i = 0; iaddItems(curve_x962); curveBox->addItems(curve_other); curveBox->setCurrentIndex(curveBox->findText(ec_default)); if (curveBox->currentIndex() == -1) curveBox->setCurrentIndex(0); #endif keyLength->setEditText(QString::number(defaultSize) + " bit"); keyDesc->setFocus(); if (pkcs11::loaded()) try { pkcs11 p11; p11_slots = p11.getSlotList(); foreach(slotid slot, p11_slots) { QList ml = p11.mechanismList(slot); if (ml.contains(CKM_RSA_PKCS_KEY_PAIR_GEN)) { keyListItem tk(&p11, slot, CKM_RSA_PKCS_KEY_PAIR_GEN); keytypes << tk; } } } catch (errorEx &err) { p11_slots.clear(); } for (int i=0; iaddItem(keytypes[i].printname, q); if (!keytypes[i].card && keytypes[i].type() == defaultType) keyType->setCurrentIndex(i); } buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create")); } void NewKey::on_keyType_currentIndexChanged(int idx) { bool curve_enabled; curve_enabled = (typeList[idx].type == EVP_PKEY_EC); curveBox->setVisible(curve_enabled); curveLabel->setVisible(curve_enabled); keySizeLabel->setVisible(!curve_enabled); keyLength->setVisible(!curve_enabled); } static keyListItem currentKey(QComboBox *keyType) { QVariant q = keyType->itemData(keyType->currentIndex()); return q.value(); } int NewKey::getKeytype() { return currentKey(keyType).type(); } int NewKey::getKeysize() { if (getKeytype() == EVP_PKEY_EC) return -1; QString size = keyLength->currentText(); size.replace(QRegExp("[^0-9]"), ""); return size.toInt(); } int NewKey::getKeyCurve_nid() { if (getKeytype() != EVP_PKEY_EC) return -1; QString desc = curveBox->currentText(); desc.replace(QRegExp("^(X9.62) "), ""); desc.replace(QRegExp(":.*"), ""); return OBJ_sn2nid(CCHAR(desc)); } bool NewKey::isToken() { keyListItem k = currentKey(keyType); return k.card; } slotid NewKey::getKeyCardSlot() { keyListItem k = currentKey(keyType); return k.slot; } QString NewKey::getAsString() { keyListItem k = currentKey(keyType); QString data; if (k.card) return QString(); if (k.type() == EVP_PKEY_EC) { data = OBJ_obj2QString(OBJ_nid2obj(getKeyCurve_nid()), 1); } else { data = QString::number(getKeysize()); } return QString("%1:%2").arg(currentKey(keyType).typeName()).arg(data); } int NewKey::setDefault(QString def) { int type = -1, size = 0, nid = NID_undef; QStringList sl = def.split(':'); if (sl.size() != 2) return -1; for (unsigned i=0; i < ARRAY_SIZE(typeList); i++ ) { if (sl[0] == typeList[i].name) { type = typeList[i].type; } } if (type == -1) return -2; if (type == EVP_PKEY_EC) { nid = OBJ_txt2nid(sl[1].toAscii()); if (nid == NID_undef) return -3; defaultEcNid = nid; } else { size = sl[1].toInt(); if (size <= 0) return -4; defaultSize = size; } defaultType = type; return 0; }