1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-05 23:07:49 +02:00

g10,scd: Fix ECC keygen.

* g10/keygen.c (generate_keypair): For card key generation, fill
parameters by KEY-ATTR.

* scd/app-openpgp.c (ecc_read_pubkey): OID should be freed at last,
after its reference by OIDBUF is finished.
(ecc_writekey): Likewise.
--

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2016-10-21 21:37:04 +09:00
parent 693e657ff0
commit d2653b1a6d
3 changed files with 70 additions and 21 deletions

View File

@ -994,9 +994,11 @@ scd_genkey_cb (void *opaque, const char *line)
return 0; return 0;
} }
/* Send a GENKEY command to the SCdaemon. If CREATETIME is not 0, it /* Send a GENKEY command to the SCdaemon. If *CREATETIME is not 0,
will be passed to SCDAEMON so that the key is created with this the value will be passed to SCDAEMON with --timestamp option so that
timestamp. On success, creation time is stored back to CREATETIME. */ the key is created with this. Otherwise, timestamp was generated by
SCDEAMON. On success, creation time is stored back to
CREATETIME. */
int int
agent_scd_genkey (int keyno, int force, u32 *createtime) agent_scd_genkey (int keyno, int force, u32 *createtime)
{ {

View File

@ -3756,17 +3756,26 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
if (card_serialno) if (card_serialno)
{ {
#ifdef ENABLE_CARD_SUPPORT #ifdef ENABLE_CARD_SUPPORT
gpg_error_t err;
struct agent_card_info_s info;
memset (&info, 0, sizeof (info));
err = agent_scd_getattr ("KEY-ATTR", &info);
if (err)
{
log_error (_("error getting current key info: %s\n"), gpg_strerror (err));
return;
}
r = xcalloc (1, sizeof *r + strlen (card_serialno) ); r = xcalloc (1, sizeof *r + strlen (card_serialno) );
r->key = pSERIALNO; r->key = pSERIALNO;
strcpy( r->u.value, card_serialno); strcpy( r->u.value, card_serialno);
r->next = para; r->next = para;
para = r; para = r;
algo = PUBKEY_ALGO_RSA;
r = xcalloc (1, sizeof *r + 20 ); r = xcalloc (1, sizeof *r + 20 );
r->key = pKEYTYPE; r->key = pKEYTYPE;
sprintf( r->u.value, "%d", algo ); sprintf( r->u.value, "%d", info.key_attr[0].algo );
r->next = para; r->next = para;
para = r; para = r;
r = xcalloc (1, sizeof *r + 20 ); r = xcalloc (1, sizeof *r + 20 );
@ -3774,10 +3783,28 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
strcpy (r->u.value, "sign"); strcpy (r->u.value, "sign");
r->next = para; r->next = para;
para = r; para = r;
if (info.key_attr[0].algo == PUBKEY_ALGO_RSA)
{
r = xcalloc (1, sizeof *r + 20 );
r->key = pKEYLENGTH;
sprintf( r->u.value, "%u", info.key_attr[0].nbits);
r->next = para;
para = r;
}
else if (info.key_attr[0].algo == PUBKEY_ALGO_ECDSA
|| info.key_attr[0].algo == PUBKEY_ALGO_EDDSA
|| info.key_attr[0].algo == PUBKEY_ALGO_ECDH)
{
r = xcalloc (1, sizeof *r + strlen (info.key_attr[0].curve));
r->key = pKEYCURVE;
strcpy (r->u.value, info.key_attr[0].curve);
r->next = para;
para = r;
}
r = xcalloc (1, sizeof *r + 20 ); r = xcalloc (1, sizeof *r + 20 );
r->key = pSUBKEYTYPE; r->key = pSUBKEYTYPE;
sprintf( r->u.value, "%d", algo ); sprintf( r->u.value, "%d", info.key_attr[1].algo );
r->next = para; r->next = para;
para = r; para = r;
r = xcalloc (1, sizeof *r + 20 ); r = xcalloc (1, sizeof *r + 20 );
@ -3785,10 +3812,28 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
strcpy (r->u.value, "encrypt"); strcpy (r->u.value, "encrypt");
r->next = para; r->next = para;
para = r; para = r;
if (info.key_attr[1].algo == PUBKEY_ALGO_RSA)
{
r = xcalloc (1, sizeof *r + 20 );
r->key = pSUBKEYLENGTH;
sprintf( r->u.value, "%u", info.key_attr[1].nbits);
r->next = para;
para = r;
}
else if (info.key_attr[1].algo == PUBKEY_ALGO_ECDSA
|| info.key_attr[1].algo == PUBKEY_ALGO_EDDSA
|| info.key_attr[1].algo == PUBKEY_ALGO_ECDH)
{
r = xcalloc (1, sizeof *r + strlen (info.key_attr[1].curve));
r->key = pSUBKEYCURVE;
strcpy (r->u.value, info.key_attr[1].curve);
r->next = para;
para = r;
}
r = xcalloc (1, sizeof *r + 20 ); r = xcalloc (1, sizeof *r + 20 );
r->key = pAUTHKEYTYPE; r->key = pAUTHKEYTYPE;
sprintf( r->u.value, "%d", algo ); sprintf( r->u.value, "%d", info.key_attr[2].algo );
r->next = para; r->next = para;
para = r; para = r;
@ -4873,6 +4918,7 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
unsigned char *public; unsigned char *public;
gcry_sexp_t s_key; gcry_sexp_t s_key;
memset (&info, 0, sizeof (info));
err = agent_scd_getattr ("KEY-ATTR", &info); err = agent_scd_getattr ("KEY-ATTR", &info);
if (err) if (err)
{ {
@ -4931,8 +4977,8 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
if (algo == PUBKEY_ALGO_RSA) if (algo == PUBKEY_ALGO_RSA)
err = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
else if (algo == PUBKEY_ALGO_ECDSA else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH ) || algo == PUBKEY_ALGO_ECDH )
err = ecckey_from_sexp (pk->pkey, s_key, algo); err = ecckey_from_sexp (pk->pkey, s_key, algo);
else else
err = gpg_error (GPG_ERR_PUBKEY_ALGO); err = gpg_error (GPG_ERR_PUBKEY_ALGO);

View File

@ -1312,10 +1312,10 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp) const unsigned char *data, size_t datalen, gcry_sexp_t *r_sexp)
{ {
gpg_error_t err; gpg_error_t err;
unsigned char *qbuf; unsigned char *qbuf = NULL;
const unsigned char *ecc_q; const unsigned char *ecc_q;
size_t ecc_q_len; size_t ecc_q_len;
gcry_mpi_t oid; gcry_mpi_t oid = NULL;
int n; int n;
const unsigned char *oidbuf; const unsigned char *oidbuf;
size_t oid_len; size_t oid_len;
@ -1338,15 +1338,16 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
if (!oidbuf) if (!oidbuf)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
gcry_mpi_release (oid); goto leave;
return err;
} }
gcry_mpi_release (oid);
oid_len = (n+7)/8; oid_len = (n+7)/8;
qbuf = xtrymalloc (ecc_q_len + 1); qbuf = xtrymalloc (ecc_q_len + 1);
if (!qbuf) if (!qbuf)
return gpg_error_from_syserror (); {
err = gpg_error_from_syserror ();
goto leave;
}
if ((app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK)) if ((app->app_local->keyattr[keyno].ecc.flags & ECC_FLAG_DJB_TWEAK))
{ /* Prepend 0x40 prefix. */ { /* Prepend 0x40 prefix. */
@ -1359,7 +1360,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
if (ctrl) if (ctrl)
{ {
send_key_data (ctrl, "q", ecc_q, ecc_q_len); send_key_data (ctrl, "q", qbuf, ecc_q_len);
send_key_data (ctrl, "curve", oidbuf, oid_len); send_key_data (ctrl, "curve", oidbuf, oid_len);
} }
@ -1399,6 +1400,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
curve = openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1); curve = openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1);
err = gcry_sexp_build (r_sexp, NULL, format, curve, (int)ecc_q_len, qbuf); err = gcry_sexp_build (r_sexp, NULL, format, curve, (int)ecc_q_len, qbuf);
leave: leave:
gcry_mpi_release (oid);
xfree (qbuf); xfree (qbuf);
return err; return err;
} }
@ -3344,8 +3346,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
const char *oidstr = NULL; const char *oidstr = NULL;
int flag_djb_tweak = 0; int flag_djb_tweak = 0;
int algo; int algo;
gcry_mpi_t oid; gcry_mpi_t oid = NULL;
const unsigned char *oidbuf = NULL; const unsigned char *oidbuf;
unsigned int n; unsigned int n;
size_t oid_len; size_t oid_len;
unsigned char fprbuf[20]; unsigned char fprbuf[20];
@ -3498,10 +3500,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
if (!oidbuf) if (!oidbuf)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
gcry_mpi_release (oid);
goto leave; goto leave;
} }
gcry_mpi_release (oid);
oid_len = (n+7)/8; oid_len = (n+7)/8;
if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC
@ -3583,6 +3583,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4); ecc_q, ecc_q_len, "\x03\x01\x08\x07", (size_t)4);
leave: leave:
gcry_mpi_release (oid);
return err; return err;
} }