PDA

View Full Version : pkcs#11 example



davidovv
23rd April 2015, 22:52
I am trying to use Private key from pkcs#11 dongle. In the qt documentation http://doc.qt.digia.com/qt-5.0/qtdoc/qt5-intro.html#connectivity-and-networking there is link to qsslkey example http://git.iksaif.net/?p=qsslkey-p11.git that shows web page not available. I couldn't find that example with google. Is there a clone of that project or similar example that anyone knows?

mrw
11th November 2015, 09:12
I was more successful googling: https://github.com/iksaif/qsslkey-p11

It was even possible to use PKCS#11 before, we're using it at SwissSign (https://swisssign.com) for the SuisseID (https://postsuisseid.ch) since some years. It runs on Linux, Mac-OSX and Windows. There is a PKCS#11 enabled Qt Browser (originally started by myself as SwissSurfer, then renamed by our company (https://swisssign.com) as SwissBrowser , then taken back to OpenSource as SwissSurfer again, and will be renamed to simply Surfer in the near future). Project is now OpenSource and available from my private Homepage:

The trick is to combine Qt with an OpenSSL Engine, as supported in my project C++ Library libpcscxx (https://dev.marc.waeckerlin.org/redmine/projects/libpcscxx/embedded/group__opensslengine.html):

Add a dummy private Key: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1CryptokiEngine.html#a8cf9e326a fcf32ef283499b94702e27d
Login to the SmartCard: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1SmartCardAuth.html#a45fd01c1e8 48f3257334391129325501
And finally sign: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1CryptokiEngine.html#ad1470ce1a ff5d324e3c60bf83f1ec6b7


You can find binaries in my repository (https://dev.marc.waeckerlin.org/repository/) and instructions to setup the repository on my projects entrance page (https://dev.marc.waeckerlin.org/redmine/).

I was more successful googling: https://github.com/iksaif/qsslkey-p11

It was even possible to use PKCS#11 before, we're using it at SwissSign (https://swisssign.com) for the SuisseID (https://postsuisseid.ch) since some years. It runs on Linux, Mac-OSX and Windows. There is a PKCS#11 enabled Qt Browser (originally started by myself as SwissSurfer, then renamed by our company (https://swisssign.com) as SwissBrowser , then taken back to OpenSource as SwissSurfer again, and will be renamed to simply Surfer in the near future). Project is now OpenSource and available from my private Homepage:

The trick is to combine Qt with an OpenSSL Engine, as supported in my project C++ Library libpcscxx (https://dev.marc.waeckerlin.org/redmine/projects/libpcscxx/embedded/group__opensslengine.html):

Add a dummy private Key: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1CryptokiEngine.html#a8cf9e326a fcf32ef283499b94702e27d
Login to the SmartCard: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1SmartCardAuth.html#a45fd01c1e8 48f3257334391129325501
And finally sign: https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1CryptokiEngine.html#ad1470ce1a ff5d324e3c60bf83f1ec6b7


You can find binaries in my repository (https://dev.marc.waeckerlin.org/repository/) and instructions to setup the repository on my projects entrance page (https://dev.marc.waeckerlin.org/redmine/).

Added after 18 minutes:

After browsing the Qt5-QSslKey documentation, This is the new method that will simplify our life: QSslKey::QSslKey(Qt::HANDLE handle, QSsl::KeyType type = QSsl::PrivateKey) (http://doc.qt.io/qt-5/qsslkey.html#QSslKey-3). Up to now I had to abuse Qt::HANDLE QSslKey::handle() const (http://doc.qt.io/qt-5/qsslkey.html#handle) for my purposes, see void qbrowserlib::CryptokiEngine::cert(cryptoki::Object &privateKey, const std::string &certVal) (https://dev.marc.waeckerlin.org/redmine/projects/swisssurfer/embedded/classqbrowserlib_1_1CryptokiEngine.html#a8cf9e326a fcf32ef283499b94702e27d). Now I can set my handle without tricks.

Up to now, I did it as follows:

void cert(cryptoki::Object& privateKey, const std::string& certVal) {
TRC;
_privateKey = std::auto_ptr<cryptoki::Object>
(new cryptoki::Object(privateKey));
try { // new
QSslConfiguration sslConfig(QSslConfiguration::defaultConfiguration( ));
QSslCertificate localcert(QByteArray(certVal.data(),
certVal.size()),
QSsl::Der);
sslConfig.setLocalCertificate(localcert);

//RSA_set_default_method(ENGINE_get_RSA(_e));
QByteArray pem // empty dummy key for qt object instantiation
("-----BEGIN RSA PRIVATE KEY-----\n"
"MIIBOwIBAAJBAMH2yqAGeVNPdgeZ2GoHo31m9aUxZ7QfK2Go2q LTahLpQ3UL1C8G\n"
"LkuMS8SNK0ZGfRMalIpIhv6bW5l3kjogOncCAwEAAQJABVGECt FCoGMsZFb2lSmy\n"
"dOzOzYHGSy0TnnDn1dEgNnZ8sIljElPtUzm9dyXs2P3ICL1sOd 7qjpzfJeyxknDL\n"
"AQIhAO5iKdLmhyuW+EDEH19vDs1Pmqs3/ZnT5UgUiJnTJqz3AiEA0ExIfUOCnxq2\n"
"a3Z46KEivcr8JB2P9VqouBbVryiq/oECIQDj8bPCejMoiEzMSX0iWWTTB9qC/KAg\n"
"FtF4skHIrXKfEwIgPCs86Uo+Ch2aQjKHvJMHSRHAgeI0OmiEwi B+e0lhE4ECIQDd\n"
"IbUmHIXt6oHLJmoGFX46bCcfil5eE5FXfiaw7Q9iPw==\n"
"-----END RSA PRIVATE KEY-----\n");
QSslKey privkey(pem, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
RSA* rsa((RSA*)privkey.handle());
if (!ENGINE_init(_e)) return;
rsa->engine=_e;
rsa->meth=ENGINE_get_RSA(_e);
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, rsa, &rsa->ex_data)) {
ENGINE_finish(_e);
return;
}
set(rsa->n, privateKey, CKA_MODULUS, "CKA_MODULUS");
set(rsa->e, privateKey, CKA_PUBLIC_EXPONENT, "CKA_PUBLIC_EXPONENT");
set(rsa->d, privateKey, CKA_PRIVATE_EXPONENT, "CKA_PRIVATE_EXPONENT");
set(rsa->p, privateKey, CKA_PRIME_1, "CKA_PRIME_1");
set(rsa->q, privateKey, CKA_PRIME_2, "CKA_PRIME_2");
set(rsa->dmp1, privateKey, CKA_EXPONENT_1, "CKA_EXPONENT_1");
set(rsa->dmq1, privateKey, CKA_EXPONENT_2, "CKA_EXPONENT_2");
set(rsa->iqmp, privateKey, CKA_COEFFICIENT, "CKA_COEFFICIENT");
rsa->flags |= RSA_FLAG_SIGN_VER; // don't emulate with encrypt/decrypt
assert(!privkey.isNull());
LOG<<"Setup RSA finished";
sslConfig.setPrivateKey(privkey);
QSslConfiguration::setDefaultConfiguration(sslConf ig);
} catch (const std::exception& e) {
LOG<<"SETUP ERROR: "<<e.what();
}
}


Now, with this new method, I probably will not need the ugly dummy private key anymore.