diff --git a/lib/exception.h b/lib/exception.h index ee05d2e8..59c081de 100644 --- a/lib/exception.h +++ b/lib/exception.h @@ -44,4 +44,5 @@ class errorEx } }; +#define check_oom(ptr) if(!ptr){throw errorEx(QObject::tr("Out of Memory"));} #endif diff --git a/lib/pk11_attribute.cpp b/lib/pk11_attribute.cpp index 78eee42a..991daa8c 100644 --- a/lib/pk11_attribute.cpp +++ b/lib/pk11_attribute.cpp @@ -8,13 +8,14 @@ #include "pkcs11.h" #include "pk11_attribute.h" #include "exception.h" +#include -void pk11_attr_ulong::load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) +void pk11_attribute::load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) { CK_RV rv; rv = pkcs11::p11->C_GetAttributeValue(sess, obj, &attr, 1); if (rv != CKR_OK) - pkcs11::pk11error("C_GetAttributeValue(ulong)", rv); + pkcs11::pk11error("C_GetAttribute()", rv); } void pk11_attr_data::load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) @@ -28,8 +29,7 @@ void pk11_attr_data::load(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) rv = pkcs11::p11->C_GetAttributeValue(sess, obj, &attr, 1); if (rv == CKR_OK) { attr.pValue = malloc(attr.ulValueLen +1); - if (!attr.pValue) - throw errorEx("Out of memory"); + check_oom(attr.pValue); rv = pkcs11::p11->C_GetAttributeValue(sess, obj, &attr, 1); \ if (rv == CKR_OK) return; @@ -37,13 +37,12 @@ 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) +void pk11_attr_data::setValue(const unsigned char *ptr, unsigned long len) { if (attr.pValue) free(attr.pValue); attr.pValue = malloc(len); - if (!attr.pValue) - throw errorEx("Out of Memory"); + check_oom(attr.pValue); memcpy(attr.pValue, ptr, len); attr.ulValueLen = len; } @@ -56,3 +55,52 @@ void pk11_attribute::store(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) pkcs11::pk11error("C_SetAttributeValue", rv); } +pk11_attlist::pk11_attlist(const pk11_attlist &a) +{ + attlen = a.attlen; + alloc_len = a.alloc_len; + if (alloc_len) { + attributes = + (CK_ATTRIBUTE *)malloc(alloc_len *sizeof(*attributes)); + check_oom(attributes); + memcpy(attributes, a.attributes, attlen *sizeof(*attributes)); + } + for (unsigned long i=0; itype = a.attr.type; + attr->ulValueLen = a.attr.ulValueLen; + attr->pValue = malloc(attr->ulValueLen); + memcpy(attr->pValue, a.attr.pValue, attr->ulValueLen); +} + +void pk11_attlist::reset() +{ + for (unsigned long i=0; i pkcs11::getSlotList() p11_slots = (CK_SLOT_ID *)realloc(p11_slots, num_slots *sizeof(CK_SLOT_ID)); - if (!p11_slots) - throw errorEx("C_GetSlotList(Out of Memory)"); + check_oom(p11_slots); } for (i=0; i pkcs11::mechanismList(unsigned long slot) rv = p11->C_GetMechanismList(slot, NULL, &count); if (count != 0) { m = (CK_MECHANISM_TYPE *)malloc(count *sizeof(*m)); - if (!m) - throw errorEx("C_GetMechanismList(Out of Memory)"); + check_oom(m); rv = p11->C_GetMechanismList(slot, m, &count); if (rv != CKR_OK) @@ -112,7 +110,7 @@ bool pkcs11::needsLogin(bool so) rv = p11->C_GetSessionInfo(session, &sinfo); if (rv != CKR_OK) pk11error("C_GetSessionInfo", rv); - printf("C_GetSessionInfo: %d\n", sinfo.state); + printf("C_GetSessionInfo: %lu\n", sinfo.state); switch (sinfo.state) { case CKS_RO_PUBLIC_SESSION: @@ -210,19 +208,33 @@ void pkcs11::storeAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object) attribute.store(session, object); } -QList pkcs11::objectList(const pk11_attribute *att) +CK_OBJECT_HANDLE pkcs11::createObject(pk11_attlist &attrs) +{ + CK_RV rv; + CK_ATTRIBUTE *attributes; + unsigned long num; + CK_OBJECT_HANDLE obj; + + num = attrs.get(&attributes); + rv = p11->C_CreateObject(session, attributes, num, &obj); + if (rv != CKR_OK) { + pk11error("C_CreateObject", rv); + } + return obj; +} + +QList pkcs11::objectList(pk11_attlist &atts) { CK_RV rv; CK_OBJECT_HANDLE objects[256]; QList list; - unsigned long len, i; - const CK_ATTRIBUTE *attribute = NULL; + unsigned long len, i, att_num; + CK_ATTRIBUTE *attribute; - if (att) - attribute = att->getAttribute(); + att_num = atts.get(&attribute); + + rv = p11->C_FindObjectsInit(session, attribute, att_num); - rv = p11->C_FindObjectsInit(session, (CK_ATTRIBUTE *)attribute, - attribute ? 1 : 0); if (rv != CKR_OK) pk11error("C_FindObjectsInit", rv); diff --git a/lib/pkcs11.h b/lib/pkcs11.h index f4b50b4c..4cf416c1 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -42,7 +42,7 @@ class pkcs11 CK_OBJECT_HANDLE object); void storeAttribute(pk11_attribute &attribute, CK_OBJECT_HANDLE object); - QList objectList(const pk11_attribute *att); + QList objectList(pk11_attlist &atts); void login(unsigned char *pin, unsigned long pinlen, bool so); void logout(); bool needsLogin(bool so); @@ -50,6 +50,7 @@ class pkcs11 unsigned char *pin, unsigned long pinLen); void initPin(unsigned char *pin, unsigned long pinLen); QList mechanismList(unsigned long slot); + CK_OBJECT_HANDLE createObject(pk11_attlist &attrs); }; #endif diff --git a/lib/pki_base.cpp b/lib/pki_base.cpp index 369a2d01..cefcee6a 100644 --- a/lib/pki_base.cpp +++ b/lib/pki_base.cpp @@ -90,12 +90,6 @@ void pki_base::my_error(const QString error) const } } -void pki_base::check_oom(const void *ptr) const -{ - if (!ptr) - my_error(tr("Out of memory")); -} - void pki_base::openssl_error(const QString txt) const { QString errtxt = ""; diff --git a/lib/pki_base.h b/lib/pki_base.h index 6d494094..8ab32a5d 100644 --- a/lib/pki_base.h +++ b/lib/pki_base.h @@ -28,7 +28,6 @@ class pki_base : public QObject pki_base *parent; void my_error(const QString myerr) const; - void check_oom(const void *ptr) const; void fopen_error(const QString fname); public: diff --git a/lib/pki_scard.cpp b/lib/pki_scard.cpp index a5857e05..cb603faa 100644 --- a/lib/pki_scard.cpp +++ b/lib/pki_scard.cpp @@ -250,6 +250,17 @@ void pki_scard::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object) openssl_error(); } +int pki_scard::getIdBin(unsigned char **to) +{ + int l; + BIGNUM *bn = NULL; + BN_hex2bn(&bn, CCHAR(object_id)); + l = BN_num_bytes(bn); + *to = (unsigned char*)malloc(l); + BN_bn2bin(bn, *to); + return l; +} + QList pki_scard::possibleHashNids() { QList nids; @@ -265,13 +276,12 @@ QList pki_scard::possibleHashNids() 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; - case CKM_RSA_PKCS: - QList n; n << NID_md5 << NID_sha1 << NID_sha256 << - NID_sha384 << NID_sha512 << NID_ripemd160; - printf("ALL NIDS\n"); - return n; } } + if (nids.count() == 0) { + nids << NID_md5 << NID_sha1 << NID_sha256 << + NID_sha384 << NID_sha512 << NID_ripemd160; + } return nids; } @@ -310,14 +320,13 @@ int pki_scard::prepare_card() const } } - pk11_attr_ulong class_att = pk11_attr_ulong(CKA_CLASS); QList objects; for (i=0; i ml) { mech_list = ml; }; QList possibleHashNids(); EVP_PKEY *load_pubkey(pkcs11 &p11, CK_OBJECT_HANDLE object) const; + int getIdBin(unsigned char **to); }; diff --git a/lib/pki_temp.cpp b/lib/pki_temp.cpp index 1e3e45a2..db6c8ccd 100644 --- a/lib/pki_temp.cpp +++ b/lib/pki_temp.cpp @@ -9,6 +9,7 @@ #include "pki_temp.h" #include "func.h" #include "db.h" +#include "exception.h" #include QPixmap *pki_temp::icon= NULL; diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index f774232e..0eac42b6 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -207,8 +207,9 @@ void pki_x509::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object) void pki_x509::store_token() { pki_scard *card = (pki_scard *)privkey; - int slot, size; - unsigned char*p, *p1; + int slot, size, id_size; + unsigned char *p, *p1, *id; + const unsigned char *label; QList objects; if (!privkey || !privkey->isScard()) @@ -219,28 +220,32 @@ void pki_x509::store_token() 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); + id_size = card->getIdBin(&id); + openssl_error(); + label = (const unsigned char *)desc.toUtf8().constData(); + + pk11_attlist p11_atts; + p11_atts << + pk11_attr_ulong(CKA_CLASS, CKO_CERTIFICATE) << + pk11_attr_ulong(CKA_CERTIFICATE_TYPE, CKC_X_509) << + pk11_attr_bool(CKA_TOKEN, true) << + pk11_attr_data(CKA_VALUE, p, size) << + pk11_attr_data(CKA_ID, id, id_size) << + pk11_attr_data(CKA_LABEL, label, strlen((const char*)label)); + + free(p); + free(id); 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(); + + p11.createObject(p11_atts); } bool pki_x509::verifyQASerial(const a1int &secret) const diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index cf9498c7..ccfc60e3 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -366,7 +366,6 @@ void MainWindow::importScard() try { ImportMulti *dlgi = new ImportMulti(this); QList objects; - pk11_attr_ulong class_att = pk11_attr_ulong(CKA_CLASS); p11_slots = p11.getSlotList(); if (p11_slots.count() == 0) @@ -377,8 +376,10 @@ void MainWindow::importScard() QList ml = p11.mechanismList(i); if (ml.count() == 0) ml << CKM_SHA1_RSA_PKCS; - class_att.setValue(CKO_PUBLIC_KEY); - objects = p11.objectList(&class_att); + pk11_attlist atts(pk11_attr_ulong(CKA_CLASS, + CKO_PUBLIC_KEY)); + + objects = p11.objectList(atts); for (int j=0; j< objects.count(); j++) { card = new pki_scard(""); @@ -392,8 +393,10 @@ void MainWindow::importScard() } card = NULL; } - class_att.setValue(CKO_CERTIFICATE); - objects = p11.objectList(&class_att); + atts.reset(); + atts << pk11_attr_ulong(CKA_CLASS, CKO_CERTIFICATE) << + pk11_attr_ulong(CKA_CERTIFICATE_TYPE,CKC_X_509); + objects = p11.objectList(atts); for (int j=0; j< objects.count(); j++) { cert = new pki_x509("");