From 1f93c8201090f3ab1c9fc9b0dc181a35cb441f55 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Fri, 6 Nov 2009 08:05:59 +0100 Subject: [PATCH] pkcs#11 fixes - support pkcs#11 library selection by file dialog - don't prompt for pin if CKF_PROTECTED_AUTHENTICATION_PATH untested, because of ENODEV on my desk --- lib/db_key.cpp | 2 + lib/load_obj.cpp | 14 +++++ lib/load_obj.h | 6 ++ lib/pkcs11.cpp | 17 ++++++ lib/pkcs11.h | 3 + lib/pki_scard.cpp | 55 +++++++++--------- ui/Options.ui | 137 ++++++++++++++++++++++---------------------- widgets/Options.cpp | 13 +++++ widgets/Options.h | 1 + 9 files changed, 154 insertions(+), 94 deletions(-) diff --git a/lib/db_key.cpp b/lib/db_key.cpp index 711e47ad..45a125d2 100644 --- a/lib/db_key.cpp +++ b/lib/db_key.cpp @@ -198,10 +198,12 @@ void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index) if (key->isScard() && pkcs11::loaded()) { menu->addAction(tr("Change PIN"), this, SLOT(changePin())); +#if 0 menu->addAction(tr("Init PIN with SO PIN (PUK)"), this, SLOT(initPin())); menu->addAction(tr("Change SO PIN (PUK)"), this, SLOT(changeSoPin())); +#endif } } menu->exec(e->globalPos()); diff --git a/lib/load_obj.cpp b/lib/load_obj.cpp index 48a903bd..fc012473 100644 --- a/lib/load_obj.cpp +++ b/lib/load_obj.cpp @@ -146,6 +146,20 @@ load_db::load_db() caption = QObject::tr("Open XCA Database"); } +/* Shared library */ +load_pkcs11::load_pkcs11() + :load_base() +{ +#ifdef WIN32 + filter = QObject::tr("PKCS#11 library ( *.dll );;") + filter; +#elif defined(Q_WS_MAC) + filter = QObject::tr("PKCS#11 library ( *.dylib );;") + filter; +#else + filter = QObject::tr("PKCS#11 library ( *.so );;") + filter; +#endif + caption = QObject::tr("Open PKCS#11 shared library"); +} + /* General PEM loader */ load_pem::load_pem() :load_base() diff --git a/lib/load_obj.h b/lib/load_obj.h index eef90d58..d4ffe95b 100644 --- a/lib/load_obj.h +++ b/lib/load_obj.h @@ -79,6 +79,12 @@ class load_db: public load_base load_db(); }; +class load_pkcs11: public load_base +{ + public: + load_pkcs11(); +}; + class load_pem: public load_base { public: diff --git a/lib/pkcs11.cpp b/lib/pkcs11.cpp index 81dd220c..05f7d137 100644 --- a/lib/pkcs11.cpp +++ b/lib/pkcs11.cpp @@ -165,6 +165,23 @@ QStringList 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 7742da86..2b2e38cb 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -33,6 +33,9 @@ class pkcs11 QStringList tokenInfo(CK_SLOT_ID slot); QStringList tokenInfo(); + bool protAuthPath(CK_SLOT_ID slot); + bool protAuthPath(); + void startSession(unsigned long slot, bool rw = false); CK_SLOT_ID *getSlotList(unsigned long *num_slots); void loadAttribute(pk11_attribute &attribute, diff --git a/lib/pki_scard.cpp b/lib/pki_scard.cpp index f097b731..0fad0f97 100644 --- a/lib/pki_scard.cpp +++ b/lib/pki_scard.cpp @@ -301,7 +301,7 @@ QString pki_scard::getTypeString(void) QString pki_scard::scardLogin(pkcs11 &p11, bool so, bool force) const { - char pin[256]; + char _pin[256], *pin = _pin; int pinlen; bool need_login; @@ -315,10 +315,16 @@ QString pki_scard::scardLogin(pkcs11 &p11, bool so, bool force) const if (force || need_login) { if (!need_login) p11.logout(); - pinlen = MainWindow::passRead(pin, 256, 0, &p); - if (pinlen == -1) - return QString(); + if (p11.protAuthPath()) { + pin = NULL; + pinlen = 0; + } else { + pinlen = MainWindow::passRead(pin, 256, 0, &p); + if (pinlen == -1) + return QString(); + } p11.login((unsigned char*)pin, pinlen, so); + pin = _pin; } else { return QString(""); } @@ -330,15 +336,10 @@ EVP_PKEY *pki_scard::decryptKey() const int slot_id; QString pin; struct { - const void *password; + char *password; const char *prompt_info; } cb_data = { NULL, NULL }; - pass_info p(XCA_TITLE, - pki_scard::tr("Please enter the PIN of the token: ") + - getIntName()); - p.setPin(); - slot_id = prepare_card(); if (slot_id == -1) return NULL; @@ -350,43 +351,45 @@ EVP_PKEY *pki_scard::decryptKey() const pin = scardLogin(p11, false); if (pin.isNull()) return NULL; - cb_data.password = CCHAR(pin); + cb_data.password = strdup(CCHAR(pin)); + printf("PASSWORT: '%s'\n", cb_data.password); EVP_PKEY *pkey = ENGINE_load_private_key(p11_engine, CCHAR(key_id), - NULL, &cb_data); + NULL, &cb_data); + free(cb_data.password); openssl_error(); return pkey; } void pki_scard::changePin() { - char oldPin[256], newPin[256]; + char newPin[256], *pinp; int slot; - - pass_info p(XCA_TITLE, - pki_scard::tr("Please enter the PIN of the token: ") + - getIntName()); - p.setPin(); + QString pin; slot = prepare_card(); if (slot == -1) return; - int oldPinLen = MainWindow::passRead(oldPin, 256, 0, &p); - if (oldPinLen == -1) - return; - pkcs11 p11; p11.startSession(slot, true); p11.logout(); - p11.login((unsigned char*)oldPin, oldPinLen, false); - p.setDescription(qApp->translate("MainWindow", - "Please enter the new Pin for the token: ") +getIntName()); + if (p11.protAuthPath()) { + p11.setPin(NULL, 0, NULL ,0); + } + pin = scardLogin(p11, false, true); + if (pin.isNull()) + return; + pass_info p(XCA_TITLE, tr("Please enter the new Pin for the token: ") + + getIntName()); + p.setPin(); int newPinLen = MainWindow::passWrite(newPin, 256, 0, &p); + pinp = strdup(CCHAR(pin)); if (newPinLen != -1) { - p11.setPin((unsigned char*)oldPin, oldPinLen, + p11.setPin((unsigned char*)pinp, pin.length(), (unsigned char*)newPin, newPinLen); } + free(pinp); } void pki_scard::initPin() diff --git a/ui/Options.ui b/ui/Options.ui index d115d978..318308e4 100644 --- a/ui/Options.ui +++ b/ui/Options.ui @@ -1,7 +1,8 @@ - + + Options - - + + 0 0 @@ -9,13 +10,13 @@ 455 - + Dialog - + - - + + Arial 14 @@ -26,59 +27,59 @@ false - - <html><head><meta name="qrichtext" content="1" /><style type="text/css"> + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Arial'; font-size:14pt; font-weight:400; font-style:normal; text-decoration:none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">XCA Options</p></body></html> +</style></head><body style=" font-family:'Arial'; font-size:14pt; font-weight:400; font-style:normal; text-decoration:none;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">XCA Options</p></body></html> - + Qt::AlignCenter - - + + Mandatory subject entries - - + + 6 - + 9 - - + + 6 - + 0 - + - + - - + + 6 - + 0 - + Qt::Vertical - + 20 40 @@ -87,15 +88,15 @@ p, li { white-space: pre-wrap; } - - + + Add - - + + Delete @@ -106,58 +107,58 @@ p, li { white-space: pre-wrap; } - - + + 6 - + 0 - - + + Default hash algorithm - + - - + + 6 - + 0 - - + + String types - + - + - - + + PKCS11 Library path: - - - + + + 0 0 @@ -165,14 +166,14 @@ p, li { white-space: pre-wrap; } - - - + + + 0 0 - + ... @@ -180,33 +181,33 @@ p, li { white-space: pre-wrap; } - - + + Qt::Horizontal - - + + 6 - + 0 - - + + Cancel - + Qt::Horizontal - + 21 21 @@ -215,8 +216,8 @@ p, li { white-space: pre-wrap; } - - + + OK @@ -245,11 +246,11 @@ p, li { white-space: pre-wrap; } Options accept() - + 224 332 - + 96 254 @@ -261,11 +262,11 @@ p, li { white-space: pre-wrap; } Options reject() - + 305 332 - + 179 282 diff --git a/widgets/Options.cpp b/widgets/Options.cpp index 62d04d2e..3569193a 100644 --- a/widgets/Options.cpp +++ b/widgets/Options.cpp @@ -69,3 +69,16 @@ QString Options::getStringOpt() return string_opts[mbstring->currentIndex()]; } +void Options::on_fileButton_clicked(void) +{ + load_pkcs11 l; + QString fname; + + fname = QFileDialog::getOpenFileName(this, l.caption, + pkcs11path->text(), l.filter); + + if (fname.isEmpty()) + return; + pkcs11path->setText(fname); +} + diff --git a/widgets/Options.h b/widgets/Options.h index 4e9cc7da..89f40d90 100644 --- a/widgets/Options.h +++ b/widgets/Options.h @@ -26,6 +26,7 @@ class Options: public QDialog, public Ui::Options QString getDnString(); void setStringOpt(const QString string_opt); QString getStringOpt(); + void on_fileButton_clicked(void); }; #endif