diff --git a/g10/call-agent.c b/g10/call-agent.c index c1ad8ddf7..e7af001df 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -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) { diff --git a/g10/keygen.c b/g10/keygen.c index 64e0d4308..a59435da4 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index f909c6f2c..e6a76988d 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -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; }