Support EC key generation on PKCS#11 token

move EC builtin sources into extra class and file
This commit is contained in:
Christian Hohnstaedt 2014-10-30 16:09:04 +01:00
parent ad93cebf5c
commit 8ed9bab7df
18 changed files with 376 additions and 198 deletions

View File

@ -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))

152
lib/builtin_curves.cpp Normal file
View File

@ -0,0 +1,152 @@
/*
* Copyright (C) 2014 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include <openssl/evp.h>
#include "builtin_curves.h"
#include "exception.h"
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
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<ARRAY_SIZE(x962_curve_nids); j++) {
if (x962_curve_nids[j] == nid) {
flag = CURVE_X962;
break;
}
}
if (!flag) {
for (j=0; j<ARRAY_SIZE(other_curve_nids); j++) {
if (other_curve_nids[j] == nid) {
flag = CURVE_OTHER;
break;
}
}
}
if (!flag)
continue;
EC_GROUP *group = EC_GROUP_new_by_curve_name(nid);
EC_GROUP_get_order(group, order, NULL);
append(builtin_curve(nid, QString(curves[i].comment),
BN_num_bits(order), flag,
EC_METHOD_get_field_type(EC_GROUP_method_of(group)))
);
EC_GROUP_free(group);
}
BN_free(order);
}
#else
builtin_curves::builtin_curves() { }
#endif

45
lib/builtin_curves.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2014 Christian Hohnstaedt.
*
* All rights reserved.
*/
#ifndef __BUILTIN_EC_CURVES_H
#define __BUILTIN_EC_CURVES_H
#include <QtCore/QString>
#include <QtCore/QList>
#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<builtin_curve>
{
public:
builtin_curves();
};
#endif

View File

@ -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,

View File

@ -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)

View File

@ -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;

View File

@ -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<CK_OBJECT_HANDLE> objects);
EVP_PKEY *getPrivateKey(EVP_PKEY *pub, CK_OBJECT_HANDLE obj);
int encrypt(int flen, const unsigned char *from,

View File

@ -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<pki_evp::num_curves; i++) {
int nid = pki_evp::curves[i].nid;
builtin = EC_GROUP_new_by_curve_name(nid);
foreach(builtin_curve curve, pki_key::builtinCurves) {
builtin = EC_GROUP_new_by_curve_name(curve.nid);
if (EC_GROUP_cmp(builtin, ec_group, NULL) == 0) {
EC_GROUP_set_curve_name((EC_GROUP *)ec_group, nid);
EC_GROUP_set_curve_name((EC_GROUP *)ec_group, curve.nid);
EC_GROUP_set_asn1_flag((EC_GROUP *)ec_group, 1);
EC_GROUP_free(builtin);
break;
} else {
EC_GROUP_free(builtin);
}
EC_GROUP_free(builtin);
}
#endif
}

View File

@ -17,9 +17,6 @@
#include "pki_key.h"
#include "Passwd.h"
#define CURVE_X962 1
#define CURVE_OTHER 2
class pki_evp: public pki_key
{
Q_OBJECT
@ -35,11 +32,6 @@ class pki_evp: public pki_key
static Passwd oldpasswd;
static QString md5passwd(QByteArray pass);
static QString sha512passwd(QByteArray pass, QString salt);
#ifndef OPENSSL_NO_EC
static EC_builtin_curve *curves;
static size_t num_curves;
static unsigned char *curve_flags;
#endif
void generate(int bits, int type, QProgressBar *progress);
void generate(int bits, int type, QProgressBar *progress,
int curve_nid);

View File

@ -15,6 +15,8 @@
#include <QtCore/QDir>
#include "widgets/PwDialog.h"
builtin_curves pki_key::builtinCurves;
pki_key::pki_key(const QString name)
:pki_base(name)
{

View File

@ -14,6 +14,7 @@
#include <openssl/pem.h>
#include <openssl/evp.h>
#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

View File

@ -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)) {

View File

@ -80,7 +80,8 @@ class pki_scard: public pki_key
QList<int> 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);

View File

@ -28,9 +28,9 @@ KeyDetail::KeyDetail(QWidget *parent)
#ifndef OPENSSL_NO_EC
static QString CurveComment(int nid)
{
for (size_t i=0; i<pki_evp::num_curves; i++) {
if (pki_evp::curves[i].nid == nid)
return QString(pki_evp::curves[i].comment);
foreach(builtin_curve curve, pki_key::builtinCurves) {
if (curve.nid == nid)
return curve.comment;
}
return QString();
}

View File

@ -71,7 +71,10 @@ void MainWindow::about()
cont = QString(
"<p><h3><center><u>XCA</u></center></h3>"
"<p>Copyright 2001 - 2014 by Christian Hohnst&auml;dt\n"
"<p>Version : <b>" VER "</b>"
"<p>Version: <b>" VER "</b>"
#ifdef OPENSSL_NO_EC
"<p>(Elliptic Curve Cryptography support disabled)"
#endif
"<p>%1"
"<hr><table border=0>"
"<tr><th align=left>Christian Hohnst&auml;dt</th><td><u>&lt;christian@hohnstaedt.de&gt;</u></td></tr>"

View File

@ -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; j<ARRAY_SIZE(x962_curve_nids); j++) {
if (x962_curve_nids[j] == pki_evp::curves[i].nid) {
pki_evp::curve_flags[i] = CURVE_X962;
break;
}
}
if (pki_evp::curve_flags[i])
continue;
for (j=0; j<ARRAY_SIZE(other_curve_nids); j++) {
if (other_curve_nids[j] == pki_evp::curves[i].nid) {
pki_evp::curve_flags[i] = CURVE_OTHER;
break;
}
}
}
#endif
}
void MainWindow::enableTokenMenu(bool enable)
{
foreach(QWidget *w, scardList) {
@ -230,8 +106,6 @@ MainWindow::MainWindow(QWidget *parent )
init_images();
homedir = getHomeDir();
init_curves();
#ifdef MDEBUG
CRYPTO_malloc_debug_init();
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

View File

@ -43,19 +43,34 @@ class keyListItem
bool card;
QString printname;
slotid slot;
unsigned minKeySize;
unsigned maxKeySize;
unsigned long ec_flags;
keyListItem(pkcs11 *p11, slotid nslot, CK_MECHANISM_TYPE m)
{
// assert(m == CKM_RSA_PKCS_KEY_PAIR_GEN);
slot = nslot;
CK_MECHANISM_INFO mechinfo;
p11->mechanismInfo(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<keyListItem> 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; i<pki_evp::num_curves; i++) {
const char *desc = pki_evp::curves[i].comment;
const char *sn = OBJ_nid2sn(pki_evp::curves[i].nid);
if (!sn)
continue;
if (desc == NULL)
desc = "---";
QString p = QString(sn) + ": " + desc;
if (pki_evp::curves[i].nid == defaultEcNid)
ec_default = p;
switch (pki_evp::curve_flags[i]) {
case CURVE_X962: curve_x962 << p; break;
case CURVE_OTHER: curve_other << p; break;
}
}
curveBox->addItems(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<keyListItem>();
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(":.*"), "");

View File

@ -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();