1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-18 00:49:50 +02:00

gpg: Add option --print-dane-records.

* g10/options.h (opt): Add field "print_dane_records".
* g10/gpg.c (oPrintDANERecords): new.
(opts): Add --print-dane-records.
(main): Set that option.
* g10/export.c (do_export): Remove EXPORT_DANE_FORMAT handling.
(do_export_stream): Add EXPORT_DANE_FORMAT handling.
* g10/keylist.c (list_keyblock_pka): Implement DANE record printing.

* g10/gpgv.c (export_pubkey_buffer): New stub.
* g10/test-stubs.c (export_pubkey_buffer): New stub.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-10-08 15:04:45 +02:00
parent a2600e42f9
commit d7b8e76f99
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 141 additions and 23 deletions

View File

@ -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}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}