- allow to generate/store decryption keys

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@693 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-10-02 10:50:15 +00:00
parent fe27ed651e
commit b2379d40d5
1 changed files with 55 additions and 12 deletions

View File

@ -70,10 +70,14 @@ static void error(struct sc_profile *, const char *, ...);
#define ETOKEN_SE_ID(idx) (0x40 + (idx))
#define ETOKEN_AC_NEVER 0xFF
#define ETOKEN_ALGO_RSA_SIG_SHA1 0xCC
#define ETOKEN_ALGO_RSA 0x08
#define ETOKEN_ALGO_RSA_PURE 0x0C
#define ETOKEN_ALGO_RSA_SIG 0x88
#define ETOKEN_ALGO_RSA_PURE_SIG 0x8C
#define ETOKEN_ALGO_RSA ETOKEN_ALGO_RSA_PURE_SIG
#define ETOKEN_ALGO_RSA_SIG_SHA1 0xC8
#define ETOKEN_ALGO_RSA_PURE_SIG_SHA1 0xCC
#define ETOKEN_SIGN_RSA ETOKEN_ALGO_RSA_PURE_SIG
#define ETOKEN_DECIPHER_RSA ETOKEN_ALGO_RSA_PURE
#define ETOKEN_ALGO_PIN 0x87
static inline void
@ -323,6 +327,31 @@ etoken_new_pin(struct sc_profile *profile, struct sc_card *card,
return r;
}
/*
* Determine the key algorithm based on the intended usage
* Note that CardOS/M4 does not support keys that can be used
* for signing _and_ decipherment
*/
#define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN)
#define USAGE_ANY_DECIPHER (SC_PKCS15_PRKEY_USAGE_DECRYPT|\
SC_PKCS15_PRKEY_USAGE_UNWRAP)
static int
etoken_key_algorithm(unsigned int usage, int *algop)
{
int sign = 0, decipher = 0;
if (usage & USAGE_ANY_SIGN) {
*algop = ETOKEN_SIGN_RSA;
sign++;
}
if (usage & USAGE_ANY_DECIPHER) {
*algop = ETOKEN_DECIPHER_RSA;
decipher++;
}
return (sign && decipher)? -1 : 0;
}
/*
* Create a private key object
*/
@ -330,6 +359,7 @@ etoken_new_pin(struct sc_profile *profile, struct sc_card *card,
#define ETOKEN_KEY_FLAGS 0x00
static int
etoken_store_key_component(struct sc_card *card,
int algorithm,
unsigned int key_id, unsigned int pin_id,
unsigned int num,
const u8 *data, size_t len,
@ -352,7 +382,7 @@ etoken_store_key_component(struct sc_card *card,
tlv_next(&tlv, 0x85);
tlv_add(&tlv, ETOKEN_KEY_OPTIONS|(last? 0x00 : 0x20));
tlv_add(&tlv, ETOKEN_KEY_FLAGS);
tlv_add(&tlv, ETOKEN_ALGO_RSA);
tlv_add(&tlv, algorithm);
tlv_add(&tlv, 0x00);
tlv_add(&tlv, 0xFF); /* use count */
tlv_add(&tlv, 0xFF); /* DEK (whatever this is) */
@ -392,7 +422,8 @@ etoken_store_key_component(struct sc_card *card,
static int
etoken_store_key(struct sc_profile *profile, struct sc_card *card,
unsigned int key_id, struct sc_pkcs15_prkey_rsa *key)
int algorithm, unsigned int key_id,
struct sc_pkcs15_prkey_rsa *key)
{
struct sc_pkcs15_pin_info pin_info;
int r, pin_id;
@ -401,12 +432,12 @@ etoken_store_key(struct sc_profile *profile, struct sc_card *card,
if ((pin_id = pin_info.reference) < 0)
pin_id = 0;
r = etoken_store_key_component(card, key_id, pin_id,
0, key->modulus.data, key->modulus.len, 0);
r = etoken_store_key_component(card, algorithm, key_id, pin_id, 0,
key->modulus.data, key->modulus.len, 0);
if (r < 0)
return r;
r = etoken_store_key_component(card, key_id, pin_id,
1, key->d.data, key->d.len, 1);
r = etoken_store_key_component(card, algorithm, key_id, pin_id, 1,
key->d.data, key->d.len, 1);
return r;
}
@ -420,15 +451,21 @@ etoken_new_key(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_prkey_info *info)
{
struct sc_pkcs15_prkey_rsa *rsa;
int key_id, r;
int algorithm, key_id, r;
if (key->algorithm != SC_ALGORITHM_RSA) {
error(profile, "eToken supports RSA keys only.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (etoken_key_algorithm(info->usage, &algorithm) < 0) {
error(profile, "eToken does not support keys "
"that can both sign _and_ decrypt.");
return SC_ERROR_NOT_SUPPORTED;
}
rsa = &key->u.rsa;
key_id = ETOKEN_KEY_ID(index);
r = etoken_store_key(profile, card, key_id, rsa);
r = etoken_store_key(profile, card, algorithm, key_id, rsa);
if (r >= 0) {
info->path = profile->df_info->file->path;
info->key_reference = key_id;
@ -553,7 +590,7 @@ etoken_generate_key(struct sc_profile *profile, struct sc_card *card,
struct sc_file *temp;
u8 abignum[RSAKEY_MAX_SIZE];
u8 randbuf[64], key_id;
int r, delete_it = 0;
int algorithm, r, delete_it = 0;
keybits &= ~7UL;
if (keybits > RSAKEY_MAX_BITS) {
@ -562,6 +599,12 @@ etoken_generate_key(struct sc_profile *profile, struct sc_card *card,
return SC_ERROR_INVALID_ARGUMENTS;
}
if (etoken_key_algorithm(info->usage, &algorithm) < 0) {
error(profile, "eToken does not support keys "
"that can both sign _and_ decrypt.");
return SC_ERROR_NOT_SUPPORTED;
}
if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {
error(profile, "Profile doesn't define temporary file "
"for key generation.\n");
@ -582,7 +625,7 @@ etoken_generate_key(struct sc_profile *profile, struct sc_card *card,
key_obj.modulus.len = keybits >> 3;
key_obj.d.data = abignum;
key_obj.d.len = keybits >> 3;
r = etoken_store_key(profile, card, key_id, &key_obj);
r = etoken_store_key(profile, card, algorithm, key_id, &key_obj);
if (r < 0)
goto out;