diff --git a/lib/Makefile b/lib/Makefile index 0bd66782..d4142414 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -9,7 +9,7 @@ MOCNAMES=db_crl db_key db_temp db_x509 db_x509req db_x509super db_base db_token\ pki_base pki_multi pki_evp pki_scard pass_info pki_pkcs7 main NAMES=$(MOCNAMES) asn1int oid x509rev asn1time \ x509v3ext func load_obj x509name db import \ - pk11_attribute pkcs11 pkcs11_lib Passwd + pk11_attribute pkcs11 pkcs11_lib Passwd builtin_curves OBJS=$(patsubst %, %.o, $(NAMES)) $(patsubst %, moc_%.o, $(MOCNAMES)) diff --git a/lib/builtin_curves.cpp b/lib/builtin_curves.cpp new file mode 100644 index 00000000..e0ffcfa6 --- /dev/null +++ b/lib/builtin_curves.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2014 Christian Hohnstaedt. + * + * All rights reserved. + */ +#include + +#include "builtin_curves.h" +#include "exception.h" + +#ifndef OPENSSL_NO_EC +#include +static const int x962_curve_nids[] = { + NID_X9_62_prime192v1, + NID_X9_62_prime192v2, + NID_X9_62_prime192v3, + NID_X9_62_prime239v1, + NID_X9_62_prime239v2, + NID_X9_62_prime239v3, + NID_X9_62_prime256v1, + + NID_X9_62_c2pnb163v1, + NID_X9_62_c2pnb163v2, + NID_X9_62_c2pnb163v3, + NID_X9_62_c2pnb176v1, + NID_X9_62_c2tnb191v1, + NID_X9_62_c2tnb191v2, + NID_X9_62_c2tnb191v3, + NID_X9_62_c2pnb208w1, + NID_X9_62_c2tnb239v1, + NID_X9_62_c2tnb239v2, + NID_X9_62_c2tnb239v3, + NID_X9_62_c2pnb272w1, + NID_X9_62_c2pnb304w1, + NID_X9_62_c2tnb359v1, + NID_X9_62_c2pnb368w1, + NID_X9_62_c2tnb431r1 +}; + +static const int other_curve_nids[] = { + NID_sect113r1, + NID_sect113r2, + NID_sect131r1, + NID_sect131r2, + NID_sect163k1, + NID_sect163r1, + NID_sect163r2, + NID_sect193r1, + NID_sect193r2, + NID_sect233k1, + NID_sect233r1, + NID_sect239k1, + NID_sect283k1, + NID_sect283r1, + NID_sect409k1, + NID_sect409r1, + NID_sect571k1, + NID_sect571r1, + + NID_secp112r1, + NID_secp112r2, + NID_secp128r1, + NID_secp128r2, + NID_secp160k1, + NID_secp160r1, + NID_secp160r2, + NID_secp192k1, + NID_secp224k1, + NID_secp224r1, + NID_secp256k1, + NID_secp384r1, + NID_secp521r1, + + NID_wap_wsg_idm_ecid_wtls1, + NID_wap_wsg_idm_ecid_wtls3, + NID_wap_wsg_idm_ecid_wtls4, + NID_wap_wsg_idm_ecid_wtls5, + NID_wap_wsg_idm_ecid_wtls6, + NID_wap_wsg_idm_ecid_wtls7, + NID_wap_wsg_idm_ecid_wtls8, + NID_wap_wsg_idm_ecid_wtls9, + NID_wap_wsg_idm_ecid_wtls10, + NID_wap_wsg_idm_ecid_wtls11, + NID_wap_wsg_idm_ecid_wtls12, + +#if OPENSSL_VERSION_NUMBER >= 0x10002001L + NID_brainpoolP160r1, + NID_brainpoolP160t1, + NID_brainpoolP192r1, + NID_brainpoolP192t1, + NID_brainpoolP224r1, + NID_brainpoolP224t1, + NID_brainpoolP256r1, + NID_brainpoolP256t1, + NID_brainpoolP320r1, + NID_brainpoolP320t1, + NID_brainpoolP384r1, + NID_brainpoolP384t1, + NID_brainpoolP512r1, + NID_brainpoolP512t1 +#endif +}; + +builtin_curves::builtin_curves() +{ + int i, num_curves = EC_get_builtin_curves(NULL, 0); + EC_builtin_curve *curves = (EC_builtin_curve*)OPENSSL_malloc( + (int)(sizeof(EC_builtin_curve) *num_curves)); + + check_oom(curves); + + BIGNUM *order = BN_new(); + check_oom(order); + + EC_get_builtin_curves(curves, num_curves); + + for (i=0; i< num_curves; i++) { + size_t j; + int flag = 0, nid = curves[i].nid; + + for (j=0; j +#include + +#include "base.h" + +#define CURVE_X962 1 +#define CURVE_OTHER 2 + +class builtin_curve +{ + public: + int nid; + QString comment; + unsigned order_size; + int flags; + /* type: + * NID_X9_62_prime_field + * NID_X9_62_characteristic_two_field + */ + int type; + builtin_curve(int n, QString c, int s, int f, int t) { + nid = n; + comment = c; + order_size = s; + flags = f; + type = t; + }; +}; + +class builtin_curves: public QList +{ + public: + builtin_curves(); +}; + +#endif diff --git a/lib/db_key.cpp b/lib/db_key.cpp index 772cbf56..feb951da 100644 --- a/lib/db_key.cpp +++ b/lib/db_key.cpp @@ -146,8 +146,9 @@ void db_key::newItem(QString name) try { if (dlg->isToken()) { key = cardkey = new pki_scard(dlg->keyDesc->text()); - cardkey->generateKey_card(dlg->getKeyCardSlot(), - ksize, bar); + cardkey->generateKey_card(dlg->getKeytype(), + dlg->getKeyCardSlot(), ksize, + dlg->getKeyCurve_nid(), bar); } else { key = nkey = new pki_evp(dlg->keyDesc->text()); nkey->generate(ksize, dlg->getKeytype(), bar, diff --git a/lib/opensc-pkcs11.h b/lib/opensc-pkcs11.h index b439d180..741ae754 100644 --- a/lib/opensc-pkcs11.h +++ b/lib/opensc-pkcs11.h @@ -268,6 +268,14 @@ struct ck_token_info #define CKF_SO_PIN_LOCKED (1 << 22) #define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) +#define CKF_EC_F_P (1 << 20) +#define CKF_EC_F_2M (1 << 21) +#define CKF_EC_ECPARAMETERS (1 << 22) +#define CKF_EC_NAMEDCURVE (1 << 23) +#define CKF_EC_UNCOMPRESS (1 << 24) +#define CKF_EC_COMPRESS (1 << 25) + + #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) #define CK_EFFECTIVELY_INFINITE (0) diff --git a/lib/pkcs11.cpp b/lib/pkcs11.cpp index 6f62fff6..eadf28b4 100644 --- a/lib/pkcs11.cpp +++ b/lib/pkcs11.cpp @@ -471,12 +471,13 @@ pk11_attr_data pkcs11::findUniqueID(unsigned long oclass) return id; } -pk11_attr_data pkcs11::generateRSAKey(QString name, unsigned long bits) +pk11_attr_data pkcs11::generateKey(QString name, unsigned long ec_rsa_mech, + unsigned long bits, int nid) { CK_RV rv; CK_OBJECT_HANDLE pubkey, privkey; pk11_attlist priv_atts, pub_atts; - CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0}; + CK_MECHANISM mechanism = {ec_rsa_mech, NULL_PTR, 0}; pk11_attr_data label(CKA_LABEL, name.toUtf8()); pk11_attr_data new_id = findUniqueID(CKO_PUBLIC_KEY); @@ -488,8 +489,6 @@ pk11_attr_data pkcs11::generateRSAKey(QString name, unsigned long bits) pk11_attr_bool(CKA_ENCRYPT, true) << pk11_attr_bool(CKA_VERIFY, true) << pk11_attr_bool(CKA_WRAP, true) << - pk11_attr_ulong(CKA_MODULUS_BITS, bits) << - pk11_attr_data(CKA_PUBLIC_EXPONENT, 0x10001) << label << new_id; priv_atts << @@ -502,6 +501,33 @@ pk11_attr_data pkcs11::generateRSAKey(QString name, unsigned long bits) pk11_attr_bool(CKA_UNWRAP, true) << label << new_id; + if (ec_rsa_mech == CKM_RSA_PKCS_KEY_PAIR_GEN) { + pub_atts << + pk11_attr_ulong(CKA_MODULUS_BITS, bits) << + pk11_attr_data(CKA_PUBLIC_EXPONENT, 0x10001); + } else if (ec_rsa_mech == CKM_EC_KEY_PAIR_GEN) { +#ifndef OPENSSL_NO_EC + CK_MECHANISM_INFO info; + mechanismInfo(p11slot, CKM_EC_KEY_PAIR_GEN, &info); + + EC_GROUP *group = EC_GROUP_new_by_curve_name(nid); + + EC_GROUP_set_asn1_flag(group, info.flags & CKF_EC_NAMEDCURVE ? + OPENSSL_EC_NAMED_CURVE : 0); + + /// WORKAROUND: + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + /// WORKAROUND END: + priv_atts << pk11_attr_bool(CKA_DERIVE, true); + pub_atts << pk11_attr_data(CKA_EC_PARAMS, + i2d_bytearray(I2D_VOID(i2d_ECPKParameters), group)); + EC_GROUP_free(group); +#else + throw errorEx(("Unsupported Key generation mechanism")); +#endif + } else { + throw errorEx(("Unsupported Key generation mechanism")); + } p11slot.isValid(); WAITCURSOR_START; rv = p11slot.p11()->C_GenerateKeyPair(session, &mechanism, @@ -684,8 +710,8 @@ static int eng_finish(ENGINE *e) static int eng_destroy(ENGINE *e) { printf("ENGINE destroy\n"); - //pkcs11 *p11 = (pkcs11 *)ENGINE_get_ex_data(e, 0); - //delete p11; + pkcs11 *p11 = (pkcs11 *)ENGINE_get_ex_data(e, 0); + delete p11; return 1; } @@ -694,9 +720,11 @@ static int eng_pmeth_ctrl_rsa(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: return p1 == RSA_PKCS1_PADDING ? 1 : -2; +#ifndef OPENSSL_NO_EC // WTF ??? case EVP_PKEY_CTRL_GET_RSA_PADDING: *(int *)p2 = RSA_PKCS1_PADDING; return 1; +#endif case EVP_PKEY_CTRL_MD: EVP_PKEY_CTX_set_data(ctx, p2); return 1; @@ -714,6 +742,7 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, return 1; } +#ifndef OPENSSL_NO_EC static int eng_pmeth_ctrl_ec(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { switch (type) { @@ -737,7 +766,7 @@ static int eng_pmeth_ctrl_ec(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) fprintf(stderr, "EC Don't call me %d\n", type); return -2; } - +#endif static unsigned char *create_x509_sig(EVP_PKEY_CTX *ctx, const unsigned char *m, size_t m_len, unsigned int *x509_siglen) @@ -808,6 +837,7 @@ static int eng_pmeth_sign_rsa(EVP_PKEY_CTX *ctx, return (len < 0) ? -1 : 1; } +#ifndef OPENSSL_NO_EC static int eng_pmeth_sign_ec(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) @@ -842,6 +872,7 @@ out: ign_openssl_error(); return ret; } +#endif static int eng_pmeth_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { @@ -855,9 +886,11 @@ static int eng_meths(ENGINE *e, EVP_PKEY_METHOD **m, const int **nids, int nid) static const int my_nids[] = { EVP_PKEY_EC, EVP_PKEY_RSA }; if (m) { switch (nid) { +#ifndef OPENSSL_NO_EC case EVP_PKEY_EC: *m = p11_ec_method; return 1; +#endif case EVP_PKEY_RSA: *m = p11_rsa_method; return 1; @@ -893,6 +926,7 @@ EVP_PKEY *pkcs11::getPrivateKey(EVP_PKEY *pub, CK_OBJECT_HANDLE obj) eng_pmeth_ctrl_rsa, pkey_rsa_ctrl_str); EVP_PKEY_meth_set_copy(p11_rsa_method, eng_pmeth_copy); } +#ifndef OPENSSL_NO_EC if (!p11_ec_method) { p11_ec_method = EVP_PKEY_meth_new(EVP_PKEY_EC, 0); EVP_PKEY_meth_set_sign(p11_ec_method, @@ -901,11 +935,14 @@ EVP_PKEY *pkcs11::getPrivateKey(EVP_PKEY *pub, CK_OBJECT_HANDLE obj) eng_pmeth_ctrl_ec, NULL); EVP_PKEY_meth_set_copy(p11_ec_method, eng_pmeth_copy); } +#endif p11obj = obj; switch (EVP_PKEY_type(pub->type)) { case EVP_PKEY_RSA: +#ifndef OPENSSL_NO_EC case EVP_PKEY_EC: +#endif return pub; } return NULL; diff --git a/lib/pkcs11.h b/lib/pkcs11.h index 8c9f3686..19fb4da4 100644 --- a/lib/pkcs11.h +++ b/lib/pkcs11.h @@ -18,8 +18,8 @@ #include "pk11_attribute.h" -#define WAITCURSOR_START QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)) -#define WAITCURSOR_END QApplication::restoreOverrideCursor() +#define WAITCURSOR_START do { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); ign_openssl_error(); } while(0); +#define WAITCURSOR_END do { QApplication::restoreOverrideCursor(); ign_openssl_error(); } while(0); class tkInfo { @@ -160,7 +160,8 @@ class pkcs11 unsigned char *pin, unsigned long pinLen); CK_OBJECT_HANDLE createObject(pk11_attlist &attrs); pk11_attr_data findUniqueID(unsigned long oclass); - pk11_attr_data generateRSAKey(QString name, unsigned long bits); + pk11_attr_data generateKey(QString name, + unsigned long ec_rsa_mech, unsigned long bits, int nid); int deleteObjects(QList objects); EVP_PKEY *getPrivateKey(EVP_PKEY *pub, CK_OBJECT_HANDLE obj); int encrypt(int flen, const unsigned char *from, diff --git a/lib/pki_evp.cpp b/lib/pki_evp.cpp index 84d646c9..c1616373 100644 --- a/lib/pki_evp.cpp +++ b/lib/pki_evp.cpp @@ -28,12 +28,6 @@ QString pki_evp::passHash = QString(); QPixmap *pki_evp::icon[2]= { NULL, NULL }; -#ifndef OPENSSL_NO_EC -EC_builtin_curve *pki_evp::curves = NULL; -size_t pki_evp::num_curves = 0; -unsigned char *pki_evp::curve_flags = NULL; -#endif - void pki_evp::init(int type) { key->type = type; @@ -250,17 +244,15 @@ static void search_ec_oid(EVP_PKEY *pkey) return; /* There is an EC_GROUP with a missing OID * because of explicit parameters */ - for (size_t i=0; i #include "widgets/PwDialog.h" +builtin_curves pki_key::builtinCurves; + pki_key::pki_key(const QString name) :pki_base(name) { diff --git a/lib/pki_key.h b/lib/pki_key.h index ca64d273..710f15e6 100644 --- a/lib/pki_key.h +++ b/lib/pki_key.h @@ -14,6 +14,7 @@ #include #include #include "pki_base.h" +#include "lib/builtin_curves.h" #define MAX_KEY_LENGTH 4096 @@ -32,6 +33,7 @@ class pki_key: public pki_base pki_key(const QString name = ""); pki_key(const pki_key *pk); virtual ~pki_key(); + static builtin_curves builtinCurves; enum passType { ptCommon, ptPrivate, ptBogus, ptPin }; virtual EVP_PKEY *decryptKey() const diff --git a/lib/pki_scard.cpp b/lib/pki_scard.cpp index 8b09f766..d2c0ac01 100644 --- a/lib/pki_scard.cpp +++ b/lib/pki_scard.cpp @@ -483,19 +483,22 @@ public: pk11_attr_data id; QString name; int size; + int curve_nid; + int method; pkcs11 *p11; void run() { try { - id = p11->generateRSAKey(name, size); + id = p11->generateKey(name, method, size, curve_nid); } catch (errorEx &e) { err = e; } } }; -void pki_scard::generateKey_card(slotid slot, int size, QProgressBar *bar) +void pki_scard::generateKey_card(int type, slotid slot, int size, + int curve_nid, QProgressBar *bar) { pk11_attlist atts; @@ -504,12 +507,27 @@ void pki_scard::generateKey_card(slotid slot, int size, QProgressBar *bar) tkInfo ti = p11.tokenInfo(); + fprintf(stderr, "TYPE: %d (EVP_PKEY_RSA:%d, EVP_PKEY_EC:%d)\n", + type, EVP_PKEY_RSA, EVP_PKEY_EC); 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; +#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)) { diff --git a/lib/pki_scard.h b/lib/pki_scard.h index cffe9104..dd4e8260 100644 --- a/lib/pki_scard.h +++ b/lib/pki_scard.h @@ -80,7 +80,8 @@ class pki_scard: public pki_key QList possibleHashNids(); EVP_PKEY *load_pubkey(pkcs11 &p11, CK_OBJECT_HANDLE object) const; const EVP_MD *getDefaultMD(); - void generateKey_card(slotid slot, int size, QProgressBar *bar); + void generateKey_card(int type, slotid slot, int size, + int curve_nid, QProgressBar *bar); void deleteFromToken(); void deleteFromToken(slotid slot); void store_token(slotid slot, EVP_PKEY *pkey); diff --git a/widgets/KeyDetail.cpp b/widgets/KeyDetail.cpp index 3f4c7b6c..a2f9d74c 100644 --- a/widgets/KeyDetail.cpp +++ b/widgets/KeyDetail.cpp @@ -28,9 +28,9 @@ KeyDetail::KeyDetail(QWidget *parent) #ifndef OPENSSL_NO_EC static QString CurveComment(int nid) { - for (size_t i=0; i

XCA

" "

Copyright 2001 - 2014 by Christian Hohnstädt\n" - "

Version : " VER "" + "

Version: " VER "" +#ifdef OPENSSL_NO_EC + "

(Elliptic Curve Cryptography support disabled)" +#endif "

%1" "


" "" diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index 406fa98c..60aa36d3 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -34,6 +34,7 @@ #include "lib/pass_info.h" #include "lib/func.h" #include "lib/pkcs11.h" +#include "lib/builtin_curves.h" #include "ui_About.h" #include "PwDialog.h" @@ -55,131 +56,6 @@ NIDlist *MainWindow::aia_nid = NULL; QString MainWindow::mandatory_dn; -static const int x962_curve_nids[] = { - NID_X9_62_prime192v1, - NID_X9_62_prime192v2, - NID_X9_62_prime192v3, - NID_X9_62_prime239v1, - NID_X9_62_prime239v2, - NID_X9_62_prime239v3, - NID_X9_62_prime256v1, - - NID_X9_62_c2pnb163v1, - NID_X9_62_c2pnb163v2, - NID_X9_62_c2pnb163v3, - NID_X9_62_c2pnb176v1, - NID_X9_62_c2tnb191v1, - NID_X9_62_c2tnb191v2, - NID_X9_62_c2tnb191v3, - NID_X9_62_c2pnb208w1, - NID_X9_62_c2tnb239v1, - NID_X9_62_c2tnb239v2, - NID_X9_62_c2tnb239v3, - NID_X9_62_c2pnb272w1, - NID_X9_62_c2pnb304w1, - NID_X9_62_c2tnb359v1, - NID_X9_62_c2pnb368w1, - NID_X9_62_c2tnb431r1 -}; - -static const int other_curve_nids[] = { - NID_sect113r1, - NID_sect113r2, - NID_sect131r1, - NID_sect131r2, - NID_sect163k1, - NID_sect163r1, - NID_sect163r2, - NID_sect193r1, - NID_sect193r2, - NID_sect233k1, - NID_sect233r1, - NID_sect239k1, - NID_sect283k1, - NID_sect283r1, - NID_sect409k1, - NID_sect409r1, - NID_sect571k1, - NID_sect571r1, - - NID_secp112r1, - NID_secp112r2, - NID_secp128r1, - NID_secp128r2, - NID_secp160k1, - NID_secp160r1, - NID_secp160r2, - NID_secp192k1, - NID_secp224k1, - NID_secp224r1, - NID_secp256k1, - NID_secp384r1, - NID_secp521r1, - - NID_wap_wsg_idm_ecid_wtls1, - NID_wap_wsg_idm_ecid_wtls3, - NID_wap_wsg_idm_ecid_wtls4, - NID_wap_wsg_idm_ecid_wtls5, - NID_wap_wsg_idm_ecid_wtls6, - NID_wap_wsg_idm_ecid_wtls7, - NID_wap_wsg_idm_ecid_wtls8, - NID_wap_wsg_idm_ecid_wtls9, - NID_wap_wsg_idm_ecid_wtls10, - NID_wap_wsg_idm_ecid_wtls11, - NID_wap_wsg_idm_ecid_wtls12, - -#if OPENSSL_VERSION_NUMBER >= 0x10002001L - NID_brainpoolP160r1, - NID_brainpoolP160t1, - NID_brainpoolP192r1, - NID_brainpoolP192t1, - NID_brainpoolP224r1, - NID_brainpoolP224t1, - NID_brainpoolP256r1, - NID_brainpoolP256t1, - NID_brainpoolP320r1, - NID_brainpoolP320t1, - NID_brainpoolP384r1, - NID_brainpoolP384t1, - NID_brainpoolP512r1, - NID_brainpoolP512t1 -#endif -}; - -static void init_curves() -{ -#ifndef OPENSSL_NO_EC - pki_evp::num_curves = EC_get_builtin_curves(NULL, 0); - pki_evp::curves = (EC_builtin_curve*)OPENSSL_malloc( - (int)(sizeof(EC_builtin_curve) *pki_evp::num_curves)); - if (!pki_evp::curves) - return; - EC_get_builtin_curves(pki_evp::curves, pki_evp::num_curves); - pki_evp::curve_flags = (unsigned char *)OPENSSL_malloc(pki_evp::num_curves); - if (!pki_evp::curve_flags) - return; - for (size_t i=0; i< pki_evp::num_curves; i++) { - size_t j; - - pki_evp::curve_flags[i] = 0; - for (j=0; jmechanismInfo(slot, m, &mechinfo); + + minKeySize = mechinfo.ulMinKeySize; + maxKeySize = mechinfo.ulMaxKeySize; + tkInfo ti = p11->tokenInfo(slot); tl = typeList; //idx of EVP_PKEY_RSA +#ifndef OPENSSL_NO_EC + if (m == CKM_EC_KEY_PAIR_GEN) { + tl = typeList +2; + CK_MECHANISM_INFO info; + p11->mechanismInfo(slot, m, &info); + ec_flags = info.flags & (CKF_EC_F_2M | CKF_EC_F_P); + } +#endif printname = QString("%1 #%2 (%3 Key of %4 - %5 bits)"). arg(ti.label()).arg(ti.serial()). arg(tl->name). - arg(mechinfo.ulMinKeySize). - arg(mechinfo.ulMaxKeySize); + arg(minKeySize). + arg(maxKeySize); card = true; } keyListItem(const struct typelist *t=typeList) @@ -64,6 +79,9 @@ class keyListItem printname = QString(tl->name); card = false; slot = slotid(); + minKeySize = 0; + maxKeySize = INT_MAX; + ec_flags = 0; } keyListItem(const keyListItem &k) { @@ -71,6 +89,9 @@ class keyListItem printname = k.printname; card = k.card; slot = k.slot; + minKeySize = k.minKeySize; + maxKeySize = k.maxKeySize; + ec_flags = k.ec_flags; } int type() { @@ -89,7 +110,6 @@ NewKey::NewKey(QWidget *parent, QString name) { static const char* const sizeList[] = { "1024", "2048", "4096" }; size_t i; - QStringList curve_x962, curve_other; slotidList p11_slots; QList keytypes; @@ -108,31 +128,7 @@ NewKey::NewKey(QWidget *parent, QString name) keyListItem gk(typeList +i); keytypes << gk; } -#ifndef OPENSSL_NO_EC - QString ec_default; - for (i = 0; iaddItems(curve_x962); - curveBox->addItems(curve_other); - curveBox->setCurrentIndex(curveBox->findText(ec_default)); - if (curveBox->currentIndex() == -1) - curveBox->setCurrentIndex(0); -#endif + updateCurves(); keyLength->setEditText(QString::number(defaultSize) + " bit"); keyDesc->setFocus(); if (pkcs11::loaded()) try { @@ -145,6 +141,12 @@ NewKey::NewKey(QWidget *parent, QString name) keyListItem tk(&p11, slot, CKM_RSA_PKCS_KEY_PAIR_GEN); keytypes << tk; } +#ifndef OPENSSL_NO_EC + if (ml.contains(CKM_EC_KEY_PAIR_GEN)) { + keyListItem tk(&p11, slot, CKM_EC_KEY_PAIR_GEN); + keytypes << tk; + } +#endif } } catch (errorEx &err) { p11_slots.clear(); @@ -159,15 +161,61 @@ NewKey::NewKey(QWidget *parent, QString name) buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create")); } +void NewKey::updateCurves(unsigned min, unsigned max, unsigned long ec_flags) +{ +#ifndef OPENSSL_NO_EC + QString ec_default; + QStringList curve_x962, curve_other; + foreach(builtin_curve curve, pki_key::builtinCurves) { + const char *sn = OBJ_nid2sn(curve.nid); + unsigned long group_type; + QString comment = curve.comment; + + if (!sn || curve.order_size < min || curve.order_size > max) + continue; + if (ec_flags) { + if (curve.type == NID_X9_62_prime_field) + group_type = CKF_EC_F_P; + else // ft = NID_X9_62_characteristic_two_field + group_type = CKF_EC_F_2M; + + if ((group_type & ec_flags) == 0) + continue; + } + if (comment.isEmpty()) + comment = "---"; + QString p = QString(sn) + ": " + comment; + if (curve.nid == defaultEcNid) + ec_default = p; + switch (curve.flags) { + case CURVE_X962: curve_x962 << p; break; + case CURVE_OTHER: curve_other << p; break; + } + } + curveBox->clear(); + curveBox->addItems(curve_x962); + curveBox->addItems(curve_other); + curveBox->setCurrentIndex(curveBox->findText(ec_default)); + if (curveBox->currentIndex() == -1) + curveBox->setCurrentIndex(0); +#endif +} + void NewKey::on_keyType_currentIndexChanged(int idx) { bool curve_enabled; + keyListItem ki = keyType->itemData(idx).value(); - curve_enabled = (typeList[idx].type == EVP_PKEY_EC); + curve_enabled = (ki.type() == EVP_PKEY_EC); curveBox->setVisible(curve_enabled); curveLabel->setVisible(curve_enabled); keySizeLabel->setVisible(!curve_enabled); keyLength->setVisible(!curve_enabled); + + rememberDefault->setEnabled(!ki.card); + if (curve_enabled && ki.card) { + updateCurves(ki.minKeySize, ki.maxKeySize, ki.ec_flags); + } } static keyListItem currentKey(QComboBox *keyType) @@ -193,7 +241,7 @@ int NewKey::getKeysize() int NewKey::getKeyCurve_nid() { if (getKeytype() != EVP_PKEY_EC) - return -1; + return NID_undef; QString desc = curveBox->currentText(); desc.replace(QRegExp("^(X9.62) "), ""); desc.replace(QRegExp(":.*"), ""); diff --git a/widgets/NewKey.h b/widgets/NewKey.h index fa379185..ee7978ad 100644 --- a/widgets/NewKey.h +++ b/widgets/NewKey.h @@ -19,6 +19,8 @@ class NewKey: public QDialog, public Ui::NewKey static int defaultType; static int defaultEcNid; static int defaultSize; + void updateCurves(unsigned min=0, unsigned max=INT_MAX, + unsigned long ec_flags=0); public: NewKey(QWidget *parent, QString name); int getKeytype();
Christian Hohnstädt<christian@hohnstaedt.de>