mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
3671. [bug] Don't allow dnssec-importkey overwrite a existing
non-imported private key.
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
3671. [bug] Don't allow dnssec-importkey overwrite a existing
|
||||||
|
non-imported private key.
|
||||||
|
|
||||||
3670. [bug] Address read after free in server side of
|
3670. [bug] Address read after free in server side of
|
||||||
lwres_getrrsetbyname. [RT #29075]
|
lwres_getrrsetbyname. [RT #29075]
|
||||||
|
|
||||||
|
@@ -61,7 +61,9 @@ static dns_fixedname_t fixed;
|
|||||||
static dns_name_t *name = NULL;
|
static dns_name_t *name = NULL;
|
||||||
static isc_mem_t *mctx = NULL;
|
static isc_mem_t *mctx = NULL;
|
||||||
static isc_boolean_t setpub = ISC_FALSE, setdel = ISC_FALSE;
|
static isc_boolean_t setpub = ISC_FALSE, setdel = ISC_FALSE;
|
||||||
|
static isc_boolean_t setttl = ISC_FALSE;
|
||||||
static isc_stdtime_t pub = 0, del = 0;
|
static isc_stdtime_t pub = 0, del = 0;
|
||||||
|
static dns_ttl_t ttl = 0;
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
initname(char *setname) {
|
initname(char *setname) {
|
||||||
@@ -190,9 +192,10 @@ static void
|
|||||||
emit(const char *dir, dns_rdata_t *rdata) {
|
emit(const char *dir, dns_rdata_t *rdata) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
char keystr[DST_KEY_FORMATSIZE];
|
char keystr[DST_KEY_FORMATSIZE];
|
||||||
char newname[1024];
|
char pubname[1024];
|
||||||
|
char priname[1024];
|
||||||
isc_buffer_t buf;
|
isc_buffer_t buf;
|
||||||
dst_key_t *key = NULL;
|
dst_key_t *key = NULL, *tmp = NULL;
|
||||||
|
|
||||||
isc_buffer_init(&buf, rdata->data, rdata->length);
|
isc_buffer_init(&buf, rdata->data, rdata->length);
|
||||||
isc_buffer_add(&buf, rdata->length);
|
isc_buffer_add(&buf, rdata->length);
|
||||||
@@ -201,18 +204,36 @@ emit(const char *dir, dns_rdata_t *rdata) {
|
|||||||
fatal("dst_key_fromdns: %s", isc_result_totext(result));
|
fatal("dst_key_fromdns: %s", isc_result_totext(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_key_setexternal(key, ISC_TRUE);
|
isc_buffer_init(&buf, pubname, sizeof(pubname));
|
||||||
if (setpub)
|
|
||||||
dst_key_settime(key, DST_TIME_PUBLISH, pub);
|
|
||||||
if (setdel)
|
|
||||||
dst_key_settime(key, DST_TIME_DELETE, del);
|
|
||||||
|
|
||||||
isc_buffer_init(&buf, newname, sizeof(newname));
|
|
||||||
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
|
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fatal("Failed to build public key filename: %s",
|
fatal("Failed to build public key filename: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
}
|
}
|
||||||
|
isc_buffer_init(&buf, priname, sizeof(priname));
|
||||||
|
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
fatal("Failed to build private key filename: %s",
|
||||||
|
isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dst_key_fromfile(dst_key_name(key), dst_key_id(key),
|
||||||
|
dst_key_alg(key),
|
||||||
|
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
|
||||||
|
dir, mctx, &tmp);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if (dst_key_isprivate(tmp) && !dst_key_isexternal(tmp))
|
||||||
|
fatal("Private key already exists in %s", priname);
|
||||||
|
dst_key_free(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_key_setexternal(key, ISC_TRUE);
|
||||||
|
if (setpub)
|
||||||
|
dst_key_settime(key, DST_TIME_PUBLISH, pub);
|
||||||
|
if (setdel)
|
||||||
|
dst_key_settime(key, DST_TIME_DELETE, del);
|
||||||
|
if (setttl)
|
||||||
|
dst_key_setttl(key, ttl);
|
||||||
|
|
||||||
result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
|
result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
|
||||||
dir);
|
dir);
|
||||||
@@ -221,8 +242,7 @@ emit(const char *dir, dns_rdata_t *rdata) {
|
|||||||
fatal("Failed to write key %s: %s", keystr,
|
fatal("Failed to write key %s: %s", keystr,
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
}
|
}
|
||||||
|
printf("%s\n", pubname);
|
||||||
printf("%s\n", newname);
|
|
||||||
|
|
||||||
isc_buffer_clear(&buf);
|
isc_buffer_clear(&buf);
|
||||||
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
|
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf);
|
||||||
@@ -230,7 +250,7 @@ emit(const char *dir, dns_rdata_t *rdata) {
|
|||||||
fatal("Failed to build private key filename: %s",
|
fatal("Failed to build private key filename: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
}
|
}
|
||||||
printf("%s\n", newname);
|
printf("%s\n", priname);
|
||||||
dst_key_free(&key);
|
dst_key_free(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,13 +260,21 @@ usage(void) ISC_PLATFORM_NORETURN_POST;
|
|||||||
static void
|
static void
|
||||||
usage(void) {
|
usage(void) {
|
||||||
fprintf(stderr, "Usage:\n");
|
fprintf(stderr, "Usage:\n");
|
||||||
fprintf(stderr, " %s options [-K dir] file\n\n", program);
|
fprintf(stderr, " %s options [-K dir] keyfile\n\n", program);
|
||||||
|
fprintf(stderr, " %s options -f file [keyname]\n\n", program);
|
||||||
fprintf(stderr, "Version: %s\n", VERSION);
|
fprintf(stderr, "Version: %s\n", VERSION);
|
||||||
fprintf(stderr, "Options:\n");
|
fprintf(stderr, "Options:\n");
|
||||||
fprintf(stderr, " -v <verbose level>\n");
|
fprintf(stderr, " -f file: read key from zone file\n");
|
||||||
fprintf(stderr, " -K <directory>: directory in which to store "
|
fprintf(stderr, " -K <directory>: directory in which to store "
|
||||||
"the keyset files\n");
|
"the key files\n");
|
||||||
fprintf(stderr, " -f file: read keyset from zone file\n");
|
fprintf(stderr, " -L ttl: set default key TTL\n");
|
||||||
|
fprintf(stderr, " -v <verbose level>\n");
|
||||||
|
fprintf(stderr, " -h: print usage and exit\n");
|
||||||
|
fprintf(stderr, "Timing options:\n");
|
||||||
|
fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
|
||||||
|
"publication date\n");
|
||||||
|
fprintf(stderr, " -D date/[+-]offset/none: set/unset key "
|
||||||
|
"deletion date\n");
|
||||||
|
|
||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
@@ -278,7 +306,8 @@ main(int argc, char **argv) {
|
|||||||
|
|
||||||
isc_commandline_errprint = ISC_FALSE;
|
isc_commandline_errprint = ISC_FALSE;
|
||||||
|
|
||||||
while ((ch = isc_commandline_parse(argc, argv, "D:f:hK:P:v:")) != -1) {
|
#define CMDLINE_FLAGS "D:f:hK:L:P:v:"
|
||||||
|
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'D':
|
case 'D':
|
||||||
if (setdel)
|
if (setdel)
|
||||||
@@ -292,6 +321,13 @@ main(int argc, char **argv) {
|
|||||||
if (strlen(dir) == 0U)
|
if (strlen(dir) == 0U)
|
||||||
fatal("directory must be non-empty string");
|
fatal("directory must be non-empty string");
|
||||||
break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
if (strcmp(isc_commandline_argument, "none") == 0)
|
||||||
|
ttl = 0;
|
||||||
|
else
|
||||||
|
ttl = strtottl(isc_commandline_argument);
|
||||||
|
setttl = ISC_TRUE;
|
||||||
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if (setpub)
|
if (setpub)
|
||||||
fatal("-P specified more than once");
|
fatal("-P specified more than once");
|
||||||
@@ -346,8 +382,8 @@ main(int argc, char **argv) {
|
|||||||
dns_rdataset_init(&rdataset);
|
dns_rdataset_init(&rdataset);
|
||||||
|
|
||||||
if (filename != NULL) {
|
if (filename != NULL) {
|
||||||
if (argc < isc_commandline_index + 1 && filename != NULL) {
|
if (argc < isc_commandline_index + 1) {
|
||||||
/* using zone name as the zone file name */
|
/* using filename as zone name */
|
||||||
namestr = filename;
|
namestr = filename;
|
||||||
} else
|
} else
|
||||||
namestr = argv[isc_commandline_index];
|
namestr = argv[isc_commandline_index];
|
||||||
|
@@ -44,22 +44,45 @@
|
|||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>dnssec-importkey</command>
|
<command>dnssec-importkey</command>
|
||||||
<arg><option>-f <replaceable class="parameter">filename</replaceable></option></arg>
|
|
||||||
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
|
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
|
||||||
|
<arg><option>-L <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||||
<arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
|
<arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||||
<arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
|
<arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||||
<arg><option>-h</option></arg>
|
<arg><option>-h</option></arg>
|
||||||
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||||
<arg><option>keyname</option></arg>
|
<arg choice="req"><option>keyfile</option></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>dnssec-importkey</command>
|
||||||
|
<arg choice="req"><option>-f <replaceable class="parameter">filename</replaceable></option></arg>
|
||||||
|
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
|
||||||
|
<arg><option>-L <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||||
|
<arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||||
|
<arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||||
|
<arg><option>-h</option></arg>
|
||||||
|
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||||
|
<arg><option>dnsname</option></arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>DESCRIPTION</title>
|
<title>DESCRIPTION</title>
|
||||||
<para><command>dnssec-importkey</command>
|
<para><command>dnssec-importkey</command>
|
||||||
read a DNSKEY record and generated a .key/.private key pair.
|
reads a public DNSKEY record and generates a pair of
|
||||||
Publication (<option>-P</option>) and deletions (<option>-D</option>)
|
.key/.private files. The DNSKEY record may be read from an
|
||||||
times can be set for the key.
|
existing .key file, in which case a corresponding .private file
|
||||||
|
will be generated, or it may be read from any other file or
|
||||||
|
from the standard input, in which case both .key and .private
|
||||||
|
files will be generated.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The newly-created .private file does <emphasis>not</command>
|
||||||
|
contain private key data, and cannot be used for signing.
|
||||||
|
However, having a .private file makes it possible to set
|
||||||
|
publication (<option>-P</option>) and deletion
|
||||||
|
(<option>-D</option>) times for the key, which means the
|
||||||
|
public key can be added to and removed from the DNSKEY RRset
|
||||||
|
on schedule even if the true private key is stored offline.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@@ -70,9 +93,16 @@
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-f <replaceable class="parameter">filename</replaceable></term>
|
<term>-f <replaceable class="parameter">filename</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Filename to read the key from.
|
Zone file mode: instead of a public keyfile name, the argument
|
||||||
</para>
|
is the DNS domain name of a zone master file, which can be read
|
||||||
|
from <option>file</option>. If the domain name is the same as
|
||||||
|
<option>file</option>, then it may be omitted.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If <option>file</option> is set to <literal>"-"</literal>, then
|
||||||
|
the zone data is read from the standard input.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@@ -93,7 +123,7 @@
|
|||||||
into a DNSKEY RR. If the key is imported into a zone,
|
into a DNSKEY RR. If the key is imported into a zone,
|
||||||
this is the TTL that will be used for it, unless there was
|
this is the TTL that will be used for it, unless there was
|
||||||
already a DNSKEY RRset in place, in which case the existing TTL
|
already a DNSKEY RRset in place, in which case the existing TTL
|
||||||
would take precedence. importkey the default TTL to
|
would take precedence. Setting the default TTL to
|
||||||
<literal>0</literal> or <literal>none</literal> removes it.
|
<literal>0</literal> or <literal>none</literal> removes it.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@@ -159,6 +189,16 @@
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>FILES</title>
|
||||||
|
<para>
|
||||||
|
A keyfile can be designed by the key identification
|
||||||
|
<filename>Knnnn.+aaa+iiiii</filename> or the full file name
|
||||||
|
<filename>Knnnn.+aaa+iiiii.key</filename> as generated by
|
||||||
|
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>SEE ALSO</title>
|
<title>SEE ALSO</title>
|
||||||
<para><citerefentry>
|
<para><citerefentry>
|
||||||
|
@@ -82,3 +82,4 @@ rm -f */*.nzf
|
|||||||
rm -f ns3/test-?.bk
|
rm -f ns3/test-?.bk
|
||||||
rm -f ns3/test-?.bk.signed
|
rm -f ns3/test-?.bk.signed
|
||||||
rm -f ns3/test-?.bk.signed.jnl
|
rm -f ns3/test-?.bk.signed.jnl
|
||||||
|
rm -f import.key Kimport*
|
||||||
|
@@ -128,7 +128,9 @@ rm -f ${k3}.* ${k4}.*
|
|||||||
#
|
#
|
||||||
# Convert k1 and k2 in to External Keys.
|
# Convert k1 and k2 in to External Keys.
|
||||||
rm -f $k1.private
|
rm -f $k1.private
|
||||||
$IMPORTKEY -P now -D now+3600 -f $k1.key $zone > /dev/null 2>&1
|
mv $k1.key a-file
|
||||||
|
$IMPORTKEY -P now -D now+3600 -f a-file $zone > /dev/null 2>&1
|
||||||
rm -f $k2.private
|
rm -f $k2.private
|
||||||
$IMPORTKEY -f $k2.key $zone > /dev/null 2>&1
|
mv $k2.key a-file
|
||||||
|
$IMPORTKEY -f a-file $zone > /dev/null 2>&1
|
||||||
done
|
done
|
||||||
|
@@ -847,4 +847,19 @@ do
|
|||||||
done
|
done
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:testing imported key won't overwrite a private key ($n)"
|
||||||
|
ret=0
|
||||||
|
key=`$KEYGEN -r $RANDFILE -q import.example`
|
||||||
|
cp ${key}.key import.key
|
||||||
|
# import should fail
|
||||||
|
$IMPORTKEY -f import.key import.example > /dev/null 2>&1 && ret=1
|
||||||
|
rm -f ${key}.private
|
||||||
|
# private key removed; import should now succeed
|
||||||
|
$IMPORTKEY -f import.key import.example > /dev/null 2>&1 || ret=1
|
||||||
|
# now that it's an external key, re-import should succeed
|
||||||
|
$IMPORTKEY -f import.key import.example > /dev/null 2>&1 || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
exit $status
|
exit $status
|
||||||
|
Reference in New Issue
Block a user