diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 21 | ||||
-rw-r--r-- | g10/call-agent.c | 22 | ||||
-rw-r--r-- | g10/call-agent.h | 5 | ||||
-rw-r--r-- | g10/card-util.c | 16 | ||||
-rw-r--r-- | g10/keydb.h | 10 | ||||
-rw-r--r-- | g10/keygen.c | 42 | ||||
-rw-r--r-- | g10/passphrase.c | 75 |
7 files changed, 119 insertions, 72 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index bd54d1976..1f9751293 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,8 +1,29 @@ +2009-05-15 Werner Koch <[email protected]> + + * keygen.c (gen_card_key_with_backup): Get the size of the key + from the card. + * call-agent.h (struct agent_card_info_s): Add field KEY_ATTR. + * call-agent.c (learn_status_cb): Support KEY-ATTR. + * card-util.c (card_status): Print key attributes. + 2009-05-15 Marcus Brinkmann <[email protected]> * gpg.c (gpgconf_list): Remove dead entry "allow-pka-lookup" (a verify option for a couple of years now). +2009-05-14 Werner Koch <[email protected]> + + * call-agent.c (agent_get_passphrase): Add arg CHECK. + * passphrase.c (passphrase_get): Pass new arg. + + * keygen.c (gen_card_key_with_backup): Print a status error. + (do_generate_keypair): Ditto. + (do_ask_passphrase): Add arg MODE. + (generate_raw_key): Call with mode 1. + * passphrase.c (ask_passphrase): Remove becuase it is not used. + (passphrase_to_dek): Factor code out to ... + (passphrase_to_dek_ext): .. New. Add args CUSTDESC and CUSTPROMPT. + 2009-05-13 Werner Koch <[email protected]> * keygen.c (parse_expire_string): Base ISO date string at noon. diff --git a/g10/call-agent.c b/g10/call-agent.c index 444048a47..c8a2013ac 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -325,7 +325,19 @@ learn_status_cb (void *opaque, const char *line) else if (no == 3) parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3); } - + else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen)) + { + int keyno, algo, nbits; + + sscanf (line, "%d %d %d", &keyno, &algo, &nbits); + keyno--; + if (keyno >= 0 && keyno < DIM (parm->key_attr)) + { + parm->key_attr[keyno].algo = algo; + parm->key_attr[keyno].nbits = nbits; + } + } + return 0; } @@ -343,6 +355,9 @@ agent_learn (struct agent_card_info_s *info) rc = assuan_transact (agent_ctx, "LEARN --send", dummy_data_cb, NULL, default_inq_cb, NULL, learn_status_cb, info); + /* Also try to get the key attributes. */ + if (!rc) + agent_scd_getattr ("KEY-ATTR", info); return rc; } @@ -535,7 +550,6 @@ scd_genkey_cb (void *opaque, const char *line) int keywordlen; gpg_error_t rc; - log_debug ("got status line `%s'\n", line); for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) ; while (spacep (line)) @@ -827,6 +841,7 @@ agent_get_passphrase (const char *cache_id, const char *prompt, const char *desc_msg, int repeat, + int check, char **r_passphrase) { int rc; @@ -863,8 +878,9 @@ agent_get_passphrase (const char *cache_id, goto no_mem; snprintf (line, DIM(line)-1, - "GET_PASSPHRASE --data --repeat=%d -- %s %s %s %s", + "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", repeat, + check? " --check --qualitybar":"", arg1? arg1:"X", arg2? arg2:"X", arg3? arg3:"X", diff --git a/g10/call-agent.h b/g10/call-agent.h index ebe37b1cd..577926e44 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -53,6 +53,10 @@ struct agent_card_info_s int is_v2; /* True if this is a v2 card. */ int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ + struct { /* Array with key attributes. */ + int algo; /* Algorithm identifier. */ + unsigned int nbits; /* Supported keysize. */ + } key_attr[3]; }; struct agent_card_genkey_s { @@ -116,6 +120,7 @@ gpg_error_t agent_get_passphrase (const char *cache_id, const char *prompt, const char *desc_msg, int repeat, + int check, char **r_passphrase); /* Send the CLEAR_PASSPHRASE command to the agent. */ diff --git a/g10/card-util.c b/g10/card-util.c index 1d263669f..7d36ebf9c 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -443,6 +443,10 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen) fputs (":\n", fp); fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached); + for (i=0; i < DIM (info.key_attr); i++) + if (info.key_attr[0].algo) + fprintf (fp, "keyattr:%d:%d:%u:\n", i+1, + info.key_attr[i].algo, info.key_attr[i].nbits); fprintf (fp, "maxpinlen:%d:%d:%d:\n", info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); fprintf (fp, "pinretry:%d:%d:%d:\n", @@ -518,6 +522,16 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen) } tty_fprintf (fp, "Signature PIN ....: %s\n", info.chv1_cached? _("not forced"): _("forced")); + if (info.key_attr[0].algo) + { + tty_fprintf (fp, "Key attributes ...:"); + for (i=0; i < DIM (info.key_attr); i++) + tty_fprintf (fp, " %u%c", + info.key_attr[i].nbits, + info.key_attr[i].algo == 1? 'R': + info.key_attr[i].algo == 17? 'D': '?'); + tty_fprintf (fp, "\n"); + } tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); tty_fprintf (fp, "PIN retry counter : %d %d %d\n", @@ -1077,7 +1091,7 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1) *forced_chv1 = !info->chv1_cached; if (*forced_chv1) - { /* Switch of the forced mode so that during key generation we + { /* Switch off the forced mode so that during key generation we don't get bothered with PIN queries for each self-signature. */ rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno); diff --git a/g10/keydb.h b/g10/keydb.h index 4e8245876..ca3ca77ec 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -202,11 +202,11 @@ int have_static_passphrase(void); void set_passphrase_from_string(const char *pass); void read_passphrase_from_fd( int fd ); void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ); -char *ask_passphrase (const char *description, - const char *tryagain_text, - const char *promptid, - const char *prompt, - const char *cacheid, int *canceled); +DEK *passphrase_to_dek_ext(u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, + const char *custdesc, const char *custprompt, + int *canceled); DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, const char *tryagain_text, int *canceled); diff --git a/g10/keygen.c b/g10/keygen.c index 8afa74e3e..96c68334e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2153,21 +2153,28 @@ ask_user_id( int mode ) } +/* MODE 0 - standard + 1 - Ask for passphrase of the card backup key. */ static DEK * -do_ask_passphrase ( STRING2KEY **ret_s2k, int *r_canceled ) +do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled) { DEK *dek = NULL; STRING2KEY *s2k; const char *errtext = NULL; + const char *custdesc = NULL; tty_printf(_("You need a Passphrase to protect your secret key.\n\n") ); + if (mode == 1) + custdesc = _("Please enter a passphrase to protect the off-card " + "backup of the new encryption key."); + s2k = xmalloc_secure( sizeof *s2k ); for(;;) { s2k->mode = opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2, - errtext, r_canceled); + dek = passphrase_to_dek_ext (NULL, 0, opt.s2k_cipher_algo, s2k, 2, + errtext, custdesc, NULL, r_canceled); if (!dek && *r_canceled) { xfree(dek); dek = NULL; xfree(s2k); s2k = NULL; @@ -2587,7 +2594,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, STRING2KEY *s2k; DEK *dek; - dek = do_ask_passphrase ( &s2k, &canceled ); + dek = do_ask_passphrase (&s2k, 0, &canceled); if (dek) { r = xmalloc_clear( sizeof *r ); @@ -3085,7 +3092,7 @@ generate_keypair (const char *fname, const char *card_serialno, para = r; canceled = 0; - dek = card_serialno? NULL : do_ask_passphrase ( &s2k, &canceled ); + dek = card_serialno? NULL : do_ask_passphrase (&s2k, 0, &canceled); if( dek ) { r = xmalloc_clear( sizeof *r ); @@ -3143,7 +3150,7 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at, log_info(_("keysize rounded up to %u bits\n"), nbits ); } - dek = do_ask_passphrase (&s2k, &canceled); + dek = do_ask_passphrase (&s2k, 1, &canceled); if (canceled) { rc = gpg_error (GPG_ERR_CANCELED); @@ -3547,6 +3554,7 @@ do_generate_keypair (struct para_data_s *para, log_error ("key generation failed: %s\n", g10_errstr(rc) ); else tty_printf (_("Key generation failed: %s\n"), g10_errstr(rc) ); + write_status_error (card? "card_key_generate":"key_generate", rc); print_status_key_not_created ( get_parameter_value (para, pHANDLE) ); } else @@ -3660,7 +3668,7 @@ generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock) canceled = 0; if (ask_pass) - dek = do_ask_passphrase (&s2k, &canceled); + dek = do_ask_passphrase (&s2k, 0, &canceled); else if (passphrase) { s2k = xmalloc_secure ( sizeof *s2k ); @@ -3951,19 +3959,35 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, PKT_public_key *pk; size_t n; int i; + unsigned int nbits; + + /* Get the size of the key directly from the card. */ + { + struct agent_card_info_s info; + + memset (&info, 0, sizeof info); + if (!agent_scd_getattr ("KEY-ATTR", &info) + && info.key_attr[1].algo) + nbits = info.key_attr[1].nbits; + else + nbits = 1024; /* All pre-v2.0 cards. */ + agent_release_card_info (&info); + } - rc = generate_raw_key (algo, 1024, timestamp, + /* Create a key of this size in memory. */ + rc = generate_raw_key (algo, nbits, timestamp, &sk_unprotected, &sk_protected); if (rc) return rc; - /* First, store the key to the card. */ + /* Store the key to the card. */ rc = save_unprotected_key_to_card (sk_unprotected, keyno); if (rc) { log_error (_("storing key onto card failed: %s\n"), g10_errstr (rc)); free_secret_key (sk_unprotected); free_secret_key (sk_protected); + write_status_error ("save_key_to_card", rc); return rc; } diff --git a/g10/passphrase.c b/g10/passphrase.c index 8b952f72a..f5d301398 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -236,7 +236,8 @@ read_passphrase_from_fd( int fd ) /* * Ask the GPG Agent for the passphrase. * Mode 0: Allow cached passphrase - * 1: No cached passphrase FIXME: Not really implemented + * 1: No cached passphrase; that is we are asking for a new passphrase + * FIXME: Only partially implemented * * Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not * NULL, the function does set it to 1 if the user canceled the @@ -260,6 +261,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, char *my_prompt; char hexfprbuf[20*2+1]; const char *my_cacheid; + int check = (mode == 1); if (canceled) *canceled = 0; @@ -347,7 +349,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL; rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, - repeat, &pw); + repeat, check, &pw); xfree (my_prompt); xfree (atext); atext = NULL; @@ -432,54 +434,6 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) } -/**************** - * Ask for a passphrase and return that string. - */ -char * -ask_passphrase (const char *description, - const char *tryagain_text, - const char *promptid, - const char *prompt, - const char *cacheid, int *canceled) -{ - char *pw = NULL; - - (void)promptid; - - if (canceled) - *canceled = 0; - - if (!opt.batch && description) - { - if (strchr (description, '%')) - { - char *tmp = percent_plus_unescape (description, 0xff); - if (!tmp) - log_fatal(_("out of core\n")); - tty_printf ("\n%s\n", tmp); - xfree (tmp); - } - else - tty_printf ("\n%s\n",description); - } - - if (have_static_passphrase ()) - { - pw = xmalloc_secure (strlen(fd_passwd)+1); - strcpy (pw, fd_passwd); - } - else - pw = passphrase_get (NULL, 0, cacheid, 0, - tryagain_text, description, prompt, - canceled ); - - if (!pw || !*pw) - write_status( STATUS_MISSING_PASSPHRASE ); - - return pw; -} - - /* Return a new DEK object Using the string-to-key sepcifier S2K. Use KEYID and PUBKEY_ALGO to prompt the user. Returns NULL is the user selected to cancel the passphrase entry and if CANCELED is not @@ -490,9 +444,11 @@ ask_passphrase (const char *description, 2: Ditto, but change the text to "repeat entry" */ DEK * -passphrase_to_dek (u32 *keyid, int pubkey_algo, - int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, int *canceled) +passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, + const char *custdesc, const char *custprompt, + int *canceled) { char *pw = NULL; DEK *dek; @@ -612,7 +568,7 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, /* Divert to the gpg-agent. */ pw = passphrase_get ( keyid, mode == 2, NULL, mode == 2? opt.passwd_repeat: 0, - tryagain_text, NULL, NULL, canceled ); + tryagain_text, custdesc, custprompt, canceled); if (*canceled) { xfree (pw); @@ -637,3 +593,14 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo, last_pw = pw; return dek; } + + +DEK * +passphrase_to_dek (u32 *keyid, int pubkey_algo, + int cipher_algo, STRING2KEY *s2k, int mode, + const char *tryagain_text, int *canceled) +{ + return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo, + s2k, mode, tryagain_text, NULL, NULL, + canceled); +} |