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;
}
/* Send a GENKEY command to the SCdaemon. If CREATETIME is not 0, it
will be passed to SCDAEMON so that the key is created with this
timestamp. On success, creation time is stored back to CREATETIME. */
/* Send a GENKEY command to the SCdaemon. If *CREATETIME is not 0,
the value will be passed to SCDAEMON with --timestamp option so that
the key is created with this. Otherwise, timestamp was generated by
SCDEAMON. On success, creation time is stored back to
CREATETIME. */
int
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)
{
#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->key = pSERIALNO;
strcpy( r->u.value, card_serialno);
r->next = para;
para = r;
algo = PUBKEY_ALGO_RSA;
r = xcalloc (1, sizeof *r + 20 );
r->key = pKEYTYPE;
sprintf( r->u.value, "%d", algo );
sprintf( r->u.value, "%d", info.key_attr[0].algo );
r->next = para;
para = r;
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");
r->next = para;
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->key = pSUBKEYTYPE;
sprintf( r->u.value, "%d", algo );
sprintf( r->u.value, "%d", info.key_attr[1].algo );
r->next = para;
para = r;
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");
r->next = para;
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->key = pAUTHKEYTYPE;
sprintf( r->u.value, "%d", algo );
sprintf( r->u.value, "%d", info.key_attr[2].algo );
r->next = para;
para = r;
@ -4873,6 +4918,7 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
unsigned char *public;
gcry_sexp_t s_key;
memset (&info, 0, sizeof (info));
err = agent_scd_getattr ("KEY-ATTR", &info);
if (err)
{
@ -4931,8 +4977,8 @@ gen_card_key (int keyno, int is_primary, kbnode_t pub_root,
if (algo == PUBKEY_ALGO_RSA)
err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
err = ecckey_from_sexp (pk->pkey, s_key, algo);
else
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)
{
gpg_error_t err;
unsigned char *qbuf;
unsigned char *qbuf = NULL;
const unsigned char *ecc_q;
size_t ecc_q_len;
gcry_mpi_t oid;
gcry_mpi_t oid = NULL;
int n;
const unsigned char *oidbuf;
size_t oid_len;
@ -1338,15 +1338,16 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
if (!oidbuf)
{
err = gpg_error_from_syserror ();
gcry_mpi_release (oid);
return err;
goto leave;
}
gcry_mpi_release (oid);
oid_len = (n+7)/8;
qbuf = xtrymalloc (ecc_q_len + 1);
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))
{ /* Prepend 0x40 prefix. */
@ -1359,7 +1360,7 @@ ecc_read_pubkey (app_t app, ctrl_t ctrl, u32 created_at, int keyno,
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);
}
@ -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);
err = gcry_sexp_build (r_sexp, NULL, format, curve, (int)ecc_q_len, qbuf);
leave:
gcry_mpi_release (oid);
xfree (qbuf);
return err;
}
@ -3344,8 +3346,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
const char *oidstr = NULL;
int flag_djb_tweak = 0;
int algo;
gcry_mpi_t oid;
const unsigned char *oidbuf = NULL;
gcry_mpi_t oid = NULL;
const unsigned char *oidbuf;
unsigned int n;
size_t oid_len;
unsigned char fprbuf[20];
@ -3498,10 +3500,8 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
if (!oidbuf)
{
err = gpg_error_from_syserror ();
gcry_mpi_release (oid);
goto leave;
}
gcry_mpi_release (oid);
oid_len = (n+7)/8;
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);
leave:
gcry_mpi_release (oid);
return err;
}