mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-23 15:07:03 +01:00
gpg: Add export options "export-pka" and "export-dane".
* g10/options.h (EXPORT_PKA_FORMAT): New. * g10/keylist.c (list_keyblock_pka): Do not use DANE flag. * g10/export.c: Include zb32.h. (parse_export_options): Add options "export-pka" and "export-dane". (do_export): Do not armor if either of these option is set. (print_pka_or_dane_records): New. (do_export_stream): Implement new options. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
b05878f32a
commit
cbe467e794
12
doc/gpg.texi
12
doc/gpg.texi
@ -2320,6 +2320,18 @@ opposite meaning. The options are:
|
|||||||
most recent self-signature on each user ID. This option is the same as
|
most recent self-signature on each user ID. This option is the same as
|
||||||
running the @option{--edit-key} command "minimize" before export except
|
running the @option{--edit-key} command "minimize" before export except
|
||||||
that the local copy of the key is not modified. Defaults to no.
|
that the local copy of the key is not modified. Defaults to no.
|
||||||
|
|
||||||
|
@item export-pka
|
||||||
|
Instead of outputting the key material output 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 export-dane
|
||||||
|
Instead of outputting the key material output 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.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item --with-colons
|
@item --with-colons
|
||||||
|
175
g10/export.c
175
g10/export.c
@ -35,6 +35,7 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "membuf.h"
|
#include "membuf.h"
|
||||||
#include "host2net.h"
|
#include "host2net.h"
|
||||||
|
#include "zb32.h"
|
||||||
#include "recsel.h"
|
#include "recsel.h"
|
||||||
#include "mbox-util.h"
|
#include "mbox-util.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@ -103,6 +104,10 @@ parse_export_options(char *str,unsigned int *options,int noisy)
|
|||||||
N_("remove unusable parts from key during export")},
|
N_("remove unusable parts from key during export")},
|
||||||
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
|
{"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL,
|
||||||
N_("remove as much as possible from key during export")},
|
N_("remove as much as possible from key during export")},
|
||||||
|
|
||||||
|
{"export-pka", EXPORT_PKA_FORMAT, NULL, NULL },
|
||||||
|
{"export-dane", EXPORT_DANE_FORMAT, NULL, NULL },
|
||||||
|
|
||||||
/* Aliases for backward compatibility */
|
/* Aliases for backward compatibility */
|
||||||
{"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL},
|
{"include-local-sigs",EXPORT_LOCAL_SIGS,NULL,NULL},
|
||||||
{"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL},
|
{"include-attributes",EXPORT_ATTRIBUTES,NULL,NULL},
|
||||||
@ -316,7 +321,7 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if ( opt.armor )
|
if ( opt.armor && !(options & (EXPORT_PKA_FORMAT|EXPORT_DANE_FORMAT)) )
|
||||||
{
|
{
|
||||||
afx = new_armor_context ();
|
afx = new_armor_context ();
|
||||||
afx->what = secret? 5 : 1;
|
afx->what = secret? 5 : 1;
|
||||||
@ -1245,9 +1250,8 @@ apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector)
|
|||||||
{
|
{
|
||||||
if (!recsel_select (selector, filter_getval, node))
|
if (!recsel_select (selector, filter_getval, node))
|
||||||
{
|
{
|
||||||
|
/* log_debug ("keep-uid: deleting '%s'\n", */
|
||||||
log_debug ("keep-uid: deleting '%s'\n",
|
/* node->pkt->pkt.user_id->name); */
|
||||||
node->pkt->pkt.user_id->name);
|
|
||||||
/* The UID packet and all following packets up to the
|
/* The UID packet and all following packets up to the
|
||||||
* next UID or a subkey. */
|
* next UID or a subkey. */
|
||||||
delete_kbnode (node);
|
delete_kbnode (node);
|
||||||
@ -1258,14 +1262,101 @@ apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector)
|
|||||||
node = node->next)
|
node = node->next)
|
||||||
delete_kbnode (node->next);
|
delete_kbnode (node->next);
|
||||||
}
|
}
|
||||||
else
|
/* else */
|
||||||
log_debug ("keep-uid: keeping '%s'\n",
|
/* log_debug ("keep-uid: keeping '%s'\n", */
|
||||||
node->pkt->pkt.user_id->name);
|
/* node->pkt->pkt.user_id->name); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print DANE or PKA records for all user IDs in KEYBLOCK to the
|
||||||
|
* stream FP. The data for the record is taken from HEXDATA. HEXFPR
|
||||||
|
* is the fingerprint of the primary key. */
|
||||||
|
static gpg_error_t
|
||||||
|
print_pka_or_dane_records (kbnode_t keyblock, const char *hexdata,
|
||||||
|
const char *hexfpr, estream_t fp,
|
||||||
|
int print_pka, int print_dane)
|
||||||
|
{
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
kbnode_t kbctx, node;
|
||||||
|
PKT_user_id *uid;
|
||||||
|
char *mbox = NULL;
|
||||||
|
char hashbuf[32];
|
||||||
|
char *hash = NULL;
|
||||||
|
char *domain;
|
||||||
|
const char *s;
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
|
||||||
|
{
|
||||||
|
if (node->pkt->pkttype != PKT_USER_ID)
|
||||||
|
continue;
|
||||||
|
uid = node->pkt->pkt.user_id;
|
||||||
|
|
||||||
|
if (uid->is_expired || uid->is_revoked)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
xfree (mbox);
|
||||||
|
mbox = mailbox_from_userid (uid->name);
|
||||||
|
if (!mbox)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
domain = strchr (mbox, '@');
|
||||||
|
*domain++ = 0;
|
||||||
|
|
||||||
|
if (print_pka)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "$ORIGIN _pka.%s.\n; %s\n; ", domain, hexfpr);
|
||||||
|
print_utf8_buffer (fp, uid->name, uid->len);
|
||||||
|
es_putc ('\n', fp);
|
||||||
|
gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
|
||||||
|
xfree (hash);
|
||||||
|
hash = zb32_encode (hashbuf, 8*20);
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
len = strlen (hexfpr)/2;
|
||||||
|
es_fprintf (fp, "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n\n",
|
||||||
|
hash, 6 + len, len, hexfpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (print_dane && hexdata)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "$ORIGIN _openpgpkey.%s.\n; %s\n; ", domain, hexfpr);
|
||||||
|
print_utf8_buffer (fp, uid->name, uid->len);
|
||||||
|
es_putc ('\n', fp);
|
||||||
|
gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, mbox, strlen (mbox));
|
||||||
|
xfree (hash);
|
||||||
|
hash = bin2hex (hashbuf, 28, NULL);
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
ascii_strlwr (hash);
|
||||||
|
len = strlen (hexdata)/2;
|
||||||
|
es_fprintf (fp, "%s TYPE61 \\# %u (\n", hash, len);
|
||||||
|
for (s = hexdata; ;)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "\t%.64s\n", s);
|
||||||
|
if (strlen (s) < 64)
|
||||||
|
break;
|
||||||
|
s += 64;
|
||||||
|
}
|
||||||
|
es_fputs ("\t)\n\n", fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
xfree (hash);
|
||||||
|
xfree (mbox);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper for do_export_stream which writes one keyblock to OUT. */
|
/* Helper for do_export_stream which writes one keyblock to OUT. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
|
do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid,
|
||||||
@ -1572,6 +1663,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
strlist_t sl;
|
strlist_t sl;
|
||||||
gcry_cipher_hd_t cipherhd = NULL;
|
gcry_cipher_hd_t cipherhd = NULL;
|
||||||
struct export_stats_s dummystats;
|
struct export_stats_s dummystats;
|
||||||
|
iobuf_t out_help = NULL;
|
||||||
|
|
||||||
if (!stats)
|
if (!stats)
|
||||||
stats = &dummystats;
|
stats = &dummystats;
|
||||||
@ -1581,10 +1673,14 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
if (!kdbhd)
|
if (!kdbhd)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
/* For the DANE format override the options. */
|
/* For the PKA and DANE format open a helper iobuf and for DANE
|
||||||
|
* enforce some options. */
|
||||||
|
if ((options & (EXPORT_PKA_FORMAT | EXPORT_DANE_FORMAT)))
|
||||||
|
{
|
||||||
|
out_help = iobuf_temp ();
|
||||||
if ((options & EXPORT_DANE_FORMAT))
|
if ((options & EXPORT_DANE_FORMAT))
|
||||||
options = (EXPORT_DANE_FORMAT | EXPORT_MINIMAL | EXPORT_CLEAN);
|
options |= EXPORT_MINIMAL | EXPORT_CLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!users)
|
if (!users)
|
||||||
{
|
{
|
||||||
@ -1731,8 +1827,9 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* And write it. */
|
/* And write it. */
|
||||||
err = do_export_one_keyblock (ctrl, keyblock, keyid, out, secret,
|
err = do_export_one_keyblock (ctrl, keyblock, keyid,
|
||||||
options, stats, any,
|
out_help? out_help : out,
|
||||||
|
secret, options, stats, any,
|
||||||
desc, ndesc, descindex, cipherhd);
|
desc, ndesc, descindex, cipherhd);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
@ -1742,11 +1839,65 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
|
|||||||
*keyblock_out = keyblock;
|
*keyblock_out = keyblock;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out_help)
|
||||||
|
{
|
||||||
|
/* We want to write PKA or DANE records. OUT_HELP has the
|
||||||
|
* keyblock and we print a record for each uid to OUT. */
|
||||||
|
char *hexdata;
|
||||||
|
const void *data;
|
||||||
|
void *vp;
|
||||||
|
size_t datalen;
|
||||||
|
estream_t fp;
|
||||||
|
|
||||||
|
iobuf_flush_temp (out_help);
|
||||||
|
data = iobuf_get_temp_buffer (out_help);
|
||||||
|
datalen = iobuf_get_temp_length (out_help);
|
||||||
|
hexdata = bin2hex (data, datalen, NULL);
|
||||||
|
if (!hexdata)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
iobuf_close (out_help);
|
||||||
|
out_help = iobuf_temp ();
|
||||||
|
ascii_strlwr (hexdata);
|
||||||
|
fp = es_fopenmem (0, "rw,samethread");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
xfree (hexdata);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *hexfpr = hexfingerprint (pk, NULL, 0);
|
||||||
|
err = print_pka_or_dane_records (keyblock, hexdata, hexfpr, fp,
|
||||||
|
(options & EXPORT_PKA_FORMAT),
|
||||||
|
(options & EXPORT_DANE_FORMAT));
|
||||||
|
xfree (hexfpr);
|
||||||
|
}
|
||||||
|
xfree (hexdata);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
es_fclose (fp);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
es_fputc (0, fp);
|
||||||
|
if (es_fclose_snatch (fp, &vp, NULL))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
iobuf_writestr (out, vp);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
iobuf_cancel (out_help);
|
||||||
gcry_cipher_close (cipherhd);
|
gcry_cipher_close (cipherhd);
|
||||||
xfree(desc);
|
xfree(desc);
|
||||||
keydb_release (kdbhd);
|
keydb_release (kdbhd);
|
||||||
|
@ -921,7 +921,7 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock)
|
|||||||
/* We do not have an export function which allows to pass a
|
/* We do not have an export function which allows to pass a
|
||||||
keyblock, thus we need to search the key again. */
|
keyblock, thus we need to search the key again. */
|
||||||
err = export_pubkey_buffer (ctrl, hexfpr,
|
err = export_pubkey_buffer (ctrl, hexfpr,
|
||||||
EXPORT_DANE_FORMAT, NULL,
|
(EXPORT_MINIMAL | EXPORT_CLEAN), NULL,
|
||||||
&dummy_keyblock, &data, &datalen);
|
&dummy_keyblock, &data, &datalen);
|
||||||
release_kbnode (dummy_keyblock);
|
release_kbnode (dummy_keyblock);
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -348,7 +348,8 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
|
|||||||
#define EXPORT_RESET_SUBKEY_PASSWD (1<<3)
|
#define EXPORT_RESET_SUBKEY_PASSWD (1<<3)
|
||||||
#define EXPORT_MINIMAL (1<<4)
|
#define EXPORT_MINIMAL (1<<4)
|
||||||
#define EXPORT_CLEAN (1<<5)
|
#define EXPORT_CLEAN (1<<5)
|
||||||
#define EXPORT_DANE_FORMAT (1<<6)
|
#define EXPORT_PKA_FORMAT (1<<6)
|
||||||
|
#define EXPORT_DANE_FORMAT (1<<7)
|
||||||
|
|
||||||
#define LIST_SHOW_PHOTOS (1<<0)
|
#define LIST_SHOW_PHOTOS (1<<0)
|
||||||
#define LIST_SHOW_POLICY_URLS (1<<1)
|
#define LIST_SHOW_POLICY_URLS (1<<1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user