remove "split-key" option and emulat sign for sign,decrypt keys with padding

and decrypt() for cardos.


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4113 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aj 2010-03-13 22:52:51 +00:00
parent 5bc11ac39c
commit 02768fb5dc
17 changed files with 60 additions and 197 deletions

View File

@ -289,15 +289,6 @@ app default {
# module = /usr/lib/opensc/drivers/p15emu_custom.so;
# }
# workaround: use rsa decrypt operation for signing
# some cardos cards need this, if initializes with certain
# versions of the siemens software
# we have an auto detection, but it is not 100% reliable,
# so you can turn it off, if it misbehaves.
# this option only affects cardos cards right now.
# Default: yes
# enable_sign_with_decrypt_workaround = no;
# workaround: fix keyReference and pinReference values
# OpenSC 0.11.4 and older have a bug: integers were not
# properly encoded in asn.1 structures. So far only

View File

@ -179,6 +179,7 @@ extern "C" {
#define SC_ALGORITHM_PBES2 256
#define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000
/* need usage = either sign or decrypt. keys with both? decrypt, emulate sign */
#define SC_ALGORITHM_NEED_USAGE 0x40000000
#define SC_ALGORITHM_SPECIFIC_FLAGS 0x0000FFFF

View File

@ -140,6 +140,12 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
return r;
}
/* copied from pkcs15-cardos.c */
#define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN|\
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
#define USAGE_ANY_DECIPHER (SC_PKCS15_PRKEY_USAGE_DECRYPT|\
SC_PKCS15_PRKEY_USAGE_UNWRAP)
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_object *obj,
unsigned long flags, const u8 *in, size_t inlen,
@ -156,30 +162,6 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
SC_FUNC_CALLED(ctx, 1);
/* some strange cards/setups need decrypt to sign ... */
if (p15card->flags & SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT) {
size_t tmplen = sizeof(buf);
if (flags & SC_ALGORITHM_RSA_RAW) {
return sc_pkcs15_decipher(p15card, obj,flags,
in, inlen, out, outlen);
}
if (modlen > tmplen) {
sc_debug(ctx, "Buffer too small, needs recompile!\n");
return SC_ERROR_NOT_ALLOWED;
}
r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen);
/* no padding needed - already done */
flags &= ~SC_ALGORITHM_RSA_PADS;
/* instead use raw rsa */
flags |= SC_ALGORITHM_RSA_RAW;
SC_TEST_RET(ctx, r, "Unable to add padding");
r = sc_pkcs15_decipher(p15card, obj,flags, buf, modlen,
out, outlen);
return r;
}
/* If the key is extractable, the caller should extract the
* key and do the crypto himself */
if (!prkey->native)
@ -208,6 +190,35 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
* algo_info->flags: what is supported by the card
* senv.algorithm_flags: what the card will have to do */
/* if the card has SC_ALGORITHM_NEED_USAGE set, and the
key is for signing and decryption, we need to emulate signing */
if ((alg_info->flags & SC_ALGORITHM_NEED_USAGE) &&
((prkey->usage & USAGE_ANY_SIGN) &&
(prkey->usage & USAGE_ANY_DECIPHER)) ) {
size_t tmplen = sizeof(buf);
if (flags & SC_ALGORITHM_RSA_RAW) {
return sc_pkcs15_decipher(p15card, obj,flags,
in, inlen, out, outlen);
}
if (modlen > tmplen) {
sc_debug(ctx, "Buffer too small, needs recompile!\n");
return SC_ERROR_NOT_ALLOWED;
}
r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen);
/* no padding needed - already done */
flags &= ~SC_ALGORITHM_RSA_PADS;
/* instead use raw rsa */
flags |= SC_ALGORITHM_RSA_RAW;
SC_TEST_RET(ctx, r, "Unable to add padding");
r = sc_pkcs15_decipher(p15card, obj,flags, buf, modlen,
out, outlen);
return r;
}
/* If the card doesn't support the requested algorithm, see if we
* can strip the input so a more restrictive algo can be used */
if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&

View File

@ -759,13 +759,6 @@ done:
if (card->caps & SC_CARD_CAP_RNG)
p15card->flags |= SC_PKCS15_CARD_FLAG_PRN_GENERATION;
/* for cardos cards initialized by Siemens: sign with decrypt */
if (strcmp(p15card->card->driver->short_name,"cardos") == 0
&& scconf_get_bool(conf_block, "enable_sign_with_decrypt_workaround", 1)
&& ( strcmp(p15card->manufacturer_id,"Siemens AG (C)") == 0
|| strcmp(p15card->manufacturer_id,"Prime") == 0 ))
p15card->flags |= SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
/* for starcos cards only: fix asn1 integers */
if (strcmp(p15card->card->driver->short_name,"starcos") == 0
&& scconf_get_bool(conf_block, "enable_fix_asn1_integers", 1))
@ -782,7 +775,6 @@ done:
* SHA1 prefix itself */
if (strstr(p15card->label, "2cc") != NULL) {
p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED;
p15card->flags &= ~SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
sc_debug(p15card->card->ctx, "D-TRUST 2cc card detected, only SHA1 works with this card\n");
/* XXX: add detection when other hash than SHA1 is used with
* such a card, as this produces invalid signatures.
@ -793,7 +785,6 @@ done:
* and no addition of prefix) */
else if (strstr(p15card->label, "2ca") != NULL) {
p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH;
p15card->flags &= ~SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
sc_debug(p15card->card->ctx, "D-TRUST 2ca card detected\n");
}

View File

@ -444,7 +444,6 @@ typedef struct sc_pkcs15_card {
#define SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED 0x02
#define SC_PKCS15_CARD_FLAG_PRN_GENERATION 0x04
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
#define SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT 0x01000000
#define SC_PKCS15_CARD_FLAG_EMULATED 0x02000000
#define SC_PKCS15_CARD_FLAG_FIX_INTEGERS 0x04000000
#define SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED 0x08000000

View File

@ -1852,16 +1852,7 @@ 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 */
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);
}
rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj);
if (rc >= 0) {
/* copy ID from private key(s) here to avoid bad link between private and public key */

View File

@ -531,23 +531,22 @@ cardos_create_sec_env(struct sc_profile *profile, sc_card_t *card,
static int cardos_key_algorithm(unsigned int usage, size_t keylen, int *algop)
{
int sign = 0, decipher = 0;
if (usage & USAGE_ANY_SIGN) {
if (keylen <= 1024)
*algop = CARDOS_ALGO_RSA_PURE_SIG;
else
*algop = CARDOS_ALGO_EXT_RSA_SIG_PURE;
sign = 1;
}
/* if it is sign and decipher, we use decipher and emulate sign */
if (usage & USAGE_ANY_DECIPHER) {
if (keylen <= 1024)
*algop = CARDOS_ALGO_RSA_PURE;
else
*algop = CARDOS_ALGO_EXT_RSA_PURE;
decipher = 1;
return 0;
}
return (sign == decipher)? -1 : 0;
if (usage & USAGE_ANY_SIGN) {
if (keylen <= 1024)
*algop = CARDOS_ALGO_RSA_PURE_SIG;
else
*algop = CARDOS_ALGO_EXT_RSA_SIG_PURE;
return 0;
}
return -1;
}
/*

View File

@ -1305,43 +1305,6 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
}
int
sc_pkcs15init_store_split_key(struct sc_pkcs15_card *p15card,
struct sc_profile *profile,
struct sc_pkcs15init_prkeyargs *keyargs,
struct sc_pkcs15_object **prk1_obj,
struct sc_pkcs15_object **prk2_obj)
{
struct sc_context *ctx = p15card->card->ctx;
unsigned int usage = keyargs->x509_usage;
int r;
SC_FUNC_CALLED(ctx, 3);
/* keyEncipherment|dataEncipherment|keyAgreement */
keyargs->x509_usage = usage & (SC_PKCS15INIT_X509_KEY_ENCIPHERMENT |
SC_PKCS15INIT_X509_DATA_ENCIPHERMENT |
SC_PKCS15INIT_X509_KEY_AGREEMENT);
r = sc_pkcs15init_store_private_key(p15card, profile,
keyargs, prk1_obj);
if (r >= 0) {
/* digitalSignature|nonRepudiation|certSign|cRLSign */
keyargs->x509_usage = usage & (SC_PKCS15INIT_X509_DIGITAL_SIGNATURE |
SC_PKCS15INIT_X509_NON_REPUDIATION |
SC_PKCS15INIT_X509_KEY_CERT_SIGN |
SC_PKCS15INIT_X509_CRL_SIGN);
/* Prevent pkcs15init from choking on duplicate ID */
keyargs->flags |= SC_PKCS15INIT_SPLIT_KEY;
r = sc_pkcs15init_store_private_key(p15card, profile,
keyargs, prk2_obj);
}
keyargs->x509_usage = usage;
SC_FUNC_RETURN(ctx, 3, r);
}
/*
* Store a public key
*
@ -1831,21 +1794,6 @@ __check_key_compatibility(struct sc_pkcs15_card *p15card,
continue;
}
/* Some cards will not support keys to do
* both sign/decrypt.
* For the convenience of the user, catch these
* here. */
if (info->flags & SC_ALGORITHM_NEED_USAGE) {
unsigned int usage;
usage = sc_pkcs15init_map_usage(x509_usage, 1);
if ((usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP
|SC_PKCS15_PRKEY_USAGE_DECRYPT))
&& (usage & SC_PKCS15_PRKEY_USAGE_SIGN)) {
bad_usage = 1;
continue;
}
}
return 1;
}
@ -1876,24 +1824,6 @@ check_key_compatibility(struct sc_pkcs15_card *p15card,
return res;
}
int
sc_pkcs15init_requires_restrictive_usage(struct sc_pkcs15_card *p15card,
struct sc_pkcs15init_prkeyargs *keyargs,
unsigned int key_length)
{
int res;
if (key_length == 0)
key_length = prkey_bits(p15card, &keyargs->key);
res = __check_key_compatibility(p15card, &keyargs->key,
keyargs->x509_usage,
key_length, 0);
return res < 0;
}
/*
* Check RSA key for consistency, and compute missing
* CRT elements

View File

@ -14,12 +14,6 @@ All test scripts accept the following set of arguments
key as determined by OpenSC works fine. [If it doesn't please
get in contact with us!]
--split-key
For CardOS/M4 - when creating or installing a key intended for
both signing and decryption, pkcs15-init must install a the same
key twice, with different usage labels: one for each usage. This
is called a "split key".
--reader N
Use the specified reader

View File

@ -47,7 +47,6 @@ if [ -z "$__p15init__" ]; then
case $1 in
-T|--use-default-transport-keys|\
--split-key|\
--no-prompt|\
--soft|\
-v*)

View File

@ -8,7 +8,7 @@
p15_init --no-so-pin
p15_set_pin -a 01
p15_gen_key rsa/1024 -a 01 --split-key --key-usage sign,decrypt
p15_gen_key rsa/1024 -a 01 --key-usage sign,decrypt
p15_validate
p15_erase --secret @01=0000

View File

@ -10,7 +10,7 @@
p15_init --so-pin 999999 --so-puk 88888888
p15_set_pin -a 27 --so-pin 999999
p15_gen_key rsa/1024 -a 27 --so-pin 999999 --split-key --key-usage sign,decrypt
p15_gen_key rsa/1024 -a 27 --so-pin 999999 --key-usage sign,decrypt
p15_validate
p15_erase --secret @27=0000

View File

@ -8,7 +8,7 @@
p15_init --no-so-pin
p15_set_pin -a 01
p15_gen_key rsa/1024 -a 01 --split-key --key-usage sign,decrypt
p15_gen_key rsa/1024 -a 01 --key-usage sign,decrypt
p15_validate
p15_erase --secret @01=0000

View File

@ -9,8 +9,8 @@
p15_init --no-so-pin
p15_set_pin -a 01
p15_set_pin -a 02 --label "User Signature PIN"
p15_gen_key rsa/512 -a 01 --split-key --key-usage sign,decrypt
p15_gen_key rsa/512 -a 02 --split-key --key-usage nonRepudiation \
p15_gen_key rsa/512 -a 01 --key-usage sign,decrypt
p15_gen_key rsa/512 -a 02 --key-usage nonRepudiation \
--id feeb \
--label "Non-Repudiation Key"
p15_validate

View File

@ -8,7 +8,7 @@
p15_init --no-so-pin
p15_set_pin -a 01
p15_store_key test.p12 --format pkcs12 --passphrase "password" -a 01 --split-key
p15_store_key test.p12 --format pkcs12 --passphrase "password" -a 01
p15_validate
p15_erase --secret @01=0000

View File

@ -6,8 +6,8 @@
. functions
p15_init --profile pkcs15+onepin --so-pin 999999 --so-puk 111111
p15_gen_key rsa/1024 -a 01 --split-key --key-usage sign,decrypt --pin 999999
p15_init --profile pkcs15+onepin --pin 999999 --puk 111111
p15_gen_key rsa/1024 -a 01 --key-usage sign,decrypt --pin 999999
p15_validate --pin 999999
p15_erase --secret @01=999999

View File

@ -124,7 +124,6 @@ enum {
OPT_UNPROTECTED,
OPT_AUTHORITY,
OPT_SOFT_KEYGEN,
OPT_SPLIT_KEY,
OPT_ASSERT_PRISTINE,
OPT_SECRET,
OPT_PUBKEY_LABEL,
@ -177,7 +176,6 @@ const struct option options[] = {
{ "passphrase", required_argument, NULL, OPT_PASSPHRASE },
{ "authority", no_argument, NULL, OPT_AUTHORITY },
{ "key-usage", required_argument, NULL, 'u' },
{ "split-key", no_argument, NULL, OPT_SPLIT_KEY },
{ "finalize", no_argument, NULL, 'F' },
{ "extractable", no_argument, NULL, OPT_EXTRACTABLE },
@ -317,7 +315,6 @@ static int opt_extractable = 0,
opt_no_prompt = 0,
opt_no_sopin = 0,
opt_use_defkeys = 0,
opt_split_key = 0,
opt_wait = 0;
static const char * opt_profile = "pkcs15";
static char * opt_card_profile = NULL;
@ -775,21 +772,6 @@ failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r));
return SC_ERROR_PKCS15INIT;
}
/*
* Display split key error message
*/
static void
split_key_error(void)
{
fprintf(stderr, "\n"
"Error - this token requires a more restrictive key usage.\n"
"Keys stored on this token can be used either for signing or decipherment,\n"
"but not both. You can either specify a more restrictive usage through\n"
"the --key-usage command line argument, or allow me to transparently\n"
"create two key objects with separate usage by specifying --split-key\n");
exit(1);
}
/*
* Store a private key
*/
@ -852,15 +834,7 @@ do_store_private_key(struct sc_profile *profile)
args.x509_usage = opt_x509_usage? opt_x509_usage : usage;
}
if (sc_pkcs15init_requires_restrictive_usage(p15card, &args, 0)) {
if (!opt_split_key)
split_key_error();
r = sc_pkcs15init_store_split_key(p15card, profile,
&args, NULL, NULL);
} else {
r = sc_pkcs15init_store_private_key(p15card, profile, &args, NULL);
}
r = sc_pkcs15init_store_private_key(p15card, profile, &args, NULL);
if (r < 0)
return r;
@ -1400,7 +1374,7 @@ do_generate_key(struct sc_profile *profile, const char *spec)
struct sc_pkcs15init_keygen_args keygen_args;
unsigned int evp_algo, keybits = 1024;
EVP_PKEY *pkey;
int r, split_key = 0;
int r;
memset(&keygen_args, 0, sizeof(keygen_args));
keygen_args.pubkey_label = opt_pubkey_label;
@ -1442,16 +1416,7 @@ do_generate_key(struct sc_profile *profile, const char *spec)
}
}
/* If the card doesn't support keys that can both sign _and_
* decipher, make sure the user specified --split-key */
if (sc_pkcs15init_requires_restrictive_usage(p15card,
&keygen_args.prkey_args, keybits)) {
if (!opt_split_key)
split_key_error();
split_key = 1;
}
if (!opt_softkeygen && !split_key) {
if (!opt_softkeygen) {
r = sc_pkcs15init_generate_key(p15card, profile, &keygen_args,
keybits, NULL);
if (r >= 0 || r != SC_ERROR_NOT_SUPPORTED)
@ -1467,13 +1432,8 @@ do_generate_key(struct sc_profile *profile, const char *spec)
|| (r = do_convert_private_key(&keygen_args.prkey_args.key, pkey) ) < 0)
goto out;
if (split_key) {
sc_pkcs15init_store_split_key(p15card,
profile, &keygen_args.prkey_args, NULL, NULL);
} else {
r = sc_pkcs15init_store_private_key(p15card,
profile, &keygen_args.prkey_args, NULL);
}
r = sc_pkcs15init_store_private_key(p15card,
profile, &keygen_args.prkey_args, NULL);
/* Store public key portion on card */
if (r >= 0)
@ -2618,9 +2578,6 @@ handle_option(const struct option *opt)
case 'T':
opt_use_defkeys = 1;
break;
case OPT_SPLIT_KEY:
opt_split_key = 1;
break;
case OPT_NO_SOPIN:
opt_no_sopin = 1;
break;