Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
22
Issues
22
List
Boards
Labels
Service Desk
Milestones
Merge Requests
16
Merge Requests
16
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
573569a1
Commit
573569a1
authored
Dec 18, 2018
by
Daniel Salzman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fix_offline_ksk' into 'master'
Fix offline ksk See merge request
!961
parents
8060b902
7da7c084
Pipeline
#43484
passed with stages
in 10 minutes and 53 seconds
Changes
22
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
184 additions
and
111 deletions
+184
-111
doc/man/keymgr.8in
doc/man/keymgr.8in
+7
-4
doc/man/knot.conf.5in
doc/man/knot.conf.5in
+14
-0
doc/man_keymgr.rst
doc/man_keymgr.rst
+7
-4
doc/operation.rst
doc/operation.rst
+10
-5
doc/reference.rst
doc/reference.rst
+16
-0
src/contrib/time.c
src/contrib/time.c
+1
-1
src/knot/conf/schema.c
src/knot/conf/schema.c
+2
-0
src/knot/conf/schema.h
src/knot/conf/schema.h
+1
-0
src/knot/dnssec/context.c
src/knot/dnssec/context.c
+4
-0
src/knot/dnssec/kasp/kasp_db.c
src/knot/dnssec/kasp/kasp_db.c
+1
-1
src/knot/dnssec/kasp/policy.h
src/knot/dnssec/kasp/policy.h
+0
-2
src/knot/dnssec/key-events.c
src/knot/dnssec/key-events.c
+1
-1
src/knot/dnssec/key_records.c
src/knot/dnssec/key_records.c
+26
-32
src/knot/dnssec/key_records.h
src/knot/dnssec/key_records.h
+1
-1
src/knot/dnssec/policy.c
src/knot/dnssec/policy.c
+3
-9
src/utils/keymgr/functions.c
src/utils/keymgr/functions.c
+4
-0
src/utils/keymgr/main.c
src/utils/keymgr/main.c
+14
-11
src/utils/keymgr/offline_ksk.c
src/utils/keymgr/offline_ksk.c
+65
-36
src/utils/keymgr/offline_ksk.h
src/utils/keymgr/offline_ksk.h
+2
-2
tests-extra/tests/dnssec/offline_ksk/test.py
tests-extra/tests/dnssec/offline_ksk/test.py
+2
-1
tests-extra/tools/dnstest/server.py
tests-extra/tools/dnstest/server.py
+2
-0
tests/contrib/test_time.c
tests/contrib/test_time.c
+1
-1
No files found.
doc/man/keymgr.8in
View file @
573569a1
...
...
@@ -130,8 +130,9 @@ owned by both zones equally.
\fBpregenerate\fP \fItimestamp\fP
Pre\-generate ZSKs for use with offline KSK, for the specified period starting from now.
.TP
\fBshow\-offline\fP \fItimestamp\fP
Print pre\-generated offline key\-related records for specified timestamp.
\fBshow\-offline\fP \fItimestamp\-from\fP [\fItimestamp\-to\fP]
Print pre\-generated offline key\-related records for specified time interval. If \fItimestamp_to\fP
is omitted, it will be to infinity.
.TP
\fBdel\-offline\fP \fItimestamp\-from\fP \fItimestamp\-to\fP
Delete pre\-generated offline key\-related records in specified time interval.
...
...
@@ -139,7 +140,7 @@ Delete pre\-generated offline key\-related records in specified time interval.
\fBdel\-all\-old\fP
Delete old keys that are in state \(aqremoved\(aq.
.TP
\fBgenerate\-ksr\fP \fItimestamp\fP
\fBgenerate\-ksr\fP \fItimestamp\
-from\fP \fItimestamp\-to\
fP
Print to stdout KeySigningRequest based on pre\-generated ZSKs for specified period.
.TP
\fBsign\-ksr\fP \fIksr_file\fP
...
...
@@ -147,7 +148,9 @@ Read KeySigingRequest from a text file, sign it using local keyset and print Sig
.TP
\fBimport\-skr\fP \fIskr_file\fP
Read SignedKeyResponse from a text file and import the signatures for later use in zone. (The signatures
are not at all checked at import time, but they will be ignored at signing time if invalid.)
are not checked at import time, but they will be ignored at signing time if invalid.) If some
signatures have already been imported, they will be deleted for the period from beginning of the SKR
to infinity.
.UNINDENT
.SS Generate arguments
.sp
...
...
doc/man/knot.conf.5in
View file @
573569a1
...
...
@@ -608,6 +608,7 @@ policy:
zsk\-size: SIZE
ksk\-shared: BOOL
dnskey\-ttl: TIME
zone\-max\-ttl: TIME
zsk\-lifetime: TIME
ksk\-lifetime: TIME
propagation\-delay: TIME
...
...
@@ -704,6 +705,19 @@ A TTL value for DNSKEY records added into zone apex.
Has infuence over ZSK key lifetime.
.UNINDENT
.UNINDENT
.SS zone\-max\-ttl
.sp
Maximal TTL value among all the records in zone.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
It\(aqs generally recommended to override the maximal TTL computation by setting this
explicitly whenever possible. It\(aqs required for DNSSEC Offline KSK\&.
.UNINDENT
.UNINDENT
.sp
\fIDefault:\fP computed after zone is loaded
.SS zsk\-lifetime
.sp
A period between ZSK publication and the next rollover initiation.
...
...
doc/man_keymgr.rst
View file @
573569a1
...
...
@@ -107,8 +107,9 @@ Commands related to Offline KSK feature
**pregenerate** *timestamp*
Pre-generate ZSKs for use with offline KSK, for the specified period starting from now.
**show-offline** *timestamp*
Print pre-generated offline key-related records for specified timestamp.
**show-offline** *timestamp-from* [*timestamp-to*]
Print pre-generated offline key-related records for specified time interval. If *timestamp_to*
is omitted, it will be to infinity.
**del-offline** *timestamp-from* *timestamp-to*
Delete pre-generated offline key-related records in specified time interval.
...
...
@@ -116,7 +117,7 @@ Commands related to Offline KSK feature
**del-all-old**
Delete old keys that are in state 'removed'.
**generate-ksr** *timestamp*
**generate-ksr** *timestamp
-from* *timestamp-to
*
Print to stdout KeySigningRequest based on pre-generated ZSKs for specified period.
**sign-ksr** *ksr_file*
...
...
@@ -124,7 +125,9 @@ Commands related to Offline KSK feature
**import-skr** *skr_file*
Read SignedKeyResponse from a text file and import the signatures for later use in zone. (The signatures
are not at all checked at import time, but they will be ignored at signing time if invalid.)
are not checked at import time, but they will be ignored at signing time if invalid.) If some
signatures have already been imported, they will be deleted for the period from beginning of the SKR
to infinity.
Generate arguments
..................
...
...
doc/operation.rst
View file @
573569a1
...
...
@@ -652,11 +652,14 @@ For the ZSK side (i.e. the operator of the DNS server), the pre-requisites are:
- properly configured :ref:`DNSSEC policy <Policy section>` (e.g. :ref:`zsk-lifetime <policy_zsk-lifetime>`),
- :ref:`manual <policy_manual>` set to `on`
- :ref:`offline-ksk <policy_offline-ksk>` set to `on`
- :ref:`dnskey-ttl <policy_dnskey-ttl>` and :ref:`zone-max-ttl <policy_zone-max-ttl>` set up explicitly
- a complete KASP DB with just ZSK(s)
For the KSK side (i.e. the operator of the KSK signer), the pre-requisites are:
- Knot configuration equal to the ZSK side (at least the :ref:`Policy section` must be identical)
- Knot configuration equal to the ZSK side (at least relevant parts of corresponding
:ref:`policy <Policy section>`, :ref:`zone <Zone section>`, and :ref:`template <Template section>`
sections must be identical)
- a KASP DB with the KSK(s)
Generating and signing future ZSKs
...
...
@@ -673,15 +676,15 @@ Generating and signing future ZSKs
they would be generated in case of automatic key management.
2. Use the ``keymgr generate-ksr`` command on the ZSK side to export the public parts of the future ZSKs in a form
similar to DNSKEY records.
U
se the same time period as in the first step::
similar to DNSKEY records.
You might u
se the same time period as in the first step::
$ keymgr -c /path/to/ZSK/side.conf example.com. generate-ksr +
6mo
$ keymgr -c /path/to/ZSK/side.conf example.com. generate-ksr +
0 +6mo > /path/to/ksr/file
Save the output of the command (called the Key Signing Request or KSR) to a file and transfer it to the KSK side e.g. via e-mail.
3. Use the ``keymgr sign-ksr`` command on the KSK side with the KSR file from the previous step as a parameter::
$ keymgr -c /path/to/KSK/side.conf example.com. sign-ksr /path/to/ksr/file
$ keymgr -c /path/to/KSK/side.conf example.com. sign-ksr /path/to/ksr/file
> /path/to/skr/file
This creates all the future forms of the DNSKEY, CDNSKEY and CSK records and all the respective RRSIGs and prints them on output. Save
the output of the command (called the Signed Key Response or SKR) to a file and transfer it back to the ZSK side.
...
...
@@ -697,7 +700,9 @@ Generating and signing future ZSKs
6. Now the future ZSKs and DNSKEY records with signatures are ready in KASP DB for later usage.
Knot automatically uses them in correct time intervals.
The entire procedure must to be repeated before the time period selected at the beginning passes.
The entire procedure must to be repeated before the time period selected at the beginning passes,
or whenever a configuration is changed significantly. Over-importing new SKR across some previously-imported
one leads to deleting the old offline records.
.. _DNSSEC Export Import KASP DB:
...
...
doc/reference.rst
View file @
573569a1
...
...
@@ -672,6 +672,7 @@ DNSSEC policy configuration.
zsk-size: SIZE
ksk-shared: BOOL
dnskey-ttl: TIME
zone-max-ttl: TIME
zsk-lifetime: TIME
ksk-lifetime: TIME
propagation-delay: TIME
...
...
@@ -773,6 +774,8 @@ If enabled, all zones with this policy assigned will share one KSK.
*Default:* off
.. _policy_dnskey-ttl:
dnskey-ttl
----------
...
...
@@ -783,6 +786,19 @@ A TTL value for DNSKEY records added into zone apex.
.. NOTE::
Has infuence over ZSK key lifetime.
.. _policy_zone-max-ttl:
zone-max-ttl
------------
Maximal TTL value among all the records in zone.
.. NOTE::
It's generally recommended to override the maximal TTL computation by setting this
explicitly whenever possible. It's required for :ref:`DNSSEC Offline KSK`.
*Default:* computed after zone is loaded
.. _policy_zsk-lifetime:
zsk-lifetime
...
...
src/contrib/time.c
View file @
573569a1
...
...
@@ -389,7 +389,7 @@ int knot_time_print(knot_time_print_t format, knot_time_t time, char *dst, size_
struct
tm
lt
;
time_t
tt
=
(
time_t
)
time
;
ret
=
(
localtime_r
(
&
tt
,
&
lt
)
==
NULL
?
-
1
:
strftime
(
dst
,
dst_len
,
"%Y-%m-%dT%H:%M:%S"
,
&
lt
));
strftime
(
dst
,
dst_len
,
"%Y-%m-%dT%H:%M:%S
Z
"
,
&
lt
));
return
(
ret
>
0
?
0
:
-
1
);
case
TIME_PRINT_RELSEC
:
ret
=
snprintf
(
dst
,
dst_len
,
"%+"
KNOT_TIMEDIFF_PRINTF
,
...
...
src/knot/conf/schema.c
View file @
573569a1
...
...
@@ -249,6 +249,8 @@ static const yp_item_t desc_policy[] = {
CONF_IO_FRLD_ZONES
},
{
C_DNSKEY_TTL
,
YP_TINT
,
YP_VINT
=
{
0
,
UINT32_MAX
,
YP_NIL
,
YP_STIME
},
CONF_IO_FRLD_ZONES
},
{
C_ZONE_MAX_TLL
,
YP_TINT
,
YP_VINT
=
{
0
,
UINT32_MAX
,
YP_NIL
,
YP_STIME
},
CONF_IO_FRLD_ZONES
},
{
C_ZSK_LIFETIME
,
YP_TINT
,
YP_VINT
=
{
0
,
UINT32_MAX
,
DAYS
(
30
),
YP_STIME
},
CONF_IO_FRLD_ZONES
},
{
C_KSK_LIFETIME
,
YP_TINT
,
YP_VINT
=
{
0
,
UINT32_MAX
,
0
,
YP_STIME
},
...
...
src/knot/conf/schema.h
View file @
573569a1
...
...
@@ -116,6 +116,7 @@
#define C_ZONE "\x04""zone"
#define C_ZONEFILE_LOAD "\x0D""zonefile-load"
#define C_ZONEFILE_SYNC "\x0D""zonefile-sync"
#define C_ZONE_MAX_TLL "\x0C""zone-max-ttl"
#define C_ZSK_LIFETIME "\x0C""zsk-lifetime"
#define C_ZSK_SIZE "\x08""zsk-size"
...
...
src/knot/dnssec/context.c
View file @
573569a1
...
...
@@ -58,6 +58,10 @@ static void policy_load(knot_kasp_policy_t *policy, conf_val_t *id)
int64_t
ttl
=
conf_int
(
&
val
);
policy
->
dnskey_ttl
=
(
ttl
!=
YP_NIL
)
?
ttl
:
UINT32_MAX
;
val
=
conf_id_get
(
conf
(),
C_POLICY
,
C_ZONE_MAX_TLL
,
id
);
ttl
=
conf_int
(
&
val
);
policy
->
zone_maximal_ttl
=
(
ttl
!=
YP_NIL
)
?
ttl
:
UINT32_MAX
;
val
=
conf_id_get
(
conf
(),
C_POLICY
,
C_ZSK_LIFETIME
,
id
);
policy
->
zsk_lifetime
=
conf_int
(
&
val
);
...
...
src/knot/dnssec/kasp/kasp_db.c
View file @
573569a1
...
...
@@ -839,7 +839,7 @@ int kasp_db_load_offline_records(kasp_db_t *db, const knot_dname_t *for_dname,
goto
cleanup
;
}
if
(
key_class
(
&
key
)
!=
KASPDBKEY_OFFLINE_RECORDS
||
knot_dname_cmp
((
const
knot_dname_t
*
)
key
.
data
+
1
,
r
->
rrsig
.
owner
)
!=
0
)
{
knot_dname_cmp
((
const
knot_dname_t
*
)
key
.
data
+
1
,
for_dname
)
!=
0
)
{
ret
=
KNOT_ENOENT
;
goto
cleanup
;
}
...
...
src/knot/dnssec/kasp/policy.h
View file @
573569a1
...
...
@@ -107,8 +107,6 @@ typedef struct {
uint32_t
nsec3_salt_lifetime
;
uint16_t
nsec3_iterations
;
uint8_t
nsec3_salt_length
;
// SOA
uint32_t
soa_minimal_ttl
;
// zone
uint32_t
zone_maximal_ttl
;
// data propagation delay
...
...
src/knot/dnssec/key-events.c
View file @
573569a1
...
...
@@ -444,7 +444,7 @@ static roll_action_t next_action(kdnssec_ctx_t *ctx, zone_sign_roll_flags_t flag
}
// else FALLTHROUGH
case
DNSSEC_KEY_STATE_RETIRED
:
keytime
=
knot_time_min
(
key
->
timing
.
retire
,
key
->
timing
.
remove
);
keytime
=
ksk_remove_time
(
keytime
,
ctx
);
;
keytime
=
zsk_remove_time
(
keytime
,
ctx
)
;
restype
=
REMOVE
;
break
;
case
DNSSEC_KEY_STATE_READY
:
...
...
src/knot/dnssec/key_records.c
View file @
573569a1
...
...
@@ -75,7 +75,7 @@ void key_records_clear_rdatasets(key_records_t *r)
knot_rdataset_clear
(
&
r
->
rrsig
.
rrs
,
NULL
);
}
int
key_records_dump
(
char
**
buf
,
size_t
*
buf_size
,
const
key_records_t
*
r
)
int
key_records_dump
(
char
**
buf
,
size_t
*
buf_size
,
const
key_records_t
*
r
,
bool
verbose
)
{
if
(
*
buf
==
NULL
)
{
if
(
*
buf_size
==
0
)
{
...
...
@@ -86,26 +86,28 @@ int key_records_dump(char **buf, size_t *buf_size, const key_records_t *r)
return
KNOT_ENOMEM
;
}
}
int
ret
=
KNOT_EOK
;
const
knot_dump_style_t
verb_style
=
{
.
wrap
=
true
,
.
show_ttl
=
true
,
.
verbose
=
true
,
.
original_ttl
=
true
,
.
human_tmstamp
=
true
};
const
knot_dump_style_t
*
style
=
verbose
?
&
verb_style
:
&
KNOT_DUMP_STYLE_DEFAULT
;
int
ret
=
0
;
size_t
total
=
1
;
const
knot_rrset_t
*
all_rr
[
4
]
=
{
&
r
->
dnskey
,
&
r
->
cdnskey
,
&
r
->
cds
,
&
r
->
rrsig
};
// first go: just detect the size
if
(
!
knot_rrset_empty
(
&
r
->
dnskey
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
dnskey
,
buf
,
buf_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
total
+=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
cdnskey
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
cdnskey
,
buf
,
buf_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
total
+=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
cds
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
cds
,
buf
,
buf_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
total
+=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
rrsig
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
rrsig
,
buf
,
buf_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
total
+=
ret
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
all_rr
[
i
]))
{
ret
=
knot_rrset_txt_dump
(
all_rr
[
i
],
buf
,
buf_size
,
style
);
(
void
)
buf
;
total
+=
ret
;
}
}
if
(
ret
>=
0
&&
total
<
*
buf_size
)
{
if
(
ret
>=
0
&&
total
>
*
buf_size
)
{
free
(
*
buf
);
*
buf_size
=
total
;
*
buf
=
malloc
(
*
buf_size
);
...
...
@@ -116,21 +118,13 @@ int key_records_dump(char **buf, size_t *buf_size, const key_records_t *r)
char
*
fake_buf
=
*
buf
;
size_t
fake_size
=
*
buf_size
;
//second go: do it
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
dnskey
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
dnskey
,
&
fake_buf
,
&
fake_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
fake_buf
+=
ret
,
fake_size
-=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
cdnskey
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
cdnskey
,
&
fake_buf
,
&
fake_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
fake_buf
+=
ret
,
fake_size
-=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
cds
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
cds
,
&
fake_buf
,
&
fake_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
fake_buf
+=
ret
,
fake_size
-=
ret
;
}
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
&
r
->
rrsig
))
{
ret
=
knot_rrset_txt_dump
(
&
r
->
rrsig
,
&
fake_buf
,
&
fake_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
if
(
ret
>=
0
&&
!
knot_rrset_empty
(
all_rr
[
i
]))
{
ret
=
knot_rrset_txt_dump
(
all_rr
[
i
],
&
fake_buf
,
&
fake_size
,
style
);
fake_buf
+=
ret
,
fake_size
-=
ret
;
}
}
assert
(
fake_buf
-
*
buf
==
total
-
1
);
return
ret
>=
0
?
KNOT_EOK
:
ret
;
}
...
...
src/knot/dnssec/key_records.h
View file @
573569a1
...
...
@@ -27,7 +27,7 @@ void key_records_clear(key_records_t *r);
void
key_records_clear_rdatasets
(
key_records_t
*
r
);
int
key_records_dump
(
char
**
buf
,
size_t
*
buf_size
,
const
key_records_t
*
r
);
int
key_records_dump
(
char
**
buf
,
size_t
*
buf_size
,
const
key_records_t
*
r
,
bool
verbose
);
int
key_records_sign
(
const
zone_key_t
*
key
,
key_records_t
*
r
,
const
kdnssec_ctx_t
*
kctx
);
...
...
src/knot/dnssec/policy.c
View file @
573569a1
...
...
@@ -19,12 +19,6 @@
#include "knot/dnssec/policy.h"
#include "libknot/rrtype/soa.h"
static
uint32_t
zone_soa_min_ttl
(
const
zone_contents_t
*
zone
)
{
knot_rrset_t
soa
=
node_rrset
(
zone
->
apex
,
KNOT_RRTYPE_SOA
);
return
knot_soa_minimum
(
soa
.
rrs
.
rdata
);
}
static
uint32_t
zone_soa_ttl
(
const
zone_contents_t
*
zone
)
{
knot_rrset_t
soa
=
node_rrset
(
zone
->
apex
,
KNOT_RRTYPE_SOA
);
...
...
@@ -37,11 +31,11 @@ void update_policy_from_zone(knot_kasp_policy_t *policy,
assert
(
policy
);
assert
(
zone
);
// Use SOA TTL if not configured.
if
(
policy
->
dnskey_ttl
==
UINT32_MAX
)
{
policy
->
dnskey_ttl
=
zone_soa_ttl
(
zone
);
}
policy
->
soa_minimal_ttl
=
zone_soa_min_ttl
(
zone
);
policy
->
zone_maximal_ttl
=
zone
->
max_ttl
;
if
(
policy
->
zone_maximal_ttl
==
UINT32_MAX
)
{
policy
->
zone_maximal_ttl
=
zone
->
max_ttl
;
}
}
src/utils/keymgr/functions.c
View file @
573569a1
...
...
@@ -205,6 +205,10 @@ int keymgr_generate_key(kdnssec_ctx_t *ctx, int argc, char *argv[])
return
ret
;
}
if
((
flags
&
DNSKEY_GENERATE_KSK
)
&&
gen_timing
.
ready
==
infty
)
{
gen_timing
.
ready
=
gen_timing
.
active
;
}
if
(
keysize
>
0
)
{
if
((
flags
&
DNSKEY_GENERATE_KSK
))
{
ctx
->
policy
->
ksk_size
=
keysize
;
...
...
src/utils/keymgr/main.c
View file @
573569a1
...
...
@@ -79,13 +79,13 @@ static void print_help(void)
" (syntax: pregenerate <timestamp>)
\n
"
" presign Pre-generate RRSIG signatures for pregenerated ZSKs.
\n
"
" (syntax: presign <timestamp>)
\n
"
" show-offline Print pre-generated offline key-related records for specified time
stamp
.
\n
"
" (syntax: show-offline <
timestamp>
)
\n
"
" show-offline Print pre-generated offline key-related records for specified time
interval (possibly to infinity)
.
\n
"
" (syntax: show-offline <
from> [<to>]
)
\n
"
" del-offline Delete pre-generated offline key-related records in specified time interval.
\n
"
" (syntax: del-offline <from> <to>)
\n
"
" del-all-old Delete old keys that are in state 'removed'.
\n
"
" generate-ksr Print to stdout KeySigningRequest based on pre-generated ZSKS.
\n
"
" (syntax: generate-ksr <
timestamp
>)
\n
"
" (syntax: generate-ksr <
from> <to
>)
\n
"
" sign-ksr Read KeySigningRequest from a file, sign it and print SignedKeyResponse to stdout.
\n
"
" (syntax: sign-ksr <ksr_file>)
\n
"
" import-skr Import DNSKEY record signatures from a SignedKeyResponse.
\n
"
...
...
@@ -144,6 +144,13 @@ static int key_command(int argc, char *argv[], int opt_ind)
goto main_end; \
}
#define CHECK_MISSING_ARG2(msg) \
if (argc < 4) { \
printf("%s\n", (msg)); \
ret = KNOT_EINVAL; \
goto main_end; \
}
bool
print_ok_on_succes
=
true
;
if
(
strcmp
(
argv
[
1
],
"generate"
)
==
0
)
{
ret
=
keymgr_generate_key
(
&
kctx
,
argc
-
2
,
argv
+
2
);
...
...
@@ -227,19 +234,15 @@ static int key_command(int argc, char *argv[], int opt_ind)
ret
=
keymgr_pregenerate_zsks
(
&
kctx
,
argv
[
2
]);
}
else
if
(
strcmp
(
argv
[
1
],
"show-offline"
)
==
0
)
{
CHECK_MISSING_ARG
(
"Timestamp not specified"
);
ret
=
keymgr_print_offline_records
(
&
kctx
,
argv
[
2
]);
ret
=
keymgr_print_offline_records
(
&
kctx
,
argv
[
2
]
,
argc
>
3
?
argv
[
3
]
:
NULL
);
}
else
if
(
strcmp
(
argv
[
1
],
"del-offline"
)
==
0
)
{
if
(
argc
<
4
)
{
printf
(
"Timestamps from-to not specified
\n
"
);
ret
=
KNOT_EINVAL
;
goto
main_end
;
}
CHECK_MISSING_ARG2
(
"Timestamps from-to not specified"
);
ret
=
keymgr_delete_offline_records
(
&
kctx
,
argv
[
2
],
argv
[
3
]);
}
else
if
(
strcmp
(
argv
[
1
],
"del-all-old"
)
==
0
)
{
ret
=
keymgr_del_all_old
(
&
kctx
);
}
else
if
(
strcmp
(
argv
[
1
],
"generate-ksr"
)
==
0
)
{
CHECK_MISSING_ARG
(
"Timestamp
not specified"
);
ret
=
keymgr_print_ksr
(
&
kctx
,
argv
[
2
]);
CHECK_MISSING_ARG
2
(
"Timestamps from-to
not specified"
);
ret
=
keymgr_print_ksr
(
&
kctx
,
argv
[
2
]
,
argv
[
3
]
);
print_ok_on_succes
=
false
;
}
else
if
(
strcmp
(
argv
[
1
],
"sign-ksr"
)
==
0
)
{
CHECK_MISSING_ARG
(
"Input file not specified"
);
...
...
src/utils/keymgr/offline_ksk.c
View file @
573569a1
...
...
@@ -93,9 +93,14 @@ int keymgr_pregenerate_zsks(kdnssec_ctx_t *ctx, char *arg)
ctx
->
keep_deleted_keys
=
true
;
ctx
->
policy
->
manual
=
false
;
if
(
ctx
->
policy
->
dnskey_ttl
==
UINT32_MAX
||
ctx
->
policy
->
zone_maximal_ttl
==
UINT32_MAX
)
{
printf
(
"Error: dnskey-ttl and zone-max-ttl not configured.
\n
"
);
return
KNOT_ESEMCHECK
;
}
while
(
ret
==
KNOT_EOK
&&
knot_time_cmp
(
next
,
upto
)
<=
0
)
{
ctx
->
now
=
next
;
printf
(
"pregenerate %"
PRIu64
"
\n
"
,
ctx
->
now
);
ret
=
pregenerate_once
(
ctx
,
&
next
);
}
...
...
@@ -110,33 +115,53 @@ static int dump_rrset_to_buf(const knot_rrset_t *rrset, char **buf, size_t *buf_
return
KNOT_ENOMEM
;
}
}
return
knot_rrset_txt_dump
(
rrset
,
buf
,
buf_size
,
&
KNOT_DUMP_STYLE_DEFAULT
);
knot_dump_style_t
style
=
{
.
wrap
=
true
,
.
show_ttl
=
true
,
.
verbose
=
true
,
.
original_ttl
=
true
,
.
human_tmstamp
=
true
};
return
knot_rrset_txt_dump
(
rrset
,
buf
,
buf_size
,
&
style
);
}
int
keymgr_print_offline_records
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
)
static
void
print_header
(
const
char
*
of_what
,
knot_time_t
timestamp
,
const
char
*
contents
)
{
knot_time_t
when
;
int
ret
=
parse_timestamp
(
arg
,
&
when
);
char
date
[
64
]
=
{
0
};
(
void
)
knot_time_print
(
TIME_PRINT_ISO8601
,
timestamp
,
date
,
sizeof
(
date
));
printf
(
";; %s %"
PRIu64
" (%s) =========
\n
%s"
,
of_what
,
timestamp
,
date
,
contents
);
}
int
keymgr_print_offline_records
(
kdnssec_ctx_t
*
ctx
,
char
*
arg_from
,
char
*
arg_to
)
{
knot_time_t
from
=
0
,
to
=
0
,
next
=
0
;
int
ret
=
parse_timestamp
(
arg_from
,
&
from
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
knot_time_t
next
=
0
;
key_records_t
r
;
memset
(
&
r
,
0
,
sizeof
(
r
));
ret
=
kasp_db_load_offline_records
(
*
ctx
->
kasp_db
,
ctx
->
zone
->
dname
,
when
,
&
next
,
&
r
);
if
(
ret
==
KNOT_EOK
)
{
char
*
buf
=
NULL
;
size_t
buf_size
=
512
;
ret
=
key_records_dump
(
&
buf
,
&
buf_size
,
&
r
);
if
(
arg_to
!=
NULL
)
{
ret
=
parse_timestamp
(
arg_to
,
&
to
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
}
char
*
buf
=
NULL
;
size_t
buf_size
=
512
;
for
(
knot_time_t
i
=
from
;
ret
==
KNOT_EOK
&&
i
!=
0
&&
(
arg_to
==
NULL
||
knot_time_cmp
(
i
,
to
)
<
0
);
i
=
next
)
{
key_records_t
r
=
{
{
0
}
};
ret
=
kasp_db_load_offline_records
(
*
ctx
->
kasp_db
,
ctx
->
zone
->
dname
,
i
,
&
next
,
&
r
);
if
(
ret
==
KNOT_EOK
)
{
printf
(
"%s"
,
buf
);
ret
=
KNOT_EOK
;
ret
=
key_records_dump
(
&
buf
,
&
buf_size
,
&
r
,
true
);
}
free
(
buf
);
printf
(
"; next %"
PRIu64
"
\n
"
,
next
);
if
(
ret
==
KNOT_EOK
)
{
print_header
(
"Offline records for"
,
i
,
buf
);
}
key_records_clear
(
&
r
);
}
key_records_clear
(
&
r
);
free
(
buf
);
return
ret
;
}
...
...
@@ -170,7 +195,7 @@ static void print_generated_message(void)
{
char
buf
[
64
]
=
{
0
};
knot_time_print
(
TIME_PRINT_ISO8601
,
knot_time
(),
buf
,
sizeof
(
buf
));
printf
(
"generated
on %s by Knot
DNS %s
\n
"
,
buf
,
VERSION
);
printf
(
"generated
at %s by Knot
DNS %s
\n
"
,
buf
,
VERSION
);
}
static
int
ksr_once
(
kdnssec_ctx_t
*
ctx
,
char
**
buf
,
size_t
*
buf_size
,
knot_time_t
*
next_ksr
)
...
...
@@ -183,8 +208,7 @@ static int ksr_once(kdnssec_ctx_t *ctx, char **buf, size_t *buf_size, knot_time_
}
ret
=
dump_rrset_to_buf
(
dnskey
,
buf
,
buf_size
);
if
(
ret
>=
0
)
{
printf
(
";; KeySigningRequest %s %"
PRIu64
" ===========
\n
%s"
,
KSR_SKR_VER
,
ctx
->
now
,
*
buf
);
print_header
(
"KeySigningRequest "
KSR_SKR_VER
,
ctx
->
now
,
*
buf
);
ret
=
KNOT_EOK
;
}
...
...
@@ -197,28 +221,29 @@ done:
return
ret
;
}
int
keymgr_print_ksr
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
)
int
keymgr_print_ksr
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
_from
,
char
*
arg_to
)
{
knot_time_t
upto
;
int
ret
=
parse_timestamp
(
arg
,
&
upto
);
knot_time_t
from
,
to
;
int
ret
=
parse_timestamp
(
arg_from
,
&
from
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
ret
=
parse_timestamp
(
arg_to
,
&
to
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
knot_time_t
next
=
ctx
->
now
;
ret
=
KNOT_EOK
;
char
*
buf
=
NULL
;
size_t
buf_size
=
4096
;
while
(
ret
==
KNOT_EOK
&&
knot_time_cmp
(
next
,
upto
)
<
0
)
{
ctx
->
now
=
next
;
ret
=
ksr_once
(
ctx
,
&
buf
,
&
buf_size
,
&
next
);
while
(
ret
==
KNOT_EOK
&&
knot_time_cmp
(
from
,
to
)
<
0
)
{
ctx
->
now
=
from
;
ret
=
ksr_once
(
ctx
,
&
buf
,
&
buf_size
,
&
from
);
}
if
(
ret
!=
KNOT_EOK
)
{
free
(
buf
);
return
ret
;
}
ctx
->
now
=
up
to
;
ctx
->
now
=
to
;
// force end of period as a KSR timestamp
ret
=
ksr_once
(
ctx
,
&
buf
,
&
buf_size
,
NULL
);
...
...
@@ -269,10 +294,9 @@ static int ksr_sign_dnskey(kdnssec_ctx_t *ctx, knot_rrset_t *zsk, knot_time_t no
goto
done
;
}
}
ret
=
key_records_dump
(
&
buf
,
&
buf_size
,
&
r
);
ret
=
key_records_dump
(
&
buf
,
&
buf_size
,
&
r
,
true
);
if
(
ret
==
KNOT_EOK
)
{
printf
(
";; SignedKeyResponse %s %"
PRIu64
" ===========
\n
%s"
,
KSR_SKR_VER
,
ctx
->
now
,
buf
);
print_header
(
"SignedKeyResponse "
KSR_SKR_VER
,
ctx
->
now
,
buf
);
*
next_sign
=
knot_get_next_zone_key_event
(
&
keyset
);
}
...
...
@@ -346,8 +370,13 @@ static void skr_import_header(zs_scanner_t *sc)
}
(
void
)
header_ver
;
// delete possibly existing conflicting offline records
sc
->
error
.
code
=
kasp_db_delete_offline_records
(
*
ctx
->
kctx
->
kasp_db
,
ctx
->
kctx
->
zone
->
dname
,
next_timestamp
,
0
);
// store previous SKR
if
(
ctx
->
timestamp
>
0
)
{
if
(
ctx
->
timestamp
>
0
&&
sc
->
error
.
code
==
KNOT_EOK
)
{
sc
->
error
.
code
=
kasp_db_store_offline_records
(
*
ctx
->
kctx
->
kasp_db
,
ctx
->
timestamp
,
&
ctx
->
r
);
key_records_clear_rdatasets
(
&
ctx
->
r
);
...
...
src/utils/keymgr/offline_ksk.h
View file @
573569a1
...
...
@@ -20,13 +20,13 @@
int
keymgr_pregenerate_zsks
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
);
int
keymgr_print_offline_records
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
);
int
keymgr_print_offline_records
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
_from
,
char
*
arg_to
);
int
keymgr_delete_offline_records
(
kdnssec_ctx_t
*
ctx
,
char
*
arg_from
,
char
*
arg_to
);
int
keymgr_del_all_old
(
kdnssec_ctx_t
*
ctx
);
int
keymgr_print_ksr
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
);
int
keymgr_print_ksr
(
kdnssec_ctx_t
*
ctx
,
char
*
arg
_from
,
char
*
arg_to
);
int
keymgr_sign_ksr
(
kdnssec_ctx_t
*
ctx
,
const
char
*
ksr_file
);
...
...
tests-extra/tests/dnssec/offline_ksk/test.py
View file @
573569a1
...
...
@@ -91,6 +91,7 @@ knot.dnssec(zone).enable = True
knot
.
dnssec
(
zone
).
manual
=
True
knot
.
dnssec
(
zone
).
alg
=
"ECDSAP384SHA384"
knot
.
dnssec
(
zone
).
dnskey_ttl
=
2
knot
.
dnssec
(
zone
).
zone_max_ttl
=
3
knot
.
dnssec
(
zone
).
zsk_lifetime
=
STARTUP
+
6
*
TICK
# see ksk1 lifetime
knot
.
dnssec
(
zone
).
ksk_lifetime
=
300
# this can be possibly left also infinity