diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 12 | ||||
-rw-r--r-- | g10/call-agent.c | 39 | ||||
-rw-r--r-- | g10/call-agent.h | 4 | ||||
-rw-r--r-- | g10/card-util.c | 81 | ||||
-rw-r--r-- | g10/keyserver.c | 3 |
5 files changed, 130 insertions, 9 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 688ff14e4..be083a6cd 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,15 @@ +2009-06-17 Werner Koch <[email protected]> + + * card-util.c (put_data_to_file, read_cert): New. + (card_edit): Add command "readcert". + (fetch_url): Allow code also for this gnupg major version 2. + * call-agent.c (agent_scd_readcert): New. + +2009-06-15 Werner Koch <[email protected]> + + * keyserver.c (keyserver_search_prompt): No prompt in batch+colons + mode. + 2009-06-09 Werner Koch <[email protected]> * card-util.c (write_sc_op_status): New. diff --git a/g10/call-agent.c b/g10/call-agent.c index 63919dd1f..cd58b90b3 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -488,7 +488,6 @@ agent_scd_writecert (const char *certidstr, } - /* Handle a KEYDATA inquiry. Note, we only send the data, assuan_transact takes care of flushing and writing the end */ @@ -539,7 +538,6 @@ agent_scd_writekey (int keyno, const char *serialno, } - /* Status callback for the SCD GENKEY command. */ static int @@ -765,6 +763,43 @@ agent_scd_pkdecrypt (const char *serialno, } + +/* Send a READCERT command to the SCdaemon. */ +int +agent_scd_readcert (const char *certidstr, + void **r_buf, size_t *r_buflen) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + membuf_t data; + size_t len; + + *r_buf = NULL; + rc = start_agent (); + if (rc) + return rc; + + init_membuf (&data, 2048); + + snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr); + line[DIM(line)-1] = 0; + rc = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, NULL, NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return rc; + } + *r_buf = get_membuf (&data, r_buflen); + if (!*r_buf) + return gpg_error (GPG_ERR_ENOMEM); + + return 0; +} + + + /* Change the PIN of an OpenPGP card or reset the retry counter. CHVNO 1: Change the PIN 2: For v1 cards: Same as 1. diff --git a/g10/call-agent.h b/g10/call-agent.h index 577926e44..6d46f5491 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -104,6 +104,10 @@ int agent_scd_pkdecrypt (const char *serialno, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen); +/* Send a READKEY command to the SCdaemon. */ +int agent_scd_readcert (const char *certidstr, + void **r_buf, size_t *r_buflen); + /* Change the PIN of an OpenPGP card or reset the retry counter. */ int agent_scd_change_pin (int chvno, const char *serialno); diff --git a/g10/card-util.c b/g10/card-util.c index 290e3b784..9295a1724 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -715,7 +715,6 @@ change_url (void) static int fetch_url(void) { -#if GNUPG_MAJOR_VERSION == 1 int rc; struct agent_card_info_s info; @@ -755,15 +754,11 @@ fetch_url(void) } return rc; -#else - #warning need to implemented fucntion - return 0; -#endif } /* Read data from file FNAME up to MAXLEN characters. On error return - -1 and store NULl at R_BUFFER; on success return the number of + -1 and store NULL at R_BUFFER; on success return the number of bytes read and store the address of a newly allocated buffer at R_BUFFER. */ static int @@ -814,6 +809,39 @@ get_data_from_file (const char *fname, size_t maxlen, char **r_buffer) } +/* Write LENGTH bytes from BUFFER to file FNAME. Return 0 on + success. */ +static int +put_data_to_file (const char *fname, const void *buffer, size_t length) +{ + FILE *fp; + + fp = fopen (fname, "wb"); +#if GNUPG_MAJOR_VERSION == 1 + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } +#endif + if (!fp) + { + tty_printf (_("can't create `%s': %s\n"), fname, strerror (errno)); + return -1; + } + + if (length && fwrite (buffer, length, 1, fp) != 1) + { + tty_printf (_("error writing `%s': %s\n"), fname, strerror (errno)); + fclose (fp); + return -1; + } + fclose (fp); + return 0; +} + + static int change_login (const char *args) { @@ -934,6 +962,37 @@ change_cert (const char *args) static int +read_cert (const char *args) +{ + const char *fname; + void *buffer; + size_t length; + int rc; + + if (args && *args == '>') /* Write it to a file */ + { + for (args++; spacep (args); args++) + ; + fname = args; + } + else + { + tty_printf ("usage error: redirectrion to file required\n"); + return -1; + } + + rc = agent_scd_readcert ("OPENPGP.3", &buffer, &length); + if (rc) + log_error ("error reading certificate from card: %s\n", gpg_strerror (rc)); + else + rc = put_data_to_file (fname, buffer, length); + xfree (buffer); + write_sc_op_status (rc); + return rc; +} + + +static int change_lang (void) { char *data, *p; @@ -1447,7 +1506,7 @@ enum cmdids cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY, cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, - cmdUNBLOCK, + cmdREADCERT, cmdUNBLOCK, cmdINVCMD }; @@ -1481,6 +1540,7 @@ static struct { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") }, /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, + { "readcert", cmdREADCERT, 0, NULL }, { "writecert", cmdWRITECERT, 1, NULL }, { NULL, cmdINVCMD, 0, NULL } }; @@ -1735,6 +1795,13 @@ card_edit (strlist_t commands) change_cert (arg_rest); break; + case cmdREADCERT: + if ( arg_number != 3 ) + tty_printf ("usage: readcert 3 > FILE\n"); + else + read_cert (arg_rest); + break; + case cmdFORCESIG: toggle_forcesig (); break; diff --git a/g10/keyserver.c b/g10/keyserver.c index 249a62f95..a7c67c00d 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -862,6 +862,9 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr) if(i!=count) validcount=0; + if (opt.with_colons && opt.batch) + break; + for(;;) { if(show_prompt(desc,i,validcount?count:0,localstr)) |