add thread during token-keygeneration

- set cursor to "wait" durng p11->C_... calls
This commit is contained in:
Christian Hohnstaedt 2010-03-02 20:54:35 +01:00
parent 7e90bd80f9
commit 4eba4c01c9
7 changed files with 106 additions and 14 deletions

View File

@ -472,7 +472,7 @@ I used the following providers for testing:
The support of Netkey 4E cards is currently restricted. Only import and using the keys is possible. For other cards the support is probably better.
<item>Aladdin eToken PKIclient-5.1: Works perfectly:
Read public keys from the token, write private keys to the token, generate keys on the token, write certificates to the token and delete them from the token.
<item>Linux only: OpenCryptoki [IBM]: may be used as a pure software token, but also supports TPMs and other IBM crypto processors
<item>Linux only: OpenCryptoki \[IBM\]: may be used as a pure software token, but also supports TPMs and other IBM crypto processors
</itemize>
<sect1>Tested compatibility with other applications
@ -492,19 +492,20 @@ I initialized the token as follows:
<item>Export server cert as "PEM Cert + key" without password for Apache2
</itemize>
<sect2>Firefox / Mozilla -> Apache
<p>
<itemize>
<item>Enable PKCS#11 token in firefox: Edit->Preferences->Advanced: [SecurityDevices]: [Load] Load PKCS#11 Device: /usr/lib/libeTPkcs11.so
<item>Import CA certificate: Edit->Preferences->Advanced: [View Certificates] [Authorities]: [Import]
<item>Prepare apache config with:
<itemize>
<item>SSLEngine on
<item>SSLCertificateFile /etc/apache2/ssl/dalek.pem
<item>SSLCertificateKeyFile /etc/apache2/ssl/dalek.pem
<item>SSLCertificateChainFile /etc/apache2/ssl/my_CA.crt
<item>SSLCACertificateFile /etc/apache2/ssl/my_CA.crt
<item>SSLVerifyClient require
<item>SSLVerifyDepth 10
</itemize>
<tscreen><verb>
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/dalek.pem
SSLCertificateKeyFile /etc/apache2/ssl/dalek.pem
SSLCertificateChainFile /etc/apache2/ssl/my_CA.crt
SSLCACertificateFile /etc/apache2/ssl/my_CA.crt
SSLVerifyClient require
SSLVerifyDepth 10
</tscreen></verb>
<item>Connect with firefox to the server. Firefox will prompt you to select one of the 2 client certificates. Both work.
</itemize>

View File

@ -17,7 +17,7 @@ class errorEx
private:
QString msg;
public:
errorEx(QString txt, QString className = "")
errorEx(QString txt = "", QString className = "")
{
msg = txt;
if (!className.isEmpty())

View File

@ -41,6 +41,11 @@ void pk11_attr_data::setValue(const unsigned char *ptr, unsigned long len)
{
if (attr.pValue)
free(attr.pValue);
if (!ptr || len == 0) {
attr.ulValueLen = 0;
attr.pValue = NULL;
return;
}
attr.pValue = malloc(len);
check_oom(attr.pValue);
memcpy(attr.pValue, ptr, len);

View File

@ -119,6 +119,7 @@ class pk11_attr_data: public pk11_attribute
{
public:
pk11_attr_data() :pk11_attribute(0) { }
pk11_attr_data(unsigned long type, const unsigned char *v = NULL,
unsigned long len = 0) :pk11_attribute(type)
{
@ -175,6 +176,14 @@ public:
void setBignum(BIGNUM *bn, bool consume=true);
void load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
void setValue(const unsigned char *ptr, unsigned long len);
pk11_attr_data &operator = (const pk11_attr_data &p)
{
const unsigned char *ptr;
unsigned long size = p.getValue(&ptr);
attr.type = p.attr.type;
setValue(ptr, size);
return *this;
}
};
class pk11_attlist {

View File

@ -32,11 +32,15 @@ void pkcs11::startSession(unsigned long slot, bool rw)
unsigned long flags = CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION : 0);
if (session != CK_INVALID_HANDLE) {
WAITCURSOR_START;
rv = p11->C_CloseSession(session);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_OpenSession", rv);
}
WAITCURSOR_START;
rv = p11->C_OpenSession(slot, flags, NULL, NULL, &session);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_OpenSession", rv);
slot_id = slot;
@ -51,7 +55,9 @@ QList<unsigned long> pkcs11::getSlotList()
/* This one helps to avoid errors.
* Fist time it fails, 2nd time it works */
WAITCURSOR_START;
p11->C_GetSlotList(CK_TRUE, p11_slots, &num_slots);
WAITCURSOR_END;
while (1) {
rv = p11->C_GetSlotList(CK_TRUE, p11_slots, &num_slots);
if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
@ -82,12 +88,16 @@ QList<CK_MECHANISM_TYPE> pkcs11::mechanismList(unsigned long slot)
QList<CK_MECHANISM_TYPE> ml;
unsigned long count;
WAITCURSOR_START;
rv = p11->C_GetMechanismList(slot, NULL, &count);
WAITCURSOR_END;
if (count != 0) {
m = (CK_MECHANISM_TYPE *)malloc(count *sizeof(*m));
check_oom(m);
WAITCURSOR_START;
rv = p11->C_GetMechanismList(slot, m, &count);
WAITCURSOR_END;
if (rv != CKR_OK) {
free(m);
pk11error("C_GetMechanismList", rv);
@ -103,7 +113,9 @@ QList<CK_MECHANISM_TYPE> pkcs11::mechanismList(unsigned long slot)
void pkcs11::mechanismInfo(unsigned long slot, CK_MECHANISM_TYPE m, CK_MECHANISM_INFO *info)
{
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_GetMechanismInfo(slot, m, info);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_GetMechanismInfo", rv);
}
@ -113,7 +125,9 @@ void pkcs11::logout() const
{
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_Logout(session);
WAITCURSOR_END;
if (rv != CKR_OK && rv != CKR_USER_NOT_LOGGED_IN)
pk11error("C_Logout", rv);
}
@ -123,7 +137,9 @@ bool pkcs11::needsLogin(bool so)
CK_SESSION_INFO sinfo;
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_GetSessionInfo(session, &sinfo);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_GetSessionInfo", rv);
@ -155,7 +171,9 @@ void pkcs11::login(unsigned char *pin, unsigned long pinlen, bool so)
unsigned long user = so ? CKU_SO : CKU_USER;
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_Login(session, user, pin, pinlen);
WAITCURSOR_END;
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
pk11error("C_Login", rv);
}
@ -223,7 +241,9 @@ bool pkcs11::selectToken(unsigned long *slot, QWidget *w)
void pkcs11::setPin(unsigned char *oldPin, unsigned long oldPinLen,
unsigned char *pin, unsigned long pinLen)
{
WAITCURSOR_START;
CK_RV rv = p11->C_SetPIN(session, oldPin, oldPinLen, pin, pinLen);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_SetPIN", rv);
}
@ -286,8 +306,10 @@ void pkcs11::initPin(unsigned long slot)
pinp = newPin;
}
if (newPinLen != -1) {
WAITCURSOR_START;
CK_RV rv = p11->C_InitPIN(session,
(unsigned char*)pinp, newPinLen);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_InitPIN", rv);
}
@ -302,7 +324,9 @@ void pkcs11::initToken(unsigned long slot, unsigned char *pin, int pinlen,
memset(clabel, ' ', 32);
memcpy(clabel, ba.constData(), ba.size());
WAITCURSOR_START;
CK_RV rv = p11->C_InitToken(slot, pin, pinlen, clabel);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_InitToken", rv);
}
@ -312,7 +336,9 @@ tkInfo pkcs11::tokenInfo(CK_SLOT_ID slot)
CK_TOKEN_INFO token_info;
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_GetTokenInfo(slot, &token_info);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_GetTokenInfo", rv);
}
@ -324,7 +350,9 @@ QString pkcs11::driverInfo()
CK_INFO info;
CK_RV rv;
WAITCURSOR_START;
rv = p11->C_GetInfo(&info);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_GetInfo", rv);
}
@ -359,7 +387,9 @@ CK_OBJECT_HANDLE pkcs11::createObject(pk11_attlist &attrs)
CK_RV rv;
CK_OBJECT_HANDLE obj;
WAITCURSOR_START;
rv = p11->C_CreateObject(session, attrs.getAttributes(), attrs.length(), &obj);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_CreateObject", rv);
}
@ -373,7 +403,9 @@ int pkcs11::deleteObjects(pk11_attlist &atts)
objects = objectList(atts);
for (int i=0; i< objects.count(); i++) {
WAITCURSOR_START;
rv = p11->C_DestroyObject(session, objects[i]);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_DestroyObject", rv);
}
@ -429,10 +461,12 @@ pk11_attr_data pkcs11::generateRSAKey(QString name, unsigned long bits)
pk11_attr_bool(CKA_UNWRAP, true) <<
label << new_id;
WAITCURSOR_START;
rv = p11->C_GenerateKeyPair(session, &mechanism,
pub_atts.getAttributes(), pub_atts.length(),
priv_atts.getAttributes(), priv_atts.length(),
&pubkey, &privkey);
WAITCURSOR_END;
if (rv != CKR_OK) {
pk11error("C_GenerateKeyPair", rv);
}
@ -449,20 +483,26 @@ QList<CK_OBJECT_HANDLE> pkcs11::objectList(pk11_attlist &atts)
att_num = atts.get(&attribute);
WAITCURSOR_START;
rv = p11->C_FindObjectsInit(session, attribute, att_num);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_FindObjectsInit", rv);
do {
WAITCURSOR_START;
rv = p11->C_FindObjects(session, objects, 256, &len);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_FindObjects", rv);
for (i=0; i<len; i++)
list += objects[i];
} while (len);
WAITCURSOR_START;
rv = p11->C_FindObjectsFinal(session);
WAITCURSOR_END;
if (rv != CKR_OK)
pk11error("C_FindObjectsFinal", rv);

View File

@ -9,6 +9,9 @@
#include "pk11_attribute.h"
#define WAITCURSOR_START QApplication::setOverrideCursor(QCursor(Qt::WaitCursor))
#define WAITCURSOR_END QApplication::restoreOverrideCursor()
class tkInfo
{
private:

View File

@ -24,6 +24,7 @@
#include <qdir.h>
#include <widgets/MainWindow.h>
#include <qmessagebox.h>
#include <qthread.h>
#include <ltdl.h>
#if defined(_WIN32) || defined(USE_CYGWIN)
@ -496,6 +497,26 @@ bool pki_scard::prepare_card(unsigned long *slot, bool verifyPubkey) const
return false;
}
class keygenThread: public QThread
{
public:
errorEx err;
pk11_attr_data id;
QString name;
int size;
pkcs11 *p11;
keygenThread() : QThread() { };
void run()
{
try {
id = p11->generateRSAKey(name, size);
} catch (errorEx &e) {
err = e;
}
}
};
void pki_scard::generateKey_card(unsigned long slot, int size, QProgressBar *bar)
{
pk11_attlist atts;
@ -508,10 +529,23 @@ void pki_scard::generateKey_card(unsigned long slot, int size, QProgressBar *bar
if (p11.tokenLogin(ti.label(), false).isNull())
return;
bar->setValue(bar->value()+1);
pk11_attr_data id = p11.generateRSAKey(getIntName(), size);
atts << pk11_attr_ulong(CKA_CLASS, CKO_PUBLIC_KEY) << id;
keygenThread kt;
kt.name = getIntName();
kt.size = size;
kt.p11 = &p11;
kt.start();
while (!kt.wait(20)) {
int value = bar->value();
if (value == bar->maximum()) {
bar->reset();
} else {
bar->setValue(value +1);
}
}
if (!kt.err.isEmpty())
throw errorEx(kt.err);
atts << pk11_attr_ulong(CKA_CLASS, CKO_PUBLIC_KEY) << kt.id;
QList<CK_OBJECT_HANDLE> objects = p11.objectList(atts);
if (objects.count() != 1)
printf("OBJECTS found: %d\n",objects.count());