diff --git a/lib/pk11_attribute.h b/lib/pk11_attribute.h index f33ff7ab..288e1def 100644 --- a/lib/pk11_attribute.h +++ b/lib/pk11_attribute.h @@ -14,7 +14,8 @@ #include "opensc-pkcs11.h" #include "exception.h" -#define UTF8QSTRING(x,s) QString::fromUtf8((const char*)(x), s).trimmed(); +#define UTF8QSTRING(x,s) QString::fromUtf8((const char*)(x), s).trimmed() +#define ASCIIQSTRING(x,s) QString::fromAscii((const char*)(x), s).trimmed() class pk11_attlist; diff --git a/lib/pkcs11.cpp b/lib/pkcs11.cpp index 27ddd746..81a897b3 100644 --- a/lib/pkcs11.cpp +++ b/lib/pkcs11.cpp @@ -176,7 +176,7 @@ QString pkcs11::tokenLogin(QString name, bool so, bool force) if (force || need_login) { if (!need_login) logout(); - if (protAuthPath()) { + if (tokenInfo().protAuthPath()) { pin = NULL; pinlen = 0; } else { @@ -201,9 +201,9 @@ bool pkcs11::selectToken(unsigned long *slot, QWidget *w) } QStringList slotnames; for (int i=0; iC_GetInfo(&info); + if (rv != CKR_OK) { + pk11error("C_GetInfo", rv); + } + + return QString( + "Cryptoki version: %1.%2\n" + "Manufacturer: %3\n" + "Library: %4 (%5.%6)\n"). + arg(info.cryptokiVersion.major).arg(info.cryptokiVersion.minor). + arg(UTF8QSTRING(info.manufacturerID, 32)). + arg(UTF8QSTRING(info.libraryDescription, 32)). + arg(info.libraryVersion.major).arg(info.libraryVersion.minor); +} + +tkInfo pkcs11::tokenInfo() { return tokenInfo(slot_id); } -bool pkcs11::protAuthPath(CK_SLOT_ID slot) -{ - CK_TOKEN_INFO token_info; - CK_RV rv; - - rv = p11->C_GetTokenInfo(slot, &token_info); - if (rv != CKR_OK) { - pk11error("C_GetTokenInfo", rv); - } - return !!(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH); -} - -bool pkcs11::protAuthPath() -{ - return protAuthPath(slot_id); -} - void pkcs11::loadAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object) { attribute.load(session, object); diff --git a/lib/pkcs11.h b/lib/pkcs11.h index 0265e2b0..9305e041 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -9,6 +9,45 @@ #include "pk11_attribute.h" +class tkInfo +{ +private: + CK_TOKEN_INFO token_info; +public: + tkInfo(const CK_TOKEN_INFO *ti) + { + set(ti); + } + tkInfo(const tkInfo &tk) + { + set(&tk.token_info); + } + void set(const CK_TOKEN_INFO *ti) + { + memcpy(&token_info, ti, sizeof(token_info)); + } + QString label() const + { + return UTF8QSTRING(token_info.label, 32); + } + QString manufacturerID() const + { + return UTF8QSTRING(token_info.manufacturerID, 32); + } + QString model() const + { + return UTF8QSTRING(token_info.model, 16); + } + QString serial() const + { + return ASCIIQSTRING(token_info.serialNumber, 16); + } + bool protAuthPath() const + { + return !!(token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH); + } +}; + class pkcs11 { friend class pk11_attribute; @@ -23,18 +62,18 @@ class pkcs11 CK_SLOT_ID slot_id; CK_OBJECT_HANDLE object; public: - void init_pkcs11(); static void pk11error(QString fmt, int r); - static bool loaded() { return !!p11; }; + static bool loaded() + { + return !!p11; + }; pkcs11(); ~pkcs11(); static bool load_lib(QString file, bool silent); - QStringList tokenInfo(CK_SLOT_ID slot); - QStringList tokenInfo(); - bool protAuthPath(CK_SLOT_ID slot); - bool protAuthPath(); + tkInfo tokenInfo(CK_SLOT_ID slot); + tkInfo tokenInfo(); void startSession(unsigned long slot, bool rw = false); QList getSlotList(); @@ -61,6 +100,7 @@ class pkcs11 void initToken(unsigned long slot, unsigned char *pin, int pinlen, QString label); bool selectToken(unsigned long *slot, QWidget *w); + QString driverInfo(); }; #endif diff --git a/lib/pki_evp.cpp b/lib/pki_evp.cpp index cfef7a07..9fd603ad 100644 --- a/lib/pki_evp.cpp +++ b/lib/pki_evp.cpp @@ -71,7 +71,8 @@ static void incProgress(int, int, void *progress) QString pki_evp::removeTypeFromIntName(QString n) { - if (n.right(1) != ")" ) return n; + if (n.right(1) != ")" ) + return n; n.truncate(n.length() - 6); return n; } @@ -644,14 +645,6 @@ void pki_evp::writeKey(const QString fname, const EVP_CIPHER *enc, fclose(fp); } -QString pki_evp::length() -{ - if (key->type == EVP_PKEY_DSA && key->pkey.dsa->p == NULL) { - return QString("???"); - } - return QString("%1 bit").arg(EVP_PKEY_bits(key)); -} - bool pki_evp::isPubKey() const { if (encKey_len == 0 || encKey == NULL) { diff --git a/lib/pki_evp.h b/lib/pki_evp.h index 0fe92803..3753b63a 100644 --- a/lib/pki_evp.h +++ b/lib/pki_evp.h @@ -64,7 +64,6 @@ class pki_evp: public pki_key void fromData(const unsigned char *p, db_header_t *head); void oldFromData(unsigned char *p, int size); unsigned char *toData(int *size); - QString length(); void writeKey(const QString fname, const EVP_CIPHER *enc, pem_password_cb *cb, bool pem); void writePKCS8(const QString fname, const EVP_CIPHER *enc, diff --git a/lib/pki_key.cpp b/lib/pki_key.cpp index 21a945f3..5f9d43aa 100644 --- a/lib/pki_key.cpp +++ b/lib/pki_key.cpp @@ -44,6 +44,14 @@ pki_key::~pki_key() EVP_PKEY_free(key); } +QString pki_key::length() +{ + if (key->type == EVP_PKEY_DSA && key->pkey.dsa->p == NULL) { + return QString("???"); + } + return QString("%1 bit").arg(EVP_PKEY_bits(key)); +} + QString pki_key::getTypeString() { QString type; diff --git a/lib/pki_key.h b/lib/pki_key.h index 9ffffba1..ab2b890d 100644 --- a/lib/pki_key.h +++ b/lib/pki_key.h @@ -39,13 +39,12 @@ class pki_key: public pki_base virtual bool isPubKey() const { return true; }; virtual const EVP_MD *getDefaultMD() { return NULL; }; virtual bool isToken(); - virtual QString length() { return tr("Unknown"); }; virtual QString getTypeString(void); virtual QString getIntNameWithType(void); virtual QList possibleHashNids() { return QList(); }; virtual QString getFriendlyClassName(); - + virtual QString length(); void writePublic(const QString fname, bool pem); bool compare(pki_base *ref); diff --git a/lib/pki_scard.cpp b/lib/pki_scard.cpp index 3e457a18..34adf03b 100644 --- a/lib/pki_scard.cpp +++ b/lib/pki_scard.cpp @@ -84,6 +84,7 @@ bool pki_scard::init_p11engine(QString file, bool silent) if (!pkcs11::load_lib(file, silent)) return false; log += "Successfully loaded PKCS#11 library: " +file +"\n"; + #ifdef WIN32 engine_path = ".\\" ENGINE_LIB; #else @@ -101,6 +102,10 @@ bool pki_scard::init_p11engine(QString file, bool silent) XCA_ENGINE_cmd("VERBOSE", NULL); ENGINE_init(e); + + pkcs11 p11; + log += p11.driverInfo(); + if (!silent) { openssl_error(log); } else { @@ -115,12 +120,12 @@ void pki_scard::init(void) { class_name = "pki_scard"; ownPass = ptPin; - dataVersion = 1; + dataVersion = 2; pkiType = smartCard; cols = 5; card_serial = card_manufacturer = card_label = ""; - bit_length = slot_label = ""; + card_model = slot_label = ""; } pki_scard::pki_scard(const QString name) @@ -212,10 +217,11 @@ EVP_PKEY *pki_scard::load_pubkey(pkcs11 &p11, CK_OBJECT_HANDLE object) const void pki_scard::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object) { - QStringList sl = p11.tokenInfo(); - card_label = sl[0]; - card_manufacturer = sl[1]; - card_serial = sl[2]; + tkInfo ti = p11.tokenInfo(); + card_label = ti.label(); + card_manufacturer = ti.manufacturerID(); + card_serial = ti.serial(); + card_model = ti.model(); pk11_attr_data id(CKA_ID); p11.loadAttribute(id, object); @@ -255,9 +261,8 @@ void pki_scard::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object) if (key) EVP_PKEY_free(key); key = pkey; - bit_length.setNum(EVP_PKEY_bits(pkey)); } - setIntName(card_label + " (" + slot_label + ")"); + setIntName(slot_label); openssl_error(); } @@ -287,7 +292,7 @@ void pki_scard::deleteFromToken() pkcs11 p11; p11.startSession(slot, true); - if (p11.tokenLogin(getIntName(), false).isNull()) + if (p11.tokenLogin(card_label, false).isNull()) return; pk11_attlist attrs(pk11_attr_ulong(CKA_CLASS, CKO_PUBLIC_KEY)); @@ -341,7 +346,7 @@ void pki_scard::store_token(unsigned int slot, EVP_PKEY *pkey) pub_atts << pk11_attr_bool(CKA_TOKEN, true) << - pk11_attr_data(CKA_LABEL, desc.toUtf8()) << + pk11_attr_data(CKA_LABEL, getIntName().toUtf8()) << new_id << pk11_attr_data(CKA_PUBLIC_EXPONENT, rsakey->e, false) << pk11_attr_bool(CKA_ENCRYPT, true) << @@ -362,9 +367,8 @@ void pki_scard::store_token(unsigned int slot, EVP_PKEY *pkey) pk11_attr_bool(CKA_DECRYPT, true) << pk11_attr_bool(CKA_SIGN, true); - QStringList sl = p11.tokenInfo(); - setIntName(sl[0] + " (" + desc + ")"); - if (p11.tokenLogin(getIntName(), false).isNull()) + tkInfo ti = p11.tokenInfo(); + if (p11.tokenLogin(ti.label(), false).isNull()) return; p11.createObject(pub_atts); @@ -445,18 +449,20 @@ bool pki_scard::prepare_card(unsigned long *slot, bool verifyPubkey) const p11_slots = p11.getSlotList(); for (i=0; isetValue(bar->value()+1); - pk11_attr_data id = p11.generateRSAKey(name, size); + pk11_attr_data id = p11.generateRSAKey(getIntName(), size); atts << pk11_attr_ulong(CKA_CLASS, CKO_PUBLIC_KEY) << id; QList objects = p11.objectList(atts); @@ -529,7 +533,7 @@ unsigned char *pki_scard::toData(int *size) int i; s = card_serial.length() + card_manufacturer.length() + - card_label.length() + bit_length.length() + + card_label.length() + card_model.length() + slot_label.length() + object_id.length() + 7 *sizeof(char) + i2d_PUBKEY(key, NULL) + (mech_list.count() + 1) * sizeof(uint32_t); @@ -543,7 +547,7 @@ unsigned char *pki_scard::toData(int *size) db::stringToData(&p1, card_manufacturer); db::stringToData(&p1, card_label); db::stringToData(&p1, slot_label); - db::stringToData(&p1, bit_length); + db::stringToData(&p1, card_model); db::stringToData(&p1, object_id); db::intToData(&p1, mech_list.count()); for (i=0; isetPixmap(*MainWindow::scardImg); pki_scard *card = (pki_scard *)key; cardBox->setTitle(tr("Token") +" [" +card->getCardLabel() +"]"); - cardManufacturer->setText(card->getManufacturer()); + cardManufacturer->setText(card->getManufacturer() + " " + + card->getModel()); cardSerial->setText(card->getSerial()); keyPrivEx->setText(tr("Security token ID:%1").arg(card->getId())); keyBox->setTitle(tr("Key") + " [" + card->getLabel() + "]"); diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 33e1d31a..a38f433d 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -375,9 +375,9 @@ void MainWindow::initToken() if (!p11.selectToken(&slot, this)) return; - QStringList info = p11.tokenInfo(slot); + tkInfo ti = p11.tokenInfo(slot); QString slotname = QString("%1 (#%2)"). - arg(info[0]).arg(info[2]); + arg(ti.label()).arg(ti.serial()); pass_info p(XCA_TITLE, tr("Please enter the SO PIN (PUK) of the token '%1'"). diff --git a/widgets/NewKey.cpp b/widgets/NewKey.cpp index 14448ca3..d9bc8ab0 100644 --- a/widgets/NewKey.cpp +++ b/widgets/NewKey.cpp @@ -42,10 +42,10 @@ class keyListItem slot = nslot; CK_MECHANISM_INFO mechinfo; p11->mechanismInfo(slot, m, &mechinfo); - QStringList info = p11->tokenInfo(slot); + tkInfo ti = p11->tokenInfo(slot); tl = typeList; //idx of EVP_PKEY_RSA printname = QString("%1 #%2 (%3 Key of %4 - %5 bits)"). - arg(info[0]).arg(info[2]). + arg(ti.label()).arg(ti.serial()). arg(tl->name). arg(mechinfo.ulMinKeySize). arg(mechinfo.ulMaxKeySize); diff --git a/widgets/Options.cpp b/widgets/Options.cpp index d7ad1037..5aa21f55 100644 --- a/widgets/Options.cpp +++ b/widgets/Options.cpp @@ -90,12 +90,20 @@ void Options::on_tryLoadButton_clicked(void) { try { QString lib = pkcs11path->text(); +#ifdef WIN32 + pkcs11::load_lib(lib, false); +#else pki_scard::init_p11engine(lib, false); - pkcs11 p11; - p11.getSlotList(); +#endif + QString info; + if (pkcs11::loaded()) { + pkcs11 p11; + info = p11.driverInfo(); + } if (!lib.isEmpty()) { QMessageBox::information(this, XCA_TITLE, - tr("Successfully loaded PKCS#11 library: ") + lib); + tr("Successfully loaded PKCS#11 library: %1\n"). + arg(lib) + info); } } catch (errorEx &err) { mw->Error(err);