gpg,gpgsm: Record the creation time of a private key.

* sm/call-agent.c (gpgsm_agent_genkey): Pass --timestamp option.
(gpgsm_agent_import_key): Ditto.
* g10/call-agent.c (agent_genkey): Add arg timestamp and pass it on.
(agent_import_key): Ditto.
* g10/import.c (transfer_secret_keys): Pass the creation date to the
agent.
* g10/keygen.c (common_gen): Ditto.
--

Having the creation time in the private key file makes it a lot easier
to re-create an OpenPGP public keyblock in case it was accidentally
lost.

Signed-off-by: Werner Koch <wk@gnupg.org>
Cherry-picked-from-master: 4031c42bfd
This commit is contained in:
Werner Koch 2020-08-19 13:43:16 +02:00
parent 051830d7b4
commit 5ac0cf1b81
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 43 additions and 12 deletions

View File

@ -1946,11 +1946,12 @@ inq_genkey_parms (void *opaque, const char *line)
gcry_pk_genkey. If NO_PROTECTION is true the agent is advised not gcry_pk_genkey. If NO_PROTECTION is true the agent is advised not
to protect the generated key. If NO_PROTECTION is not set and to protect the generated key. If NO_PROTECTION is not set and
PASSPHRASE is not NULL the agent is requested to protect the key PASSPHRASE is not NULL the agent is requested to protect the key
with that passphrase instead of asking for one. */ with that passphrase instead of asking for one. TIMESTAMP is the
creation time of the key or zero. */
gpg_error_t gpg_error_t
agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr, agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
const char *keyparms, int no_protection, const char *keyparms, int no_protection,
const char *passphrase, gcry_sexp_t *r_pubkey) const char *passphrase, time_t timestamp, gcry_sexp_t *r_pubkey)
{ {
gpg_error_t err; gpg_error_t err;
struct genkey_parm_s gk_parm; struct genkey_parm_s gk_parm;
@ -1959,6 +1960,7 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
membuf_t data; membuf_t data;
size_t len; size_t len;
unsigned char *buf; unsigned char *buf;
char timestamparg[16 + 16]; /* The 2nd 16 is sizeof(gnupg_isotime_t) */
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
memset (&dfltparm, 0, sizeof dfltparm); memset (&dfltparm, 0, sizeof dfltparm);
@ -1970,6 +1972,14 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
return err; return err;
dfltparm.ctx = agent_ctx; dfltparm.ctx = agent_ctx;
if (timestamp)
{
strcpy (timestamparg, " --timestamp=");
epoch2isotime (timestamparg+13, timestamp);
}
else
*timestamparg = 0;
if (passwd_nonce_addr && *passwd_nonce_addr) if (passwd_nonce_addr && *passwd_nonce_addr)
; /* A RESET would flush the passwd nonce cache. */ ; /* A RESET would flush the passwd nonce cache. */
else else
@ -1984,7 +1994,8 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, char **passwd_nonce_addr,
gk_parm.dflt = &dfltparm; gk_parm.dflt = &dfltparm;
gk_parm.keyparms = keyparms; gk_parm.keyparms = keyparms;
gk_parm.passphrase = passphrase; gk_parm.passphrase = passphrase;
snprintf (line, sizeof line, "GENKEY%s%s%s%s%s", snprintf (line, sizeof line, "GENKEY%s%s%s%s%s%s",
*timestamparg? timestamparg : "",
no_protection? " --no-protection" : no_protection? " --no-protection" :
passphrase ? " --inq-passwd" : passphrase ? " --inq-passwd" :
/* */ "", /* */ "",
@ -2388,11 +2399,12 @@ inq_import_key_parms (void *opaque, const char *line)
gpg_error_t gpg_error_t
agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr, agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
const void *key, size_t keylen, int unattended, int force, const void *key, size_t keylen, int unattended, int force,
u32 *keyid, u32 *mainkeyid, int pubkey_algo) u32 *keyid, u32 *mainkeyid, int pubkey_algo, u32 timestamp)
{ {
gpg_error_t err; gpg_error_t err;
struct import_key_parm_s parm; struct import_key_parm_s parm;
struct cache_nonce_parm_s cn_parm; struct cache_nonce_parm_s cn_parm;
char timestamparg[16 + 16]; /* The 2nd 16 is sizeof(gnupg_isotime_t) */
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
struct default_inq_parm_s dfltparm; struct default_inq_parm_s dfltparm;
@ -2407,6 +2419,14 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
return err; return err;
dfltparm.ctx = agent_ctx; dfltparm.ctx = agent_ctx;
if (timestamp)
{
strcpy (timestamparg, " --timestamp=");
epoch2isotime (timestamparg+13, timestamp);
}
else
*timestamparg = 0;
if (desc) if (desc)
{ {
snprintf (line, DIM(line), "SETKEYDESC %s", desc); snprintf (line, DIM(line), "SETKEYDESC %s", desc);
@ -2420,7 +2440,8 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
parm.key = key; parm.key = key;
parm.keylen = keylen; parm.keylen = keylen;
snprintf (line, sizeof line, "IMPORT_KEY%s%s%s%s", snprintf (line, sizeof line, "IMPORT_KEY%s%s%s%s%s",
*timestamparg? timestamparg : "",
unattended? " --unattended":"", unattended? " --unattended":"",
force? " --force":"", force? " --force":"",
cache_nonce_addr && *cache_nonce_addr? " ":"", cache_nonce_addr && *cache_nonce_addr? " ":"",

View File

@ -166,7 +166,7 @@ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
gpg_error_t agent_genkey (ctrl_t ctrl, gpg_error_t agent_genkey (ctrl_t ctrl,
char **cache_nonce_addr, char **passwd_nonce_addr, char **cache_nonce_addr, char **passwd_nonce_addr,
const char *keyparms, int no_protection, const char *keyparms, int no_protection,
const char *passphrase, const char *passphrase, time_t timestamp,
gcry_sexp_t *r_pubkey); gcry_sexp_t *r_pubkey);
/* Read a public key. */ /* Read a public key. */
@ -196,7 +196,8 @@ gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc, gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
char **cache_nonce_addr, const void *key, char **cache_nonce_addr, const void *key,
size_t keylen, int unattended, int force, size_t keylen, int unattended, int force,
u32 *keyid, u32 *mainkeyid, int pubkey_algo); u32 *keyid, u32 *mainkeyid, int pubkey_algo,
u32 timestamp);
/* Receive a key from the agent. */ /* Receive a key from the agent. */
gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip, gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip,

View File

@ -2630,7 +2630,8 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
char *desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_IMPORT, 1); char *desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_IMPORT, 1);
err = agent_import_key (ctrl, desc, &cache_nonce, err = agent_import_key (ctrl, desc, &cache_nonce,
wrappedkey, wrappedkeylen, batch, force, wrappedkey, wrappedkeylen, batch, force,
pk->keyid, pk->main_keyid, pk->pubkey_algo); pk->keyid, pk->main_keyid, pk->pubkey_algo,
pk->timestamp);
xfree (desc); xfree (desc);
} }
if (!err) if (!err)

View File

@ -1367,7 +1367,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
err = agent_genkey (NULL, cache_nonce_addr, passwd_nonce_addr, keyparms, err = agent_genkey (NULL, cache_nonce_addr, passwd_nonce_addr, keyparms,
!!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION), !!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION),
passphrase, passphrase, timestamp,
&s_key); &s_key);
if (err) if (err)
{ {

View File

@ -565,7 +565,7 @@ inq_genkey_parms (void *opaque, const char *line)
/* Call the agent to generate a newkey */ /* Call the agent to generate a new key */
int int
gpgsm_agent_genkey (ctrl_t ctrl, gpgsm_agent_genkey (ctrl_t ctrl,
ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey) ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey)
@ -575,6 +575,8 @@ gpgsm_agent_genkey (ctrl_t ctrl,
membuf_t data; membuf_t data;
size_t len; size_t len;
unsigned char *buf; unsigned char *buf;
gnupg_isotime_t timebuf;
char line[ASSUAN_LINELENGTH];
*r_pubkey = NULL; *r_pubkey = NULL;
rc = start_agent (ctrl); rc = start_agent (ctrl);
@ -592,7 +594,9 @@ gpgsm_agent_genkey (ctrl_t ctrl,
gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL);
if (!gk_parm.sexplen) if (!gk_parm.sexplen)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
rc = assuan_transact (agent_ctx, "GENKEY", gnupg_get_isotime (timebuf);
snprintf (line, sizeof line, "GENKEY --timestamp=%s", timebuf);
rc = assuan_transact (agent_ctx, line,
put_membuf_cb, &data, put_membuf_cb, &data,
inq_genkey_parms, &gk_parm, NULL, NULL); inq_genkey_parms, &gk_parm, NULL, NULL);
if (rc) if (rc)
@ -1344,6 +1348,8 @@ gpgsm_agent_import_key (ctrl_t ctrl, const void *key, size_t keylen)
{ {
gpg_error_t err; gpg_error_t err;
struct import_key_parm_s parm; struct import_key_parm_s parm;
gnupg_isotime_t timebuf;
char line[ASSUAN_LINELENGTH];
err = start_agent (ctrl); err = start_agent (ctrl);
if (err) if (err)
@ -1354,7 +1360,9 @@ gpgsm_agent_import_key (ctrl_t ctrl, const void *key, size_t keylen)
parm.key = key; parm.key = key;
parm.keylen = keylen; parm.keylen = keylen;
err = assuan_transact (agent_ctx, "IMPORT_KEY", gnupg_get_isotime (timebuf);
snprintf (line, sizeof line, "IMPORT_KEY --timestamp=%s", timebuf);
err = assuan_transact (agent_ctx, line,
NULL, NULL, inq_import_key_parms, &parm, NULL, NULL); NULL, NULL, inq_import_key_parms, &parm, NULL, NULL);
return err; return err;
} }