xca/lib/pki_scard.cpp
Christian Hohnstaedt 4b3ee2c705 Switch database format to SQL(ite)
This is a large squash of many small commits.

Allow porting data from the legacy format to SQL.
Store Binaries base64 encoded and use db->transaction
Update password hash to be 8000 x SHA512 with 8 byte Salt
Add revocations table and fixup CRL generation
Add comment and insertion date columns

Fix column saving, remove trust, add XcaDialog
Allow changing the internal name and comment in Cert/Req details view
Extend Comment functionality, Replace About.ui by XcaDialog.ui
2018-03-05 07:42:36 +01:00

881 lines
19 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2009 -2014 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "pki_scard.h"
#include "pass_info.h"
#include "pk11_attribute.h"
#include "exception.h"
#include "db_base.h"
#include "pkcs11.h"
#include "x509name.h"
#include "func.h"
#include "db.h"
#include "widgets/MainWindow.h"
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <QProgressDialog>
#include <QApplication>
#include <QDir>
#include <QMessageBox>
#include <QThread>
#include <ltdl.h>
#include "openssl_compat.h"
QPixmap *pki_scard::icon[1] = { NULL };
bool pki_scard::only_token_hashes = false;
void pki_scard::init(void)
{
ownPass = ptPin;
pkiType = smartCard;
card_serial = card_manufacturer = card_label = "";
card_model = slot_label = "";
}
const char *pki_scard::getClassName() const
{
return "pki_scard";
}
pki_scard::pki_scard(const QString name)
:pki_key(name)
{
init();
}
QString pki_scard::getMsg(msg_type msg)
{
/*
* We do not construct english sentences from fragments
* to allow proper translations.
*
* %1 will be replaced by the name of the smartcard
*/
switch (msg) {
case msg_import: return tr("Successfully imported the token key '%1'");
case msg_delete: return tr("Delete the token key '%1'?");
case msg_create: return tr("Successfully created the token key '%1'");
/* %1: Number of ktemplates; %2: list of templatenames */
case msg_delete_multi: return tr("Delete the %1 keys: %2?");
}
return pki_base::getMsg(msg);
}
QSqlError pki_scard::insertSqlData()
{
XSqlQuery q;
QSqlError e = pki_key::insertSqlData();
if (e.isValid())
return e;
SQL_PREPARE(q, "INSERT INTO tokens (item, card_manufacturer, card_serial, "
"card_model, card_label, slot_label, "
"object_id) "
"VALUES (?, ?, ?, ?, ?, ?, ?)");
q.bindValue(0, sqlItemId);
q.bindValue(1, card_manufacturer);
q.bindValue(2, card_serial);
q.bindValue(3, card_model);
q.bindValue(4, card_label);
q.bindValue(5, slot_label);
q.bindValue(6, object_id);
q.exec();
e = q.lastError();
if (e.isValid())
return e;
SQL_PREPARE(q, "INSERT INTO token_mechanism (item, mechanism) "
"VALUES (?, ?)");
q.bindValue(0, sqlItemId);
foreach(CK_MECHANISM_TYPE m, mech_list) {
q.bindValue(1, QVariant((uint)m));
q.exec();
}
return q.lastError();
}
QSqlError pki_scard::deleteSqlData()
{
XSqlQuery q;
QSqlError e = pki_key::deleteSqlData();
if (e.isValid())
return e;
SQL_PREPARE(q, "DELETE FROM tokens WHERE item=?");
q.bindValue(0, sqlItemId);
q.exec();
e = q.lastError();
if (e.isValid())
return e;
SQL_PREPARE(q, "DELETE FROM token_mechanism WHERE item=?");
q.bindValue(0, sqlItemId);
q.exec();
return q.lastError();
}
EVP_PKEY *pki_scard::load_pubkey(pkcs11 &p11, CK_OBJECT_HANDLE object) const
{
unsigned long keytype;
EVP_PKEY *pkey = NULL;
pk11_attr_ulong type(CKA_KEY_TYPE);
p11.loadAttribute(type, object);
keytype = type.getValue();
switch (keytype) {
case CKK_RSA: {
RSA *rsa = RSA_new();
pk11_attr_data n(CKA_MODULUS);
p11.loadAttribute(n, object);
pk11_attr_data e(CKA_PUBLIC_EXPONENT);
p11.loadAttribute(e, object);
RSA_set0_key(rsa, n.getBignum(), e.getBignum(), NULL);
pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);
break;
}
case CKK_DSA: {
DSA *dsa = DSA_new();
pk11_attr_data p(CKA_PRIME);
p11.loadAttribute(p, object);
pk11_attr_data q(CKA_SUBPRIME);
p11.loadAttribute(q, object);
pk11_attr_data g(CKA_BASE);
p11.loadAttribute(g, object);
pk11_attr_data pub(CKA_VALUE);
p11.loadAttribute(pub, object);
DSA_set0_pqg(dsa, p.getBignum(), q.getBignum(), g.getBignum());
DSA_set0_key(dsa, pub.getBignum(), NULL);
pkey = EVP_PKEY_new();
EVP_PKEY_assign_DSA(pkey, dsa);
break;
}
#ifndef OPENSSL_NO_EC
case CKK_EC: {
QByteArray ba;
EC_GROUP *group;
ASN1_OCTET_STRING *os;
EC_KEY *ec = EC_KEY_new();
pk11_attr_data grp(CKA_EC_PARAMS);
p11.loadAttribute(grp, object);
ba = grp.getData();
group = (EC_GROUP *)
d2i_bytearray(D2I_VOID(d2i_ECPKParameters), ba);
pki_openssl_error();
EC_GROUP_set_asn1_flag(group, 1);
EC_KEY_set_group(ec, group);
pki_openssl_error();
pk11_attr_data pt(CKA_EC_POINT);
p11.loadAttribute(pt, object);
ba = pt.getData();
os = (ASN1_OCTET_STRING *)
d2i_bytearray(D2I_VOID(d2i_ASN1_OCTET_STRING), ba);
pki_openssl_error();
BIGNUM *bn = BN_bin2bn(os->data, os->length, NULL);
pki_openssl_error();
EC_POINT *point = EC_POINT_bn2point(group, bn, NULL, NULL);
BN_free(bn);
ASN1_OCTET_STRING_free(os);
pki_openssl_error();
EC_KEY_set_public_key(ec, point);
pki_openssl_error();
pkey = EVP_PKEY_new();
EVP_PKEY_assign_EC_KEY(pkey, ec);
break;
}
#endif
default:
throw errorEx(QString("Unsupported CKA_KEY_TYPE: %1\n").arg(keytype));
}
pki_openssl_error();
return pkey;
}
void pki_scard::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object)
{
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);
if (id.getAttribute()->ulValueLen > 0) {
BIGNUM *cka_id = id.getBignum();
object_id = BNoneLine(cka_id);
BN_free(cka_id);
}
try {
pk11_attr_data label(CKA_LABEL);
p11.loadAttribute(label, object);
slot_label = label.getText();
} catch (errorEx &err) {
printf("No PubKey Label: %s\n", err.getCString());
// ignore
}
if (slot_label.isEmpty()) {
try{
x509name xn;
pk11_attr_data subj(CKA_SUBJECT);
p11.loadAttribute(subj, object);
QByteArray der = subj.getData();
xn.d2i(der);
slot_label = xn.getMostPopular();
pki_openssl_error();
} catch (errorEx &err) {
printf("No Pubkey Subject: %s\n", err.getCString());
// ignore
}
}
EVP_PKEY *pkey = load_pubkey(p11, object);
if (pkey) {
if (key)
EVP_PKEY_free(key);
key = pkey;
}
setIntName(slot_label);
pki_openssl_error();
}
pk11_attr_data pki_scard::getIdAttr() const
{
pk11_attr_data id(CKA_ID);
if (object_id.isEmpty())
return id;
BIGNUM *bn = NULL;
BN_hex2bn(&bn, CCHAR(object_id));
id.setBignum(bn, true);
return id;
}
void pki_scard::deleteFromToken()
{
slotid slot;
if (!prepare_card(&slot))
return;
deleteFromToken(slot);
}
pk11_attlist pki_scard::objectAttributesNoId(EVP_PKEY *pk, bool priv) const
{
QByteArray ba;
RSA *rsa;
DSA *dsa;
#ifndef OPENSSL_NO_EC
EC_KEY *ec;
#endif
const BIGNUM *n = NULL;
const BIGNUM *e = NULL;
const BIGNUM *p = NULL;
const BIGNUM *q = NULL;
const BIGNUM *g = NULL;
pk11_attlist attrs(pk11_attr_ulong(CKA_CLASS,
priv ? CKO_PRIVATE_KEY : CKO_PUBLIC_KEY));
switch (EVP_PKEY_type(EVP_PKEY_id(pk))) {
case EVP_PKEY_RSA:
rsa = EVP_PKEY_get0_RSA(pk);
RSA_get0_key(rsa, &n, &e, NULL);
attrs << pk11_attr_ulong(CKA_KEY_TYPE, CKK_RSA) <<
pk11_attr_data(CKA_MODULUS, n) <<
pk11_attr_data(CKA_PUBLIC_EXPONENT, e);
break;
case EVP_PKEY_DSA:
dsa = EVP_PKEY_get0_DSA(pk);
DSA_get0_pqg(dsa, &p, &q, &g);
attrs << pk11_attr_ulong(CKA_KEY_TYPE, CKK_DSA) <<
pk11_attr_data(CKA_PRIME, p) <<
pk11_attr_data(CKA_SUBPRIME, q) <<
pk11_attr_data(CKA_BASE, g);
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
ec = EVP_PKEY_get0_EC_KEY(pk);
ba = i2d_bytearray(I2D_VOID(i2d_ECPKParameters),
EC_KEY_get0_group(ec));
attrs << pk11_attr_ulong(CKA_KEY_TYPE, CKK_EC) <<
pk11_attr_data(CKA_EC_PARAMS, ba);
break;
#endif
default:
throw errorEx(QString("Unknown Keytype %d")
.arg(EVP_PKEY_type(EVP_PKEY_id(pk))));
}
return attrs;
}
pk11_attlist pki_scard::objectAttributes(bool priv) const
{
pk11_attlist attrs = objectAttributesNoId(key, priv);
attrs << getIdAttr();
return attrs;
}
void pki_scard::deleteFromToken(slotid slot)
{
pkcs11 p11;
p11.startSession(slot, true);
tkInfo ti = p11.tokenInfo();
if (!XCA_YESNO(tr("Delete the private key '%1' from the token '%2 (#%3)' ?").
arg(getIntName()).arg(ti.label()).arg(ti.serial())))
return;
if (p11.tokenLogin(card_label, false).isNull())
return;
pk11_attlist atts = objectAttributes(true);
QList<CK_OBJECT_HANDLE> priv_objects = p11.objectList(atts);
atts = objectAttributes(false);
QList<CK_OBJECT_HANDLE> pub_objects = p11.objectList(atts);
p11.deleteObjects(priv_objects);
p11.deleteObjects(pub_objects);
}
int pki_scard::renameOnToken(slotid slot, QString name)
{
pkcs11 p11;
p11.startSession(slot, true);
QList<CK_OBJECT_HANDLE> objs;
if (p11.tokenLogin(card_label, false).isNull())
return 0;
pk11_attr_data label(CKA_LABEL, name.toUtf8());
/* Private key */
pk11_attlist attrs = objectAttributes(true);
objs = p11.objectList(attrs);
if (!objs.count())
return 0;
p11.storeAttribute(label, objs[0]);
/* Public key */
attrs = objectAttributes(false);
objs = p11.objectList(attrs);
if (objs.count())
p11.storeAttribute(label, objs[0]);
return 1;
}
void pki_scard::store_token(slotid slot, EVP_PKEY *pkey)
{
QByteArray ba;
RSA *rsa;
DSA *dsa;
#ifndef OPENSSL_NO_EC
EC_KEY *ec;
#endif
pk11_attlist pub_atts;
pk11_attlist priv_atts;
QList<CK_OBJECT_HANDLE> objects;
const BIGNUM *d = NULL;
const BIGNUM *p = NULL;
const BIGNUM *q = NULL;
const BIGNUM *dmp1 = NULL;
const BIGNUM *dmq1 = NULL;
const BIGNUM *iqmp = NULL;
const BIGNUM *priv_key = NULL;
const BIGNUM *pub_key = NULL;
pub_atts = objectAttributesNoId(pkey, false);
priv_atts = objectAttributesNoId(pkey, true);
pkcs11 p11;
p11.startSession(slot, true);
QList<CK_OBJECT_HANDLE> objs = p11.objectList(pub_atts);
if (objs.count() == 0)
objs = p11.objectList(priv_atts);
if (objs.count() != 0) {
XCA_INFO(tr("This Key is already on the token"));
load_token(p11, objs[0]);
return;
}
pk11_attr_data new_id = p11.findUniqueID(CKO_PUBLIC_KEY);
pub_atts << new_id <<
pk11_attr_bool(CKA_TOKEN, true) <<
pk11_attr_data(CKA_LABEL, getIntName().toUtf8()) <<
pk11_attr_bool(CKA_PRIVATE, false) <<
pk11_attr_bool(CKA_WRAP, true) <<
pk11_attr_bool(CKA_ENCRYPT, true) <<
pk11_attr_bool(CKA_VERIFY, true);
priv_atts << new_id <<
pk11_attr_bool(CKA_TOKEN, true) <<
pk11_attr_data(CKA_LABEL, desc.toUtf8()) <<
pk11_attr_bool(CKA_PRIVATE, true) <<
pk11_attr_bool(CKA_UNWRAP, true) <<
pk11_attr_bool(CKA_DECRYPT, true) <<
pk11_attr_bool(CKA_SIGN, true);
switch (EVP_PKEY_type(EVP_PKEY_id(pkey))) {
case EVP_PKEY_RSA:
rsa = EVP_PKEY_get0_RSA(pkey);
RSA_get0_key(rsa, NULL, NULL, &d);
RSA_get0_factors(rsa, &p, &q);
RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
priv_atts <<
pk11_attr_data(CKA_PRIVATE_EXPONENT, d) <<
pk11_attr_data(CKA_PRIME_1, p) <<
pk11_attr_data(CKA_PRIME_2, q) <<
pk11_attr_data(CKA_EXPONENT_1, dmp1) <<
pk11_attr_data(CKA_EXPONENT_2, dmq1) <<
pk11_attr_data(CKA_COEFFICIENT, iqmp);
break;
case EVP_PKEY_DSA:
dsa = EVP_PKEY_get0_DSA(pkey);
DSA_get0_key(dsa, &pub_key, &priv_key);
priv_atts << pk11_attr_data(CKA_VALUE, priv_key);
pub_atts << pk11_attr_data(CKA_VALUE, pub_key);
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC: {
/* Public Key */
BIGNUM *point;
int size;
unsigned char *buf;
ASN1_OCTET_STRING *os;
ec = EVP_PKEY_get0_EC_KEY(pkey);
point = EC_POINT_point2bn(EC_KEY_get0_group(ec),
EC_KEY_get0_public_key(ec),
EC_KEY_get_conv_form(ec), NULL, NULL);
pki_openssl_error();
size = BN_num_bytes(point);
buf = (unsigned char *)OPENSSL_malloc(size);
check_oom(buf);
BN_bn2bin(point, buf);
os = ASN1_OCTET_STRING_new();
/* set0 -> ASN1_OCTET_STRING_free() also free()s buf */
ASN1_STRING_set0(os, buf, size);
ba = i2d_bytearray(I2D_VOID(i2d_ASN1_OCTET_STRING), os);
ASN1_OCTET_STRING_free(os);
BN_free(point);
pki_openssl_error();
pub_atts << pk11_attr_data(CKA_EC_POINT, ba);
/* Private key */
priv_atts << pk11_attr_data(CKA_VALUE,
EC_KEY_get0_private_key(ec));
break;
}
#endif
default:
throw errorEx(QString("Unknown Keytype %d")
.arg(EVP_PKEY_id(pkey)));
}
tkInfo ti = p11.tokenInfo();
if (p11.tokenLogin(ti.label(), false).isNull())
throw errorEx(tr("PIN input aborted"));
p11.createObject(pub_atts);
p11.createObject(priv_atts);
pub_atts.reset();
pub_atts = objectAttributesNoId(pkey, false);
pub_atts << new_id;
objs = p11.objectList(pub_atts);
if (objs.count() == 0)
throw errorEx(tr("Unable to find copied key on the token"));
load_token(p11, objs[0]);
}
QList<int> pki_scard::possibleHashNids()
{
QList<int> nids;
if (!only_token_hashes)
return pki_key::possibleHashNids();
foreach(CK_MECHANISM_TYPE mechanism, mech_list) {
switch (EVP_PKEY_type(getKeyType())) {
case EVP_PKEY_RSA:
switch (mechanism) {
case CKM_MD5_RSA_PKCS: nids << NID_md5; break;
case CKM_SHA1_RSA_PKCS: nids << NID_sha1; break;
case CKM_SHA256_RSA_PKCS: nids << NID_sha256; break;
case CKM_SHA384_RSA_PKCS: nids << NID_sha384; break;
case CKM_SHA512_RSA_PKCS: nids << NID_sha512; break;
case CKM_RIPEMD160_RSA_PKCS: nids << NID_ripemd160; break;
}
break;
case EVP_PKEY_DSA:
switch (mechanism) {
case CKM_DSA_SHA1: nids << NID_sha1; break;
}
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
switch (mechanism) {
case CKM_ECDSA_SHA1: nids << NID_sha1; break;
}
break;
#endif
}
}
if (nids.count() == 0) {
switch (EVP_PKEY_type(getKeyType())) {
case EVP_PKEY_RSA:
nids << NID_md5 << NID_sha1 << NID_sha256 <<
NID_sha384 << NID_sha512 << NID_ripemd160;
break;
case EVP_PKEY_DSA:
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
#endif
nids << NID_sha1;
break;
}
}
return nids;
}
const EVP_MD *pki_scard::getDefaultMD()
{
if (mech_list.contains(CKM_SHA1_RSA_PKCS))
return EVP_sha1();
if (mech_list.contains(CKM_DSA_SHA1))
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return EVP_sha1();
#else
return EVP_dss1();
#endif
#ifndef OPENSSL_NO_EC
if (mech_list.contains(CKM_ECDSA_SHA1))
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return EVP_sha1();
#else
return EVP_ecdsa();
#endif
#endif
if (mech_list.contains(CKM_SHA512_RSA_PKCS))
return EVP_sha512();
if (mech_list.contains(CKM_SHA384_RSA_PKCS))
return EVP_sha384();
if (mech_list.contains(CKM_SHA256_RSA_PKCS))
return EVP_sha256();
if (mech_list.contains(CKM_RIPEMD160_RSA_PKCS))
return EVP_ripemd160();
if (mech_list.contains(CKM_MD5_RSA_PKCS))
return EVP_md5();
/* Last resort */
return EVP_sha1();
}
/* Assures the correct card is inserted and
* returns the slot ID in slot true on success */
bool pki_scard::prepare_card(slotid *slot, bool verifyPubkey) const
{
pkcs11 p11;
slotidList p11_slots;
int i;
if (!pkcs11::loaded())
return false;
while (1) {
p11_slots = p11.getSlotList();
for (i=0; i<p11_slots.count(); i++) {
pkcs11 myp11;
tkInfo ti = myp11.tokenInfo(p11_slots[i]);
if (ti.label() == card_label &&
ti.serial() == card_serial)
{
break;
}
}
if (i < p11_slots.count())
break;
QString msg = tr("Please insert card: %1 %2 [%3] with Serial: %4").
arg(card_manufacturer).arg(card_model).
arg(card_label).arg(card_serial);
if (!XCA_OKCANCEL(msg)) {
return false;
}
}
*slot = p11_slots[i];
if (!verifyPubkey)
return true;
QList<CK_OBJECT_HANDLE> objects;
p11.startSession(p11_slots[i]);
pk11_attlist cls (pk11_attr_ulong(CKA_CLASS, CKO_PUBLIC_KEY));
cls << getIdAttr();
objects = p11.objectList(cls);
for (int j=0; j< objects.count(); j++) {
CK_OBJECT_HANDLE object = objects[j];
EVP_PKEY *pkey = load_pubkey(p11, object);
if (EVP_PKEY_cmp(key, pkey) == 1)
return true;
if (!object_id.isEmpty())
XCA_WARN(tr("Public Key mismatch. Please re-import card"));
}
return false;
}
class keygenThread: public QThread
{
public:
errorEx err;
pk11_attr_data id;
QString name;
int size;
int curve_nid;
int method;
pkcs11 *p11;
void run()
{
try {
id = p11->generateKey(name, method, size, curve_nid);
} catch (errorEx &e) {
err = e;
}
}
};
void pki_scard::generateKey_card(int type, slotid slot, int size,
int curve_nid, QProgressBar *bar)
{
pk11_attlist atts;
pkcs11 p11;
p11.startSession(slot, true);
p11.getRandom();
tkInfo ti = p11.tokenInfo();
if (p11.tokenLogin(ti.label(), false).isNull())
return;
keygenThread kt;
kt.name = getIntName();
kt.size = size;
kt.curve_nid = curve_nid;
switch (type) {
case EVP_PKEY_RSA:
kt.method = CKM_RSA_PKCS_KEY_PAIR_GEN;
break;
case EVP_PKEY_DSA:
kt.method = CKM_DSA_KEY_PAIR_GEN;
break;
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
kt.method = CKM_EC_KEY_PAIR_GEN;
break;
#endif
default:
throw errorEx(tr("Illegal Key generation method"));
}
kt.p11 = &p11;
kt.start();
while (!kt.wait(20)) {
inc_progress_bar(0, 0, bar);
}
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());
if (objects.count() == 0)
throw errorEx(tr("Unable to find generated key on card"));
load_token(p11, objects[0]);
}
pki_scard::~pki_scard()
{
}
void pki_scard::fromData(const unsigned char *p, db_header_t *head )
{
int version, size;
void *ptr = NULL;
size = head->len - sizeof(db_header_t);
version = head->version;
QByteArray ba((const char*)p, size);
card_serial = db::stringFromData(ba);
card_manufacturer = db::stringFromData(ba);
card_label = db::stringFromData(ba);
slot_label = db::stringFromData(ba);
card_model = db::stringFromData(ba);
if (version < 2)
card_model.clear();
object_id = db::stringFromData(ba);
int count = db::intFromData(ba);
mech_list.clear();
for (int i=0; i<count; i++)
mech_list << db::intFromData(ba);
d2i(ba);
if (key)
ptr = EVP_PKEY_get0(key);
if (!ptr)
throw errorEx(tr("Ignoring unsupported token key"));
if (ba.count() > 0) {
my_error(tr("Wrong Size %1").arg(ba.count()));
}
}
QString pki_scard::getTypeString(void) const
{
return tr("Token %1").arg(pki_key::getTypeString());
}
EVP_PKEY *pki_scard::decryptKey(int oldkey) const
{
slotid slot_id;
QString pin, key_id;
(void)oldkey;
if (!prepare_card(&slot_id))
throw errorEx(tr("Failed to find the key on the token"));
pkcs11 *p11 = new pkcs11();
p11->startSession(slot_id);
pin = p11->tokenLogin(card_label, false);
if (pin.isNull()) {
delete p11;
throw errorEx(tr("Invalid Pin for the token"));
}
pk11_attlist atts = objectAttributes(true);
QList<CK_OBJECT_HANDLE> priv_objects = p11->objectList(atts);
if (priv_objects.count() != 1) {
delete p11;
throw errorEx(tr("Failed to find the key on the token"));
}
EVP_PKEY *pkey = p11->getPrivateKey(key, priv_objects[0]);
if (!pkey) {
delete p11;
throw errorEx(tr("Failed to initialize the key on the token"));
}
pki_openssl_error();
return pkey;
}
void pki_scard::changePin()
{
slotid slot;
if (!prepare_card(&slot))
return;
pkcs11 p11;
p11.changePin(slot, false);
}
void pki_scard::changeSoPin()
{
slotid slot;
if (!prepare_card(&slot))
return;
pkcs11 p11;
p11.changePin(slot, true);
}
void pki_scard::initPin()
{
slotid slot;
if (!prepare_card(&slot))
return;
pkcs11 p11;
p11.initPin(slot);
}
int pki_scard::verify()
{
return true;
}
bool pki_scard::isToken()
{
return true;
}
QVariant pki_scard::getIcon(dbheader *hd)
{
return hd->id == HD_internal_name ? QVariant(*icon[0]) : QVariant();
}
bool pki_scard::visible()
{
QStringList sl;
if (pki_base::visible())
return true;
sl << card_serial << card_manufacturer << card_model <<
card_label << slot_label << object_id;
foreach(QString s, sl) {
if (s.contains(limitPattern))
return true;
}
return false;
}