mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
more Smart card
- add support to store a certificate on the card (did not work with my TCOS card, but in theory....) - init PIN via PUK - be more robust regarding card changes - improve PIN handling
This commit is contained in:
parent
7cf3862467
commit
f41411902f
@ -197,6 +197,10 @@ void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
if (key->isScard()) {
|
||||
menu->addAction(tr("Change PIN"), this,
|
||||
SLOT(changePin()));
|
||||
menu->addAction(tr("Init PIN with SO PIN (PUK)"), this,
|
||||
SLOT(initPin()));
|
||||
menu->addAction(tr("Change SO PIN (PUK)"), this,
|
||||
SLOT(changeSoPin()));
|
||||
}
|
||||
}
|
||||
menu->exec(e->globalPos());
|
||||
@ -295,10 +299,43 @@ void db_key::changePin()
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isScard()) {
|
||||
throw errorEx(tr("Tried to change password of a smart card"));
|
||||
throw errorEx(tr("Tried to change PIN of a key"));
|
||||
}
|
||||
scard->changePin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::initPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isScard()) {
|
||||
throw errorEx(tr("Tried to init PIN of a key"));
|
||||
}
|
||||
scard->initPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::changeSoPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isScard()) {
|
||||
throw errorEx(tr("Tried to change SO PIN of a key"));
|
||||
}
|
||||
scard->changeSoPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,8 @@ class db_key: public db_base
|
||||
void setOwnPass();
|
||||
void resetOwnPass();
|
||||
void changePin();
|
||||
void initPin();
|
||||
void changeSoPin();
|
||||
|
||||
signals:
|
||||
void delKey(pki_key *delkey);
|
||||
|
||||
@ -549,10 +549,10 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
QMenu *subExport, *subCa;
|
||||
QAction *itemReq, *itemRevoke, *itemExtend,
|
||||
*itemTrust;
|
||||
bool parentCanSign, canSign, hasTemplates, hasPrivkey;
|
||||
QAction *itemReq, *itemRevoke, *itemExtend, *itemTrust, *itemScard;
|
||||
bool parentCanSign, canSign, hasTemplates;
|
||||
currentIdx = index;
|
||||
pki_key *privkey;
|
||||
|
||||
pki_x509 *cert = static_cast<pki_x509*>(index.internalPointer());
|
||||
|
||||
@ -567,6 +567,8 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
subExport->addAction(tr("File"), this, SLOT(store()));
|
||||
itemReq = subExport->addAction(tr("Request"),
|
||||
this, SLOT(toRequest()));
|
||||
itemScard = subExport->addAction(tr("Smart Card"),
|
||||
this, SLOT(toScard()));
|
||||
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
itemTrust = menu->addAction(tr("Trust"), this, SLOT(setTrust()));
|
||||
@ -594,13 +596,14 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
&& (cert->getSigner() != cert));
|
||||
canSign = cert->canSign();
|
||||
hasTemplates = mainwin->temps->getDesc().count() > 0 ;
|
||||
hasPrivkey = cert->getRefKey();
|
||||
privkey = cert->getRefKey();
|
||||
itemRevoke->setEnabled(parentCanSign);
|
||||
itemExtend->setEnabled(parentCanSign);
|
||||
subCa->setEnabled(canSign);
|
||||
itemReq->setEnabled(hasPrivkey);
|
||||
itemReq->setEnabled(privkey);
|
||||
itemScard->setEnabled(privkey && privkey->isScard());
|
||||
#if 0
|
||||
subP7->setEnabled(hasPrivkey);
|
||||
subP7->setEnabled(privkey);
|
||||
#endif
|
||||
}
|
||||
menu->exec(e->globalPos());
|
||||
@ -1013,6 +1016,18 @@ void db_x509::toRequest()
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::toScard()
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
try {
|
||||
cert->store_token();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::caProperties()
|
||||
{
|
||||
Ui::CaProperties ui;
|
||||
|
||||
@ -66,6 +66,7 @@ class db_x509: public db_x509super
|
||||
void genCrl();
|
||||
void caProperties();
|
||||
void toRequest();
|
||||
void toScard();
|
||||
void newCert(pki_temp *);
|
||||
void newCert(pki_x509req *);
|
||||
void loadPKCS12();
|
||||
|
||||
@ -37,3 +37,22 @@ void pk11_attr_data::load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
pkcs11::pk11error("C_GetAttributeValue(data)", rv); \
|
||||
}
|
||||
|
||||
void pk11_attr_data::setValue(const void *ptr, unsigned long len)
|
||||
{
|
||||
if (attr.pValue)
|
||||
free(attr.pValue);
|
||||
attr.pValue = malloc(len);
|
||||
if (!attr.pValue)
|
||||
throw errorEx("Out of Memory");
|
||||
memcpy(attr.pValue, ptr, len);
|
||||
attr.ulValueLen = len;
|
||||
}
|
||||
|
||||
void pk11_attribute::store(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
CK_RV rv;
|
||||
rv = pkcs11::p11->C_SetAttributeValue(sess, obj, &attr, 1);
|
||||
if (rv != CKR_OK)
|
||||
pkcs11::pk11error("C_SetAttributeValue", rv);
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ public:
|
||||
{
|
||||
return &attr;
|
||||
}
|
||||
void store(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
|
||||
};
|
||||
|
||||
class pk11_attr_ulong: public pk11_attribute
|
||||
@ -45,7 +46,6 @@ public:
|
||||
attr.pValue = &value;
|
||||
attr.ulValueLen = sizeof(value);
|
||||
}
|
||||
|
||||
unsigned long getValue() const
|
||||
{
|
||||
return value;
|
||||
@ -66,13 +66,11 @@ public:
|
||||
attr.pValue = NULL;
|
||||
attr.ulValueLen = 0;
|
||||
}
|
||||
|
||||
unsigned long getValue(const unsigned char **ptr)
|
||||
{
|
||||
*ptr = (unsigned char*)attr.pValue;
|
||||
return attr.ulValueLen;
|
||||
}
|
||||
|
||||
~pk11_attr_data()
|
||||
{
|
||||
if (attr.pValue)
|
||||
@ -84,11 +82,11 @@ public:
|
||||
}
|
||||
BIGNUM *getBignum() const
|
||||
{
|
||||
printf("attr.ulValueLen %lu\n", attr.ulValueLen);
|
||||
return BN_bin2bn((unsigned char*)attr.pValue,
|
||||
attr.ulValueLen, NULL);
|
||||
}
|
||||
void load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
|
||||
void setValue(const void *ptr, unsigned long len);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -21,17 +21,6 @@ pkcs11::pkcs11()
|
||||
session = CK_INVALID_HANDLE;
|
||||
object = CK_INVALID_HANDLE;
|
||||
slot_id = 0;
|
||||
|
||||
init_pkcs11();
|
||||
}
|
||||
|
||||
void pkcs11::init_pkcs11()
|
||||
{
|
||||
if (p11) {
|
||||
CK_RV rv = p11->C_Initialize(NULL);
|
||||
if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)
|
||||
pk11error("C_Initialize", rv);
|
||||
}
|
||||
}
|
||||
|
||||
pkcs11::~pkcs11()
|
||||
@ -59,27 +48,69 @@ void pkcs11::startSession(unsigned long slot, bool rw)
|
||||
CK_SLOT_ID *pkcs11::getSlotList(unsigned long *num_slots)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_SLOT_ID *p11_slots;
|
||||
CK_SLOT_ID *p11_slots = NULL;
|
||||
|
||||
rv = p11->C_GetSlotList(CK_TRUE, NULL, num_slots);
|
||||
if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
|
||||
pk11error("C_GetSlotList", rv);
|
||||
p11_slots = (CK_SLOT_ID *)malloc(*num_slots *sizeof(CK_SLOT_ID));
|
||||
//oom_check(p11_slots);
|
||||
|
||||
rv = p11->C_GetSlotList(CK_TRUE, p11_slots, num_slots);
|
||||
if (rv != CKR_OK)
|
||||
pk11error("C_GetSlotList", rv);
|
||||
p11->C_GetSlotList(CK_TRUE, p11_slots, num_slots);
|
||||
do {
|
||||
rv = p11->C_GetSlotList(CK_TRUE, p11_slots, num_slots);
|
||||
if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)
|
||||
pk11error("C_GetSlotList", rv);
|
||||
printf("*num_slots = %d\n", *num_slots);
|
||||
if (*num_slots == 0)
|
||||
break;
|
||||
p11_slots = (CK_SLOT_ID *)realloc(p11_slots,
|
||||
*num_slots *sizeof(CK_SLOT_ID));
|
||||
if (!p11_slots)
|
||||
throw errorEx("C_GetSlotList(Out of Memory)");
|
||||
} while (rv == CKR_BUFFER_TOO_SMALL);
|
||||
return p11_slots;
|
||||
}
|
||||
|
||||
void pkcs11::login(unsigned long slot,
|
||||
unsigned char *pin, unsigned long pinlen, bool so)
|
||||
void pkcs11::logout()
|
||||
{
|
||||
CK_RV rv;
|
||||
|
||||
rv = p11->C_Logout(session);
|
||||
if (rv != CKR_OK)
|
||||
pk11error("C_Logout", rv);
|
||||
}
|
||||
|
||||
bool pkcs11::needsLogin(bool so)
|
||||
{
|
||||
CK_SESSION_INFO sinfo;
|
||||
CK_RV rv;
|
||||
|
||||
rv = p11->C_GetSessionInfo(session, &sinfo);
|
||||
if (rv != CKR_OK)
|
||||
pk11error("C_GetSessionInfo", rv);
|
||||
switch (sinfo.state) {
|
||||
case CKS_RO_PUBLIC_SESSION:
|
||||
case CKS_RW_PUBLIC_SESSION:
|
||||
return true;
|
||||
case CKS_RW_SO_FUNCTIONS:
|
||||
if (so) {
|
||||
return false;
|
||||
} else {
|
||||
logout();
|
||||
return true;
|
||||
}
|
||||
case CKS_RO_USER_FUNCTIONS:
|
||||
case CKS_RW_USER_FUNCTIONS:
|
||||
if (!so) {
|
||||
return false;
|
||||
} else {
|
||||
logout();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void pkcs11::login(unsigned char *pin, unsigned long pinlen, bool so)
|
||||
{
|
||||
unsigned long user = so ? CKU_SO : CKU_USER;
|
||||
CK_RV rv;
|
||||
|
||||
startSession(slot, true);
|
||||
rv = p11->C_Login(session, user, pin, pinlen);
|
||||
if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
|
||||
pk11error("C_Login", rv);
|
||||
@ -126,6 +157,11 @@ void pkcs11::loadAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object)
|
||||
attribute.load(session, object);
|
||||
}
|
||||
|
||||
void pkcs11::storeAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object)
|
||||
{
|
||||
attribute.store(session, object);
|
||||
}
|
||||
|
||||
QList<CK_OBJECT_HANDLE> pkcs11::objectList(const pk11_attribute *att)
|
||||
{
|
||||
CK_RV rv;
|
||||
|
||||
@ -31,9 +31,12 @@ class pkcs11
|
||||
CK_SLOT_ID *getSlotList(unsigned long *num_slots);
|
||||
void loadAttribute(pk11_attribute &attribute,
|
||||
CK_OBJECT_HANDLE object);
|
||||
void storeAttribute(pk11_attribute &attribute,
|
||||
CK_OBJECT_HANDLE object);
|
||||
QList<CK_OBJECT_HANDLE> objectList(const pk11_attribute *att);
|
||||
void login(unsigned long slot,
|
||||
unsigned char *pin, unsigned long pinlen, bool so);
|
||||
void login(unsigned char *pin, unsigned long pinlen, bool so);
|
||||
void logout();
|
||||
bool needsLogin(bool so);
|
||||
void setPin(unsigned char *oldPin, unsigned long oldPinLen,
|
||||
unsigned char *pin, unsigned long pinLen);
|
||||
void initPin(unsigned char *pin, unsigned long pinLen);
|
||||
|
||||
@ -38,24 +38,26 @@ QPixmap *pki_scard::icon[1] = { NULL };
|
||||
#define XCA_ENGINE_cmd(e, cmd, value) \
|
||||
do { \
|
||||
if (!ENGINE_ctrl_cmd_string(e, cmd, value, 0)) { \
|
||||
openssl_error(); \
|
||||
printf("FAILED: '%s' : '%s'\n", cmd, value ? value:"");\
|
||||
ENGINE_free(e); \
|
||||
return 0; \
|
||||
} \
|
||||
printf("SUCCESS: '%s' : '%s'\n", cmd, value ? value:""); \
|
||||
} while(0);
|
||||
|
||||
ENGINE *pki_scard::p11_engine = NULL;
|
||||
|
||||
int pki_scard::init_p11engine(void) const
|
||||
int pki_scard::init_p11engine(void)
|
||||
{
|
||||
ENGINE *e;
|
||||
|
||||
if (p11_engine)
|
||||
return 1;
|
||||
|
||||
pkcs11::load_lib("", true);
|
||||
|
||||
ENGINE_load_dynamic();
|
||||
e = ENGINE_by_id("dynamic");
|
||||
openssl_error();
|
||||
|
||||
XCA_ENGINE_cmd(e, "SO_PATH", ENGINE_LIB);
|
||||
XCA_ENGINE_cmd(e, "ID", "pkcs11");
|
||||
@ -63,6 +65,7 @@ int pki_scard::init_p11engine(void) const
|
||||
XCA_ENGINE_cmd(e, "LOAD", NULL);
|
||||
XCA_ENGINE_cmd(e, "MODULE_PATH", PKCS11_DEFAULT_MODULE_NAME);
|
||||
|
||||
ENGINE_init(e);
|
||||
p11_engine = e;
|
||||
return 1;
|
||||
}
|
||||
@ -137,9 +140,7 @@ int pki_scard::prepare_card() const
|
||||
CK_SLOT_ID *p11_slots = NULL;
|
||||
unsigned long i, num_slots;
|
||||
|
||||
|
||||
while (1) {
|
||||
p11.init_pkcs11();
|
||||
p11_slots = p11.getSlotList(&num_slots);
|
||||
for (i=0; i<num_slots; i++) {
|
||||
pkcs11 myp11;
|
||||
@ -260,20 +261,62 @@ QString pki_scard::getTypeString(void)
|
||||
return tr("SmartCard") + " " + pki_key::getTypeString();
|
||||
}
|
||||
|
||||
QString pki_scard::scardLogin(pkcs11 &p11, bool so, bool force) const
|
||||
{
|
||||
char pin[256];
|
||||
int pinlen;
|
||||
bool need_login;
|
||||
|
||||
QString text = so ?
|
||||
tr("Please enter the SO PIN (PUK) of the token: "):
|
||||
tr("Please enter the PIN of the token: ");
|
||||
|
||||
pass_info p(XCA_TITLE, text + getIntName());
|
||||
p.setPin();
|
||||
need_login = p11.needsLogin(so);
|
||||
if (force || need_login) {
|
||||
if (!need_login)
|
||||
p11.logout();
|
||||
pinlen = MainWindow::passRead(pin, 256, 0, &p);
|
||||
if (pinlen == -1)
|
||||
return QString();
|
||||
p11.login((unsigned char*)pin, pinlen, so);
|
||||
} else {
|
||||
return QString("");
|
||||
}
|
||||
return QString::fromLocal8Bit(pin, pinlen);
|
||||
}
|
||||
|
||||
EVP_PKEY *pki_scard::decryptKey() const
|
||||
{
|
||||
int slot_id = prepare_card();
|
||||
int slot_id;
|
||||
QString pin;
|
||||
struct {
|
||||
const void *password;
|
||||
const char *prompt_info;
|
||||
} cb_data = { NULL, NULL };
|
||||
|
||||
pass_info p(XCA_TITLE,
|
||||
pki_scard::tr("Please enter the PIN of the token: ") +
|
||||
getIntName());
|
||||
p.setPin();
|
||||
|
||||
slot_id = prepare_card();
|
||||
if (slot_id == -1)
|
||||
return NULL;
|
||||
|
||||
QString key_id = QString("%1:").arg(slot_id) + object_id;
|
||||
printf("SLOT:ID = '%s'\n", CCHAR(key_id));
|
||||
init_p11engine();
|
||||
ENGINE_init(p11_engine);
|
||||
ign_openssl_error();
|
||||
|
||||
pkcs11 p11;
|
||||
p11.startSession(slot_id, true);
|
||||
pin = scardLogin(p11, false);
|
||||
if (pin.isNull())
|
||||
return NULL;
|
||||
cb_data.password = CCHAR(pin);
|
||||
EVP_PKEY *pkey = ENGINE_load_private_key(p11_engine, CCHAR(key_id),
|
||||
NULL, NULL);
|
||||
NULL, &cb_data);
|
||||
openssl_error();
|
||||
return pkey;
|
||||
}
|
||||
|
||||
@ -282,8 +325,72 @@ void pki_scard::changePin()
|
||||
char oldPin[256], newPin[256];
|
||||
int slot;
|
||||
|
||||
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
|
||||
"Please enter the PIN of the token: ")+ getIntName());
|
||||
pass_info p(XCA_TITLE,
|
||||
pki_scard::tr("Please enter the PIN of the token: ") +
|
||||
getIntName());
|
||||
p.setPin();
|
||||
|
||||
slot = prepare_card();
|
||||
if (slot == -1)
|
||||
return;
|
||||
|
||||
int oldPinLen = MainWindow::passRead(oldPin, 256, 0, &p);
|
||||
if (oldPinLen == -1)
|
||||
return;
|
||||
|
||||
pkcs11 p11;
|
||||
p11.startSession(slot, true);
|
||||
p11.logout();
|
||||
p11.login((unsigned char*)oldPin, oldPinLen, false);
|
||||
p.setDescription(qApp->translate("MainWindow",
|
||||
"Please enter the new Pin for the token: ") +getIntName());
|
||||
|
||||
int newPinLen = MainWindow::passWrite(newPin, 256, 0, &p);
|
||||
if (newPinLen != -1) {
|
||||
p11.setPin((unsigned char*)oldPin, oldPinLen,
|
||||
(unsigned char*)newPin, newPinLen);
|
||||
}
|
||||
}
|
||||
|
||||
void pki_scard::initPin()
|
||||
{
|
||||
char soPin[256], newPin[256];
|
||||
int slot;
|
||||
|
||||
pass_info p(XCA_TITLE,
|
||||
pki_scard::tr("Please enter the SO PIN (PUK) of the token: ") +
|
||||
getIntName());
|
||||
p.setPin();
|
||||
|
||||
slot = prepare_card();
|
||||
if (slot == -1)
|
||||
return;
|
||||
pkcs11 p11;
|
||||
p11.startSession(slot, true);
|
||||
if (p11.needsLogin(true)) {
|
||||
int soPinLen = MainWindow::passRead(soPin, 256, 0, &p);
|
||||
if (soPinLen == -1)
|
||||
return;
|
||||
p11.login((unsigned char*)soPin, soPinLen, true);
|
||||
}
|
||||
p.setDescription(qApp->translate("MainWindow",
|
||||
"Please enter the new Pin for the token: ") +getIntName());
|
||||
|
||||
int newPinLen = MainWindow::passWrite(newPin, 256, 0, &p);
|
||||
if (newPinLen != -1) {
|
||||
p11.initPin((unsigned char*)newPin, newPinLen);
|
||||
}
|
||||
p11.logout();
|
||||
}
|
||||
|
||||
void pki_scard::changeSoPin()
|
||||
{
|
||||
char oldPin[256], newPin[256];
|
||||
int slot;
|
||||
|
||||
pass_info p(XCA_TITLE,
|
||||
pki_scard::tr("Please enter the SO PIN (PUK) of the token: ") +
|
||||
getIntName());
|
||||
p.setPin();
|
||||
|
||||
slot = prepare_card();
|
||||
@ -293,48 +400,19 @@ void pki_scard::changePin()
|
||||
if (oldPinLen == -1)
|
||||
return;
|
||||
pkcs11 p11;
|
||||
p11.init_pkcs11();
|
||||
p11.login(slot, (unsigned char*)oldPin, oldPinLen, false);
|
||||
p11.startSession(slot, true);
|
||||
p11.logout();
|
||||
p11.login((unsigned char*)oldPin, oldPinLen, true);
|
||||
|
||||
p.setDescription(qApp->translate("MainWindow",
|
||||
"Please enter the new Pin for the token: ") +getIntName());
|
||||
"Please enter the new SO Pin for the token: ") +getIntName());
|
||||
|
||||
int newPinLen = MainWindow::passWrite(newPin, 256, 0, &p);
|
||||
if (newPinLen == -1)
|
||||
return;
|
||||
|
||||
p11.setPin((unsigned char*)oldPin, oldPinLen,
|
||||
(unsigned char*)newPin, newPinLen);
|
||||
}
|
||||
|
||||
void pki_scard::initPin()
|
||||
{
|
||||
char soPin[256], newPin[256];
|
||||
int slot;
|
||||
|
||||
pass_info p(XCA_TITLE, qApp->translate("MainWindow",
|
||||
"Please enter the SO PIN (PUK) of the token: ") +
|
||||
getIntName());
|
||||
p.setPin();
|
||||
|
||||
slot = prepare_card();
|
||||
if (slot == -1)
|
||||
return;
|
||||
int soPinLen = MainWindow::passRead(soPin, 256, 0, &p);
|
||||
if (soPinLen == -1)
|
||||
return;
|
||||
pkcs11 p11;
|
||||
p11.init_pkcs11();
|
||||
p11.login(slot, (unsigned char*)soPin, soPinLen, true);
|
||||
|
||||
p.setDescription(qApp->translate("MainWindow",
|
||||
"Please enter the new Pin for the token: ") +getIntName());
|
||||
|
||||
int newPinLen = MainWindow::passWrite(newPin, 256, 0, &p);
|
||||
if (newPinLen == -1)
|
||||
return;
|
||||
|
||||
p11.initPin((unsigned char*)newPin, newPinLen);
|
||||
if (newPinLen == -1) {
|
||||
p11.setPin((unsigned char*)oldPin, oldPinLen,
|
||||
(unsigned char*)newPin, newPinLen);
|
||||
}
|
||||
p11.logout();
|
||||
}
|
||||
|
||||
int pki_scard::verify()
|
||||
|
||||
@ -32,7 +32,7 @@ class pki_scard: public pki_key
|
||||
virtual ~pki_scard();
|
||||
static QPixmap *icon[1];
|
||||
void load_token(pkcs11 &p11, CK_OBJECT_HANDLE object);
|
||||
int init_p11engine(void) const;
|
||||
static int init_p11engine(void);
|
||||
int prepare_card() const;
|
||||
void fromData(const unsigned char *p, db_header_t *head);
|
||||
unsigned char *toData(int *size);
|
||||
@ -45,8 +45,10 @@ class pki_scard: public pki_key
|
||||
QString getCardLabel() const { return card_label; }
|
||||
EVP_PKEY *decryptKey() const;
|
||||
QString length();
|
||||
QString scardLogin(pkcs11 &p11, bool so, bool force=false)const;
|
||||
void changePin();
|
||||
void initPin();
|
||||
void changeSoPin();
|
||||
int verify();
|
||||
bool isScard();
|
||||
QVariant getIcon();
|
||||
|
||||
@ -8,8 +8,12 @@
|
||||
|
||||
#include "pki_x509.h"
|
||||
#include "pki_evp.h"
|
||||
#include "pki_scard.h"
|
||||
#include "func.h"
|
||||
#include "base.h"
|
||||
#include "exception.h"
|
||||
#include "pass_info.h"
|
||||
#include "widgets/MainWindow.h"
|
||||
#include <qdir.h>
|
||||
|
||||
QPixmap *pki_x509::icon[5] = { NULL, NULL, NULL, NULL, NULL };
|
||||
@ -172,6 +176,45 @@ void pki_x509::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object)
|
||||
openssl_error();
|
||||
}
|
||||
|
||||
void pki_x509::store_token()
|
||||
{
|
||||
pki_scard *card = (pki_scard *)privkey;
|
||||
int slot, size;
|
||||
unsigned char*p, *p1;
|
||||
QList<CK_OBJECT_HANDLE> objects;
|
||||
|
||||
if (!privkey || !privkey->isScard())
|
||||
throw errorEx(tr("No associated Smart card"));
|
||||
|
||||
slot = card->prepare_card();
|
||||
|
||||
size = i2d_X509(cert, NULL);
|
||||
openssl_error();
|
||||
p = p1 = (unsigned char*)OPENSSL_malloc(size);
|
||||
|
||||
i2d_X509(cert, &p1);
|
||||
openssl_error();
|
||||
pk11_attr_data x509(CKA_VALUE);
|
||||
x509.setValue(p, size);
|
||||
free(p);
|
||||
|
||||
pk11_attr_ulong class_att = pk11_attr_ulong(CKA_CLASS);
|
||||
class_att.setValue(CKO_CERTIFICATE);
|
||||
|
||||
pkcs11 p11;
|
||||
p11.startSession(slot, true);
|
||||
objects = p11.objectList(&class_att);
|
||||
if (objects.count() == 0)
|
||||
throw errorEx(tr("No certificate object found"));
|
||||
if (objects.count() > 1)
|
||||
throw errorEx(tr("More than one certificate objects found"));
|
||||
|
||||
if (card->scardLogin(p11, false).isNull())
|
||||
return;
|
||||
p11.storeAttribute(x509, objects[0]);
|
||||
openssl_error();
|
||||
}
|
||||
|
||||
bool pki_x509::verifyQASerial(const a1int &secret) const
|
||||
{
|
||||
return getQASerial(secret) == getSerial();
|
||||
@ -329,8 +372,7 @@ unsigned char *pki_x509::toData(int *size)
|
||||
*size = i2d_X509(cert, NULL) + 11 + caSerial.toHex().length() +
|
||||
caTemplate.length() + crlExpiry.derSize() + revoked.derSize();
|
||||
openssl_error();
|
||||
p = (unsigned char*)OPENSSL_malloc(*size);
|
||||
p1 = p;
|
||||
p = p1 = (unsigned char*)OPENSSL_malloc(*size);
|
||||
|
||||
i2d_X509(cert, &p1); // cert
|
||||
db::intToData(&p1, trust); // trust
|
||||
|
||||
@ -44,6 +44,7 @@ class pki_x509 : public pki_x509super
|
||||
|
||||
void fload(const QString fname);
|
||||
void load_token(pkcs11 &p11, CK_OBJECT_HANDLE object);
|
||||
void store_token();
|
||||
void fromPEM_BIO(BIO *bio, QString name);
|
||||
void writeDefault(const QString fname);
|
||||
a1int hashInfo(const EVP_MD *md) const;
|
||||
|
||||
@ -151,7 +151,7 @@ MainWindow::MainWindow(QWidget *parent )
|
||||
homedir = getHomeDir();
|
||||
|
||||
init_curves();
|
||||
pkcs11::load_lib("", true);
|
||||
pki_scard::init_p11engine();
|
||||
|
||||
// FIXME: Change pass isn't functional yet.
|
||||
BNchangePass->setDisabled(true);
|
||||
@ -357,6 +357,9 @@ void MainWindow::importScard()
|
||||
pk11_attr_ulong class_att = pk11_attr_ulong(CKA_CLASS);
|
||||
p11_slots = p11.getSlotList(&num_slots);
|
||||
|
||||
if (num_slots == 0)
|
||||
QMessageBox::warning(this, XCA_TITLE,
|
||||
tr("No Smart card found"));
|
||||
for (i=0; i<num_slots; i++) {
|
||||
p11.startSession(i);
|
||||
|
||||
@ -482,6 +485,25 @@ int MainWindow::initPass()
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hex2bin(QString &x, char *buf, int buflen)
|
||||
{
|
||||
int len = x.length();
|
||||
bool ok = false;
|
||||
if (len % 2)
|
||||
return -1;
|
||||
len /= 2;
|
||||
if (len > buflen)
|
||||
return -1;
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
buf[i] = x.mid(i*2, 2).toInt(&ok, 16);
|
||||
if (!ok)
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static const QString hexwarn = MainWindow::tr("Hex password must only contain the characters '0' - '9' and 'a' - 'f' and it must consist of an even number of characters");
|
||||
// Static Password Callback functions
|
||||
int MainWindow::passRead(char *buf, int size, int, void *userdata)
|
||||
{
|
||||
@ -500,15 +522,18 @@ int MainWindow::passRead(char *buf, int size, int, void *userdata)
|
||||
ui.takeHex->hide();
|
||||
}
|
||||
|
||||
if (dlg->exec()) {
|
||||
while (dlg->exec()) {
|
||||
QString x = ui.pass->text();
|
||||
if (ui.takeHex->isChecked()) {
|
||||
// PARSE Hex string
|
||||
abort();
|
||||
ret = hex2bin(x, buf, size);
|
||||
if (ret != -1)
|
||||
break;
|
||||
} else {
|
||||
strncpy(buf, x.toAscii(), size);
|
||||
ret = x.length();
|
||||
break;
|
||||
}
|
||||
QMessageBox::warning(p->getWidget(), XCA_TITLE, hexwarn);
|
||||
}
|
||||
delete dlg;
|
||||
return ret;
|
||||
@ -539,13 +564,24 @@ int MainWindow::passWrite(char *buf, int size, int, void *userdata)
|
||||
QString A = ui.passA->text();
|
||||
QString B = ui.passB->text();
|
||||
if (A == B) {
|
||||
strncpy(buf, A.toAscii(), size);
|
||||
ret = A.length();
|
||||
break;
|
||||
if (ui.takeHex->isChecked()) {
|
||||
ret = hex2bin(A, buf, size);
|
||||
if (ret != -1)
|
||||
break;
|
||||
} else {
|
||||
strncpy(buf, A.toAscii(), size);
|
||||
ret = A.length();
|
||||
break;
|
||||
}
|
||||
QMessageBox::warning(p->getWidget(), XCA_TITLE,
|
||||
hexwarn);
|
||||
} else {
|
||||
QMessageBox::warning(p->getWidget(), tr(XCA_TITLE), p->getType() + tr(" missmatch"));
|
||||
QMessageBox::warning(p->getWidget(), XCA_TITLE,
|
||||
p->getType() + tr(" missmatch"));
|
||||
}
|
||||
}
|
||||
for (int i=0; i<ret; i++)
|
||||
printf("NewPass[%d] = 0x%02x\n", i, buf[i]);
|
||||
delete dlg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user