diff --git a/NEWS b/NEWS index a1e77db0c..313e7c076 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ Noteworthy changes in version 1.9.18 ------------------------------------------------- + * [gpgsm] Now allows for more than one email address as well as URIs + and dnsNames in certificate request generation. A keygrip may be + given to create a request from an existing key. + Noteworthy changes in version 1.9.17 (2005-06-20) ------------------------------------------------- diff --git a/TODO b/TODO index 478f437c2..32b728588 100644 --- a/TODO +++ b/TODO @@ -28,11 +28,6 @@ might want to have an agent context for each service request ** mark all unimplemented commands and options. ** Print a hint when MD2 is the cause for a problem. ** Implement --default-key -** Using --export-secret-key-p12 with a non-pth agent - This leads to a lockup because gpgsm is still accessing the agent - while gpg-protect-tool wants to pop up the pinentry. Solution is - to release the connection. This is not trivial, thus we are going - to do that while changing gpgsm to allow concurrent operations. ** support the anyPolicy semantic ** Check that we are really following the verification procedures in rfc3280. ** Implement a --card-status command. @@ -45,11 +40,6 @@ might want to have an agent context for each service request ** Remove the inter-module dependencies between gpgsm and keybox ** Add an source_of_key field -* agent/gpg-agent.c -** A SIGHUP should also restart the scdaemon - But do this only after all connections terminated. As of now we - only send a RESET. - * agent/command.c ** Make sure that secure memory is used where appropriate @@ -104,4 +94,4 @@ might want to have an agent context for each service request * sm/ -** --include-certs seems to be a dummy option. +** --include-certs is as of now still a dummy command line option diff --git a/agent/ChangeLog b/agent/ChangeLog index 4d539d485..bcb00e341 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2005-07-25 Werner Koch + + * findkey.c (agent_public_key_from_file): Fixed array assignment. + This was the cause for random segvs. + 2005-06-29 Werner Koch * command-ssh.c (data_sign): Removed empty statement. diff --git a/agent/findkey.c b/agent/findkey.c index 1cb7efaf3..73ffb530d 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -671,7 +671,7 @@ agent_public_key_from_file (ctrl_t ctrl, *p++ = *s; p = stpcpy (p, " %m)"); assert (argidx < DIM (args)); - args[argidx++] = array[idx]; + args[argidx++] = &array[idx]; } *p++ = ')'; if (uri) diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index ba98ae87c..653ada332 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -790,8 +790,8 @@ client must provide it. This is used to generate a new keypair, store the secret part in the @acronym{PSE} and the public key in the key database. We will probably add optional commands to allow the client to select whether a hardware -token is used to store the key. Configuration options to @command{GPGSM} can be -used to restrict the use of this command. +token is used to store the key. Configuration options to +@command{GPGSM} can be used to restrict the use of this command. @example GENKEY diff --git a/sm/call-agent.c b/sm/call-agent.c index 92a29928c..c47f6b19a 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -1,5 +1,5 @@ /* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -432,6 +432,51 @@ gpgsm_agent_genkey (ctrl_t ctrl, return 0; } + +/* Call the agent to read the public key part for a given keygrip. */ +int +gpgsm_agent_readkey (ctrl_t ctrl, const char *hexkeygrip, + ksba_sexp_t *r_pubkey) +{ + int rc; + membuf_t data; + size_t len; + unsigned char *buf; + char line[ASSUAN_LINELENGTH]; + + *r_pubkey = NULL; + rc = start_agent (ctrl); + if (rc) + return rc; + + rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return map_assuan_err (rc); + + snprintf (line, DIM(line)-1, "READKEY %s", hexkeygrip); + line[DIM(line)-1] = 0; + + init_membuf (&data, 1024); + rc = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + NULL, NULL, NULL, NULL); + if (rc) + { + xfree (get_membuf (&data, &len)); + return map_assuan_err (rc); + } + buf = get_membuf (&data, &len); + if (!buf) + return gpg_error (GPG_ERR_ENOMEM); + if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_SEXP); + } + *r_pubkey = buf; + return 0; +} + /* Ask the agent whether the certificate is in the list of trusted keys */ diff --git a/sm/certreqgen.c b/sm/certreqgen.c index c9a092046..c523c992a 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -63,6 +63,9 @@ The format of the native parameter file is follows: algorithm is "rsa". Key-Length: Length of the key in bits. Default is 1024. + Key-Grip: hexstring + This is optional and used to generate a request for an already + existsing key. Key-Length will be ignored when given, Key-Usage: Space or comma delimited list of key usage, allowed values are "encrypt" and "sign". This is used to generate the KeyUsage extension. @@ -111,6 +114,7 @@ EOF enum para_name { pKEYTYPE, pKEYLENGTH, + pKEYGRIP, pKEYUSAGE, pNAMEDN, pNAMEEMAIL, @@ -252,6 +256,7 @@ read_parameters (ctrl_t ctrl, FILE *fp, ksba_writer_t writer) } keywords[] = { { "Key-Type", pKEYTYPE}, { "Key-Length", pKEYLENGTH }, + { "Key-Grip", pKEYGRIP }, { "Key-Usage", pKEYUSAGE }, { "Name-DN", pNAMEDN }, { "Name-Email", pNAMEEMAIL, 1 }, @@ -502,16 +507,32 @@ proc_parameters (ctrl_t ctrl, } } - sprintf (numbuf, "%u", nbits); - snprintf ((char*)keyparms, DIM (keyparms)-1, - "(6:genkey(3:rsa(5:nbits%d:%s)))", (int)strlen (numbuf), numbuf); - rc = gpgsm_agent_genkey (ctrl, keyparms, &public); - if (rc) + s = get_parameter_value (para, pKEYGRIP, 0); + if (s) /* Use existing key. */ { - r = get_parameter (para, pKEYTYPE, 0); - log_error (_("line %d: key generation failed: %s\n"), - r->lnr, gpg_strerror (rc)); - return rc; + rc = gpgsm_agent_readkey (ctrl, s, &public); + if (rc) + { + r = get_parameter (para, pKEYTYPE, 0); + log_error (_("line %d: error getting key by keygrip `%s': %s\n"), + r->lnr, s, gpg_strerror (rc)); + return rc; + } + } + else /* Generate new key. */ + { + sprintf (numbuf, "%u", nbits); + snprintf ((char*)keyparms, DIM (keyparms)-1, + "(6:genkey(3:rsa(5:nbits%d:%s)))", + (int)strlen (numbuf), numbuf); + rc = gpgsm_agent_genkey (ctrl, keyparms, &public); + if (rc) + { + r = get_parameter (para, pKEYTYPE, 0); + log_error (_("line %d: key generation failed: %s\n"), + r->lnr, gpg_strerror (rc)); + return rc; + } } rc = create_request (ctrl, para, public, outctrl); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 2f3e83485..63d07a8c2 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -299,6 +299,8 @@ int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, char **r_buf, size_t *r_buflen); int gpgsm_agent_genkey (ctrl_t ctrl, ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey); +int gpgsm_agent_readkey (ctrl_t ctrl, const char *hexkeygrip, + ksba_sexp_t *r_pubkey); int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert); int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip); int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert);