From 7d376ffa321d4af6e62a2bc64ef2b8574b122b1a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 22 Feb 2013 11:00:27 +0900 Subject: gpg: fix keytocard and support ECC card for key attribute. * g10/call-agent.c (agent_keytocard): Supply PARM arg. * g10/card-util.c (card_status): Support ECC. (card_store_subkey): Don't assume RSA. --- g10/call-agent.c | 8 ++++++-- g10/card-util.c | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'g10') diff --git a/g10/call-agent.c b/g10/call-agent.c index 85a3f2842..e3250fe46 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -606,6 +606,10 @@ agent_keytocard (const char *hexgrip, int keyno, int force, { int rc; char line[ASSUAN_LINELENGTH]; + struct default_inq_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.ctx = agent_ctx; snprintf (line, DIM(line)-1, "KEYTOCARD %s%s %s OPENPGP.%d %s", force?"--force ": "", hexgrip, serialno, keyno, timestamp); @@ -615,8 +619,8 @@ agent_keytocard (const char *hexgrip, int keyno, int force, if (rc) return rc; - rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, - NULL, NULL, NULL); + rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm, + NULL, NULL); if (rc) return rc; diff --git a/g10/card-util.c b/g10/card-util.c index 75208cc86..add8eed09 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -550,7 +550,9 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen) tty_fprintf (fp, " %u%c", info.key_attr[i].nbits, info.key_attr[i].algo == 1? 'R': - info.key_attr[i].algo == 17? 'D': '?'); + info.key_attr[i].algo == 17? 'D': + info.key_attr[i].algo == 18? 'e': + info.key_attr[i].algo == 19? 'E': '?'); tty_fprintf (fp, "\n"); } tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", @@ -1560,7 +1562,7 @@ card_store_subkey (KBNODE node, int use) nbits = nbits_from_pk (pk); - if (!is_RSA (pk->pubkey_algo) || (!info.is_v2 && nbits != 1024) ) + if (!info.is_v2 && nbits != 1024) { tty_printf ("You may only store a 1024 bit RSA key on the card\n"); tty_printf ("\n"); -- cgit v1.2.3 From baee681d2406530c45fd6d4bde77193ba23ac263 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Feb 2013 20:27:20 +0100 Subject: gpg: Handle the agent's NEW_PASSPHRASE inquiry. * g10/call-agent.c (default_inq_cb): Take care of NEW_PASSPHRASE. --- g10/call-agent.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'g10') diff --git a/g10/call-agent.c b/g10/call-agent.c index e3250fe46..908d2761c 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -336,7 +336,7 @@ default_inq_cb (void *opaque, const char *line) gpg_error_t err = 0; struct default_inq_parm_s *parm = opaque; - if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17])) + if (has_leading_keyword (line, "PINENTRY_LAUNCHED")) { err = gpg_proxy_pinentry_notify (parm->ctrl, line); if (err) @@ -344,7 +344,8 @@ default_inq_cb (void *opaque, const char *line) "PINENTRY_LAUNCHED"); /* We do not pass errors to avoid breaking other code. */ } - else if (!strncmp (line, "PASSPHRASE", 10) && (line[10]==' '||!line[10]) + else if ((has_leading_keyword (line, "PASSPHRASE") + || has_leading_keyword (line, "NEW_PASSPHRASE")) && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK) { if (have_static_passphrase ()) -- cgit v1.2.3 From 161674118d568025896026ede5e03d26bdfdfa68 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Feb 2013 20:35:10 +0100 Subject: gpg: Fix a memory leak in batch key generation * g10/keygen.c (append_to_parameter): New. (proc_parameter_file): Use new func to extend the parameter list. * g10/passphrase.c (passphrase_to_dek_ext): Print a diagnostic of gcry_kdf_derive failed. * g10/keygen.c (proc_parameter_file): Print a diagnostic if passphrase_to_dek failed. -- Due to an improper way of using the linked list head, all memory for items allocated in proc_parameter_file was never released. If batched key generation with a passphrase and more than ~200 keys was used this exhausted the secure memory. --- g10/keygen.c | 48 +++++++++++++++++++++++++++++------------------- g10/passphrase.c | 18 +++++++++++------- 2 files changed, 40 insertions(+), 26 deletions(-) (limited to 'g10') diff --git a/g10/keygen.c b/g10/keygen.c index b5ccf0287..fc985eef3 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2591,6 +2591,17 @@ generate_user_id (KBNODE keyblock) } +/* Append R to the linked list PARA. */ +static void +append_to_parameter (struct para_data_s *para, struct para_data_s *r) +{ + assert (para); + while (para->next) + para = para->next; + para->next = r; +} + +/* Release the parameter list R. */ static void release_parameter_list (struct para_data_s *r) { @@ -2817,8 +2828,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, r->u.usage = (is_default ? (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG) : openpgp_pk_algo_usage(algo)); - r->next = para; - para = r; + append_to_parameter (para, r); } else if (err == -1) return -1; @@ -2854,8 +2864,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, r->u.usage = (is_default ? PUBKEY_USAGE_ENC : openpgp_pk_algo_usage (algo)); - r->next = para; - para = r; + append_to_parameter (para, r); } else if (err == -1) return -1; @@ -2892,8 +2901,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")"); if( s3 ) p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">"); - r->next = para; - para = r; + append_to_parameter (para, r); have_user_id=1; } } @@ -2946,13 +2954,11 @@ proc_parameter_file( struct para_data_s *para, const char *fname, r = xmalloc_clear( sizeof *r ); r->key = pPASSPHRASE_DEK; r->u.dek = dek; - r->next = para; - para = r; + append_to_parameter (para, r); r = xmalloc_clear( sizeof *r ); r->key = pPASSPHRASE_S2K; r->u.s2k = s2k; - r->next = para; - para = r; + append_to_parameter (para, r); } if (canceled) @@ -2971,27 +2977,32 @@ proc_parameter_file( struct para_data_s *para, const char *fname, * but because we do this always, why not here. */ STRING2KEY *s2k; DEK *dek; + static int count; - s2k = xmalloc_secure ( sizeof *s2k ); + s2k = xmalloc ( sizeof *s2k ); s2k->mode = opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; set_next_passphrase ( r->u.value ); dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2, NULL, NULL); - set_next_passphrase (NULL ); - assert (dek); + if (!dek) + { + log_error ("%s:%d: error post processing the passphrase\n", + fname, r->lnr ); + xfree (s2k); + return -1; + } + set_next_passphrase (NULL); memset (r->u.value, 0, strlen(r->u.value)); r = xmalloc_clear (sizeof *r); r->key = pPASSPHRASE_S2K; r->u.s2k = s2k; - r->next = para; - para = r; + append_to_parameter (para, r); r = xmalloc_clear (sizeof *r); r->key = pPASSPHRASE_DEK; r->u.dek = dek; - r->next = para; - para = r; + append_to_parameter (para, r); } } @@ -3029,8 +3040,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, r = xmalloc_clear( sizeof *r + 20 ); r->key = pSUBKEYEXPIRE; r->u.expire = seconds; - r->next = para; - para = r; + append_to_parameter (para, r); } do_generate_keypair( para, outctrl, card ); diff --git a/g10/passphrase.c b/g10/passphrase.c index d872e36ae..f83e66825 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -569,17 +569,21 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, dek->keylen = 0; else { + gpg_error_t err; + dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo); if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key))) BUG (); - if (gcry_kdf_derive (pw, strlen (pw), - s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K : - s2k->mode == 1? GCRY_KDF_SALTED_S2K : - /* */ GCRY_KDF_SIMPLE_S2K, - s2k->hash_algo, s2k->salt, 8, - S2K_DECODE_COUNT(s2k->count), - dek->keylen, dek->key)) + err = gcry_kdf_derive (pw, strlen (pw), + s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K : + s2k->mode == 1? GCRY_KDF_SALTED_S2K : + /* */ GCRY_KDF_SIMPLE_S2K, + s2k->hash_algo, s2k->salt, 8, + S2K_DECODE_COUNT(s2k->count), + dek->keylen, dek->key); + if (err) { + log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err)); xfree (pw); xfree (dek); write_status( STATUS_MISSING_PASSPHRASE ); -- cgit v1.2.3 From 585d5c62eece23911a768d97d11f159be138b13d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 22 Feb 2013 10:56:13 +0100 Subject: Use has_leading_keyword in the assuan callbacks. * agent/call-pinentry.c (inq_quality): Use has_leading_keyword. * agent/call-scd.c (inq_needpin, inq_writekey_parms): Ditto. * g10/call-agent.c (inq_writecert_parms, keyinfo_status_cb): Ditto. (inq_genkey_parms, inq_ciphertext_cb, inq_import_key_parms): Ditto. * g10/call-dirmngr.c (ks_put_inq_cb): Ditto. * sm/call-agent.c (default_inq_cb, inq_ciphertext_cb): Ditto. (inq_genkey_parms, istrusted_status_cb, learn_status_cb): Ditto. (keyinfo_status_cb, inq_import_key_parms): Ditto. * sm/call-dirmngr.c (inq_certificate, isvalid_status_cb): Ditto. (lookup_status_cb, run_command_inq_cb, run_command_status_cb): Ditto. --- g10/call-agent.c | 14 +++++++------- g10/call-dirmngr.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'g10') diff --git a/g10/call-agent.c b/g10/call-agent.c index 908d2761c..cb965e9ad 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -725,7 +725,7 @@ inq_writecert_parms (void *opaque, const char *line) int rc; struct writecert_parm_s *parm = opaque; - if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8])) + if (has_leading_keyword (line, "CERTDATA")) { rc = assuan_send_data (parm->dflt->ctx, parm->certdata, parm->certdatalen); @@ -778,7 +778,7 @@ inq_writekey_parms (void *opaque, const char *line) int rc; struct writekey_parm_s *parm = opaque; - if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7])) + if (has_leading_keyword (line, "KEYDATA")) { rc = assuan_send_data (parm->dflt->ctx, parm->keydata, parm->keydatalen); } @@ -1471,9 +1471,9 @@ keyinfo_status_cb (void *opaque, const char *line) char **serialno = opaque; const char *s, *s2; - if (!strncmp (line, "KEYINFO ", 8) && !*serialno) + if ((s = has_leading_keyword (line, "KEYINFO ")) && !*serialno) { - s = strchr (line+8, ' '); + s = strchr (s, ' '); if (s && s[1] == 'T' && s[2] == ' ' && s[3]) { s += 3; @@ -1575,7 +1575,7 @@ inq_genkey_parms (void *opaque, const char *line) struct genkey_parm_s *parm = opaque; gpg_error_t err; - if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8])) + if (has_leading_keyword (line, "KEYPARAM")) { err = assuan_send_data (parm->dflt->ctx, parm->keyparms, strlen (parm->keyparms)); @@ -1802,7 +1802,7 @@ inq_ciphertext_cb (void *opaque, const char *line) struct cipher_parm_s *parm = opaque; int rc; - if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10])) + if (has_leading_keyword (line, "CIPHERTEXT")) { assuan_begin_confidential (parm->ctx); rc = assuan_send_data (parm->dflt->ctx, @@ -1984,7 +1984,7 @@ inq_import_key_parms (void *opaque, const char *line) struct import_key_parm_s *parm = opaque; gpg_error_t err; - if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7])) + if (has_leading_keyword (line, "KEYDATA")) { err = assuan_send_data (parm->dflt->ctx, parm->key, parm->keylen); } diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 09ade4eb9..75f25f8a4 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -515,12 +515,12 @@ ks_put_inq_cb (void *opaque, const char *line) struct ks_put_parm_s *parm = opaque; gpg_error_t err = 0; - if (!strncmp (line, "KEYBLOCK", 8) && (line[8] == ' ' || !line[8])) + if (has_leading_keyword (line, "KEYBLOCK")) { if (parm->data) err = assuan_send_data (parm->ctx, parm->data, parm->datalen); } - else if (!strncmp (line, "KEYBLOCK_INFO", 13) && (line[13]==' ' || !line[13])) + else if (has_leading_keyword (line, "KEYBLOCK_INFO")) { kbnode_t node; estream_t fp; -- cgit v1.2.3 From 4bde12206c5bf199dc6e12a74af8da4558ba41bf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 15 Mar 2013 15:46:03 +0100 Subject: gpg: Distinguish between missing and cleared key flags. * include/cipher.h (PUBKEY_USAGE_NONE): New. * g10/getkey.c (parse_key_usage): Set new flag. -- We do not want to use the default capabilities (derived from the algorithm) if any key flags are given in a signature. Thus if key flags are used in any way, the default key capabilities are never used. This allows to create a key with key flags set to all zero so it can't be used. This better reflects common sense. --- g10/getkey.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'g10') diff --git a/g10/getkey.c b/g10/getkey.c index 929427302..8cc560100 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1276,13 +1276,19 @@ parse_key_usage (PKT_signature * sig) if (flags) key_usage |= PUBKEY_USAGE_UNKNOWN; + + if (!key_usage) + key_usage |= PUBKEY_USAGE_NONE; } + else if (p) /* Key flags of length zero. */ + key_usage |= PUBKEY_USAGE_NONE; /* We set PUBKEY_USAGE_UNKNOWN to indicate that this key has a capability that we do not handle. This serves to distinguish between a zero key usage which we handle as the default capabilities for that algorithm, and a usage that we do not - handle. */ + handle. Likewise we use PUBKEY_USAGE_NONE to indicate that + key_flags have been given but they do not specify any usage. */ return key_usage; } -- cgit v1.2.3 From b693ec02c467696bf9d7324dd081e279f9965151 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Tue, 19 Mar 2013 11:25:25 -0400 Subject: gpg: Allow setting of all zero key flags * g10/keygen.c (do_add_key_flags): Do not check for empty key flags. --- g10/keygen.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'g10') diff --git a/g10/keygen.c b/g10/keygen.c index fc985eef3..2017662e7 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -216,9 +216,6 @@ do_add_key_flags (PKT_signature *sig, unsigned int use) if (use & PUBKEY_USAGE_AUTH) buf[0] |= 0x20; - if (!buf[0]) - return; - build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1); } -- cgit v1.2.3 From c4dbd1b2de8ae3847a040444e86500848868bcf4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 19 Mar 2013 17:23:56 +0100 Subject: gpg: Print indicator for unknown key capability. * g10/keylist.c (print_capabilities): Print '?' for unknown usage. --- g10/keylist.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'g10') diff --git a/g10/keylist.c b/g10/keylist.c index 87f3a4bb0..d45aed672 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -627,6 +627,9 @@ print_capabilities (PKT_public_key *pk, KBNODE keyblock) if ((use & PUBKEY_USAGE_AUTH)) es_putc ('a', es_stdout); + if ((use & PUBKEY_USAGE_UNKNOWN)) + es_putc ('?', es_stdout); + if (keyblock) { /* Figure out the usable capabilities. */ -- cgit v1.2.3