mirror of
https://github.com/chris2511/xca.git
synced 2026-09-14 11:06:19 +05:00
Support EC key generation on PKCS#11 token
move EC builtin sources into extra class and file
This commit is contained in:
parent
ad93cebf5c
commit
8ed9bab7df
@ -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
152
lib/builtin_curves.cpp
Normal 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
45
lib/builtin_curves.h
Normal 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
|
||||
@ -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,
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -71,7 +71,10 @@ void MainWindow::about()
|
||||
cont = QString(
|
||||
"<p><h3><center><u>XCA</u></center></h3>"
|
||||
"<p>Copyright 2001 - 2014 by Christian Hohnstä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ädt</th><td><u><christian@hohnstaedt.de></u></td></tr>"
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(":.*"), "");
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user