aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2016-06-20 21:58:16 +0000
committerWerner Koch <[email protected]>2016-06-20 21:59:18 +0000
commit955baf04364721457cd99aad21942523cd50498c (patch)
tree1d1746bde9fd38230261943f1c870eea9dc58dbd
parentgpg: New option --rfc4880bis. (diff)
downloadgnupg-955baf04364721457cd99aad21942523cd50498c.tar.gz
gnupg-955baf04364721457cd99aad21942523cd50498c.zip
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 <[email protected]>
-rw-r--r--common/openpgpdefs.h1
-rw-r--r--g10/build-packet.c49
-rw-r--r--g10/gpgv.c11
-rw-r--r--g10/mainproc.c33
-rw-r--r--g10/packet.h2
-rw-r--r--g10/parse-packet.c18
-rw-r--r--g10/sign.c6
-rw-r--r--g10/test-stubs.c11
8 files changed, 100 insertions, 31 deletions
diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h
index f8b86e1bd..2c0ace2a5 100644
--- a/common/openpgpdefs.h
+++ b/common/openpgpdefs.h
@@ -115,6 +115,7 @@ typedef enum
SIGSUBPKT_FEATURES = 30, /* Feature flags. */
SIGSUBPKT_SIGNATURE = 32, /* Embedded signature. */
+ SIGSUBPKT_ISSUER_FPR = 33, /* EXPERIMENTAL: Issuer fingerprint. */
SIGSUBPKT_FLAG_CRITICAL = 128
}
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 2745734b4..21cd004a8 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -972,28 +972,49 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
sig->unhashed = newarea;
}
-/****************
+/*
* 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?
*/
void
-build_sig_subpkt_from_sig( PKT_signature *sig )
+build_sig_subpkt_from_sig (PKT_signature *sig, PKT_public_key *pksk)
{
u32 u;
- byte buf[8];
+ byte buf[1+MAX_FINGERPRINT_LEN];
+ size_t fprlen;
- u = sig->keyid[0];
- buf[0] = (u >> 24) & 0xff;
- buf[1] = (u >> 16) & 0xff;
- buf[2] = (u >> 8) & 0xff;
- buf[3] = u & 0xff;
- u = sig->keyid[1];
- 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 v4 keys we need to write the ISSUER subpacket. We do not
+ * want that for a future v5 format. */
+ if (pksk->version < 5)
+ {
+ u = sig->keyid[0];
+ buf[0] = (u >> 24) & 0xff;
+ buf[1] = (u >> 16) & 0xff;
+ buf[2] = (u >> 8) & 0xff;
+ buf[3] = u & 0xff;
+ u = sig->keyid[1];
+ 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;
buf[0] = (u >> 24) & 0xff;
buf[1] = (u >> 16) & 0xff;
diff --git a/g10/gpgv.c b/g10/gpgv.c
index 2aed10c2a..9ccc0da99 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -365,6 +365,17 @@ keyserver_import_keyid (u32 *keyid, void *dummy)
}
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
keyserver_import_cert (const char *name)
{
(void)name;
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 453d1b07b..bd738abaa 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -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
* arbitrary keyserver is less subject to web bug like
* monitoring. */
- /* if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY */
- /* && signature_hash_full_fingerprint (sig) */
- /* && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE) */
- /* && keyserver_any_configured (c->ctrl)) */
- /* { */
- /* int res; */
-
- /* glo_ctrl.in_auto_key_retrieve++; */
- /* res = keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); */
- /* glo_ctrl.in_auto_key_retrieve--; */
- /* if (!res) */
- /* rc = do_check_sig (c, node, NULL, &is_expkey, &is_revkey ); */
- /* } */
+ if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
+ && opt.flags.rfc4880bis
+ && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
+ && keyserver_any_configured (c->ctrl))
+ {
+ int res;
+ const byte *p;
+ size_t n;
+
+ p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_ISSUER_FPR, &n);
+ if (p && n == 21 && p[0] == 4)
+ {
+ /* v4 packet with a SHA-1 fingerprint. */
+ 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
* key from the WKD. */
diff --git a/g10/packet.h b/g10/packet.h
index 8fb6fc48f..0ff28c82b 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -764,7 +764,7 @@ gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a);
u32 calc_packet_length( PACKET *pkt );
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
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 );
void build_attribute_subpkt(PKT_user_id *uid,byte type,
const void *buf,u32 buflen,
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index e02238bfd..1c1b389d8 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1335,6 +1335,19 @@ dump_sig_subpkt (int hashed, int type, int critical,
(ulong) buf32_to_u32 (buffer),
(ulong) buf32_to_u32 (buffer + 4));
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:
{
es_fputs ("notation: ", listfp);
@@ -1485,6 +1498,10 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type)
if (n < 8)
break;
return 0;
+ case SIGSUBPKT_ISSUER_FPR: /* issuer key ID */
+ if (n < 21)
+ break;
+ return 0;
case SIGSUBPKT_NOTATION:
/* minimum length needed, and the subpacket must be well-formed
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_REV_KEY:
case SIGSUBPKT_ISSUER: /* issuer key ID */
+ case SIGSUBPKT_ISSUER_FPR: /* issuer fingerprint */
case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR:
diff --git a/g10/sign.c b/g10/sign.c
index a4974be85..3a96f0f1f 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -690,7 +690,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
if (sig->version >= 4)
{
- build_sig_subpkt_from_sig (sig);
+ build_sig_subpkt_from_sig (sig, 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->sig_class = sigclass;
- build_sig_subpkt_from_sig( sig );
+ build_sig_subpkt_from_sig (sig, pksk);
mk_notation_policy_etc (sig, pk, pksk);
/* 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
correspond to the differences in the timestamps (i.e. the
duration will shrink). */
- build_sig_subpkt_from_sig( sig );
+ build_sig_subpkt_from_sig (sig, pksk);
if (mksubpkt)
rc = (*mksubpkt)(sig, opaque);
diff --git a/g10/test-stubs.c b/g10/test-stubs.c
index 42c91f869..f4d952665 100644
--- a/g10/test-stubs.c
+++ b/g10/test-stubs.c
@@ -177,6 +177,17 @@ keyserver_import_keyid (u32 *keyid, void *dummy)
}
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
keyserver_import_cert (const char *name)
{
(void)name;