merge [3823:3844/trunk]

git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3845 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2009-11-13 19:01:21 +00:00
parent 533a33521f
commit df20fe72e1
5 changed files with 113 additions and 22 deletions

View File

@ -101,7 +101,7 @@ static int default_init(sc_card_t *card)
{
int r;
card->name = "Unidentified card";
card->name = "Unsupported card";
card->drv_data = NULL;
r = autodetect_class(card);
if (r) {

View File

@ -89,7 +89,8 @@ const char *sc_strerror(int error)
"Wrong padding",
"Unsupported card",
"Unable to load external module",
"EF offset too large"
"EF offset too large",
"Not implemented"
};
const int int_base = -SC_ERROR_INTERNAL;
const char *p15i_errors[] = {

View File

@ -90,6 +90,7 @@ extern "C" {
#define SC_ERROR_WRONG_CARD -1413
#define SC_ERROR_CANNOT_LOAD_MODULE -1414
#define SC_ERROR_OFFSET_TOO_LARGE -1415
#define SC_ERROR_NOT_IMPLEMENTED -1416
/* Relating to PKCS #15 init stuff */
#define SC_ERROR_PKCS15INIT -1500

View File

@ -1735,13 +1735,13 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
goto kpgen_done;
}
/* Write the new public and private keys to the pkcs15 files */
/* To support smartcards that require different keybobjects for signing and encryption */
/* Write the new public and private keys to the pkcs15 files */
/* To support smartcards that require different keybobjects for signing and encryption */
if (sc_pkcs15init_requires_restrictive_usage(p15card, &keygen_args.prkey_args, 0)) {
sc_debug(context, "store split key required for this card", rv);
/* second key is the signature keyobject */
rc = sc_pkcs15init_store_split_key(p15card, profile, &keygen_args.prkey_args, NULL, &priv_key_obj);
}
}
else {
rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj);
}

View File

@ -36,6 +36,13 @@
#include <ctype.h>
#include <stdarg.h>
#include <assert.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
#include <openssl/conf.h>
#endif
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
@ -45,6 +52,12 @@
#include <openssl/bn.h>
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#include <openssl/opensslconf.h> /* for OPENSSL_NO_EC */
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
#include <opensc/cardctl.h>
#include <opensc/pkcs15.h>
#include <opensc/pkcs15-init.h>
@ -89,6 +102,7 @@ static int do_store_data_object(struct sc_profile *profile);
static void set_secrets(struct sc_profile *);
static int init_keyargs(struct sc_pkcs15init_prkeyargs *);
static void init_gost_params(struct sc_pkcs15init_keyarg_gost_params *, EVP_PKEY *);
static int get_new_pin(sc_ui_hints_t *, const char *, const char *,
char **);
static int get_pin_callback(struct sc_profile *profile,
@ -107,7 +121,7 @@ static int do_read_certificate(const char *, const char *, X509 **);
static void parse_commandline(int argc, char **argv);
static void read_options_file(const char *);
static void ossl_print_errors(void);
static void set_userpin_ref(void);
static void set_userpin_ref(void);
enum {
@ -132,7 +146,7 @@ enum {
OPT_PUK2 = 0x10003,
OPT_SERIAL = 0x10004,
OPT_NO_SOPIN = 0x10005,
OPT_NO_PROMPT= 0x10006,
OPT_NO_PROMPT= 0x10006
};
const struct option options[] = {
@ -343,6 +357,9 @@ main(int argc, char **argv)
unsigned int n;
int r = 0;
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
OPENSSL_config(NULL);
#endif
/* OpenSSL magic */
SSLeay_add_all_algorithms();
CRYPTO_malloc_init();
@ -409,19 +426,7 @@ main(int argc, char **argv)
if (verbose && action != ACTION_ASSERT_PRISTINE)
printf("About to %s.\n", action_names[action]);
/*
{
sc_path_t p1, p2, p3, p4;
sc_format_path("3F0050156666", &p1); p1.index = 0; p1.count = 50;
sc_format_path("3F0050157777", &p2); p2.index = 50; p2.count = 50;
sc_format_path("3F0050156666", &p3); p3.index = 200; p3.count = 50;
sc_format_path("3F0050156666", &p4); p4.index = 50; p4.count = 150;
r = sc_pkcs15init_remove_unusedspace(p15card, profile, &p1, NULL);
printf("sc_pkcs15init_add_unusedspace(): %d\n", r);
//r = sc_pkcs15init_add_unusedspace(p15card, profile, &p3, NULL);
//printf("sc_pkcs15init_add_unusedspace(): %d\n", r);
}
*/
switch (action) {
case ACTION_ASSERT_PRISTINE:
/* skip printing error message */
@ -763,6 +768,8 @@ do_store_private_key(struct sc_profile *profile)
if ((r = do_convert_private_key(&args.key, pkey)) < 0)
return r;
init_gost_params(&args.gost_params, pkey);
if (ncerts) {
unsigned int usage;
@ -913,8 +920,11 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey)
if (pkey == NULL)
r = do_read_public_key(opt_infile, opt_format, &pkey);
if (r >= 0)
if (r >= 0) {
r = do_convert_public_key(&args.key, pkey);
if (r >= 0)
init_gost_params(&args.gost_params, pkey);
}
if (r >= 0)
r = sc_pkcs15init_store_public_key(p15card, profile,
&args, &dummy);
@ -1346,6 +1356,14 @@ do_generate_key(struct sc_profile *profile, const char *spec)
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_DSA;
evp_algo = EVP_PKEY_DSA;
spec += 3;
} else if (!strncasecmp(spec, "gost2001", strlen("gost2001"))) {
keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410;
keybits = SC_PKCS15_GOSTR3410_KEYSIZE;
/* FIXME: now only SC_PKCS15_PARAMSET_GOSTR3410_A */
keygen_args.prkey_args.gost_params.gostr3410 =
SC_PKCS15_PARAMSET_GOSTR3410_A;
evp_algo = 0; /* FIXME */
spec += strlen("gost2001");
} else {
util_error("Unknown algorithm \"%s\"", spec);
return SC_ERROR_INVALID_ARGUMENTS;
@ -1437,6 +1455,36 @@ static int init_keyargs(struct sc_pkcs15init_prkeyargs *args)
return 0;
}
static void
init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
EC_KEY *key;
assert(pkey);
if (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
key = EVP_PKEY_get0(pkey);
assert(key);
assert(params);
assert(EC_KEY_get0_group(key));
assert(EC_GROUP_get_curve_name(EC_KEY_get0_group(key)) > 0);
switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(key))) {
case NID_id_GostR3410_2001_CryptoPro_A_ParamSet:
params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_A;
break;
case NID_id_GostR3410_2001_CryptoPro_B_ParamSet:
params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_B;
break;
case NID_id_GostR3410_2001_CryptoPro_C_ParamSet:
params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_C;
break;
}
}
#else
(void)params, (void)pkey; /* no warning */
#endif
}
/*
* Intern secrets given on the command line (mostly for testing)
*/
@ -2076,7 +2124,7 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen)
}
static int
do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src)
do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src)
{
if (src == 0)
return 0;
@ -2121,6 +2169,18 @@ static int do_convert_private_key(struct sc_pkcs15_prkey *key, EVP_PKEY *pk)
DSA_free(src);
break;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
case NID_id_GostR3410_2001: {
struct sc_pkcs15_prkey_gostr3410 *dst = &key->u.gostr3410;
EC_KEY *src = EVP_PKEY_get0(pk);
assert(src);
key->algorithm = SC_ALGORITHM_GOSTR3410;
assert(EC_KEY_get0_private_key(src));
do_convert_bignum(&dst->d, EC_KEY_get0_private_key(src));
break;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
default:
util_fatal("Unsupported key algorithm\n");
}
@ -2154,6 +2214,35 @@ static int do_convert_public_key(struct sc_pkcs15_pubkey *key, EVP_PKEY *pk)
DSA_free(src);
break;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
case NID_id_GostR3410_2001: {
struct sc_pkcs15_pubkey_gostr3410 *dst = &key->u.gostr3410;
EC_KEY *eckey = EVP_PKEY_get0(pk);
const EC_POINT *point;
BIGNUM *X, *Y;
int r = 0;
assert(eckey);
point = EC_KEY_get0_public_key(eckey);
if (!point)
return SC_ERROR_INTERNAL;
X = BN_new();
Y = BN_new();
if (X && Y && EC_KEY_get0_group(eckey))
r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
point, X, Y, NULL);
if (r == 1) {
do_convert_bignum(&dst->x, X);
do_convert_bignum(&dst->y, Y);
key->algorithm = SC_ALGORITHM_GOSTR3410;
}
BN_free(X);
BN_free(Y);
if (r != 1)
return SC_ERROR_INTERNAL;
break;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
default:
util_fatal("Unsupported key algorithm\n");
}