2005-07-28 12:41:07 +00:00
|
|
|
/*
|
2006-04-03 21:14:17 +00:00
|
|
|
* Copyright (C) 2004 Justin Karneges
|
|
|
|
* Copyright (C) 2006 Alon Bar-Lev <alon.barlev@gmail.com>
|
2005-07-28 12:41:07 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
/*
|
|
|
|
* The routines in this file deal with providing private key cryptography
|
|
|
|
* using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-07-28 12:41:07 +00:00
|
|
|
#include <QtCore>
|
|
|
|
#include <QtCrypto>
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
#include "pkcs11-helper.h"
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
using namespace QCA;
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// pkcs11Provider
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
class pkcs11Provider : public QCA::Provider
|
2005-07-28 12:41:07 +00:00
|
|
|
{
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
bool _fLowLevelInitialized;
|
|
|
|
int _log_level;
|
|
|
|
bool _fSlotEventsActive;
|
|
|
|
bool _fSlotEventsLowLevelActive;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
pkcs11Provider ();
|
|
|
|
~pkcs11Provider ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
2006-11-13 05:44:45 +00:00
|
|
|
virtual
|
|
|
|
int
|
|
|
|
version() const;
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
init ();
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
name () const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
credit () const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QStringList
|
|
|
|
features () const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
Context *
|
|
|
|
createContext (
|
|
|
|
const QString &type
|
|
|
|
);
|
|
|
|
|
|
|
|
void
|
|
|
|
startSlotEvents ();
|
|
|
|
|
|
|
|
void
|
|
|
|
stopSlotEvents ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
protected:
|
|
|
|
static
|
|
|
|
void
|
|
|
|
_logHook (
|
|
|
|
const void *pData,
|
|
|
|
const unsigned flags,
|
|
|
|
const char * const szFormat,
|
|
|
|
va_list args
|
|
|
|
);
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
_slotEventHook (
|
|
|
|
const void *pData
|
|
|
|
);
|
|
|
|
|
|
|
|
static
|
|
|
|
PKCS11H_BOOL
|
|
|
|
_tokenPromptHook (
|
|
|
|
const void *pData,
|
|
|
|
const pkcs11h_token_id_t token
|
|
|
|
);
|
|
|
|
|
|
|
|
static
|
|
|
|
PKCS11H_BOOL
|
|
|
|
_pinPromptHook (
|
|
|
|
const void *pData,
|
|
|
|
const pkcs11h_token_id_t token,
|
|
|
|
char * const szPIN,
|
|
|
|
const size_t nMaxPIN
|
|
|
|
);
|
|
|
|
|
|
|
|
void
|
|
|
|
logHook (
|
|
|
|
const unsigned flags,
|
|
|
|
const char * const szFormat,
|
|
|
|
va_list args
|
|
|
|
);
|
|
|
|
|
|
|
|
void
|
|
|
|
slotEventHook ();
|
|
|
|
|
|
|
|
PKCS11H_BOOL
|
|
|
|
cardPromptHook (
|
|
|
|
const pkcs11h_token_id_t token
|
|
|
|
);
|
|
|
|
|
|
|
|
PKCS11H_BOOL
|
|
|
|
pinPromptHook (
|
|
|
|
const pkcs11h_token_id_t token,
|
|
|
|
char * const szPIN,
|
|
|
|
const size_t nMaxPIN
|
|
|
|
);
|
2005-07-28 12:41:07 +00:00
|
|
|
};
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
namespace pkcs11QCAPlugin {
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
class MyKeyStoreEntry;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// MyKeyStoreList
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
class MyKeyStoreList : public KeyStoreListContext
|
2005-07-28 12:41:07 +00:00
|
|
|
{
|
2006-04-03 21:14:17 +00:00
|
|
|
Q_OBJECT
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
class KeyStoreItem {
|
|
|
|
public:
|
|
|
|
int id;
|
|
|
|
pkcs11h_token_id_t token_id;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
KeyStoreItem () {
|
|
|
|
id = 0;
|
|
|
|
token_id = NULL;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
~KeyStoreItem () {
|
|
|
|
if (token_id != NULL) {
|
|
|
|
pkcs11h_freeTokenId (token_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
int _last_id;
|
|
|
|
typedef QList<KeyStoreItem *> _stores_t;
|
|
|
|
_stores_t _stores;
|
|
|
|
QHash<int, KeyStoreItem *> _storesById;
|
|
|
|
QMutex _mutexStores;
|
|
|
|
bool _initialized;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
public:
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreList (Provider *p);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
~MyKeyStoreList ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
Provider::Context *
|
|
|
|
clone () const;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
virtual
|
|
|
|
void
|
|
|
|
start ();
|
|
|
|
|
|
|
|
virtual
|
|
|
|
void
|
|
|
|
setUpdatesEnabled (bool enabled);
|
|
|
|
|
|
|
|
virtual
|
|
|
|
KeyStoreEntryContext *
|
|
|
|
entry (
|
|
|
|
int id,
|
|
|
|
const QString &entryId
|
|
|
|
) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
KeyStoreEntryContext *
|
|
|
|
entryPassive (
|
|
|
|
const QString &storeId,
|
|
|
|
const QString &entryId
|
|
|
|
) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
KeyStore::Type
|
|
|
|
type (int id) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
storeId (int id) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
name (int id) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QList<KeyStoreEntry::Type>
|
|
|
|
entryTypes (int id) const;
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QList<int>
|
|
|
|
keyStores ();
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QList<KeyStoreEntryContext*>
|
|
|
|
entryList (int id);
|
|
|
|
|
|
|
|
void
|
2006-04-07 11:13:05 +00:00
|
|
|
pinPrompt (
|
2006-04-03 21:14:17 +00:00
|
|
|
const pkcs11h_token_id_t token_id,
|
|
|
|
QSecureArray &pin
|
|
|
|
);
|
|
|
|
|
|
|
|
void
|
|
|
|
emit_updated ();
|
|
|
|
|
|
|
|
void
|
|
|
|
emit_diagnosticText (
|
|
|
|
const QString &t
|
|
|
|
);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private slots:
|
|
|
|
void
|
|
|
|
doReady ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
doUpdated ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
KeyStoreItem *
|
|
|
|
registerTokenId (
|
|
|
|
const pkcs11h_token_id_t token_id
|
|
|
|
);
|
|
|
|
|
|
|
|
void
|
|
|
|
clearStores ();
|
|
|
|
|
|
|
|
MyKeyStoreEntry *
|
|
|
|
getKeyStoreEntryByCertificateId (
|
|
|
|
const pkcs11h_certificate_id_t certificate_id,
|
|
|
|
bool fPrivate,
|
|
|
|
const QList<Certificate> &listIssuers
|
|
|
|
) const;
|
|
|
|
|
|
|
|
QString
|
2006-04-10 08:00:07 +00:00
|
|
|
tokenId2storeId (
|
2006-04-03 21:14:17 +00:00
|
|
|
const pkcs11h_token_id_t token_id
|
|
|
|
) const;
|
|
|
|
|
|
|
|
QString
|
|
|
|
serializeCertificateId (
|
|
|
|
const pkcs11h_certificate_id_t certificate_id,
|
|
|
|
const CertificateChain &chain,
|
|
|
|
const bool fPrivate
|
|
|
|
) const;
|
|
|
|
|
|
|
|
void
|
|
|
|
deserializeCertificateId (
|
|
|
|
const QString &from,
|
|
|
|
pkcs11h_certificate_id_t * const p_certificate_id,
|
|
|
|
bool * const fPrivate,
|
|
|
|
QList<Certificate> *listIssuers
|
|
|
|
) const;
|
|
|
|
|
|
|
|
QString
|
|
|
|
escapeString (
|
|
|
|
const QString &from
|
|
|
|
) const;
|
|
|
|
|
|
|
|
QString
|
|
|
|
unescapeString (
|
|
|
|
const QString &from
|
|
|
|
) const;
|
|
|
|
};
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
static MyKeyStoreList *s_keyStoreList = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// PKCS11Exception
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
class PKCS11Exception {
|
|
|
|
|
|
|
|
private:
|
|
|
|
CK_RV rv;
|
|
|
|
QString msg;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
PKCS11Exception () {}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
public:
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11Exception (CK_RV rv, const QString &msg) {
|
|
|
|
this->rv = rv;
|
|
|
|
this->msg = msg;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11Exception (const PKCS11Exception &other) {
|
|
|
|
*this = other;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11Exception &
|
|
|
|
operator = (const PKCS11Exception &other) {
|
|
|
|
this->rv = other.rv;
|
|
|
|
this->msg = other.msg;
|
|
|
|
return *this;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
CK_RV
|
|
|
|
getRV () const {
|
|
|
|
return rv;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
getMessage () const {
|
|
|
|
return msg + QString (" ") + pkcs11h_getMessage (rv);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// MyRSAKey
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
class MyRSAKey : public RSAContext
|
2005-07-28 12:41:07 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private:
|
2006-04-03 21:14:17 +00:00
|
|
|
bool _fPrivateKeyRole;
|
|
|
|
pkcs11h_certificate_id_t _pkcs11h_certificate_id;
|
|
|
|
pkcs11h_certificate_t _pkcs11h_certificate;
|
|
|
|
RSAPublicKey _pubkey;
|
|
|
|
|
|
|
|
struct sign_data_s {
|
|
|
|
SignatureAlgorithm alg;
|
|
|
|
QCA::Hash *hash;
|
|
|
|
QSecureArray raw;
|
|
|
|
|
|
|
|
sign_data_s() {
|
|
|
|
hash = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
} sign_data;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
MyRSAKey (
|
|
|
|
Provider *p,
|
|
|
|
pkcs11h_certificate_id_t pkcs11h_certificate_id,
|
|
|
|
RSAPublicKey pubkey
|
|
|
|
) : RSAContext (p) {
|
|
|
|
_fPrivateKeyRole = true;
|
|
|
|
_pkcs11h_certificate_id = NULL;
|
|
|
|
_pkcs11h_certificate = NULL;
|
|
|
|
|
|
|
|
_pubkey = pubkey;
|
|
|
|
clearSign ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
setCertificateId (pkcs11h_certificate_id);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
MyRSAKey (const MyRSAKey &from) : RSAContext (from.provider ()) {
|
|
|
|
_fPrivateKeyRole = from._fPrivateKeyRole;
|
|
|
|
_pkcs11h_certificate_id = NULL;
|
|
|
|
_pkcs11h_certificate = NULL;
|
|
|
|
_pubkey = from._pubkey;
|
|
|
|
sign_data.hash = NULL;
|
|
|
|
clearSign ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
setCertificateId (from._pkcs11h_certificate_id);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
~MyRSAKey () {
|
|
|
|
clearSign ();
|
|
|
|
freeResources ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
Provider::Context *
|
|
|
|
clone () const {
|
|
|
|
return new MyRSAKey (*this);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
isNull () const {
|
|
|
|
return _pubkey.isNull ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
PKey::Type
|
|
|
|
type () const {
|
|
|
|
return _pubkey.type ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
isPrivate () const {
|
|
|
|
return _fPrivateKeyRole;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
canExport () const {
|
|
|
|
return !_fPrivateKeyRole;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
convertToPublic () {
|
|
|
|
if (_fPrivateKeyRole) {
|
|
|
|
if (_pkcs11h_certificate != NULL) {
|
|
|
|
pkcs11h_freeCertificate (_pkcs11h_certificate);
|
|
|
|
_pkcs11h_certificate = NULL;
|
|
|
|
}
|
|
|
|
_fPrivateKeyRole = false;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
int
|
|
|
|
bits () const {
|
|
|
|
return _pubkey.bitSize ();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
int
|
|
|
|
maximumEncryptSize (
|
|
|
|
EncryptionAlgorithm alg
|
|
|
|
) const {
|
|
|
|
return _pubkey.maximumEncryptSize (alg);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QSecureArray
|
|
|
|
encrypt (
|
|
|
|
const QSecureArray &in,
|
|
|
|
EncryptionAlgorithm alg
|
|
|
|
) {
|
|
|
|
return _pubkey.encrypt (in, alg);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
decrypt (
|
|
|
|
const QSecureArray &in,
|
|
|
|
QSecureArray *out,
|
|
|
|
EncryptionAlgorithm alg
|
|
|
|
) {
|
|
|
|
try {
|
|
|
|
CK_MECHANISM_TYPE mech;
|
|
|
|
CK_RV rv;
|
|
|
|
size_t my_size;
|
|
|
|
|
|
|
|
switch (alg) {
|
|
|
|
case EME_PKCS1v15:
|
|
|
|
mech = CKM_RSA_PKCS;
|
2005-07-28 12:41:07 +00:00
|
|
|
break;
|
2006-04-03 21:14:17 +00:00
|
|
|
case EME_PKCS1_OAEP:
|
|
|
|
mech = CKM_RSA_PKCS_OAEP;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_NOT_SUPPORTED, "Invalid algorithm");
|
|
|
|
break;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
ensureCertificate ();
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_certificate_decrypt (
|
|
|
|
_pkcs11h_certificate,
|
|
|
|
mech,
|
|
|
|
(const unsigned char * const)in.constData (),
|
|
|
|
in.size (),
|
|
|
|
NULL,
|
|
|
|
&my_size
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Decryption error");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
out->resize (my_size);
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_certificate_decrypt (
|
|
|
|
_pkcs11h_certificate,
|
|
|
|
mech,
|
|
|
|
(const unsigned char * const)in.constData (),
|
|
|
|
in.size (),
|
|
|
|
(unsigned char *)out->data (),
|
|
|
|
&my_size
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Decryption error");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
rv = out->resize (my_size);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return true;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
if (s_keyStoreList != NULL) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Cannot decrypt: %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2005-07-28 12:41:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
startSign (
|
|
|
|
SignatureAlgorithm alg,
|
|
|
|
SignatureFormat
|
|
|
|
) {
|
|
|
|
clearSign ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
sign_data.alg = alg;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
switch (sign_data.alg) {
|
|
|
|
case EMSA3_SHA1:
|
2006-08-25 07:52:08 +00:00
|
|
|
sign_data.hash = new QCA::Hash ("sha1");
|
2005-07-28 12:41:07 +00:00
|
|
|
break;
|
2006-04-03 21:14:17 +00:00
|
|
|
case EMSA3_MD5:
|
2006-08-25 07:52:08 +00:00
|
|
|
sign_data.hash = new QCA::Hash ("md5");
|
2006-04-03 21:14:17 +00:00
|
|
|
break;
|
|
|
|
case EMSA3_MD2:
|
2006-08-25 07:52:08 +00:00
|
|
|
sign_data.hash = new QCA::Hash ("md2");
|
2006-04-03 21:14:17 +00:00
|
|
|
break;
|
|
|
|
case EMSA3_Raw:
|
|
|
|
break;
|
|
|
|
case SignatureUnknown:
|
|
|
|
case EMSA1_SHA1:
|
|
|
|
case EMSA3_RIPEMD160:
|
|
|
|
default:
|
2005-07-28 12:41:07 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
startVerify (
|
|
|
|
SignatureAlgorithm alg,
|
|
|
|
SignatureFormat sf
|
|
|
|
) {
|
|
|
|
_pubkey.startVerify (alg, sf);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
update (
|
|
|
|
const QSecureArray &in
|
|
|
|
) {
|
|
|
|
if (_fPrivateKeyRole) {
|
|
|
|
if (sign_data.hash != NULL) {
|
|
|
|
sign_data.hash->update (in);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sign_data.raw.append (in);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_pubkey.update (in);
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QSecureArray
|
|
|
|
endSign () {
|
|
|
|
QSecureArray result;
|
|
|
|
unsigned char *enc_alloc = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
try {
|
|
|
|
int myrsa_size = 0;
|
|
|
|
|
|
|
|
unsigned char *enc = NULL;
|
|
|
|
int enc_len = 0;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
CK_RV rv;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QSecureArray final;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
int type;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (sign_data.hash != NULL) {
|
|
|
|
final = sign_data.hash->final ();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
final = sign_data.raw;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
switch (sign_data.alg) {
|
|
|
|
case EMSA3_SHA1:
|
|
|
|
type = NID_sha1;
|
|
|
|
break;
|
|
|
|
case EMSA3_MD5:
|
|
|
|
type = NID_md5;
|
|
|
|
break;
|
|
|
|
case EMSA3_MD2:
|
|
|
|
type = NID_md2;
|
|
|
|
break;
|
|
|
|
case EMSA3_Raw:
|
|
|
|
type = NID_rsa;
|
|
|
|
break;
|
|
|
|
case SignatureUnknown:
|
|
|
|
case EMSA1_SHA1:
|
|
|
|
case EMSA3_RIPEMD160:
|
|
|
|
default:
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_NOT_SUPPORTED, "Invalid algorithm");
|
|
|
|
break;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
ensureCertificate ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
// from some strange reason I got 2047... (for some) <---- BUG?!?!?!
|
|
|
|
myrsa_size=(_pubkey.bitSize () + 7) / 8;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (type == NID_md5_sha1 || type == NID_rsa) {
|
|
|
|
enc = (unsigned char *)final.data ();
|
|
|
|
enc_len = final.size ();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
X509_SIG sig;
|
|
|
|
ASN1_TYPE parameter;
|
|
|
|
X509_ALGOR algor;
|
|
|
|
ASN1_OCTET_STRING digest;
|
|
|
|
|
|
|
|
if ((enc = (unsigned char *)malloc (myrsa_size+1)) == NULL) {
|
|
|
|
throw PKCS11Exception (CKR_HOST_MEMORY, "Memory error");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
enc_alloc = enc;
|
|
|
|
sig.algor= &algor;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if ((sig.algor->algorithm=OBJ_nid2obj (type)) == NULL) {
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_FAILED, "Invalid algorithm");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sig.algor->algorithm->length == 0) {
|
|
|
|
throw PKCS11Exception (CKR_KEY_SIZE_RANGE, "Key size error");
|
|
|
|
}
|
|
|
|
|
|
|
|
parameter.type = V_ASN1_NULL;
|
|
|
|
parameter.value.ptr = NULL;
|
|
|
|
|
|
|
|
sig.algor->parameter = ¶meter;
|
|
|
|
|
|
|
|
sig.digest = &digest;
|
|
|
|
sig.digest->data = (unsigned char *)final.data ();
|
|
|
|
sig.digest->length = final.size ();
|
|
|
|
|
|
|
|
if ((enc_len=i2d_X509_SIG (&sig, NULL)) < 0) {
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_FAILED, "Signature prepare failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char *p = enc;
|
|
|
|
i2d_X509_SIG (&sig, &p);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)) {
|
|
|
|
throw PKCS11Exception (CKR_KEY_SIZE_RANGE, "Padding too small");
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
size_t my_size;
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_certificate_signAny (
|
|
|
|
_pkcs11h_certificate,
|
|
|
|
CKM_RSA_PKCS,
|
|
|
|
enc,
|
|
|
|
enc_len,
|
|
|
|
NULL,
|
|
|
|
&my_size
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Signature failed");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
result.resize (my_size);
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_certificate_signAny (
|
|
|
|
_pkcs11h_certificate,
|
|
|
|
CKM_RSA_PKCS,
|
|
|
|
enc,
|
|
|
|
enc_len,
|
|
|
|
(unsigned char *)result.data (),
|
|
|
|
&my_size
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Signature failed");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
result.resize (my_size);
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
result.clear ();
|
|
|
|
|
|
|
|
if (s_keyStoreList != NULL) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Cannot sign: %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (enc_alloc != NULL) {
|
|
|
|
free (enc_alloc);
|
|
|
|
}
|
|
|
|
|
|
|
|
clearSign ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return result;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
validSignature (
|
|
|
|
const QSecureArray &sig
|
|
|
|
) {
|
|
|
|
return _pubkey.validSignature (sig);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
createPrivate (
|
|
|
|
int bits,
|
|
|
|
int exp,
|
|
|
|
bool block
|
|
|
|
) {
|
|
|
|
Q_UNUSED(bits);
|
|
|
|
Q_UNUSED(exp);
|
|
|
|
Q_UNUSED(block);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
createPrivate (
|
|
|
|
const QBigInteger &n,
|
|
|
|
const QBigInteger &e,
|
|
|
|
const QBigInteger &p,
|
|
|
|
const QBigInteger &q,
|
|
|
|
const QBigInteger &d
|
|
|
|
) {
|
|
|
|
Q_UNUSED(n);
|
|
|
|
Q_UNUSED(e);
|
|
|
|
Q_UNUSED(p);
|
|
|
|
Q_UNUSED(q);
|
|
|
|
Q_UNUSED(d);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
createPublic (
|
|
|
|
const QBigInteger &n,
|
|
|
|
const QBigInteger &e
|
|
|
|
) {
|
|
|
|
Q_UNUSED(n);
|
|
|
|
Q_UNUSED(e);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QBigInteger
|
|
|
|
n () const {
|
|
|
|
return _pubkey.n ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QBigInteger
|
|
|
|
e () const {
|
|
|
|
return _pubkey.e ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QBigInteger
|
|
|
|
p () const {
|
|
|
|
return QBigInteger();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QBigInteger
|
|
|
|
q () const {
|
|
|
|
return QBigInteger();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QBigInteger
|
|
|
|
d () const {
|
|
|
|
return QBigInteger();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
PublicKey
|
|
|
|
getPublicKey () const {
|
|
|
|
return _pubkey;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ensureTokenAccess () {
|
|
|
|
try {
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_token_ensureAccess (
|
|
|
|
_pkcs11h_certificate_id->token_id,
|
|
|
|
0
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Token access");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return true;
|
|
|
|
}
|
2006-04-06 14:22:48 +00:00
|
|
|
catch (const PKCS11Exception &) {
|
2005-07-28 12:41:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
void
|
|
|
|
clearSign () {
|
|
|
|
sign_data.raw.clear ();
|
|
|
|
sign_data.alg = SignatureUnknown;
|
|
|
|
delete sign_data.hash;
|
|
|
|
sign_data.hash = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
freeResources () {
|
|
|
|
if (_pkcs11h_certificate != NULL) {
|
|
|
|
pkcs11h_freeCertificate (_pkcs11h_certificate);
|
|
|
|
_pkcs11h_certificate = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (_pkcs11h_certificate_id != NULL) {
|
|
|
|
pkcs11h_freeCertificateId (_pkcs11h_certificate_id);
|
|
|
|
_pkcs11h_certificate_id = NULL;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
setCertificateId (
|
|
|
|
pkcs11h_certificate_id_t pkcs11h_certificate_id
|
|
|
|
) {
|
|
|
|
CK_RV rv;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
freeResources ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (
|
|
|
|
(rv = pkcs11h_duplicateCertificateId (
|
|
|
|
&_pkcs11h_certificate_id,
|
|
|
|
pkcs11h_certificate_id
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Memory error");
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
ensureCertificate () {
|
|
|
|
CK_RV rv;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (_pkcs11h_certificate == NULL) {
|
|
|
|
if (
|
2006-04-06 14:22:48 +00:00
|
|
|
(rv = pkcs11h_certificate_create (
|
2006-04-03 21:14:17 +00:00
|
|
|
_pkcs11h_certificate_id,
|
|
|
|
PKCS11H_PIN_CACHE_INFINITE,
|
|
|
|
&_pkcs11h_certificate
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot create low-level certificate");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// MyPKeyContext
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
class MyPKeyContext : public PKeyContext
|
|
|
|
{
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
PKeyBase *_k;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
MyPKeyContext (Provider *p) : PKeyContext (p) {
|
|
|
|
_k = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
~MyPKeyContext () {
|
|
|
|
delete _k;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
Provider::Context *
|
|
|
|
clone () const {
|
|
|
|
MyPKeyContext *c = new MyPKeyContext(*this);
|
|
|
|
c->_k = (PKeyBase *)_k->clone();
|
|
|
|
return c;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
virtual
|
|
|
|
QList<PKey::Type>
|
|
|
|
supportedTypes () const {
|
|
|
|
QList<PKey::Type> list;
|
|
|
|
list += PKey::RSA;
|
|
|
|
return list;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QList<PKey::Type>
|
|
|
|
supportedIOTypes () const {
|
|
|
|
QList<PKey::Type> list;
|
|
|
|
list += PKey::RSA;
|
|
|
|
return list;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QList<PBEAlgorithm>
|
|
|
|
supportedPBEAlgorithms () const {
|
|
|
|
QList<PBEAlgorithm> list;
|
|
|
|
return list;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
PKeyBase *
|
|
|
|
key () {
|
|
|
|
return _k;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
const PKeyBase *
|
|
|
|
key () const {
|
|
|
|
return _k;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
void
|
|
|
|
setKey (PKeyBase *key) {
|
|
|
|
delete _k;
|
|
|
|
_k = key;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
importKey (
|
|
|
|
const PKeyBase *key
|
|
|
|
) {
|
|
|
|
Q_UNUSED(key);
|
|
|
|
return false;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
static
|
|
|
|
int
|
|
|
|
passphrase_cb (
|
|
|
|
char *buf,
|
|
|
|
int size,
|
|
|
|
int rwflag,
|
|
|
|
void *u
|
|
|
|
) {
|
|
|
|
Q_UNUSED(buf);
|
|
|
|
Q_UNUSED(size);
|
|
|
|
Q_UNUSED(rwflag);
|
|
|
|
Q_UNUSED(u);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QSecureArray
|
|
|
|
publicToDER () const {
|
|
|
|
return static_cast<MyRSAKey *>(_k)->getPublicKey ().toDER ();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
publicToPEM () const {
|
|
|
|
return static_cast<MyRSAKey *>(_k)->getPublicKey ().toPEM ();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
ConvertResult
|
|
|
|
publicFromDER (
|
|
|
|
const QSecureArray &in
|
|
|
|
) {
|
|
|
|
Q_UNUSED(in);
|
|
|
|
return ErrorDecode;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
ConvertResult
|
|
|
|
publicFromPEM (
|
|
|
|
const QString &s
|
|
|
|
) {
|
|
|
|
Q_UNUSED(s);
|
|
|
|
return ErrorDecode;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QSecureArray
|
|
|
|
privateToDER(
|
|
|
|
const QSecureArray &passphrase,
|
|
|
|
PBEAlgorithm pbe
|
|
|
|
) const {
|
|
|
|
Q_UNUSED(passphrase);
|
|
|
|
Q_UNUSED(pbe);
|
|
|
|
return QSecureArray ();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
privateToPEM (
|
|
|
|
const QSecureArray &passphrase,
|
|
|
|
PBEAlgorithm pbe
|
|
|
|
) const {
|
|
|
|
Q_UNUSED(passphrase);
|
|
|
|
Q_UNUSED(pbe);
|
|
|
|
return QString ();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
ConvertResult
|
|
|
|
privateFromDER (
|
|
|
|
const QSecureArray &in,
|
|
|
|
const QSecureArray &passphrase
|
|
|
|
) {
|
|
|
|
Q_UNUSED(in);
|
|
|
|
Q_UNUSED(passphrase);
|
|
|
|
return ErrorDecode;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual
|
|
|
|
ConvertResult
|
|
|
|
privateFromPEM (
|
|
|
|
const QString &s,
|
|
|
|
const QSecureArray &passphrase
|
|
|
|
) {
|
|
|
|
Q_UNUSED(s);
|
|
|
|
Q_UNUSED(passphrase);
|
|
|
|
return ErrorDecode;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
2006-04-03 21:14:17 +00:00
|
|
|
// MyKeyStoreEntry
|
2005-07-28 12:41:07 +00:00
|
|
|
//----------------------------------------------------------------------------
|
2006-04-03 21:14:17 +00:00
|
|
|
class MyKeyStoreEntry : public KeyStoreEntryContext
|
2005-07-28 12:41:07 +00:00
|
|
|
{
|
2006-04-03 21:14:17 +00:00
|
|
|
private:
|
|
|
|
KeyStoreEntry::Type _item_type;
|
|
|
|
KeyBundle _key;
|
|
|
|
Certificate _cert;
|
|
|
|
QString _storeId;
|
|
|
|
QString _id;
|
|
|
|
QString _storeName;
|
|
|
|
QString _name;
|
|
|
|
|
2005-07-28 12:41:07 +00:00
|
|
|
public:
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreEntry (
|
|
|
|
const Certificate &cert,
|
|
|
|
const QString &storeId,
|
|
|
|
const QString &id,
|
|
|
|
const QString &storeName,
|
|
|
|
const QString &name,
|
|
|
|
Provider *p
|
|
|
|
) : KeyStoreEntryContext(p) {
|
|
|
|
_item_type = KeyStoreEntry::TypeCertificate;
|
|
|
|
_cert = cert;
|
|
|
|
_storeId = storeId;
|
|
|
|
_id = id;
|
|
|
|
_storeName = storeName;
|
|
|
|
_name = name;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreEntry (
|
|
|
|
const KeyBundle &key,
|
|
|
|
const QString &storeId,
|
|
|
|
const QString &id,
|
|
|
|
const QString &storeName,
|
|
|
|
const QString &name,
|
|
|
|
Provider *p
|
|
|
|
) : KeyStoreEntryContext(p) {
|
|
|
|
_item_type = KeyStoreEntry::TypeKeyBundle;
|
|
|
|
_key = key;
|
|
|
|
_storeId = storeId,
|
|
|
|
_id = id;
|
|
|
|
_storeName = storeName;
|
|
|
|
_name = name;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreEntry (
|
|
|
|
const MyKeyStoreEntry &from
|
|
|
|
) : KeyStoreEntryContext(from) {
|
|
|
|
_item_type = from._item_type;
|
|
|
|
_key = from._key;
|
|
|
|
_storeId = from._storeId;
|
|
|
|
_id = from._id;
|
|
|
|
_storeName = from._storeName;
|
|
|
|
_name = from._name;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
~MyKeyStoreEntry() {
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
Provider::Context *
|
|
|
|
clone () const {
|
|
|
|
return new MyKeyStoreEntry(*this);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
public:
|
|
|
|
virtual
|
|
|
|
KeyStoreEntry::Type
|
|
|
|
type () const {
|
|
|
|
return _item_type;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
name () const {
|
|
|
|
return _name;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
id () const {
|
|
|
|
return _id;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
KeyBundle
|
|
|
|
keyBundle () const {
|
|
|
|
return _key;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
Certificate
|
|
|
|
certificate () const {
|
|
|
|
return _cert;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
storeId () const {
|
|
|
|
return _storeId;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
QString
|
|
|
|
storeName () const {
|
|
|
|
return _storeName;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
virtual
|
|
|
|
bool
|
|
|
|
ensureAccess () {
|
|
|
|
return static_cast<MyRSAKey *>(static_cast<PKeyContext *>(_key.privateKey ().context ())->key ())->ensureTokenAccess ();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// MyKeyStoreList
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
MyKeyStoreList::MyKeyStoreList (Provider *p) : KeyStoreListContext(p) {
|
|
|
|
_last_id = 0;
|
|
|
|
_initialized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MyKeyStoreList::~MyKeyStoreList () {
|
|
|
|
s_keyStoreList = NULL;
|
|
|
|
clearStores ();
|
|
|
|
}
|
|
|
|
|
|
|
|
QCA::Provider::Context *
|
|
|
|
MyKeyStoreList::clone () const {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MyKeyStoreList::start () {
|
|
|
|
|
|
|
|
CK_RV rv = CKR_OK;
|
|
|
|
|
|
|
|
try {
|
|
|
|
QString strProvider = qgetenv ("QCA_PKCS11_LIB");
|
|
|
|
|
|
|
|
if (!strProvider.isEmpty()) {
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_addProvider (
|
|
|
|
qPrintable (strProvider),
|
|
|
|
qPrintable (strProvider),
|
|
|
|
FALSE,
|
|
|
|
PKCS11H_SLOTEVENT_METHOD_AUTO,
|
|
|
|
PKCS11H_SLOTEVENT_METHOD_AUTO,
|
|
|
|
0,
|
|
|
|
FALSE
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Adding provider " + strProvider);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Start failed %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(this, "doReady", Qt::QueuedConnection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MyKeyStoreList::setUpdatesEnabled (bool enabled) {
|
|
|
|
try {
|
|
|
|
pkcs11Provider *p = static_cast<pkcs11Provider *>(provider ());
|
|
|
|
if (enabled) {
|
|
|
|
p->startSlotEvents ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
else {
|
|
|
|
p->stopSlotEvents ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Start event failed %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
KeyStoreEntryContext *
|
|
|
|
MyKeyStoreList::entry (
|
|
|
|
int id,
|
|
|
|
const QString &entryId
|
|
|
|
) const {
|
|
|
|
Q_UNUSED(id);
|
|
|
|
Q_UNUSED(entryId);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
KeyStoreEntryContext *
|
|
|
|
MyKeyStoreList::entryPassive (
|
|
|
|
const QString &storeId,
|
|
|
|
const QString &entryId
|
|
|
|
) const {
|
|
|
|
Q_UNUSED(storeId);
|
|
|
|
|
|
|
|
try {
|
|
|
|
QList<Certificate> listIssuers;
|
|
|
|
pkcs11h_certificate_id_t certificate_id;
|
|
|
|
bool fPrivate;
|
|
|
|
|
|
|
|
deserializeCertificateId (entryId, &certificate_id, &fPrivate, &listIssuers);
|
|
|
|
|
|
|
|
return getKeyStoreEntryByCertificateId (certificate_id, fPrivate, listIssuers);
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Add key store entry %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
KeyStore::Type
|
|
|
|
MyKeyStoreList::type (int id) const {
|
|
|
|
Q_UNUSED(id);
|
|
|
|
return KeyStore::SmartCard;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::storeId (int id) const {
|
|
|
|
QString ret;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (_storesById.contains (id)) {
|
|
|
|
if (_storesById[id]->token_id != NULL) {
|
|
|
|
ret = tokenId2storeId (_storesById[id]->token_id);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::name (int id) const {
|
|
|
|
QString ret;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (_storesById.contains (id)) {
|
|
|
|
if (_storesById[id]->token_id != NULL) {
|
|
|
|
ret = _storesById[id]->token_id->label;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<KeyStoreEntry::Type>
|
|
|
|
MyKeyStoreList::entryTypes (int id) const {
|
|
|
|
Q_UNUSED(id);
|
|
|
|
QList<KeyStoreEntry::Type> list;
|
|
|
|
list += KeyStoreEntry::TypeKeyBundle;
|
|
|
|
list += KeyStoreEntry::TypeCertificate;
|
|
|
|
return list;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QList<int>
|
|
|
|
MyKeyStoreList::keyStores () {
|
|
|
|
pkcs11h_token_id_list_t tokens = NULL;
|
|
|
|
QList<int> out;
|
|
|
|
|
|
|
|
try {
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get available tokens
|
|
|
|
*/
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_enum_getTokenIds (
|
|
|
|
PKCS11H_ENUM_METHOD_CACHE,
|
|
|
|
&tokens
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Enumerating tokens");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
/*
|
|
|
|
* Register all tokens, unmark
|
|
|
|
* them from remove list
|
|
|
|
*/
|
|
|
|
QList<int> to_remove = _storesById.keys ();
|
|
|
|
for (
|
|
|
|
pkcs11h_token_id_list_t entry = tokens;
|
|
|
|
entry != NULL;
|
|
|
|
entry = entry->next
|
|
|
|
) {
|
|
|
|
KeyStoreItem *item = registerTokenId (entry->token_id);
|
|
|
|
out += item->id;
|
|
|
|
to_remove.removeAll (item->id);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
/*
|
|
|
|
* Remove all items
|
|
|
|
* that were not discovered
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
QMutexLocker l(&_mutexStores);
|
|
|
|
|
|
|
|
for (
|
|
|
|
QList<int>::iterator i = to_remove.begin ();
|
|
|
|
i != to_remove.end ();
|
|
|
|
i++
|
|
|
|
) {
|
|
|
|
KeyStoreItem *item = _storesById[*i];
|
|
|
|
_storesById.remove (item->id);
|
|
|
|
_stores.removeAll (item);
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Cannot get key stores: %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (tokens != NULL) {
|
|
|
|
pkcs11h_freeTokenIdList (tokens);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<KeyStoreEntryContext*>
|
|
|
|
MyKeyStoreList::entryList (int id) {
|
|
|
|
pkcs11h_certificate_id_list_t certs = NULL;
|
|
|
|
QList<KeyStoreEntryContext*> out;
|
|
|
|
|
|
|
|
try {
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
if (_storesById.contains (id)) {
|
|
|
|
KeyStoreItem *entry = _storesById[id];
|
|
|
|
|
|
|
|
if (entry->token_id != NULL) {
|
|
|
|
pkcs11h_certificate_id_list_t issuers = NULL;
|
|
|
|
pkcs11h_certificate_id_list_t current = NULL;
|
|
|
|
QList<Certificate> listIssuers;
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_enum_getTokenCertificateIds (
|
|
|
|
entry->token_id,
|
|
|
|
PKCS11H_ENUM_METHOD_CACHE,
|
|
|
|
&issuers,
|
|
|
|
&certs
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Enumerate certificates");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (current=issuers;current!=NULL;current=current->next) {
|
|
|
|
listIssuers += Certificate::fromDER (
|
|
|
|
QByteArray (
|
|
|
|
(char *)current->certificate_id->certificate_blob,
|
|
|
|
current->certificate_id->certificate_blob_size
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
for (current=issuers;current!=NULL;current=current->next) {
|
|
|
|
try {
|
|
|
|
out += getKeyStoreEntryByCertificateId (
|
|
|
|
current->certificate_id,
|
|
|
|
false,
|
|
|
|
listIssuers
|
|
|
|
);
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Add key store entry %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
for (current=certs;current!=NULL;current=current->next) {
|
|
|
|
try {
|
|
|
|
out += getKeyStoreEntryByCertificateId (
|
|
|
|
current->certificate_id,
|
|
|
|
true,
|
|
|
|
listIssuers
|
|
|
|
);
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Add key store entry %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (const PKCS11Exception &e) {
|
|
|
|
s_keyStoreList->emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Enumerating store failed %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (certs != NULL) {
|
|
|
|
pkcs11h_freeCertificateIdList (certs);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return out;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
2006-04-07 11:13:05 +00:00
|
|
|
MyKeyStoreList::pinPrompt (
|
2006-04-03 21:14:17 +00:00
|
|
|
const pkcs11h_token_id_t token_id,
|
|
|
|
QSecureArray &pin
|
|
|
|
) {
|
|
|
|
KeyStoreItem *entry = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
{
|
2006-04-03 21:14:17 +00:00
|
|
|
QMutexLocker l(&_mutexStores);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_stores_t::iterator i=_stores.begin ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
while (
|
|
|
|
i != _stores.end () &&
|
|
|
|
!pkcs11h_sameTokenId (
|
|
|
|
token_id,
|
|
|
|
(*i)->token_id
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
i++;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (i != _stores.end ()) {
|
|
|
|
entry = (*i);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (entry == NULL) {
|
|
|
|
entry = registerTokenId (token_id);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-07 11:13:05 +00:00
|
|
|
PasswordAsker asker;
|
|
|
|
asker.ask (
|
|
|
|
Event::StylePIN,
|
|
|
|
tokenId2storeId (entry->token_id),
|
|
|
|
QString(),
|
|
|
|
0
|
|
|
|
);
|
|
|
|
asker.waitForResponse ();
|
|
|
|
if (asker.accepted ()) {
|
|
|
|
pin = asker.password();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pin = QSecureArray();
|
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::emit_updated () {
|
|
|
|
QMetaObject::invokeMethod(this, "doUpdated", Qt::QueuedConnection);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::emit_diagnosticText (
|
|
|
|
const QString &t
|
|
|
|
) {
|
|
|
|
emit diagnosticText (t);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::doReady () {
|
|
|
|
emit busyEnd ();
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::doUpdated () {
|
|
|
|
emit updated ();
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreList::KeyStoreItem *
|
|
|
|
MyKeyStoreList::registerTokenId (
|
|
|
|
const pkcs11h_token_id_t token_id
|
|
|
|
) {
|
|
|
|
QMutexLocker l(&_mutexStores);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_stores_t::iterator i=_stores.begin ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
while (
|
|
|
|
i != _stores.end () &&
|
|
|
|
!pkcs11h_sameTokenId (
|
|
|
|
token_id,
|
|
|
|
(*i)->token_id
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
i++;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
KeyStoreItem *entry = NULL;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (i == _stores.end ()) {
|
|
|
|
/*
|
|
|
|
* Deal with last_id overlap
|
|
|
|
*/
|
|
|
|
while (_storesById.find (++_last_id) != _storesById.end ());
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
entry = new KeyStoreItem;
|
|
|
|
entry->id = _last_id;
|
|
|
|
pkcs11h_duplicateTokenId (&entry->token_id, token_id);
|
|
|
|
|
|
|
|
_stores += entry;
|
|
|
|
_storesById.insert (entry->id, entry);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
entry = (*i);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return entry;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::clearStores () {
|
|
|
|
QMutexLocker l(&_mutexStores);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_storesById.clear ();
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
for (
|
|
|
|
_stores_t::iterator i=_stores.begin ();
|
|
|
|
i != _stores.end ();
|
|
|
|
i++
|
|
|
|
) {
|
|
|
|
KeyStoreItem *entry = (*i);
|
|
|
|
delete entry;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_stores.clear ();
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
MyKeyStoreEntry *
|
|
|
|
MyKeyStoreList::getKeyStoreEntryByCertificateId (
|
|
|
|
const pkcs11h_certificate_id_t certificate_id,
|
|
|
|
bool fPrivate,
|
|
|
|
const QList<Certificate> &listIssuers
|
|
|
|
) const {
|
|
|
|
MyKeyStoreEntry *entry = NULL;
|
|
|
|
|
|
|
|
if (certificate_id == 0) {
|
|
|
|
throw PKCS11Exception (CKR_ARGUMENTS_BAD, "Missing certificate object");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (certificate_id->certificate_blob_size == 0) {
|
|
|
|
throw PKCS11Exception (CKR_ARGUMENTS_BAD, "Missing certificate");
|
|
|
|
}
|
|
|
|
|
|
|
|
Certificate cert = Certificate::fromDER (
|
|
|
|
QByteArray (
|
|
|
|
(char *)certificate_id->certificate_blob,
|
|
|
|
certificate_id->certificate_blob_size
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (cert.isNull ()) {
|
|
|
|
throw PKCS11Exception (CKR_ARGUMENTS_BAD, "Invalid certificate");
|
|
|
|
}
|
|
|
|
|
|
|
|
CertificateChain chain = CertificateChain (cert).complete (listIssuers);
|
|
|
|
|
|
|
|
QString strDescription = cert.commonName () + " by " + cert.issuerInfo ().value (CommonName, "Unknown");
|
|
|
|
|
|
|
|
QString id = serializeCertificateId (
|
|
|
|
certificate_id,
|
|
|
|
chain,
|
|
|
|
fPrivate
|
|
|
|
);
|
|
|
|
|
|
|
|
if (fPrivate) {
|
|
|
|
MyRSAKey *rsakey = new MyRSAKey (
|
|
|
|
provider(),
|
|
|
|
certificate_id,
|
|
|
|
cert.subjectPublicKey ().toRSA ()
|
|
|
|
);
|
|
|
|
|
|
|
|
MyPKeyContext *pkc = new MyPKeyContext (provider ());
|
|
|
|
pkc->setKey (rsakey);
|
|
|
|
PrivateKey privkey;
|
|
|
|
privkey.change (pkc);
|
|
|
|
KeyBundle key;
|
|
|
|
key.setCertificateChainAndKey (
|
|
|
|
chain,
|
|
|
|
privkey
|
|
|
|
);
|
|
|
|
|
|
|
|
entry = new MyKeyStoreEntry (
|
|
|
|
key,
|
|
|
|
tokenId2storeId (certificate_id->token_id),
|
|
|
|
id,
|
|
|
|
certificate_id->token_id->label,
|
|
|
|
strDescription,
|
|
|
|
provider ()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
entry = new MyKeyStoreEntry (
|
|
|
|
cert,
|
|
|
|
tokenId2storeId (certificate_id->token_id),
|
|
|
|
id,
|
|
|
|
certificate_id->token_id->label,
|
|
|
|
strDescription,
|
|
|
|
provider()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return entry;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::tokenId2storeId (
|
|
|
|
const pkcs11h_token_id_t token_id
|
|
|
|
) const {
|
2006-08-25 07:52:08 +00:00
|
|
|
QCA::Hash hash1 ("md2");
|
2006-04-03 21:14:17 +00:00
|
|
|
hash1.update (token_id->manufacturerID, strlen (token_id->manufacturerID));
|
|
|
|
hash1.update (token_id->model, strlen (token_id->model));
|
|
|
|
hash1.update (token_id->serialNumber, strlen (token_id->serialNumber));
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-04 10:54:58 +00:00
|
|
|
return "qca-pkcs11/" + escapeString (Base64 ().arrayToString (hash1.final ()));
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::serializeCertificateId (
|
|
|
|
const pkcs11h_certificate_id_t certificate_id,
|
|
|
|
const CertificateChain &chain,
|
|
|
|
const bool fPrivate
|
|
|
|
) const {
|
|
|
|
QString strSerialized;
|
|
|
|
|
2006-04-04 10:54:58 +00:00
|
|
|
strSerialized += QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"qca-pkcs11/%s/%s/%s/%s/%s/%d",
|
|
|
|
qPrintable (escapeString (certificate_id->token_id->manufacturerID)),
|
|
|
|
qPrintable (escapeString (certificate_id->token_id->model)),
|
|
|
|
qPrintable (escapeString (certificate_id->token_id->serialNumber)),
|
|
|
|
qPrintable (escapeString (certificate_id->token_id->label)),
|
2006-04-04 10:54:58 +00:00
|
|
|
qPrintable (escapeString (Base64 ().arrayToString (
|
2006-04-03 21:14:17 +00:00
|
|
|
(QByteArray (
|
|
|
|
(const char *)certificate_id->attrCKA_ID,
|
|
|
|
(int)certificate_id->attrCKA_ID_size
|
|
|
|
)
|
|
|
|
)))),
|
|
|
|
fPrivate ? 1 : 0
|
|
|
|
);
|
|
|
|
|
|
|
|
for (
|
|
|
|
CertificateChain::const_iterator i = chain.begin ();
|
|
|
|
i != chain.end ();
|
|
|
|
i++
|
|
|
|
) {
|
2006-04-04 10:54:58 +00:00
|
|
|
strSerialized += "/" + escapeString (Base64 ().arrayToString ((*i).toDER ()));
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return strSerialized;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
MyKeyStoreList::deserializeCertificateId (
|
|
|
|
const QString &from,
|
|
|
|
pkcs11h_certificate_id_t * const p_certificate_id,
|
|
|
|
bool * const fPrivate,
|
|
|
|
QList<Certificate> *listIssuers
|
|
|
|
) const {
|
|
|
|
*p_certificate_id = NULL;
|
|
|
|
*fPrivate = false;
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
QStringList list = from.split ("/");
|
|
|
|
|
|
|
|
if (list.size () < 8) {
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_FAILED, "Invalid serialization");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list[n++] != "qca-pkcs11") {
|
|
|
|
throw PKCS11Exception (CKR_FUNCTION_FAILED, "Invalid serialization");
|
|
|
|
}
|
|
|
|
|
|
|
|
pkcs11h_token_id_s token_id_s;
|
|
|
|
pkcs11h_certificate_id_s certificate_id_s;
|
|
|
|
|
|
|
|
memset (&token_id_s, 0, sizeof (token_id_s));
|
|
|
|
memset (&certificate_id_s, 0, sizeof (certificate_id_s));
|
|
|
|
|
|
|
|
certificate_id_s.token_id = &token_id_s;
|
|
|
|
|
|
|
|
strncpy (
|
|
|
|
token_id_s.manufacturerID,
|
|
|
|
qPrintable (unescapeString (list[n++])),
|
|
|
|
sizeof (token_id_s.manufacturerID)
|
|
|
|
);
|
|
|
|
token_id_s.manufacturerID[sizeof (token_id_s.manufacturerID)-1] = '\0';
|
|
|
|
strncpy (
|
|
|
|
token_id_s.model,
|
|
|
|
qPrintable (unescapeString (list[n++])),
|
|
|
|
sizeof (token_id_s.model)
|
|
|
|
);
|
|
|
|
token_id_s.model[sizeof (token_id_s.model)-1] = '\0';
|
|
|
|
strncpy (
|
|
|
|
token_id_s.serialNumber,
|
|
|
|
qPrintable (unescapeString (list[n++])),
|
|
|
|
sizeof (token_id_s.serialNumber)
|
|
|
|
);
|
|
|
|
token_id_s.serialNumber[sizeof (token_id_s.serialNumber)-1] = '\0';
|
|
|
|
strncpy (
|
|
|
|
token_id_s.label,
|
|
|
|
qPrintable (unescapeString (list[n++])),
|
|
|
|
sizeof (token_id_s.label)
|
|
|
|
);
|
|
|
|
token_id_s.serialNumber[sizeof (token_id_s.label)-1] = '\0';
|
|
|
|
|
2006-04-04 10:54:58 +00:00
|
|
|
QSecureArray arrayCKA_ID = Base64 ().stringToArray (unescapeString (list[n++]));
|
2006-04-03 21:14:17 +00:00
|
|
|
certificate_id_s.attrCKA_ID = (unsigned char *)arrayCKA_ID.data ();
|
|
|
|
certificate_id_s.attrCKA_ID_size = (size_t)arrayCKA_ID.size ();
|
|
|
|
|
|
|
|
*fPrivate = list[n++].toInt () != 0;
|
|
|
|
|
2006-04-04 10:54:58 +00:00
|
|
|
QSecureArray arrayCertificate = Base64 ().stringToArray (unescapeString (list[n++]));
|
2006-04-03 21:14:17 +00:00
|
|
|
certificate_id_s.certificate_blob = (unsigned char *)arrayCertificate.data ();
|
|
|
|
certificate_id_s.certificate_blob_size = (size_t)arrayCertificate.size ();
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_duplicateCertificateId (
|
|
|
|
p_certificate_id,
|
|
|
|
&certificate_id_s
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Memory error");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (n < list.size ()) {
|
|
|
|
*listIssuers += Certificate::fromDER (
|
2006-04-04 10:54:58 +00:00
|
|
|
Base64 ().stringToArray (unescapeString (list[n++]))
|
2006-04-03 21:14:17 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::escapeString (
|
|
|
|
const QString &from
|
|
|
|
) const {
|
|
|
|
QString to;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
for (int i=0;i<from.size ();i++) {
|
|
|
|
QChar c = from[i];
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (c == '/' || c == '\\') {
|
2006-04-04 10:54:58 +00:00
|
|
|
to += QString ().sprintf ("\\x%02x", c.toLatin1 ());
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
to += c;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return to;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
MyKeyStoreList::unescapeString (
|
|
|
|
const QString &from
|
|
|
|
) const {
|
|
|
|
QString to;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
for (int i=0;i<from.size ();i++) {
|
|
|
|
QChar c = from[i];
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (c == '\\') {
|
|
|
|
to += QChar ((uchar)from.mid (i+2, 2).toInt (0, 16));
|
|
|
|
i+=3;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
to += c;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
return to;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
using namespace pkcs11QCAPlugin;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// pkcs11Provider
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
pkcs11Provider::pkcs11Provider () {
|
|
|
|
_fLowLevelInitialized = false;
|
|
|
|
_log_level = PKCS11H_LOG_QUITE;
|
|
|
|
_fSlotEventsActive = false;
|
|
|
|
_fSlotEventsLowLevelActive = false;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
pkcs11Provider::~pkcs11Provider () {
|
|
|
|
delete s_keyStoreList;
|
|
|
|
s_keyStoreList = NULL;
|
|
|
|
pkcs11h_terminate ();
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-11-13 05:44:45 +00:00
|
|
|
int pkcs11Provider::version() const
|
|
|
|
{
|
|
|
|
return QCA_VERSION;
|
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void pkcs11Provider::init () {
|
|
|
|
try {
|
|
|
|
QString strLogLevel = qgetenv ("QCA_PKCS11_LOGLEVEL");
|
|
|
|
CK_RV rv;
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (!strLogLevel.isEmpty ()) {
|
|
|
|
_log_level = strLogLevel.toInt ();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rv = pkcs11h_initialize ()) != CKR_OK) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot initialize");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_setLogHook (
|
|
|
|
_logHook,
|
|
|
|
this
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot set hook");
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
pkcs11h_setLogLevel (_log_level);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
if (
|
|
|
|
(rv = pkcs11h_setTokenPromptHook (
|
|
|
|
_tokenPromptHook,
|
|
|
|
this
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot set hook");
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_setPINPromptHook (
|
|
|
|
_pinPromptHook,
|
|
|
|
this
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot set hook");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv == CKR_OK) {
|
|
|
|
_fLowLevelInitialized = true;
|
|
|
|
}
|
|
|
|
}
|
2006-04-06 14:22:48 +00:00
|
|
|
catch (const PKCS11Exception &) {
|
2006-04-03 21:14:17 +00:00
|
|
|
/*CANNOT DO ANYTHING HERE
|
|
|
|
emit_diagnosticText (
|
2006-04-04 10:54:58 +00:00
|
|
|
QString ().sprintf (
|
2006-04-03 21:14:17 +00:00
|
|
|
"PKCS#11: Cannot initialize: %ld-'%s'.\n",
|
|
|
|
e.getRV (),
|
|
|
|
qPrintable (e.getMessage ())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
catch (...) {
|
|
|
|
/*CANNOT DO ANYTHING HERE
|
|
|
|
emit_diagnosticText ("PKCS#11: Unknown error during provider initialization.\n");
|
|
|
|
*/
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
pkcs11Provider::name () const {
|
|
|
|
return "qca-pkcs11";
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
QString
|
|
|
|
pkcs11Provider::credit () const {
|
|
|
|
return "RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).";
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList
|
|
|
|
pkcs11Provider::features() const {
|
|
|
|
QStringList list;
|
|
|
|
list += "smartcard"; // indicator, not algorithm
|
|
|
|
list += "pkey";
|
|
|
|
list += "keystorelist";
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
QCA::Provider::Context
|
|
|
|
*pkcs11Provider::createContext (const QString &type) {
|
|
|
|
if (_fLowLevelInitialized) {
|
|
|
|
if(type == "keystorelist") {
|
|
|
|
if (s_keyStoreList == NULL) {
|
|
|
|
s_keyStoreList = new MyKeyStoreList (this);
|
|
|
|
return s_keyStoreList;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::startSlotEvents () {
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
if (_fLowLevelInitialized) {
|
|
|
|
if (!_fSlotEventsLowLevelActive) {
|
|
|
|
if (
|
|
|
|
(rv = pkcs11h_setSlotEventHook (
|
|
|
|
_slotEventHook,
|
|
|
|
this
|
|
|
|
)) != CKR_OK
|
|
|
|
) {
|
|
|
|
throw PKCS11Exception (rv, "Cannot start slot events");
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_fSlotEventsLowLevelActive = true;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
_fSlotEventsActive = true;
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::stopSlotEvents () {
|
|
|
|
_fSlotEventsActive = false;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::_logHook (
|
|
|
|
const void *pData,
|
|
|
|
const unsigned flags,
|
|
|
|
const char * const szFormat,
|
|
|
|
va_list args
|
|
|
|
) {
|
|
|
|
pkcs11Provider *me = (pkcs11Provider *)pData;
|
|
|
|
me->logHook (flags, szFormat, args);
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::_slotEventHook (
|
|
|
|
const void *pData
|
|
|
|
) {
|
|
|
|
pkcs11Provider *me = (pkcs11Provider *)pData;
|
|
|
|
me->slotEventHook ();
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11H_BOOL
|
|
|
|
pkcs11Provider::_tokenPromptHook (
|
|
|
|
const void *pData,
|
|
|
|
const pkcs11h_token_id_t token
|
|
|
|
) {
|
|
|
|
pkcs11Provider *me = (pkcs11Provider *)pData;
|
|
|
|
return me->cardPromptHook (token);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11H_BOOL
|
|
|
|
pkcs11Provider::_pinPromptHook (
|
|
|
|
const void *pData,
|
|
|
|
const pkcs11h_token_id_t token,
|
|
|
|
char * const szPIN,
|
|
|
|
const size_t nMaxPIN
|
|
|
|
) {
|
|
|
|
pkcs11Provider *me = (pkcs11Provider *)pData;
|
|
|
|
return me->pinPromptHook (token, szPIN, nMaxPIN);
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::logHook (
|
|
|
|
const unsigned flags,
|
|
|
|
const char * const szFormat,
|
|
|
|
va_list args
|
|
|
|
) {
|
|
|
|
Q_UNUSED(flags);
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
vprintf (szFormat, args);
|
|
|
|
printf ("\n");
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
void
|
|
|
|
pkcs11Provider::slotEventHook () {
|
|
|
|
/*
|
|
|
|
* This is called from a seperate
|
|
|
|
* thread.
|
|
|
|
*/
|
|
|
|
if (s_keyStoreList != NULL && _fSlotEventsActive) {
|
|
|
|
s_keyStoreList->emit_updated ();
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
2006-04-03 21:14:17 +00:00
|
|
|
PKCS11H_BOOL
|
|
|
|
pkcs11Provider::cardPromptHook (
|
|
|
|
const pkcs11h_token_id_t token
|
|
|
|
) {
|
|
|
|
printf ("PKCS#11: Token prompt '%s'\n", token->label);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PKCS11H_BOOL
|
|
|
|
pkcs11Provider::pinPromptHook (
|
|
|
|
const pkcs11h_token_id_t token,
|
|
|
|
char * const szPIN,
|
|
|
|
const size_t nMaxPIN
|
|
|
|
) {
|
|
|
|
QSecureArray pin;
|
|
|
|
if (s_keyStoreList != NULL) {
|
|
|
|
|
2006-04-07 11:13:05 +00:00
|
|
|
s_keyStoreList->pinPrompt (token, pin);
|
2006-04-03 21:14:17 +00:00
|
|
|
|
|
|
|
if (!pin.isEmpty ()) {
|
|
|
|
if ((size_t)pin.size () < nMaxPIN-1) {
|
|
|
|
memmove (szPIN, pin.constData (), pin.size ());
|
|
|
|
szPIN[pin.size ()] = '\0';
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
}
|
2006-04-03 21:14:17 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-07-28 12:41:07 +00:00
|
|
|
|
|
|
|
class pkcs11Plugin : public QCAPlugin
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2006-02-25 00:40:51 +00:00
|
|
|
Q_INTERFACES(QCAPlugin)
|
2006-04-03 21:14:17 +00:00
|
|
|
|
2005-07-28 12:41:07 +00:00
|
|
|
public:
|
|
|
|
virtual QCA::Provider *createProvider() { return new pkcs11Provider; }
|
|
|
|
};
|
|
|
|
|
|
|
|
#include "qca-pkcs11.moc"
|
|
|
|
|
2006-02-25 00:40:51 +00:00
|
|
|
Q_EXPORT_PLUGIN2(qca-pkcs11, pkcs11Plugin);
|