1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: Fix key expiration and usage for keys created at the Epoch.

* g10/getkey.c (merge_selfsigs_main): Take a zero key creation time in
account.
--

Keys created at the Epoch have a creation time of 0; when figuring out
the latest signature with properties to apply to a key the usual
comparison A > B does not work if A is always 0.  We now special case
this for the expiration and usage data.

Co-authored-by: gniibe@fsij.org
GnuPG-bug-id: 4670
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-03-18 12:30:06 +01:00
parent 8c0323a758
commit 161a098be6
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -2348,7 +2348,7 @@ parse_key_usage (PKT_signature * sig)
/* Apply information from SIGNODE (which is the valid self-signature /* Apply information from SIGNODE (which is the valid self-signature
* associated with that UID) to the UIDNODE: * associated with that UID) to the UIDNODE:
* - weather the UID has been revoked * - wether the UID has been revoked
* - assumed creation date of the UID * - assumed creation date of the UID
* - temporary store the keyflags here * - temporary store the keyflags here
* - temporary store the key expiration time here * - temporary store the key expiration time here
@ -2525,7 +2525,7 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
KBNODE signode, uidnode, uidnode2; KBNODE signode, uidnode, uidnode2;
u32 curtime = make_timestamp (); u32 curtime = make_timestamp ();
unsigned int key_usage = 0; unsigned int key_usage = 0;
u32 keytimestamp = 0; u32 keytimestamp = 0; /* Creation time of the key. */
u32 key_expire = 0; u32 key_expire = 0;
int key_expire_seen = 0; int key_expire_seen = 0;
byte sigversion = 0; byte sigversion = 0;
@ -2556,7 +2556,9 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
{ {
/* Before v4 the key packet itself contains the expiration date /* Before v4 the key packet itself contains the expiration date
* and there was no way to change it, so we start with the one * and there was no way to change it, so we start with the one
* from the key packet. */ * from the key packet. We do not support v3 keys anymore but
* we keep the code in case a future key versions introduces a
* hadr expire time again. */
key_expire = pk->max_expiredate; key_expire = pk->max_expiredate;
key_expire_seen = 1; key_expire_seen = 1;
} }
@ -2696,8 +2698,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
sizeof (struct revocation_key)); sizeof (struct revocation_key));
} }
/* SIGNODE is the 1F signature packet with the latest creation time. /* SIGNODE is the direct key signature packet (sigclass 0x1f) with
* Extract some information from it. */ * the latest creation time. Extract some information from it. */
if (signode) if (signode)
{ {
/* Some information from a direct key signature take precedence /* Some information from a direct key signature take precedence
@ -2898,7 +2900,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
{ {
PKT_user_id *uid = k->pkt->pkt.user_id; PKT_user_id *uid = k->pkt->pkt.user_id;
if (uid->help_key_usage && uid->created > uiddate) if (uid->help_key_usage
&& (uid->created > uiddate || (!uid->created && !uiddate)))
{ {
key_usage = uid->help_key_usage; key_usage = uid->help_key_usage;
uiddate = uid->created; uiddate = uid->created;
@ -2925,9 +2928,9 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
if (!key_expire_seen) if (!key_expire_seen)
{ {
/* Find the latest valid user ID with a key expiration set /* Find the latest valid user ID with a key expiration set.
* Note, that this may be a different one from the above because * This may be a different one than from usage computation above
* some user IDs may have no expiration date set. */ * because some user IDs may have no expiration date set. */
uiddate = 0; uiddate = 0;
for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; for (k = keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
k = k->next) k = k->next)
@ -2935,7 +2938,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
if (k->pkt->pkttype == PKT_USER_ID) if (k->pkt->pkttype == PKT_USER_ID)
{ {
PKT_user_id *uid = k->pkt->pkt.user_id; PKT_user_id *uid = k->pkt->pkt.user_id;
if (uid->help_key_expire && uid->created > uiddate) if (uid->help_key_expire
&& (uid->created > uiddate || (!uid->created && !uiddate)))
{ {
key_expire = uid->help_key_expire; key_expire = uid->help_key_expire;
uiddate = uid->created; uiddate = uid->created;
@ -2944,8 +2948,8 @@ merge_selfsigs_main (ctrl_t ctrl, kbnode_t keyblock, int *r_revoked,
} }
} }
/* Currently only v3 keys have a maximum expiration date, but I'll /* Currently only the not anymore supported v3 keys have a maximum
* bet v5 keys get this feature again. */ * expiration date, but future key versions may get this feature again. */
if (key_expire == 0 if (key_expire == 0
|| (pk->max_expiredate && key_expire > pk->max_expiredate)) || (pk->max_expiredate && key_expire > pk->max_expiredate))
key_expire = pk->max_expiredate; key_expire = pk->max_expiredate;