mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-14 18:31:03 +02:00
scd:piv: Support rsa3072
* scd/app-piv.c (PIV_ALGORITHM_RSA): Rename to PIV_ALGORITHM_RSA_2048. (PIV_ALGORITHM_RSA_3072): New. (get_key_algorithm_by_dobj): Decide whether to use 3072 or 2048. (do_sign): Support rsa3072. (do_decipher): Ditto. (do_genkey): Ditto. -- Take care: Due to a lack of a PIV token capable of 3072, this has not been tested at all.
This commit is contained in:
parent
15a71f108d
commit
e2732b8e19
@ -70,7 +70,9 @@
|
|||||||
#define PIV_ALGORITHM_2DES_CBC 0x02
|
#define PIV_ALGORITHM_2DES_CBC 0x02
|
||||||
#define PIV_ALGORITHM_3DES_ECB 0x03
|
#define PIV_ALGORITHM_3DES_ECB 0x03
|
||||||
#define PIV_ALGORITHM_3DES_CBC 0x04
|
#define PIV_ALGORITHM_3DES_CBC 0x04
|
||||||
#define PIV_ALGORITHM_RSA 0x07
|
#define PIV_ALGORITHM_RSA_3072 0x05
|
||||||
|
/*#define PIV_ALGORITHM_RSA_1024 0x06*/
|
||||||
|
#define PIV_ALGORITHM_RSA_2048 0x07
|
||||||
#define PIV_ALGORITHM_AES128_ECB 0x08
|
#define PIV_ALGORITHM_AES128_ECB 0x08
|
||||||
#define PIV_ALGORITHM_AES128_CBC 0x09
|
#define PIV_ALGORITHM_AES128_CBC 0x09
|
||||||
#define PIV_ALGORITHM_AES192_ECB 0x0A
|
#define PIV_ALGORITHM_AES192_ECB 0x0A
|
||||||
@ -1271,7 +1273,7 @@ get_keygrip_by_tag (app_t app, unsigned int tag,
|
|||||||
goto leave;
|
goto leave;
|
||||||
if (mechanism) /* Compute keygrip from public key. */
|
if (mechanism) /* Compute keygrip from public key. */
|
||||||
{
|
{
|
||||||
if (mechanism == PIV_ALGORITHM_RSA)
|
if (mechanism == PIV_ALGORITHM_RSA_2048)
|
||||||
err = genkey_parse_rsa (certbuf, certbuflen, &s_pkey);
|
err = genkey_parse_rsa (certbuf, certbuflen, &s_pkey);
|
||||||
else if (mechanism == PIV_ALGORITHM_ECC_P256
|
else if (mechanism == PIV_ALGORITHM_ECC_P256
|
||||||
|| mechanism == PIV_ALGORITHM_ECC_P384)
|
|| mechanism == PIV_ALGORITHM_ECC_P384)
|
||||||
@ -1486,7 +1488,7 @@ do_readkey (app_t app, ctrl_t ctrl, const char *keyrefstr, unsigned int flags,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Convert the public key into the expected s-expression. */
|
/* Convert the public key into the expected s-expression. */
|
||||||
if (mechanism == PIV_ALGORITHM_RSA)
|
if (mechanism == PIV_ALGORITHM_RSA_2048)
|
||||||
err = genkey_parse_rsa (cert, certlen, &s_pkey);
|
err = genkey_parse_rsa (cert, certlen, &s_pkey);
|
||||||
else if (mechanism == PIV_ALGORITHM_ECC_P256
|
else if (mechanism == PIV_ALGORITHM_ECC_P256
|
||||||
|| mechanism == PIV_ALGORITHM_ECC_P384)
|
|| mechanism == PIV_ALGORITHM_ECC_P384)
|
||||||
@ -1573,7 +1575,8 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_mechanism)
|
|||||||
/* A public key was found. That makes it easy. */
|
/* A public key was found. That makes it easy. */
|
||||||
switch (mechanism)
|
switch (mechanism)
|
||||||
{
|
{
|
||||||
case PIV_ALGORITHM_RSA:
|
case PIV_ALGORITHM_RSA_2048:
|
||||||
|
case PIV_ALGORITHM_RSA_3072:
|
||||||
case PIV_ALGORITHM_ECC_P256:
|
case PIV_ALGORITHM_ECC_P256:
|
||||||
case PIV_ALGORITHM_ECC_P384:
|
case PIV_ALGORITHM_ECC_P384:
|
||||||
*r_mechanism = mechanism;
|
*r_mechanism = mechanism;
|
||||||
@ -1636,7 +1639,10 @@ get_key_algorithm_by_dobj (app_t app, data_object_t dobj, int *r_mechanism)
|
|||||||
switch (algo)
|
switch (algo)
|
||||||
{
|
{
|
||||||
case GCRY_PK_RSA:
|
case GCRY_PK_RSA:
|
||||||
algo = PIV_ALGORITHM_RSA;
|
if (gcry_pk_get_nbits (s_pkey) > 3000)
|
||||||
|
algo = PIV_ALGORITHM_RSA_3072;
|
||||||
|
else
|
||||||
|
algo = PIV_ALGORITHM_RSA_2048;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GCRY_PK_ECC:
|
case GCRY_PK_ECC:
|
||||||
@ -2260,7 +2266,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
indatalen -= oidbuflen;
|
indatalen -= oidbuflen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mechanism == PIV_ALGORITHM_RSA
|
else if (mechanism == PIV_ALGORITHM_RSA_2048
|
||||||
&& indatalen == 2048/8 && indata[indatalen-1] == 0xBC)
|
&& indatalen == 2048/8 && indata[indatalen-1] == 0xBC)
|
||||||
{
|
{
|
||||||
/* If the provided data length matches the supported RSA
|
/* If the provided data length matches the supported RSA
|
||||||
@ -2268,13 +2274,27 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
* this is PSS formatted data and we use it verbatim; PIV cards
|
* this is PSS formatted data and we use it verbatim; PIV cards
|
||||||
* accept PSS as well as PKCS#1. */
|
* accept PSS as well as PKCS#1. */
|
||||||
}
|
}
|
||||||
else if (mechanism == PIV_ALGORITHM_RSA)
|
else if (mechanism == PIV_ALGORITHM_RSA_3072
|
||||||
|
&& indatalen == 3072/8 && indata[indatalen-1] == 0xBC)
|
||||||
{
|
{
|
||||||
/* PIV requires 2048 bit RSA. */
|
/* If the provided data length matches the supported RSA
|
||||||
unsigned int framelen = 2048 / 8;
|
* framelen and the last octet of the data is 0xBC, we assume
|
||||||
|
* this is PSS formatted data and we use it verbatim; PIV cards
|
||||||
|
* accept PSS as well as PKCS#1. */
|
||||||
|
}
|
||||||
|
else if (mechanism == PIV_ALGORITHM_RSA_2048
|
||||||
|
|| mechanism == PIV_ALGORITHM_RSA_3072)
|
||||||
|
{
|
||||||
|
/* PIV requires 2048 bit or 3072 bit RSA. */
|
||||||
|
unsigned int framelen;
|
||||||
unsigned char *frame;
|
unsigned char *frame;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (mechanism == PIV_ALGORITHM_RSA_2048)
|
||||||
|
framelen = 2048 / 8;
|
||||||
|
else
|
||||||
|
framelen = 3072 / 8;
|
||||||
|
|
||||||
oidbuflen = sizeof oidbuf;
|
oidbuflen = sizeof oidbuf;
|
||||||
if (!hashalgo)
|
if (!hashalgo)
|
||||||
{
|
{
|
||||||
@ -2380,7 +2400,12 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
if (outdatalen && *outdata == 0x7c
|
if (outdatalen && *outdata == 0x7c
|
||||||
&& (s = find_tlv (outdata, outdatalen, 0x82, &n)))
|
&& (s = find_tlv (outdata, outdatalen, 0x82, &n)))
|
||||||
{
|
{
|
||||||
if (mechanism == PIV_ALGORITHM_RSA)
|
if (mechanism == PIV_ALGORITHM_RSA_2048)
|
||||||
|
{
|
||||||
|
memmove (outdata, outdata + (s - outdata), n);
|
||||||
|
outdatalen = n;
|
||||||
|
}
|
||||||
|
else if (mechanism == PIV_ALGORITHM_RSA_3072)
|
||||||
{
|
{
|
||||||
memmove (outdata, outdata + (s - outdata), n);
|
memmove (outdata, outdata + (s - outdata), n);
|
||||||
outdatalen = n;
|
outdatalen = n;
|
||||||
@ -2526,9 +2551,12 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
|
|||||||
case PIV_ALGORITHM_ECC_P384:
|
case PIV_ALGORITHM_ECC_P384:
|
||||||
framelen = 1+48+48;
|
framelen = 1+48+48;
|
||||||
break;
|
break;
|
||||||
case PIV_ALGORITHM_RSA:
|
case PIV_ALGORITHM_RSA_2048:
|
||||||
framelen = 2048 / 8;
|
framelen = 2048 / 8;
|
||||||
break;
|
break;
|
||||||
|
case PIV_ALGORITHM_RSA_3072:
|
||||||
|
framelen = 3072 / 8;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
err = gpg_error (GPG_ERR_INTERNAL);
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
log_debug ("piv: unknown PIV mechanism %d while decrypting\n", mechanism);
|
log_debug ("piv: unknown PIV mechanism %d while decrypting\n", mechanism);
|
||||||
@ -2545,7 +2573,8 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
|
|||||||
* uncompressed point. */
|
* uncompressed point. */
|
||||||
if (indatalen > framelen)
|
if (indatalen > framelen)
|
||||||
{
|
{
|
||||||
if (mechanism == PIV_ALGORITHM_RSA
|
if ((mechanism == PIV_ALGORITHM_RSA_2048
|
||||||
|
|| mechanism == PIV_ALGORITHM_RSA_3072)
|
||||||
&& indatalen == framelen + 1 && !*indata)
|
&& indatalen == framelen + 1 && !*indata)
|
||||||
{
|
{
|
||||||
indata_buffer = xtrycalloc (1, framelen);
|
indata_buffer = xtrycalloc (1, framelen);
|
||||||
@ -2588,7 +2617,8 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
|
|||||||
err = concat_tlv_list (0, &apdudata, &apdudatalen,
|
err = concat_tlv_list (0, &apdudata, &apdudatalen,
|
||||||
(int)0x7c, (size_t)0, NULL, /* Constructed. */
|
(int)0x7c, (size_t)0, NULL, /* Constructed. */
|
||||||
(int)0x82, (size_t)0, "",
|
(int)0x82, (size_t)0, "",
|
||||||
mechanism == PIV_ALGORITHM_RSA?
|
(mechanism == PIV_ALGORITHM_RSA_2048
|
||||||
|
|| mechanism == PIV_ALGORITHM_RSA_3072)?
|
||||||
(int)0x81 : (int)0x85, (size_t)indatalen, indata,
|
(int)0x81 : (int)0x85, (size_t)indatalen, indata,
|
||||||
(int)0, (size_t)0, NULL);
|
(int)0, (size_t)0, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2678,6 +2708,7 @@ writekey_rsa (app_t app, data_object_t dobj, int keyref,
|
|||||||
const unsigned char *tok;
|
const unsigned char *tok;
|
||||||
size_t toklen;
|
size_t toklen;
|
||||||
int last_depth1, last_depth2;
|
int last_depth1, last_depth2;
|
||||||
|
int mechanism;
|
||||||
const unsigned char *rsa_n = NULL;
|
const unsigned char *rsa_n = NULL;
|
||||||
const unsigned char *rsa_e = NULL;
|
const unsigned char *rsa_e = NULL;
|
||||||
const unsigned char *rsa_p = NULL;
|
const unsigned char *rsa_p = NULL;
|
||||||
@ -2796,11 +2827,16 @@ writekey_rsa (app_t app, data_object_t dobj, int keyref,
|
|||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
if (rsa_n_len > 3000/8)
|
||||||
|
mechanism = PIV_ALGORITHM_RSA_3072;
|
||||||
|
else
|
||||||
|
mechanism = PIV_ALGORITHM_RSA_2048;
|
||||||
|
|
||||||
err = iso7816_send_apdu (app_get_slot (app),
|
err = iso7816_send_apdu (app_get_slot (app),
|
||||||
-1, /* Use command chaining. */
|
-1, /* Use command chaining. */
|
||||||
0, /* Class */
|
0, /* Class */
|
||||||
0xfe, /* Ins: Yubikey Import Asym. Key. */
|
0xfe, /* Ins: Yubikey Import Asym. Key. */
|
||||||
PIV_ALGORITHM_RSA, /* P1 */
|
mechanism, /* P1 */
|
||||||
keyref, /* P2 */
|
keyref, /* P2 */
|
||||||
apdudatalen,/* Lc */
|
apdudatalen,/* Lc */
|
||||||
apdudata, /* data */
|
apdudata, /* data */
|
||||||
@ -2817,7 +2853,7 @@ writekey_rsa (app_t app, data_object_t dobj, int keyref,
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
tmpl[0] = PIV_ALGORITHM_RSA;
|
tmpl[0] = mechanism;
|
||||||
err = put_data (app_get_slot (app), dobj->tag,
|
err = put_data (app_get_slot (app), dobj->tag,
|
||||||
(int)0x80, (size_t)1, tmpl,
|
(int)0x80, (size_t)1, tmpl,
|
||||||
(int)0x7f49, (size_t)apdudatalen, apdudata,
|
(int)0x7f49, (size_t)apdudatalen, apdudata,
|
||||||
@ -3208,7 +3244,7 @@ genkey_parse_ecc (const unsigned char *data, size_t datalen, int mechanism,
|
|||||||
|
|
||||||
/* Create a new keypair for KEYREF. If KEYTYPE is NULL a default
|
/* Create a new keypair for KEYREF. If KEYTYPE is NULL a default
|
||||||
* keytype is selected, else it may be one of the strings:
|
* keytype is selected, else it may be one of the strings:
|
||||||
* "rsa2048", "nistp256, or "nistp384".
|
* "rsa2048", "rsa3072", "nistp256, or "nistp384".
|
||||||
*
|
*
|
||||||
* Supported FLAGS are:
|
* Supported FLAGS are:
|
||||||
* APP_GENKEY_FLAG_FORCE Overwrite existing key.
|
* APP_GENKEY_FLAG_FORCE Overwrite existing key.
|
||||||
@ -3249,7 +3285,9 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype,
|
|||||||
keytype = "rsa2048";
|
keytype = "rsa2048";
|
||||||
|
|
||||||
if (!strcmp (keytype, "rsa2048"))
|
if (!strcmp (keytype, "rsa2048"))
|
||||||
mechanism = PIV_ALGORITHM_RSA;
|
mechanism = PIV_ALGORITHM_RSA_2048;
|
||||||
|
else if (!strcmp (keytype, "rsa3072"))
|
||||||
|
mechanism = PIV_ALGORITHM_RSA_3072;
|
||||||
else if (!strcmp (keytype, "nistp256"))
|
else if (!strcmp (keytype, "nistp256"))
|
||||||
mechanism = PIV_ALGORITHM_ECC_P256;
|
mechanism = PIV_ALGORITHM_ECC_P256;
|
||||||
else if (!strcmp (keytype, "nistp384"))
|
else if (!strcmp (keytype, "nistp384"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user