From 02768fb5dc8e7fe782e40994ebf0a7f4a2372936 Mon Sep 17 00:00:00 2001 From: aj Date: Sat, 13 Mar 2010 22:52:51 +0000 Subject: [PATCH] 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 --- etc/opensc.conf.in | 9 ----- src/libopensc/opensc.h | 1 + src/libopensc/pkcs15-sec.c | 59 ++++++++++++++++------------ src/libopensc/pkcs15.c | 9 ----- src/libopensc/pkcs15.h | 1 - src/pkcs11/framework-pkcs15.c | 11 +----- src/pkcs15init/pkcs15-cardos.c | 21 +++++----- src/pkcs15init/pkcs15-lib.c | 70 ---------------------------------- src/tests/regression/README | 6 --- src/tests/regression/functions | 1 - src/tests/regression/init0001 | 2 +- src/tests/regression/init0002 | 2 +- src/tests/regression/init0005 | 2 +- src/tests/regression/init0007 | 4 +- src/tests/regression/init0008 | 2 +- src/tests/regression/init0012 | 4 +- src/tools/pkcs15-init.c | 53 +++---------------------- 17 files changed, 60 insertions(+), 197 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 081c4023..0364cb04 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -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 diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index e18aadb3..328bf001 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -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 diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 54b209d0..38c756ad 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -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)) && diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index d34d2c35..273af5a7 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -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"); } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 6260bc67..647c4f0e 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -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 diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index e4ef3407..985839fa 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -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 */ diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 51f883c0..ddf2f9ff 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -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; } /* diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index d36ff801..7df37107 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -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 diff --git a/src/tests/regression/README b/src/tests/regression/README index 339c125a..fa372186 100644 --- a/src/tests/regression/README +++ b/src/tests/regression/README @@ -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 diff --git a/src/tests/regression/functions b/src/tests/regression/functions index 8bd6e106..1b0adab4 100755 --- a/src/tests/regression/functions +++ b/src/tests/regression/functions @@ -47,7 +47,6 @@ if [ -z "$__p15init__" ]; then case $1 in -T|--use-default-transport-keys|\ - --split-key|\ --no-prompt|\ --soft|\ -v*) diff --git a/src/tests/regression/init0001 b/src/tests/regression/init0001 index 504c8d98..8eb5505f 100755 --- a/src/tests/regression/init0001 +++ b/src/tests/regression/init0001 @@ -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 diff --git a/src/tests/regression/init0002 b/src/tests/regression/init0002 index 34c40ffb..30681b0c 100755 --- a/src/tests/regression/init0002 +++ b/src/tests/regression/init0002 @@ -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 diff --git a/src/tests/regression/init0005 b/src/tests/regression/init0005 index 504c8d98..8eb5505f 100755 --- a/src/tests/regression/init0005 +++ b/src/tests/regression/init0005 @@ -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 diff --git a/src/tests/regression/init0007 b/src/tests/regression/init0007 index 24592247..a771515a 100755 --- a/src/tests/regression/init0007 +++ b/src/tests/regression/init0007 @@ -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 diff --git a/src/tests/regression/init0008 b/src/tests/regression/init0008 index efeb7643..3231f207 100755 --- a/src/tests/regression/init0008 +++ b/src/tests/regression/init0008 @@ -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 diff --git a/src/tests/regression/init0012 b/src/tests/regression/init0012 index 2c49ce36..82b6edbf 100755 --- a/src/tests/regression/init0012 +++ b/src/tests/regression/init0012 @@ -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 diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index a17f9ac0..935d912d 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -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;