gpg: Add experimental support for an issuer fpr.

* common/openpgpdefs.h (SIGSUBPKT_ISSUER_FPR): New.
* g10/build-packet.c (build_sig_subpkt_from_sig): Add arg PKSK and
insert the issuer fpr if needed.
* g10/sign.c (write_signature_packets): Pass signing key.
(make_keysig_packet): Ditto.
(update_keysig_packet): Ditto.
* g10/parse-packet.c (dump_sig_subpkt): Print issuer fpr.
(parse_one_sig_subpkt): Detect issuer fpr.
(can_handle_critical): Add issuer fpr.
* g10/mainproc.c (check_sig_and_print): Try to get key via fingerprint.
* g10/gpgv.c (keyserver_import_fprint): New stub.
* g10/test-stubs.c (keyserver_import_fprint): New stub.
--

This support is enabled with the --rfc4880bis option and intended to
test to recently proposed issuer fpr.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-06-20 23:58:16 +02:00
parent ee2d9061d7
commit 955baf0436
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
8 changed files with 99 additions and 30 deletions

View File

@ -115,6 +115,7 @@ typedef enum
SIGSUBPKT_FEATURES = 30, /* Feature flags. */ SIGSUBPKT_FEATURES = 30, /* Feature flags. */
SIGSUBPKT_SIGNATURE = 32, /* Embedded signature. */ SIGSUBPKT_SIGNATURE = 32, /* Embedded signature. */
SIGSUBPKT_ISSUER_FPR = 33, /* EXPERIMENTAL: Issuer fingerprint. */
SIGSUBPKT_FLAG_CRITICAL = 128 SIGSUBPKT_FLAG_CRITICAL = 128
} }

View File

@ -972,28 +972,49 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
sig->unhashed = newarea; sig->unhashed = newarea;
} }
/**************** /*
* Put all the required stuff from SIG into subpackets of sig. * Put all the required stuff from SIG into subpackets of sig.
* PKSK is the signing key.
* Hmmm, should we delete those subpackets which are in a wrong area? * Hmmm, should we delete those subpackets which are in a wrong area?
*/ */
void void
build_sig_subpkt_from_sig( PKT_signature *sig ) build_sig_subpkt_from_sig (PKT_signature *sig, PKT_public_key *pksk)
{ {
u32 u; u32 u;
byte buf[8]; byte buf[1+MAX_FINGERPRINT_LEN];
size_t fprlen;
u = sig->keyid[0]; /* For v4 keys we need to write the ISSUER subpacket. We do not
buf[0] = (u >> 24) & 0xff; * want that for a future v5 format. */
buf[1] = (u >> 16) & 0xff; if (pksk->version < 5)
buf[2] = (u >> 8) & 0xff; {
buf[3] = u & 0xff; u = sig->keyid[0];
u = sig->keyid[1]; buf[0] = (u >> 24) & 0xff;
buf[4] = (u >> 24) & 0xff; buf[1] = (u >> 16) & 0xff;
buf[5] = (u >> 16) & 0xff; buf[2] = (u >> 8) & 0xff;
buf[6] = (u >> 8) & 0xff; buf[3] = u & 0xff;
buf[7] = u & 0xff; u = sig->keyid[1];
build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 ); buf[4] = (u >> 24) & 0xff;
buf[5] = (u >> 16) & 0xff;
buf[6] = (u >> 8) & 0xff;
buf[7] = u & 0xff;
build_sig_subpkt (sig, SIGSUBPKT_ISSUER, buf, 8);
}
/* For a future v5 keys we write the ISSUER_FPR subpacket. We
* also write that for a v4 key is experimental support for
* RFC4880bis is requested. */
if (pksk->version > 4 || opt.flags.rfc4880bis)
{
fingerprint_from_pk (pksk, buf+1, &fprlen);
if (fprlen == 20)
{
buf[0] = pksk->version;
build_sig_subpkt (sig, SIGSUBPKT_ISSUER_FPR, buf, 21);
}
}
/* Write the timestamp. */
u = sig->timestamp; u = sig->timestamp;
buf[0] = (u >> 24) & 0xff; buf[0] = (u >> 24) & 0xff;
buf[1] = (u >> 16) & 0xff; buf[1] = (u >> 16) & 0xff;

View File

@ -364,6 +364,17 @@ keyserver_import_keyid (u32 *keyid, void *dummy)
return -1; return -1;
} }
int
keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
struct keyserver_spec *keyserver)
{
(void)ctrl;
(void)fprint;
(void)fprint_len;
(void)keyserver;
return -1;
}
int int
keyserver_import_cert (const char *name) keyserver_import_cert (const char *name)
{ {

View File

@ -1805,19 +1805,26 @@ check_sig_and_print (CTX c, kbnode_t node)
* favor this over the WKD method (to be tried next), because an * favor this over the WKD method (to be tried next), because an
* arbitrary keyserver is less subject to web bug like * arbitrary keyserver is less subject to web bug like
* monitoring. */ * monitoring. */
/* if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY */ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
/* && signature_hash_full_fingerprint (sig) */ && opt.flags.rfc4880bis
/* && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) */ && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
/* && keyserver_any_configured (c->ctrl)) */ && keyserver_any_configured (c->ctrl))
/* { */ {
/* int res; */ int res;
const byte *p;
size_t n;
/* glo_ctrl.in_auto_key_retrieve++; */ p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_ISSUER_FPR, &n);
/* res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); */ if (p && n == 21 && p[0] == 4)
/* glo_ctrl.in_auto_key_retrieve--; */ {
/* if (!res) */ /* v4 packet with a SHA-1 fingerprint. */
/* rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); */ glo_ctrl.in_auto_key_retrieve++;
/* } */ res = keyserver_import_fprint (c->ctrl, p+1, n-1, opt.keyserver);
glo_ctrl.in_auto_key_retrieve--;
if (!res)
rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey );
}
}
/* If the above methods didn't work, our next try is to retrieve the /* If the above methods didn't work, our next try is to retrieve the
* key from the WKD. */ * key from the WKD. */

View File

@ -764,7 +764,7 @@ gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a);
u32 calc_packet_length( PACKET *pkt ); u32 calc_packet_length( PACKET *pkt );
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
const byte *buffer, size_t buflen ); const byte *buffer, size_t buflen );
void build_sig_subpkt_from_sig( PKT_signature *sig ); void build_sig_subpkt_from_sig (PKT_signature *sig, PKT_public_key *pksk);
int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type ); int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type );
void build_attribute_subpkt(PKT_user_id *uid,byte type, void build_attribute_subpkt(PKT_user_id *uid,byte type,
const void *buf,u32 buflen, const void *buf,u32 buflen,

View File

@ -1335,6 +1335,19 @@ dump_sig_subpkt (int hashed, int type, int critical,
(ulong) buf32_to_u32 (buffer), (ulong) buf32_to_u32 (buffer),
(ulong) buf32_to_u32 (buffer + 4)); (ulong) buf32_to_u32 (buffer + 4));
break; break;
case SIGSUBPKT_ISSUER_FPR:
if (length >= 21)
{
char *tmp;
es_fprintf (listfp, "issuer fpr v%d ", buffer[0]);
tmp = bin2hex (buffer+1, length-1, NULL);
if (tmp)
{
es_fputs (tmp, listfp);
xfree (tmp);
}
}
break;
case SIGSUBPKT_NOTATION: case SIGSUBPKT_NOTATION:
{ {
es_fputs ("notation: ", listfp); es_fputs ("notation: ", listfp);
@ -1485,6 +1498,10 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type)
if (n < 8) if (n < 8)
break; break;
return 0; return 0;
case SIGSUBPKT_ISSUER_FPR: /* issuer key ID */
if (n < 21)
break;
return 0;
case SIGSUBPKT_NOTATION: case SIGSUBPKT_NOTATION:
/* minimum length needed, and the subpacket must be well-formed /* minimum length needed, and the subpacket must be well-formed
where the name length and value length all fit inside the where the name length and value length all fit inside the
@ -1543,6 +1560,7 @@ can_handle_critical (const byte * buffer, size_t n, int type)
case SIGSUBPKT_REVOCABLE: case SIGSUBPKT_REVOCABLE:
case SIGSUBPKT_REV_KEY: case SIGSUBPKT_REV_KEY:
case SIGSUBPKT_ISSUER: /* issuer key ID */ case SIGSUBPKT_ISSUER: /* issuer key ID */
case SIGSUBPKT_ISSUER_FPR: /* issuer fingerprint */
case SIGSUBPKT_PREF_SYM: case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH: case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_PREF_COMPR:

View File

@ -690,7 +690,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
if (sig->version >= 4) if (sig->version >= 4)
{ {
build_sig_subpkt_from_sig (sig); build_sig_subpkt_from_sig (sig, pk);
mk_notation_policy_etc (sig, NULL, pk); mk_notation_policy_etc (sig, NULL, pk);
} }
@ -1456,7 +1456,7 @@ make_keysig_packet (PKT_signature **ret_sig, PKT_public_key *pk,
sig->expiredate=sig->timestamp+duration; sig->expiredate=sig->timestamp+duration;
sig->sig_class = sigclass; sig->sig_class = sigclass;
build_sig_subpkt_from_sig( sig ); build_sig_subpkt_from_sig (sig, pksk);
mk_notation_policy_etc (sig, pk, pksk); mk_notation_policy_etc (sig, pk, pksk);
/* Crucial that the call to mksubpkt comes LAST before the calls /* Crucial that the call to mksubpkt comes LAST before the calls
@ -1559,7 +1559,7 @@ update_keysig_packet( PKT_signature **ret_sig,
automagically lower any sig expiration dates to correctly automagically lower any sig expiration dates to correctly
correspond to the differences in the timestamps (i.e. the correspond to the differences in the timestamps (i.e. the
duration will shrink). */ duration will shrink). */
build_sig_subpkt_from_sig( sig ); build_sig_subpkt_from_sig (sig, pksk);
if (mksubpkt) if (mksubpkt)
rc = (*mksubpkt)(sig, opaque); rc = (*mksubpkt)(sig, opaque);

View File

@ -176,6 +176,17 @@ keyserver_import_keyid (u32 *keyid, void *dummy)
return -1; return -1;
} }
int
keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
struct keyserver_spec *keyserver)
{
(void)ctrl;
(void)fprint;
(void)fprint_len;
(void)keyserver;
return -1;
}
int int
keyserver_import_cert (const char *name) keyserver_import_cert (const char *name)
{ {