diff options
-rw-r--r-- | doc/gpg.texi | 7 | ||||
-rw-r--r-- | g10/export.c | 17 | ||||
-rw-r--r-- | g10/gpg.c | 3 | ||||
-rw-r--r-- | g10/gpgv.c | 14 | ||||
-rw-r--r-- | g10/keylist.c | 108 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/test-stubs.c | 14 |
7 files changed, 141 insertions, 23 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi index 980d32643..35291a821 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2039,6 +2039,13 @@ Modify the output of the list commands to print PKA records suitable to put into DNS zone files. An ORIGIN line is printed before each record to allow diverting the records to the corresponding zone file. +@item --print-dane-records +@opindex print-dane-records +Modify the output of the list commands to print OpenPGP DANE records +suitable to put into DNS zone files. An ORIGIN line is printed before +each record to allow diverting the records to the corresponding zone +file. + @item --fixed-list-mode @opindex fixed-list-mode Do not merge primary user ID and primary key in @option{--with-colon} diff --git a/g10/export.c b/g10/export.c index 94a325629..2e9e61c69 100644 --- a/g10/export.c +++ b/g10/export.c @@ -198,15 +198,11 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options ) if (rc) return rc; - /* We don't want an Armor for DANE format. */ - if (!(options & EXPORT_DANE_FORMAT)) + if ( opt.armor ) { - if ( opt.armor ) - { - afx = new_armor_context (); - afx->what = secret? 5 : 1; - push_armor_filter (afx, out); - } + afx = new_armor_context (); + afx->what = secret? 5 : 1; + push_armor_filter (afx, out); } rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any ); @@ -776,6 +772,11 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, init_packet (&pkt); kdbhd = keydb_new (); + /* For the DANE format override the options. */ + if ((options & EXPORT_DANE_FORMAT)) + options = (EXPORT_DANE_FORMAT | EXPORT_MINIMAL | EXPORT_CLEAN); + + if (!users) { ndesc = 1; @@ -384,6 +384,7 @@ enum cmd_and_opt_values oFakedSystemTime, oNoAutostart, oPrintPKARecords, + oPrintDANERecords, oNoop }; @@ -716,6 +717,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oLegacyListMode, "legacy-list-mode", "@"), ARGPARSE_s_n (oListOnly, "list-only", "@"), ARGPARSE_s_n (oPrintPKARecords, "print-pka-records", "@"), + ARGPARSE_s_n (oPrintDANERecords, "print-dane-records", "@"), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"), ARGPARSE_s_n (oIgnoreValidFrom, "ignore-valid-from", "@"), ARGPARSE_s_n (oIgnoreCrcError, "ignore-crc-error", "@"), @@ -2998,6 +3000,7 @@ main (int argc, char **argv) case oFixedListMode: /* Dummy */ break; case oLegacyListMode: opt.legacy_list_mode = 1; break; case oPrintPKARecords: opt.print_pka_records = 1; break; + case oPrintDANERecords: opt.print_dane_records = 1; break; case oListOnly: opt.list_only=1; break; case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; diff --git a/g10/gpgv.c b/g10/gpgv.c index 412f4bee3..8bb3fc41a 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -592,3 +592,17 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, *r_url = NULL; return gpg_error (GPG_ERR_NOT_FOUND); } + +gpg_error_t +export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) +{ + (void)ctrl; + (void)keyspec; + (void)options; + + *r_keyblock = NULL; + *r_data = NULL; + *r_datalen = 0; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} diff --git a/g10/keylist.c b/g10/keylist.c index 192ced7ef..3814f1c7c 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -847,6 +847,9 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock) PKT_public_key *pk; char pkstrbuf[PUBKEY_STRING_SIZE]; char *hexfpr; + char *hexkeyblock = NULL; + unsigned int hexkeyblocklen; + const char *s; /* Get the keyid from the keyblock. */ node = find_kbnode (keyblock, PKT_PUBLIC_KEY); @@ -859,11 +862,55 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock) pk = node->pkt->pkt.public_key; - es_fprintf (es_stdout, ";; pub %s/%s %s\n;; ", + /* First print an overview of the key with all userids. */ + es_fprintf (es_stdout, ";; pub %s/%s %s\n;;", pubkey_string (pk, pkstrbuf, sizeof pkstrbuf), keystr_from_pk (pk), datestr_from_pk (pk)); print_fingerprint (NULL, pk, 10); + for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));) + { + if (node->pkt->pkttype == PKT_USER_ID) + { + PKT_user_id *uid = node->pkt->pkt.user_id; + + if (pk && (uid->is_expired || uid->is_revoked) + && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS)) + continue; + + es_fputs (";; uid ", es_stdout); + print_utf8_buffer (es_stdout, uid->name, uid->len); + es_putc ('\n', es_stdout); + } + } + + hexfpr = hexfingerprint (pk); + if (opt.print_dane_records) + { + kbnode_t dummy_keyblock; + void *data; + size_t datalen; + gpg_error_t err; + + /* We do not have an export fucntion which allows to pass a + keyblock, thus we need to search the key again. */ + err = export_pubkey_buffer (ctrl, hexfpr, + EXPORT_DANE_FORMAT, + &dummy_keyblock, &data, &datalen); + release_kbnode (dummy_keyblock); + if (!err) + { + hexkeyblocklen = datalen; + hexkeyblock = bin2hex (data, datalen, NULL); + if (!hexkeyblock) + err = gpg_error_from_syserror (); + xfree (data); + ascii_strlwr (hexkeyblock); + } + if (err) + log_error (_("skipped \"%s\": %s\n"), hexfpr, gpg_strerror (err)); + + } for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));) { @@ -877,27 +924,57 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock) && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS)) continue; - es_fputs (";; uid ", es_stdout); - print_utf8_buffer (es_stdout, uid->name, uid->len); - es_putc ('\n', es_stdout); mbox = mailbox_from_userid (uid->name); if (mbox && (p = strchr (mbox, '@'))) { - char hashbuf[20]; + char hashbuf[32]; char *hash; unsigned int len; *p++ = 0; - es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n", p); - gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox)); - hash = zb32_encode (hashbuf, 8*20); - if (hash) + if (opt.print_pka_records) { - len = strlen (hexfpr)/2; - es_fprintf (es_stdout, - "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n", - hash, 6 + len, len, hexfpr); - xfree (hash); + es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n; %s\n; ", + p, hexfpr); + print_utf8_buffer (es_stdout, uid->name, uid->len); + es_putc ('\n', es_stdout); + gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, + mbox, strlen (mbox)); + hash = zb32_encode (hashbuf, 8*20); + if (hash) + { + len = strlen (hexfpr)/2; + es_fprintf (es_stdout, + "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n", + hash, 6 + len, len, hexfpr); + xfree (hash); + } + } + if (opt.print_dane_records && hexkeyblock) + { + es_fprintf (es_stdout, "$ORIGIN _openpgpkey.%s.\n; %s\n; ", + p, hexfpr); + print_utf8_buffer (es_stdout, uid->name, uid->len); + es_putc ('\n', es_stdout); + gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, + mbox, strlen (mbox)); + hash = bin2hex (hashbuf, 28, NULL); + if (hash) + { + ascii_strlwr (hash); + es_fprintf (es_stdout, "%s TYPE61 \\# %u (\n", + hash, hexkeyblocklen); + xfree (hash); + s = hexkeyblock; + for (;;) + { + es_fprintf (es_stdout, "\t%.64s\n", s); + if (strlen (s) < 64) + break; + s += 64; + } + es_fputs ("\t)\n", es_stdout); + } } } xfree (mbox); @@ -906,6 +983,7 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock) } es_putc ('\n', es_stdout); + xfree (hexkeyblock); xfree (hexfpr); } @@ -1679,7 +1757,7 @@ list_keyblock (ctrl_t ctrl, struct keylist_context *listctx) { reorder_keyblock (keyblock); - if (opt.print_pka_records) + if (opt.print_pka_records || opt.print_dane_records) list_keyblock_pka (ctrl, keyblock); else if (opt.with_colons) list_keyblock_colon (keyblock, secret, has_secret, fpr); diff --git a/g10/options.h b/g10/options.h index 694c29f8e..d57ab5d11 100644 --- a/g10/options.h +++ b/g10/options.h @@ -74,6 +74,7 @@ struct int fingerprint; /* list fingerprints */ int list_sigs; /* list signatures */ int print_pka_records; + int print_dane_records; int no_armor; int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/ int def_cipher_algo; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index c6f6d68e9..f3155fd1f 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -411,3 +411,17 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, *r_url = NULL; return gpg_error (GPG_ERR_NOT_FOUND); } + +gpg_error_t +export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) +{ + (void)ctrl; + (void)keyspec; + (void)options; + + *r_keyblock = NULL; + *r_data = NULL; + *r_datalen = 0; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} |