openpgp: handle cards with static algorithms
fixes https://github.com/OpenSC/OpenSC/issues/1659
This commit is contained in:
parent
530175009c
commit
a1d3e76999
|
@ -2292,53 +2292,63 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_
|
|||
r = pgp_seek_blob(card, priv->mf, tag, &algo_blob);
|
||||
LOG_TEST_RET(card->ctx, r, "Cannot get old algorithm attributes");
|
||||
|
||||
/* ECDSA and ECDH */
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){
|
||||
data_len = key_info->u.ec.oid_len+1;
|
||||
data = malloc(data_len);
|
||||
if (!data)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
|
||||
if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) {
|
||||
/* ECDSA and ECDH */
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){
|
||||
data_len = key_info->u.ec.oid_len+1;
|
||||
data = malloc(data_len);
|
||||
if (!data)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
||||
data[0] = key_info->algorithm;
|
||||
/* oid.value is type int, therefore we need to loop over the values */
|
||||
for (i=0; i < key_info->u.ec.oid_len; i++){
|
||||
data[i+1] = key_info->u.ec.oid.value[i];
|
||||
data[0] = key_info->algorithm;
|
||||
/* oid.value is type int, therefore we need to loop over the values */
|
||||
for (i=0; i < key_info->u.ec.oid_len; i++){
|
||||
data[i+1] = key_info->u.ec.oid.value[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* RSA */
|
||||
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){
|
||||
|
||||
/* We can not rely on previous key attributes anymore, as it might be ECC */
|
||||
if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0)
|
||||
LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
data_len = 6;
|
||||
data = malloc(data_len);
|
||||
if (!data)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
||||
data[0] = key_info->algorithm;
|
||||
ushort2bebytes(data+1, key_info->u.rsa.modulus_len);
|
||||
/* OpenPGP Card only accepts 32bit as exponent lenght field,
|
||||
* although you can import keys with smaller exponent;
|
||||
* thus we don't change rsa.exponent_len, but ignore it here */
|
||||
ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS);
|
||||
/* Import-Format of private key (e,p,q) */
|
||||
data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD;
|
||||
}
|
||||
else {
|
||||
sc_log(card->ctx, "Unknown algorithm id");
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
pgp_set_blob(algo_blob, data, data_len);
|
||||
free(data);
|
||||
r = pgp_put_data(card, tag, algo_blob->data, data_len);
|
||||
/* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */
|
||||
LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes");
|
||||
} else {
|
||||
sc_cardctl_openpgp_keygen_info_t old_key_info;
|
||||
|
||||
if (pgp_parse_algo_attr_blob(algo_blob, &old_key_info) != SC_SUCCESS
|
||||
|| old_key_info.algorithm != key_info->algorithm)
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT,
|
||||
"Requested algorithm not supported");
|
||||
/* FIXME check whether the static parameters match the requested ones. */
|
||||
}
|
||||
|
||||
/* RSA */
|
||||
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA){
|
||||
|
||||
/* We can not rely on previous key attributes anymore, as it might be ECC */
|
||||
if (key_info->u.rsa.exponent_len == 0 || key_info->u.rsa.modulus_len == 0)
|
||||
LOG_FUNC_RETURN(card->ctx,SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
data_len = 6;
|
||||
data = malloc(data_len);
|
||||
if (!data)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
|
||||
|
||||
data[0] = key_info->algorithm;
|
||||
ushort2bebytes(data+1, key_info->u.rsa.modulus_len);
|
||||
/* OpenPGP Card only accepts 32bit as exponent lenght field,
|
||||
* although you can import keys with smaller exponent;
|
||||
* thus we don't change rsa.exponent_len, but ignore it here */
|
||||
ushort2bebytes(data+3, SC_OPENPGP_MAX_EXP_BITS);
|
||||
/* Import-Format of private key (e,p,q) */
|
||||
data[5] = SC_OPENPGP_KEYFORMAT_RSA_STD;
|
||||
}
|
||||
else {
|
||||
sc_log(card->ctx, "Unknown algorithm id");
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
pgp_set_blob(algo_blob, data, data_len);
|
||||
free(data);
|
||||
r = pgp_put_data(card, tag, algo_blob->data, data_len);
|
||||
/* Note: Don't use pgp_set_blob to set data, because it won't touch the real DO */
|
||||
LOG_TEST_RET(card->ctx, r, "Cannot set new algorithm attributes");
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
|
|
|
@ -705,10 +705,14 @@ int do_genkey(sc_card_t *card, u8 in_key_id, const char *keytype)
|
|||
key_info.key_id = in_key_id;
|
||||
key_info.algorithm = SC_OPENPGP_KEYALGO_RSA;
|
||||
key_info.u.rsa.modulus_len = keylen;
|
||||
key_info.u.rsa.modulus = malloc(BYTES4BITS(keylen));
|
||||
key_info.u.rsa.modulus = calloc(BYTES4BITS(keylen), 1);
|
||||
/* The OpenPGP supports only 32-bit exponent. */
|
||||
key_info.u.rsa.exponent_len = 32;
|
||||
key_info.u.rsa.exponent = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1);
|
||||
|
||||
r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
|
||||
free(key_info.u.rsa.modulus);
|
||||
free(key_info.u.rsa.exponent);
|
||||
if (r < 0) {
|
||||
util_error("failed to generate key: %s", sc_strerror(r));
|
||||
return EXIT_FAILURE;
|
||||
|
|
Loading…
Reference in New Issue