Home | History | Annotate | Line # | Download | only in rollover
      1  1.1  christos # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      2  1.1  christos #
      3  1.1  christos # SPDX-License-Identifier: MPL-2.0
      4  1.1  christos #
      5  1.1  christos # This Source Code Form is subject to the terms of the Mozilla Public
      6  1.1  christos # License, v. 2.0.  If a copy of the MPL was not distributed with this
      7  1.1  christos # file, you can obtain one at https://mozilla.org/MPL/2.0/.
      8  1.1  christos #
      9  1.1  christos # See the COPYRIGHT file distributed with this work for additional
     10  1.1  christos # information regarding copyright ownership.
     11  1.1  christos 
     12  1.1  christos import shutil
     13  1.1  christos from typing import List
     14  1.1  christos 
     15  1.1  christos import isctest
     16  1.1  christos from isctest.kasp import private_type_record
     17  1.1  christos from isctest.template import Nameserver, TrustAnchor, Zone
     18  1.1  christos from isctest.run import EnvCmd
     19  1.1  christos from rollover.common import default_algorithm
     20  1.1  christos 
     21  1.1  christos 
     22  1.1  christos def configure_tld(zonename: str, delegations: List[Zone]) -> Zone:
     23  1.1  christos     templates = isctest.template.TemplateEngine(".")
     24  1.1  christos     alg = default_algorithm()
     25  1.1  christos     keygen = EnvCmd("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600")
     26  1.1  christos     signer = EnvCmd("SIGNER", "-S -g")
     27  1.1  christos 
     28  1.1  christos     isctest.log.info(f"create {zonename} zone with delegations and sign")
     29  1.1  christos 
     30  1.1  christos     for zone in delegations:
     31  1.1  christos         try:
     32  1.1  christos             shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns2/")
     33  1.1  christos         except FileNotFoundError:
     34  1.1  christos             # Some delegations are unsigned.
     35  1.1  christos             pass
     36  1.1  christos 
     37  1.1  christos     ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").out.strip()
     38  1.1  christos     zsk_name = keygen(f"{zonename}", cwd="ns2").out.strip()
     39  1.1  christos     ksk = isctest.kasp.Key(ksk_name, keydir="ns2")
     40  1.1  christos     zsk = isctest.kasp.Key(zsk_name, keydir="ns2")
     41  1.1  christos     dnskeys = [ksk.dnskey, zsk.dnskey]
     42  1.1  christos 
     43  1.1  christos     template = "template.db.j2.manual"
     44  1.1  christos     outfile = f"{zonename}.db"
     45  1.1  christos     tdata = {
     46  1.1  christos         "fqdn": f"{zonename}.",
     47  1.1  christos         "delegations": delegations,
     48  1.1  christos         "dnskeys": dnskeys,
     49  1.1  christos     }
     50  1.1  christos     templates.render(f"ns2/{outfile}", tdata, template=f"ns2/{template}")
     51  1.1  christos     signer(f"-P -x -O full -o {zonename} -f {outfile}.signed {outfile}", cwd="ns2")
     52  1.1  christos 
     53  1.1  christos     return Zone(zonename, f"{outfile}.signed", Nameserver("ns2", "10.53.0.2"))
     54  1.1  christos 
     55  1.1  christos 
     56  1.1  christos def configure_root(delegations: List[Zone]) -> TrustAnchor:
     57  1.1  christos     templates = isctest.template.TemplateEngine(".")
     58  1.1  christos     alg = default_algorithm()
     59  1.1  christos     keygen = EnvCmd("KEYGEN", f"-q -a {alg.number} -b {alg.bits} -L 3600")
     60  1.1  christos     signer = EnvCmd("SIGNER", "-S -g")
     61  1.1  christos 
     62  1.1  christos     zonename = "."
     63  1.1  christos     isctest.log.info("create root zone with delegations and sign")
     64  1.1  christos 
     65  1.1  christos     for zone in delegations:
     66  1.1  christos         shutil.copy(f"{zone.ns.name}/dsset-{zone.name}.", "ns1/")
     67  1.1  christos 
     68  1.1  christos     ksk_name = keygen(f"-f KSK {zonename}", cwd="ns1").out.strip()
     69  1.1  christos     zsk_name = keygen(f"{zonename}", cwd="ns1").out.strip()
     70  1.1  christos     ksk = isctest.kasp.Key(ksk_name, keydir="ns1")
     71  1.1  christos     zsk = isctest.kasp.Key(zsk_name, keydir="ns1")
     72  1.1  christos     dnskeys = [ksk.dnskey, zsk.dnskey]
     73  1.1  christos 
     74  1.1  christos     template = "root.db.j2.manual"
     75  1.1  christos     infile = "root.db.in"
     76  1.1  christos     outfile = "root.db.signed"
     77  1.1  christos     tdata = {
     78  1.1  christos         "fdqn": f"{zonename}.",
     79  1.1  christos         "delegations": delegations,
     80  1.1  christos         "dnskeys": dnskeys,
     81  1.1  christos     }
     82  1.1  christos     templates.render(f"ns1/{infile}", tdata, template=f"ns1/{template}")
     83  1.1  christos     signer(f"-P -x -O full -o {zonename} -f {outfile} {infile}", cwd="ns1")
     84  1.1  christos 
     85  1.1  christos     return ksk.into_ta("static-ds")
     86  1.1  christos 
     87  1.1  christos 
     88  1.1  christos def fake_lifetime(key: str, lifetime: int):
     89  1.1  christos     """
     90  1.1  christos     Fake lifetime of key.
     91  1.1  christos     """
     92  1.1  christos     with open(f"ns3/{key}.state", "a", encoding="utf-8") as statefile:
     93  1.1  christos         statefile.write(f"Lifetime: {lifetime}\n")
     94  1.1  christos 
     95  1.1  christos 
     96  1.1  christos def set_key_relationship(key1: str, key2: str):
     97  1.1  christos     """
     98  1.1  christos     Set in the key state files the Predecessor/Successor fields.
     99  1.1  christos     """
    100  1.1  christos     predecessor = isctest.kasp.Key(key1, keydir="ns3")
    101  1.1  christos     successor = isctest.kasp.Key(key2, keydir="ns3")
    102  1.1  christos 
    103  1.1  christos     with open(f"ns3/{key1}.state", "a", encoding="utf-8") as statefile:
    104  1.1  christos         statefile.write(f"Successor: {successor.tag}\n")
    105  1.1  christos 
    106  1.1  christos     with open(f"ns3/{key2}.state", "a", encoding="utf-8") as statefile:
    107  1.1  christos         statefile.write(f"Predecessor: {predecessor.tag}\n")
    108  1.1  christos 
    109  1.1  christos 
    110  1.1  christos def render_and_sign_zone(
    111  1.1  christos     zonename: str, keys: List[str], signing: bool = True, extra_options: str = ""
    112  1.1  christos ):
    113  1.1  christos     dnskeys = []
    114  1.1  christos     privaterrs = []
    115  1.1  christos     for key_name in keys:
    116  1.1  christos         key = isctest.kasp.Key(key_name, keydir="ns3")
    117  1.1  christos         privaterr = private_type_record(zonename, key)
    118  1.1  christos         dnskeys.append(key.dnskey)
    119  1.1  christos         privaterrs.append(privaterr)
    120  1.1  christos 
    121  1.1  christos     outfile = f"{zonename}.db"
    122  1.1  christos     templates = isctest.template.TemplateEngine(".")
    123  1.1  christos     template = "template.db.j2.manual"
    124  1.1  christos     tdata = {
    125  1.1  christos         "fqdn": f"{zonename}.",
    126  1.1  christos         "dnskeys": dnskeys,
    127  1.1  christos         "privaterrs": privaterrs,
    128  1.1  christos     }
    129  1.1  christos     templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}")
    130  1.1  christos 
    131  1.1  christos     if signing:
    132  1.1  christos         signer = EnvCmd("SIGNER", "-S -g -x -s now-1h -e now+2w -O raw")
    133  1.1  christos         signer(
    134  1.1  christos             f"{extra_options} -o {zonename} -f {outfile}.signed {outfile}", cwd="ns3"
    135  1.1  christos         )
    136  1.1  christos 
    137  1.1  christos 
    138  1.1  christos def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> List[Zone]:
    139  1.1  christos     # The zones at csk-algorithm-roll.$tld represent the various steps
    140  1.1  christos     # of a CSK algorithm rollover.
    141  1.1  christos     zones = []
    142  1.1  christos     zone = f"csk-algorithm-roll.{tld}"
    143  1.1  christos     keygen = EnvCmd("KEYGEN", f"-k {policy}")
    144  1.1  christos     settime = EnvCmd("SETTIME", "-s")
    145  1.1  christos 
    146  1.1  christos     # Step 1:
    147  1.1  christos     # Introduce the first key. This will immediately be active.
    148  1.1  christos     zonename = f"step1.{zone}"
    149  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    150  1.1  christos     isctest.log.info(f"setup {zonename}")
    151  1.1  christos     TactN = "now-7d"
    152  1.1  christos     TsbmN = "now-161h"
    153  1.1  christos     csktimes = f"-P {TactN} -A {TactN}"
    154  1.1  christos     # Key generation.
    155  1.1  christos     csk_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    156  1.1  christos     settime(
    157  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}",
    158  1.1  christos         cwd="ns3",
    159  1.1  christos     )
    160  1.1  christos     # Signing.
    161  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
    162  1.1  christos 
    163  1.1  christos     if reconfig:
    164  1.1  christos         # Step 2:
    165  1.1  christos         # After the publication interval has passed the DNSKEY is OMNIPRESENT.
    166  1.1  christos         zonename = f"step2.{zone}"
    167  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    168  1.1  christos         isctest.log.info(f"setup {zonename}")
    169  1.1  christos         # The time passed since the new algorithm keys have been introduced is 3 hours.
    170  1.1  christos         TpubN1 = "now-3h"
    171  1.1  christos         csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I now"
    172  1.1  christos         newtimes = f"-P {TpubN1} -A {TpubN1}"
    173  1.1  christos         # Key generation.
    174  1.1  christos         csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    175  1.1  christos         csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip()
    176  1.1  christos         settime(
    177  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}",
    178  1.1  christos             cwd="ns3",
    179  1.1  christos         )
    180  1.1  christos         settime(
    181  1.1  christos             f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
    182  1.1  christos             cwd="ns3",
    183  1.1  christos         )
    184  1.1  christos         # Signing.
    185  1.1  christos         render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z")
    186  1.1  christos 
    187  1.1  christos         # Step 3:
    188  1.1  christos         # The zone signatures are also OMNIPRESENT.
    189  1.1  christos         zonename = f"step3.{zone}"
    190  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    191  1.1  christos         isctest.log.info(f"setup {zonename}")
    192  1.1  christos         # The time passed since the new algorithm keys have been introduced is 7 hours.
    193  1.1  christos         TpubN1 = "now-7h"
    194  1.1  christos         TsbmN1 = "now"
    195  1.1  christos         csktimes = f"-P {TactN} -A {TactN}  -P sync {TsbmN} -I {TsbmN1}"
    196  1.1  christos         newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    197  1.1  christos         # Key generation.
    198  1.1  christos         csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    199  1.1  christos         csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip()
    200  1.1  christos         settime(
    201  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}",
    202  1.1  christos             cwd="ns3",
    203  1.1  christos         )
    204  1.1  christos         settime(
    205  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
    206  1.1  christos             cwd="ns3",
    207  1.1  christos         )
    208  1.1  christos         # Signing.
    209  1.1  christos         render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z")
    210  1.1  christos 
    211  1.1  christos         # Step 4:
    212  1.1  christos         # The DS is swapped and can become OMNIPRESENT.
    213  1.1  christos         zonename = f"step4.{zone}"
    214  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    215  1.1  christos         isctest.log.info(f"setup {zonename}")
    216  1.1  christos         # The time passed since the DS has been swapped is 3 hours.
    217  1.1  christos         TpubN1 = "now-10h"
    218  1.1  christos         TsbmN1 = "now-3h"
    219  1.1  christos         csktimes = f"-P {TactN} -A {TactN}  -P sync {TsbmN} -I {TsbmN1}"
    220  1.1  christos         newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    221  1.1  christos         # Key generation.
    222  1.1  christos         csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    223  1.1  christos         csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip()
    224  1.1  christos         settime(
    225  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TsbmN1} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {csk1_name}",
    226  1.1  christos             cwd="ns3",
    227  1.1  christos         )
    228  1.1  christos         settime(
    229  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {csk2_name}",
    230  1.1  christos             cwd="ns3",
    231  1.1  christos         )
    232  1.1  christos         # Signing.
    233  1.1  christos         render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z")
    234  1.1  christos 
    235  1.1  christos         # Step 5:
    236  1.1  christos         # The DNSKEY is removed long enough to be HIDDEN.
    237  1.1  christos         zonename = f"step5.{zone}"
    238  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    239  1.1  christos         isctest.log.info(f"setup {zonename}")
    240  1.1  christos         # The time passed since the DNSKEY has been removed is 2 hours.
    241  1.1  christos         TpubN1 = "now-12h"
    242  1.1  christos         TsbmN1 = "now-5h"
    243  1.1  christos         csktimes = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
    244  1.1  christos         newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    245  1.1  christos         # Key generation.
    246  1.1  christos         csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    247  1.1  christos         csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip()
    248  1.1  christos         settime(
    249  1.1  christos             f"-g HIDDEN -k UNRETENTIVE {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {csk1_name}",
    250  1.1  christos             cwd="ns3",
    251  1.1  christos         )
    252  1.1  christos         settime(
    253  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}",
    254  1.1  christos             cwd="ns3",
    255  1.1  christos         )
    256  1.1  christos         # Signing.
    257  1.1  christos         render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z")
    258  1.1  christos 
    259  1.1  christos         # Step 6:
    260  1.1  christos         # The RRSIGs have been removed long enough to be HIDDEN.
    261  1.1  christos         zonename = f"step6.{zone}"
    262  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    263  1.1  christos         isctest.log.info(f"setup {zonename}")
    264  1.1  christos         # Additional time passed: 7h.
    265  1.1  christos         TpubN1 = "now-19h"
    266  1.1  christos         TsbmN1 = "now-12h"
    267  1.1  christos         csktimes = f"-P {TactN}  -A {TactN}  -P sync {TsbmN} -I {TsbmN1}"
    268  1.1  christos         newtimes = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    269  1.1  christos         # Key generation.
    270  1.1  christos         csk1_name = keygen(f"-l csk1.conf {csktimes} {zonename}", cwd="ns3").out.strip()
    271  1.1  christos         csk2_name = keygen(f"-l csk2.conf {newtimes} {zonename}", cwd="ns3").out.strip()
    272  1.1  christos         settime(
    273  1.1  christos             f"-g HIDDEN -k HIDDEN {TactN} -r UNRETENTIVE {TactN} -z UNRETENTIVE {TactN} -d HIDDEN {TsbmN1} {csk1_name}",
    274  1.1  christos             cwd="ns3",
    275  1.1  christos         )
    276  1.1  christos         settime(
    277  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -z OMNIPRESENT {TsbmN1} -d OMNIPRESENT {TsbmN1} {csk2_name}",
    278  1.1  christos             cwd="ns3",
    279  1.1  christos         )
    280  1.1  christos         # Signing.
    281  1.1  christos         render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options="-z")
    282  1.1  christos 
    283  1.1  christos     return zones
    284  1.1  christos 
    285  1.1  christos 
    286  1.1  christos def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
    287  1.1  christos     # The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK
    288  1.1  christos     # algorithm rollover.
    289  1.1  christos     zones = []
    290  1.1  christos     zone = f"algorithm-roll.{tld}"
    291  1.1  christos     keygen = EnvCmd("KEYGEN", "-L 3600")
    292  1.1  christos     settime = EnvCmd("SETTIME", "-s")
    293  1.1  christos 
    294  1.1  christos     # Step 1:
    295  1.1  christos     # Introduce the first key. This will immediately be active.
    296  1.1  christos     zonename = f"step1.{zone}"
    297  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    298  1.1  christos     isctest.log.info(f"setup {zonename}")
    299  1.1  christos     TactN = "now-7d"
    300  1.1  christos     TsbmN = "now-161h"
    301  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
    302  1.1  christos     # Key generation.
    303  1.1  christos     ksk_name = keygen(
    304  1.1  christos         f"-a RSASHA256 -f KSK {keytimes} {zonename}", cwd="ns3"
    305  1.1  christos     ).out.strip()
    306  1.1  christos     zsk_name = keygen(f"-a RSASHA256 {keytimes} {zonename}", cwd="ns3").out.strip()
    307  1.1  christos     settime(
    308  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
    309  1.1  christos         cwd="ns3",
    310  1.1  christos     )
    311  1.1  christos     settime(
    312  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
    313  1.1  christos         cwd="ns3",
    314  1.1  christos     )
    315  1.1  christos     # Signing.
    316  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk_name])
    317  1.1  christos 
    318  1.1  christos     if reconfig:
    319  1.1  christos         # Step 2:
    320  1.1  christos         # After the publication interval has passed the DNSKEY is OMNIPRESENT.
    321  1.1  christos         zonename = f"step2.{zone}"
    322  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    323  1.1  christos         isctest.log.info(f"setup {zonename}")
    324  1.1  christos         # The time passed since the new algorithm keys have been introduced is 3 hours.
    325  1.1  christos         # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
    326  1.1  christos         TpubN1 = "now-3h"
    327  1.1  christos         TsbmN1 = "now+4h"
    328  1.1  christos         ksk1times = f"-P {TactN}  -A {TactN}  -P sync {TsbmN} -I {TsbmN1}"
    329  1.1  christos         zsk1times = f"-P {TactN}  -A {TactN}  -I {TsbmN1}"
    330  1.1  christos         ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    331  1.1  christos         zsk2times = f"-P {TpubN1} -A {TpubN1}"
    332  1.1  christos         # Key generation.
    333  1.1  christos         ksk1_name = keygen(
    334  1.1  christos             f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3"
    335  1.1  christos         ).out.strip()
    336  1.1  christos         zsk1_name = keygen(
    337  1.1  christos             f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3"
    338  1.1  christos         ).out.strip()
    339  1.1  christos         ksk2_name = keygen(
    340  1.1  christos             f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3"
    341  1.1  christos         ).out.strip()
    342  1.1  christos         zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.strip()
    343  1.1  christos         settime(
    344  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}",
    345  1.1  christos             cwd="ns3",
    346  1.1  christos         )
    347  1.1  christos         settime(
    348  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}",
    349  1.1  christos             cwd="ns3",
    350  1.1  christos         )
    351  1.1  christos         settime(
    352  1.1  christos             f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}",
    353  1.1  christos             cwd="ns3",
    354  1.1  christos         )
    355  1.1  christos         settime(
    356  1.1  christos             f"-g OMNIPRESENT -k RUMOURED {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}",
    357  1.1  christos             cwd="ns3",
    358  1.1  christos         )
    359  1.1  christos         # Signing.
    360  1.1  christos         fake_lifetime(ksk1_name, 0)
    361  1.1  christos         fake_lifetime(zsk1_name, 0)
    362  1.1  christos         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
    363  1.1  christos 
    364  1.1  christos         # Step 3:
    365  1.1  christos         # The zone signatures are also OMNIPRESENT.
    366  1.1  christos         zonename = f"step3.{zone}"
    367  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    368  1.1  christos         isctest.log.info(f"setup {zonename}")
    369  1.1  christos         # The time passed since the new algorithm keys have been introduced is 7 hours.
    370  1.1  christos         TpubN1 = "now-7h"
    371  1.1  christos         TsbmN1 = "now"
    372  1.1  christos         ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
    373  1.1  christos         zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}"
    374  1.1  christos         ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    375  1.1  christos         zsk2times = f"-P {TpubN1} -A {TpubN1}"
    376  1.1  christos         # Key generation.
    377  1.1  christos         ksk1_name = keygen(
    378  1.1  christos             f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3"
    379  1.1  christos         ).out.strip()
    380  1.1  christos         zsk1_name = keygen(
    381  1.1  christos             f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3"
    382  1.1  christos         ).out.strip()
    383  1.1  christos         ksk2_name = keygen(
    384  1.1  christos             f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3"
    385  1.1  christos         ).out.strip()
    386  1.1  christos         zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.strip()
    387  1.1  christos         settime(
    388  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}",
    389  1.1  christos             cwd="ns3",
    390  1.1  christos         )
    391  1.1  christos         settime(
    392  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}",
    393  1.1  christos             cwd="ns3",
    394  1.1  christos         )
    395  1.1  christos         settime(
    396  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}",
    397  1.1  christos             cwd="ns3",
    398  1.1  christos         )
    399  1.1  christos         settime(
    400  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}",
    401  1.1  christos             cwd="ns3",
    402  1.1  christos         )
    403  1.1  christos         # Signing.
    404  1.1  christos         fake_lifetime(ksk1_name, 0)
    405  1.1  christos         fake_lifetime(zsk1_name, 0)
    406  1.1  christos         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
    407  1.1  christos 
    408  1.1  christos         # Step 4:
    409  1.1  christos         # The DS is swapped and can become OMNIPRESENT.
    410  1.1  christos         zonename = f"step4.{zone}"
    411  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    412  1.1  christos         isctest.log.info(f"setup {zonename}")
    413  1.1  christos         # The time passed since the DS has been swapped is 3 hours.
    414  1.1  christos         TpubN1 = "now-10h"
    415  1.1  christos         TsbmN1 = "now-3h"
    416  1.1  christos         ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
    417  1.1  christos         zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}"
    418  1.1  christos         ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    419  1.1  christos         zsk2times = f"-P {TpubN1} -A {TpubN1}"
    420  1.1  christos         # Key generation.
    421  1.1  christos         ksk1_name = keygen(
    422  1.1  christos             f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3"
    423  1.1  christos         ).out.strip()
    424  1.1  christos         zsk1_name = keygen(
    425  1.1  christos             f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3"
    426  1.1  christos         ).out.strip()
    427  1.1  christos         ksk2_name = keygen(
    428  1.1  christos             f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3"
    429  1.1  christos         ).out.strip()
    430  1.1  christos         zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.strip()
    431  1.1  christos         settime(
    432  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TsbmN1} -D ds {TsbmN1} {ksk1_name}",
    433  1.1  christos             cwd="ns3",
    434  1.1  christos         )
    435  1.1  christos         settime(
    436  1.1  christos             f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}",
    437  1.1  christos             cwd="ns3",
    438  1.1  christos         )
    439  1.1  christos         settime(
    440  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d RUMOURED {TsbmN1} -P ds {TsbmN1} {ksk2_name}",
    441  1.1  christos             cwd="ns3",
    442  1.1  christos         )
    443  1.1  christos         settime(
    444  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}",
    445  1.1  christos             cwd="ns3",
    446  1.1  christos         )
    447  1.1  christos         # Signing.
    448  1.1  christos         fake_lifetime(ksk1_name, 0)
    449  1.1  christos         fake_lifetime(zsk1_name, 0)
    450  1.1  christos         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
    451  1.1  christos 
    452  1.1  christos         # Step 5:
    453  1.1  christos         # The DNSKEY is removed long enough to be HIDDEN.
    454  1.1  christos         zonename = f"step5.{zone}"
    455  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    456  1.1  christos         isctest.log.info(f"setup {zonename}")
    457  1.1  christos         # The time passed since the DNSKEY has been removed is 2 hours.
    458  1.1  christos         TpubN1 = "now-12h"
    459  1.1  christos         TsbmN1 = "now-5h"
    460  1.1  christos         ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
    461  1.1  christos         zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}"
    462  1.1  christos         ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    463  1.1  christos         zsk2times = f"-P {TpubN1} -A {TpubN1}"
    464  1.1  christos         # Key generation.
    465  1.1  christos         ksk1_name = keygen(
    466  1.1  christos             f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3"
    467  1.1  christos         ).out.strip()
    468  1.1  christos         zsk1_name = keygen(
    469  1.1  christos             f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3"
    470  1.1  christos         ).out.strip()
    471  1.1  christos         ksk2_name = keygen(
    472  1.1  christos             f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3"
    473  1.1  christos         ).out.strip()
    474  1.1  christos         zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.strip()
    475  1.1  christos         settime(
    476  1.1  christos             f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}",
    477  1.1  christos             cwd="ns3",
    478  1.1  christos         )
    479  1.1  christos         settime(
    480  1.1  christos             f"-g HIDDEN -k UNRETENTIVE {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}",
    481  1.1  christos             cwd="ns3",
    482  1.1  christos         )
    483  1.1  christos         settime(
    484  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}",
    485  1.1  christos             cwd="ns3",
    486  1.1  christos         )
    487  1.1  christos         settime(
    488  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}",
    489  1.1  christos             cwd="ns3",
    490  1.1  christos         )
    491  1.1  christos         # Signing.
    492  1.1  christos         fake_lifetime(ksk1_name, 0)
    493  1.1  christos         fake_lifetime(zsk1_name, 0)
    494  1.1  christos         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
    495  1.1  christos 
    496  1.1  christos         # Step 6:
    497  1.1  christos         # The RRSIGs have been removed long enough to be HIDDEN.
    498  1.1  christos         zonename = f"step6.{zone}"
    499  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    500  1.1  christos         isctest.log.info(f"setup {zonename}")
    501  1.1  christos         # Additional time passed: 7h.
    502  1.1  christos         TpubN1 = "now-19h"
    503  1.1  christos         TsbmN1 = "now-12h"
    504  1.1  christos         ksk1times = f"-P {TactN} -A {TactN} -P sync {TsbmN} -I {TsbmN1}"
    505  1.1  christos         zsk1times = f"-P {TactN} -A {TactN} -I {TsbmN1}"
    506  1.1  christos         ksk2times = f"-P {TpubN1} -A {TpubN1} -P sync {TsbmN1}"
    507  1.1  christos         zsk2times = f"-P {TpubN1} -A {TpubN1}"
    508  1.1  christos         ksk1_name = keygen(
    509  1.1  christos             f"-a RSASHA256 -f KSK {ksk1times} {zonename}", cwd="ns3"
    510  1.1  christos         ).out.strip()
    511  1.1  christos         zsk1_name = keygen(
    512  1.1  christos             f"-a RSASHA256 {zsk1times} {zonename}", cwd="ns3"
    513  1.1  christos         ).out.strip()
    514  1.1  christos         ksk2_name = keygen(
    515  1.1  christos             f"-a ECDSA256 -f KSK {ksk2times} {zonename}", cwd="ns3"
    516  1.1  christos         ).out.strip()
    517  1.1  christos         zsk2_name = keygen(f"-a ECDSA256 {zsk2times} {zonename}", cwd="ns3").out.strip()
    518  1.1  christos         settime(
    519  1.1  christos             f"-g HIDDEN -k HIDDEN {TsbmN1} -r UNRETENTIVE {TsbmN1} -d HIDDEN {TsbmN1} {ksk1_name}",
    520  1.1  christos             cwd="ns3",
    521  1.1  christos         )
    522  1.1  christos         settime(
    523  1.1  christos             f"-g HIDDEN -k HIDDEN {TsbmN1} -z UNRETENTIVE {TsbmN1} {zsk1_name}",
    524  1.1  christos             cwd="ns3",
    525  1.1  christos         )
    526  1.1  christos         settime(
    527  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -r OMNIPRESENT {TpubN1} -d OMNIPRESENT {TsbmN1} {ksk2_name}",
    528  1.1  christos             cwd="ns3",
    529  1.1  christos         )
    530  1.1  christos         settime(
    531  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN1} -z RUMOURED {TpubN1} {zsk2_name}",
    532  1.1  christos             cwd="ns3",
    533  1.1  christos         )
    534  1.1  christos         # Signing.
    535  1.1  christos         fake_lifetime(ksk1_name, 0)
    536  1.1  christos         fake_lifetime(zsk1_name, 0)
    537  1.1  christos         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
    538  1.1  christos 
    539  1.1  christos     return zones
    540  1.1  christos 
    541  1.1  christos 
    542  1.1  christos def configure_cskroll1(tld: str, policy: str) -> List[Zone]:
    543  1.1  christos     # The zones at csk-roll1.$tld represent the various steps of a CSK rollover
    544  1.1  christos     # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
    545  1.1  christos     zones = []
    546  1.1  christos     zone = f"csk-roll1.{tld}"
    547  1.1  christos     cds = "cdnskey,cds:sha384"
    548  1.1  christos     keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf")
    549  1.1  christos     settime = EnvCmd("SETTIME", "-s")
    550  1.1  christos 
    551  1.1  christos     # Step 1:
    552  1.1  christos     # Introduce the first key. This will immediately be active.
    553  1.1  christos     zonename = f"step1.{zone}"
    554  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    555  1.1  christos     isctest.log.info(f"setup {zonename}")
    556  1.1  christos     TactN = "now-7d"
    557  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
    558  1.1  christos     # Key generation.
    559  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    560  1.1  christos     settime(
    561  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}",
    562  1.1  christos         cwd="ns3",
    563  1.1  christos     )
    564  1.1  christos     # Signing.
    565  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}")
    566  1.1  christos 
    567  1.1  christos     # Step 2:
    568  1.1  christos     # It is time to introduce the new CSK.
    569  1.1  christos     zonename = f"step2.{zone}"
    570  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    571  1.1  christos     isctest.log.info(f"setup {zonename}")
    572  1.1  christos     # According to RFC 7583:
    573  1.1  christos     # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
    574  1.1  christos     # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
    575  1.1  christos     # IpubC = DprpC + TTLkey (+publish-safety)
    576  1.1  christos     # Ipub  = IpubC
    577  1.1  christos     # Lcsk = Lksk = Lzsk
    578  1.1  christos     #
    579  1.1  christos     # Lcsk:           6mo (186d, 4464h)
    580  1.1  christos     # Dreg:           N/A
    581  1.1  christos     # DprpC:          1h
    582  1.1  christos     # TTLkey:         1h
    583  1.1  christos     # publish-safety: 1h
    584  1.1  christos     # Ipub:           3h
    585  1.1  christos     #
    586  1.1  christos     # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h
    587  1.1  christos     #         = now - 4464h + 3h  = now - 4461h
    588  1.1  christos     TactN = "now-4461h"
    589  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
    590  1.1  christos     # Key generation.
    591  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    592  1.1  christos     settime(
    593  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}",
    594  1.1  christos         cwd="ns3",
    595  1.1  christos     )
    596  1.1  christos     # Signing.
    597  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}")
    598  1.1  christos 
    599  1.1  christos     # Step 3:
    600  1.1  christos     # It is time to submit the DS and to roll signatures.
    601  1.1  christos     zonename = f"step3.{zone}"
    602  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    603  1.1  christos     isctest.log.info(f"setup {zonename}")
    604  1.1  christos     # According to RFC 7583:
    605  1.1  christos     #
    606  1.1  christos     # Tsbm(N+1) >= Trdy(N+1)
    607  1.1  christos     # KSK: Tact(N+1) = Tsbm(N+1)
    608  1.1  christos     # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1)
    609  1.1  christos     # KSK: Iret  = DprpP + TTLds (+retire-safety)
    610  1.1  christos     # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety)
    611  1.1  christos     #
    612  1.1  christos     # Lcsk:           186d
    613  1.1  christos     # Dprp:           1h
    614  1.1  christos     # DprpP:          1h
    615  1.1  christos     # Dreg:           N/A
    616  1.1  christos     # Dsgn:           25d
    617  1.1  christos     # TTLds:          1h
    618  1.1  christos     # TTLsig:         1d
    619  1.1  christos     # retire-safety:  2h
    620  1.1  christos     # Iret:           4h
    621  1.1  christos     # IretZ:          26d3h
    622  1.1  christos     # Ipub:           3h
    623  1.1  christos     #
    624  1.1  christos     # Tpub(N)   = now - Lcsk = now - 186d
    625  1.1  christos     # Tact(N)   = now - Lcsk + Dprp + TTLsig = now - 4439h
    626  1.1  christos     # Tret(N)   = now
    627  1.1  christos     # Trem(N)   = now + IretZ = now + 26d3h = now + 627h
    628  1.1  christos     # Tpub(N+1) = now - Ipub = now - 3h
    629  1.1  christos     # Tact(N+1) = Tret(N)
    630  1.1  christos     # Tret(N+1) = now + Lcsk = now + 186d = now + 186d
    631  1.1  christos     # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h =
    632  1.1  christos     #           = now + 5091h
    633  1.1  christos     TpubN = "now-186d"
    634  1.1  christos     TactN = "now-4439h"
    635  1.1  christos     TretN = "now"
    636  1.1  christos     TremN = "now+627h"
    637  1.1  christos     TpubN1 = "now-3h"
    638  1.1  christos     TactN1 = TretN
    639  1.1  christos     TretN1 = "now+186d"
    640  1.1  christos     TremN1 = "now+5091h"
    641  1.1  christos     keytimes = (
    642  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    643  1.1  christos     )
    644  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    645  1.1  christos     # Key generation.
    646  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    647  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    648  1.1  christos     settime(
    649  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}",
    650  1.1  christos         cwd="ns3",
    651  1.1  christos     )
    652  1.1  christos     settime(
    653  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z HIDDEN {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
    654  1.1  christos         cwd="ns3",
    655  1.1  christos     )
    656  1.1  christos     # Set key rollover relationship.
    657  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    658  1.1  christos     # Signing.
    659  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    660  1.1  christos 
    661  1.1  christos     # Step 4:
    662  1.1  christos     # Some time later all the ZRRSIG records should be from the new CSK, and the
    663  1.1  christos     # DS should be swapped.  The ZRRSIG records are all replaced after IretZ
    664  1.1  christos     # (which is 26d3h).  The DS is swapped after Iret (which is 4h).
    665  1.1  christos     # In other words, the DS is swapped before all zone signatures are replaced.
    666  1.1  christos     zonename = f"step4.{zone}"
    667  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    668  1.1  christos     isctest.log.info(f"setup {zonename}")
    669  1.1  christos     # According to RFC 7583:
    670  1.1  christos     # Trem(N)    = Tret(N) - Iret + IretZ
    671  1.1  christos     # now       = Tsbm(N+1) + Iret
    672  1.1  christos     #
    673  1.1  christos     # Lcsk:   186d
    674  1.1  christos     # Iret:   4h
    675  1.1  christos     # IretZ:  26d3h
    676  1.1  christos     #
    677  1.1  christos     # Tpub(N)   = now - Iret - Lcsk = now - 4h - 186d = now - 4468h
    678  1.1  christos     # Tret(N)   = now - Iret = now - 4h = now - 4h
    679  1.1  christos     # Trem(N)   = now - Iret + IretZ = now - 4h + 26d3h
    680  1.1  christos     #           = now + 623h
    681  1.1  christos     # Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h
    682  1.1  christos     # Tact(N+1) = Tret(N)
    683  1.1  christos     # Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h
    684  1.1  christos     # Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h
    685  1.1  christos     #           = now + 5087h
    686  1.1  christos     TpubN = "now-4468h"
    687  1.1  christos     TactN = "now-4443h"
    688  1.1  christos     TretN = "now-4h"
    689  1.1  christos     TremN = "now+623h"
    690  1.1  christos     TpubN1 = "now-7h"
    691  1.1  christos     TactN1 = TretN
    692  1.1  christos     TretN1 = "now+4460h"
    693  1.1  christos     TremN1 = "now+5087h"
    694  1.1  christos     keytimes = (
    695  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    696  1.1  christos     )
    697  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    698  1.1  christos     # Key generation.
    699  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    700  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    701  1.1  christos     settime(
    702  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z UNRETENTIVE {TactN1} -d UNRETENTIVE {TactN1} -D ds {TactN1} {csk1_name}",
    703  1.1  christos         cwd="ns3",
    704  1.1  christos     )
    705  1.1  christos     settime(
    706  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}",
    707  1.1  christos         cwd="ns3",
    708  1.1  christos     )
    709  1.1  christos     # Set key rollover relationship.
    710  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    711  1.1  christos     # Signing.
    712  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    713  1.1  christos 
    714  1.1  christos     # Step 5:
    715  1.1  christos     # After the DS is swapped in step 4, also the KRRSIG records can be removed.
    716  1.1  christos     # At this time these have all become hidden.
    717  1.1  christos     zonename = f"step5.{zone}"
    718  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    719  1.1  christos     isctest.log.info(f"setup {zonename}")
    720  1.1  christos     # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
    721  1.1  christos     TpubN = "now-4470h"
    722  1.1  christos     TactN = "now-4445h"
    723  1.1  christos     TretN = "now-6h"
    724  1.1  christos     TremN = "now+621h"
    725  1.1  christos     TpubN1 = "now-9h"
    726  1.1  christos     TactN1 = TretN
    727  1.1  christos     TretN1 = "now+4458h"
    728  1.1  christos     TremN1 = "now+5085h"
    729  1.1  christos     keytimes = (
    730  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    731  1.1  christos     )
    732  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    733  1.1  christos     # Key generation.
    734  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    735  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    736  1.1  christos     settime(
    737  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r UNRETENTIVE now-2h -z UNRETENTIVE {TactN1} -d HIDDEN now-2h {csk1_name}",
    738  1.1  christos         cwd="ns3",
    739  1.1  christos     )
    740  1.1  christos     settime(
    741  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d OMNIPRESENT now-2h {csk2_name}",
    742  1.1  christos         cwd="ns3",
    743  1.1  christos     )
    744  1.1  christos     # Set key rollover relationship.
    745  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    746  1.1  christos     # Signing.
    747  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    748  1.1  christos 
    749  1.1  christos     # Step 6:
    750  1.1  christos     # After the retire interval has passed the predecessor DNSKEY can be
    751  1.1  christos     # removed from the zone.
    752  1.1  christos     zonename = f"step6.{zone}"
    753  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    754  1.1  christos     isctest.log.info(f"setup {zonename}")
    755  1.1  christos     # According to RFC 7583:
    756  1.1  christos     # Trem(N) = Tret(N) + IretZ
    757  1.1  christos     # Tret(N) = Tact(N) + Lcsk
    758  1.1  christos     #
    759  1.1  christos     # Lcsk:   186d
    760  1.1  christos     # Iret:   4h
    761  1.1  christos     # IretZ:  26d3h
    762  1.1  christos     #
    763  1.1  christos     # Tpub(N)   = now - IretZ - Lcsk = now - 627h - 186d
    764  1.1  christos     #           = now - 627h - 4464h = now - 5091h
    765  1.1  christos     # Tact(N)   = now - 627h - 186d
    766  1.1  christos     # Tret(N)   = now - IretZ = now - 627h
    767  1.1  christos     # Trem(N)   = now
    768  1.1  christos     # Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h
    769  1.1  christos     # Tact(N+1) = Tret(N)
    770  1.1  christos     # Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h
    771  1.1  christos     # Trem(N+1) = now + Lcsk = now + 186d
    772  1.1  christos     TpubN = "now-5091h"
    773  1.1  christos     TactN = "now-5066h"
    774  1.1  christos     TretN = "now-627h"
    775  1.1  christos     TremN = "now"
    776  1.1  christos     TpubN1 = "now-630h"
    777  1.1  christos     TactN1 = TretN
    778  1.1  christos     TretN1 = "now+3837h"
    779  1.1  christos     TremN1 = "now+186d"
    780  1.1  christos     keytimes = (
    781  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    782  1.1  christos     )
    783  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    784  1.1  christos     # Key generation.
    785  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    786  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    787  1.1  christos     settime(
    788  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r HIDDEN {TremN} -z UNRETENTIVE {TactN1} -d HIDDEN {TremN} {csk1_name}",
    789  1.1  christos         cwd="ns3",
    790  1.1  christos     )
    791  1.1  christos     settime(
    792  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d OMNIPRESENT {TremN} {csk2_name}",
    793  1.1  christos         cwd="ns3",
    794  1.1  christos     )
    795  1.1  christos     # Set key rollover relationship.
    796  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    797  1.1  christos     # Signing.
    798  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    799  1.1  christos 
    800  1.1  christos     # Step 7:
    801  1.1  christos     # Some time later the predecessor DNSKEY enters the HIDDEN state.
    802  1.1  christos     zonename = f"step7.{zone}"
    803  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    804  1.1  christos     isctest.log.info(f"setup {zonename}")
    805  1.1  christos     # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
    806  1.1  christos     TpubN = "now-5093h"
    807  1.1  christos     TactN = "now-5068h"
    808  1.1  christos     TretN = "now-629h"
    809  1.1  christos     TremN = "now-2h"
    810  1.1  christos     TpubN1 = "now-632h"
    811  1.1  christos     TactN1 = TretN
    812  1.1  christos     TretN1 = "now+3835h"
    813  1.1  christos     TremN1 = "now+4462h"
    814  1.1  christos     keytimes = (
    815  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    816  1.1  christos     )
    817  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    818  1.1  christos     # Key generation.
    819  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    820  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    821  1.1  christos     settime(
    822  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}",
    823  1.1  christos         cwd="ns3",
    824  1.1  christos     )
    825  1.1  christos     settime(
    826  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {csk2_name}",
    827  1.1  christos         cwd="ns3",
    828  1.1  christos     )
    829  1.1  christos     # Set key rollover relationship.
    830  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    831  1.1  christos     # Signing.
    832  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    833  1.1  christos 
    834  1.1  christos     # Step 8:
    835  1.1  christos     # The predecessor DNSKEY can be purged.
    836  1.1  christos     zonename = f"step8.{zone}"
    837  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    838  1.1  christos     isctest.log.info(f"setup {zonename}")
    839  1.1  christos     # Subtract purge-keys interval from all the times (1h).
    840  1.1  christos     TpubN = "now-5094h"
    841  1.1  christos     TactN = "now-5069h"
    842  1.1  christos     TretN = "now-630h"
    843  1.1  christos     TremN = "now-3h"
    844  1.1  christos     TpubN1 = "now-633h"
    845  1.1  christos     TactN1 = TretN
    846  1.1  christos     TretN1 = "now+3834h"
    847  1.1  christos     TremN1 = "now+4461h"
    848  1.1  christos     keytimes = (
    849  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    850  1.1  christos     )
    851  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    852  1.1  christos     # Key generation.
    853  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    854  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    855  1.1  christos     settime(
    856  1.1  christos         f"-g HIDDEN -k HIDDEN {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}",
    857  1.1  christos         cwd="ns3",
    858  1.1  christos     )
    859  1.1  christos     settime(
    860  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {csk2_name}",
    861  1.1  christos         cwd="ns3",
    862  1.1  christos     )
    863  1.1  christos     # Set key rollover relationship.
    864  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    865  1.1  christos     # Signing.
    866  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    867  1.1  christos 
    868  1.1  christos     return zones
    869  1.1  christos 
    870  1.1  christos 
    871  1.1  christos def configure_cskroll2(tld: str, policy: str) -> List[Zone]:
    872  1.1  christos     # The zones at csk-roll2.$tld represent the various steps of a CSK rollover
    873  1.1  christos     # (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
    874  1.1  christos     # This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG)
    875  1.1  christos     # are replaced with the new key sooner than the DS is swapped.
    876  1.1  christos     zones = []
    877  1.1  christos     zone = f"csk-roll2.{tld}"
    878  1.1  christos     cds = "cdnskey,cds:sha-256,cds:sha-384"
    879  1.1  christos     keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf")
    880  1.1  christos     settime = EnvCmd("SETTIME", "-s")
    881  1.1  christos 
    882  1.1  christos     # Step 1:
    883  1.1  christos     # Introduce the first key. This will immediately be active.
    884  1.1  christos     zonename = f"step1.{zone}"
    885  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    886  1.1  christos     isctest.log.info(f"setup {zonename}")
    887  1.1  christos     TactN = "now-7d"
    888  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
    889  1.1  christos     # Key generation.
    890  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    891  1.1  christos     settime(
    892  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}",
    893  1.1  christos         cwd="ns3",
    894  1.1  christos     )
    895  1.1  christos     # Signing.
    896  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}")
    897  1.1  christos 
    898  1.1  christos     # Step 2:
    899  1.1  christos     # It is time to introduce the new CSK.
    900  1.1  christos     zonename = f"step2.{zone}"
    901  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    902  1.1  christos     isctest.log.info(f"setup {zonename}")
    903  1.1  christos     # According to RFC 7583:
    904  1.1  christos     # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
    905  1.1  christos     # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
    906  1.1  christos     # IpubC = DprpC + TTLkey (+publish-safety)
    907  1.1  christos     # Ipub  = IpubC
    908  1.1  christos     # Lcsk = Lksk = Lzsk
    909  1.1  christos     #
    910  1.1  christos     # Lcsk:           6mo (186d, 4464h)
    911  1.1  christos     # Dreg:           N/A
    912  1.1  christos     # DprpC:          1h
    913  1.1  christos     # TTLkey:         1h
    914  1.1  christos     # publish-safety: 1h
    915  1.1  christos     # Ipub:           3h
    916  1.1  christos     #
    917  1.1  christos     # Tact(N)  = now - Lcsk + Ipub = now - 186d + 3h
    918  1.1  christos     #          = now - 4464h + 3h = now - 4461h
    919  1.1  christos     TactN = "now-4461h"
    920  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
    921  1.1  christos     # Key generation.
    922  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    923  1.1  christos     settime(
    924  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk_name}",
    925  1.1  christos         cwd="ns3",
    926  1.1  christos     )
    927  1.1  christos     # Signing.
    928  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options=f"-z -G {cds}")
    929  1.1  christos 
    930  1.1  christos     # Step 3:
    931  1.1  christos     # It is time to submit the DS and to roll signatures.
    932  1.1  christos     zonename = f"step3.{zone}"
    933  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    934  1.1  christos     isctest.log.info(f"setup {zonename}")
    935  1.1  christos     # According to RFC 7583:
    936  1.1  christos     #
    937  1.1  christos     # Tsbm(N+1) >= Trdy(N+1)
    938  1.1  christos     # KSK: Tact(N+1) = Tsbm(N+1)
    939  1.1  christos     # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1)
    940  1.1  christos     # KSK: Iret  = DprpP + TTLds (+retire-safety)
    941  1.1  christos     # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety)
    942  1.1  christos     #
    943  1.1  christos     # Lcsk:           186d
    944  1.1  christos     # Dprp:           1h
    945  1.1  christos     # DprpP:          1w
    946  1.1  christos     # Dreg:           N/A
    947  1.1  christos     # Dsgn:           12h
    948  1.1  christos     # TTLds:          1h
    949  1.1  christos     # TTLsig:         1d
    950  1.1  christos     # retire-safety:  1h
    951  1.1  christos     # Iret:           170h
    952  1.1  christos     # IretZ:          38h
    953  1.1  christos     # Ipub:           3h
    954  1.1  christos     #
    955  1.1  christos     # Tpub(N)   = now - Lcsk = now - 186d
    956  1.1  christos     # Tact(N)   = now - Lcsk + Dprp + TTLsig = now - 4439h
    957  1.1  christos     # Tret(N)   = now
    958  1.1  christos     # Trem(N)   = now + IretZ = now + 26d3h = now + 627h
    959  1.1  christos     # Tpub(N+1) = now - Ipub = now - 3h
    960  1.1  christos     # Tact(N+1) = Tret(N)
    961  1.1  christos     # Tret(N+1) = now + Lcsk = now + 186d = now + 186d
    962  1.1  christos     # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h =
    963  1.1  christos     #           = now + 5091h
    964  1.1  christos     TpubN = "now-186d"
    965  1.1  christos     TactN = "now-4439h"
    966  1.1  christos     TretN = "now"
    967  1.1  christos     TremN = "now+170h"
    968  1.1  christos     TpubN1 = "now-3h"
    969  1.1  christos     TactN1 = TretN
    970  1.1  christos     TretN1 = "now+186d"
    971  1.1  christos     TremN1 = "now+4634h"
    972  1.1  christos     keytimes = (
    973  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
    974  1.1  christos     )
    975  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
    976  1.1  christos     # Key generation.
    977  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
    978  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
    979  1.1  christos     settime(
    980  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {csk1_name}",
    981  1.1  christos         cwd="ns3",
    982  1.1  christos     )
    983  1.1  christos     settime(
    984  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -z HIDDEN {TpubN1} -d HIDDEN {TpubN1} {csk2_name}",
    985  1.1  christos         cwd="ns3",
    986  1.1  christos     )
    987  1.1  christos     # Set key rollover relationship.
    988  1.1  christos     set_key_relationship(csk1_name, csk2_name)
    989  1.1  christos     # Signing.
    990  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
    991  1.1  christos 
    992  1.1  christos     # Step 4:
    993  1.1  christos     # Some time later all the ZRRSIG records should be from the new CSK, and the
    994  1.1  christos     # DS should be swapped.  The ZRRSIG records are all replaced after IretZ (38h).
    995  1.1  christos     # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone
    996  1.1  christos     # signatures are replaced before the DS is swapped.
    997  1.1  christos     zonename = f"step4.{zone}"
    998  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
    999  1.1  christos     isctest.log.info(f"setup {zonename}")
   1000  1.1  christos     # According to RFC 7583:
   1001  1.1  christos     # Trem(N)    = Tret(N) + IretZ
   1002  1.1  christos     #
   1003  1.1  christos     # Lcsk:   186d
   1004  1.1  christos     # Dreg:   N/A
   1005  1.1  christos     # Iret:   170h
   1006  1.1  christos     # IretZ:  38h
   1007  1.1  christos     #
   1008  1.1  christos     # Tpub(N)    = now - IretZ - Lcsk = now - 38h - 186d
   1009  1.1  christos     #            = now - 38h - 4464h = now - 4502h
   1010  1.1  christos     # Tact(N)    = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h
   1011  1.1  christos     # Tret(N)    = now - IretZ = now - 38h
   1012  1.1  christos     # Trem(N)    = now - IretZ + Iret = now - 38h + 170h = now + 132h
   1013  1.1  christos     # Tpub(N+1)  = now - IretZ - IpubC = now - 38h - 3h = now - 41h
   1014  1.1  christos     # Tact(N+1)  = Tret(N)
   1015  1.1  christos     # Tret(N+1)  = now - IretZ + Lcsk = now - 38h + 186d
   1016  1.1  christos     #            = now + 4426h
   1017  1.1  christos     # Trem(N+1)  = now - IretZ + Lcsk + Iret
   1018  1.1  christos     #            = now + 4426h + 3h = now + 4429h
   1019  1.1  christos     TpubN = "now-4502h"
   1020  1.1  christos     TactN = "now-4477h"
   1021  1.1  christos     TretN = "now-38h"
   1022  1.1  christos     TremN = "now+132h"
   1023  1.1  christos     TpubN1 = "now-41h"
   1024  1.1  christos     TactN1 = TretN
   1025  1.1  christos     TretN1 = "now+4426h"
   1026  1.1  christos     TremN1 = "now+4429h"
   1027  1.1  christos     keytimes = (
   1028  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1029  1.1  christos     )
   1030  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
   1031  1.1  christos     # Key generation.
   1032  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1033  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1034  1.1  christos     settime(
   1035  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z UNRETENTIVE {TretN} -d UNRETENTIVE {TretN} -D ds {TretN} {csk1_name}",
   1036  1.1  christos         cwd="ns3",
   1037  1.1  christos     )
   1038  1.1  christos     settime(
   1039  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z RUMOURED {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}",
   1040  1.1  christos         cwd="ns3",
   1041  1.1  christos     )
   1042  1.1  christos     # Set key rollover relationship.
   1043  1.1  christos     set_key_relationship(csk1_name, csk2_name)
   1044  1.1  christos     # Signing.
   1045  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
   1046  1.1  christos 
   1047  1.1  christos     # Step 5:
   1048  1.1  christos     # Some time later the DS can be swapped and the old DNSKEY can be removed from
   1049  1.1  christos     # the zone.
   1050  1.1  christos     zonename = f"step5.{zone}"
   1051  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1052  1.1  christos     isctest.log.info(f"setup {zonename}")
   1053  1.1  christos     # Subtract Iret (170h) - IretZ (38h) = 132h.
   1054  1.1  christos     #
   1055  1.1  christos     # Tpub(N)   = now - 4502h - 132h = now - 4634h
   1056  1.1  christos     # Tact(N)   = now - 4477h - 132h = now - 4609h
   1057  1.1  christos     # Tret(N)   = now - 38h - 132h = now - 170h
   1058  1.1  christos     # Trem(N)   = now + 132h - 132h = now
   1059  1.1  christos     # Tpub(N+1) = now - 41h - 132h = now - 173h
   1060  1.1  christos     # Tact(N+1) = Tret(N)
   1061  1.1  christos     # Tret(N+1) = now + 4426h - 132h = now + 4294h
   1062  1.1  christos     # Trem(N+1) = now + 4492h - 132h = now + 4360h
   1063  1.1  christos     TpubN = "now-4634h"
   1064  1.1  christos     TactN = "now-4609h"
   1065  1.1  christos     TretN = "now-170h"
   1066  1.1  christos     TremN = "now"
   1067  1.1  christos     TpubN1 = "now-173h"
   1068  1.1  christos     TactN1 = TretN
   1069  1.1  christos     TretN1 = "now+4294h"
   1070  1.1  christos     TremN1 = "now+4360h"
   1071  1.1  christos     keytimes = (
   1072  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1073  1.1  christos     )
   1074  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
   1075  1.1  christos     # Key generation.
   1076  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1077  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1078  1.1  christos     settime(
   1079  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -z HIDDEN now-133h -d UNRETENTIVE {TactN1} -D ds {TactN1} {csk1_name}",
   1080  1.1  christos         cwd="ns3",
   1081  1.1  christos     )
   1082  1.1  christos     settime(
   1083  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-133h -d RUMOURED {TactN1} -P ds {TactN1} {csk2_name}",
   1084  1.1  christos         cwd="ns3",
   1085  1.1  christos     )
   1086  1.1  christos     # Set key rollover relationship.
   1087  1.1  christos     set_key_relationship(csk1_name, csk2_name)
   1088  1.1  christos     # Signing.
   1089  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
   1090  1.1  christos 
   1091  1.1  christos     # Step 6:
   1092  1.1  christos     # Some time later the predecessor DNSKEY enters the HIDDEN state.
   1093  1.1  christos     zonename = f"step6.{zone}"
   1094  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1095  1.1  christos     isctest.log.info(f"setup {zonename}")
   1096  1.1  christos     # Subtract DNSKEY TTL plus zone propagation delay (2h).
   1097  1.1  christos     #
   1098  1.1  christos     # Tpub(N)   = now - 4634h - 2h = now - 4636h
   1099  1.1  christos     # Tact(N)   = now - 4609h - 2h = now - 4611h
   1100  1.1  christos     # Tret(N)   = now - 170h - 2h = now - 172h
   1101  1.1  christos     # Trem(N)   = now - 2h
   1102  1.1  christos     # Tpub(N+1) = now - 173h - 2h = now - 175h
   1103  1.1  christos     # Tact(N+1) = Tret(N)
   1104  1.1  christos     # Tret(N+1) = now + 4294h - 2h = now + 4292h
   1105  1.1  christos     # Trem(N+1) = now + 4360h - 2h = now + 4358h
   1106  1.1  christos     TpubN = "now-4636h"
   1107  1.1  christos     TactN = "now-4611h"
   1108  1.1  christos     TretN = "now-172h"
   1109  1.1  christos     TremN = "now-2h"
   1110  1.1  christos     TpubN1 = "now-175h"
   1111  1.1  christos     TactN1 = TretN
   1112  1.1  christos     TretN1 = "now+4292h"
   1113  1.1  christos     TremN1 = "now+4358h"
   1114  1.1  christos     keytimes = (
   1115  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1116  1.1  christos     )
   1117  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
   1118  1.1  christos     # Key generation.
   1119  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1120  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1121  1.1  christos     settime(
   1122  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-135h -d HIDDEN {TremN} {csk1_name}",
   1123  1.1  christos         cwd="ns3",
   1124  1.1  christos     )
   1125  1.1  christos     settime(
   1126  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-135h -d OMNIPRESENT {TremN} {csk2_name}",
   1127  1.1  christos         cwd="ns3",
   1128  1.1  christos     )
   1129  1.1  christos     # Set key rollover relationship.
   1130  1.1  christos     set_key_relationship(csk1_name, csk2_name)
   1131  1.1  christos     # Signing.
   1132  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
   1133  1.1  christos 
   1134  1.1  christos     # Step 7:
   1135  1.1  christos     # The predecessor DNSKEY can be purged, but purge-keys is disabled.
   1136  1.1  christos     zonename = f"step7.{zone}"
   1137  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1138  1.1  christos     isctest.log.info(f"setup {zonename}")
   1139  1.1  christos     # Subtract 90 days (default, 2160h) from all the times.
   1140  1.1  christos     #
   1141  1.1  christos     # Tpub(N)   = now - 4636h - 2160h = now - 6796h
   1142  1.1  christos     # Tact(N)   = now - 4611h - 2160h = now - 6771h
   1143  1.1  christos     # Tret(N)   = now - 172h - 2160h = now - 2332h
   1144  1.1  christos     # Trem(N)   = now - 2h - 2160h = now - 2162h
   1145  1.1  christos     # Tpub(N+1) = now - 175h - 2160h = now - 2335h
   1146  1.1  christos     # Tact(N+1) = Tret(N)
   1147  1.1  christos     # Tret(N+1) = now + 4292h - 2160h = now + 2132h
   1148  1.1  christos     # Trem(N+1) = now + 4358h - 2160h = now + 2198h
   1149  1.1  christos     TpubN = "now-6796h"
   1150  1.1  christos     TactN = "now-6771h"
   1151  1.1  christos     TretN = "now-2332h"
   1152  1.1  christos     TremN = "now-2162h"
   1153  1.1  christos     TpubN1 = "now-2335h"
   1154  1.1  christos     TactN1 = TretN
   1155  1.1  christos     TretN1 = "now+2132h"
   1156  1.1  christos     TremN1 = "now+2198h"
   1157  1.1  christos 
   1158  1.1  christos     keytimes = (
   1159  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1160  1.1  christos     )
   1161  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
   1162  1.1  christos     # Key generation.
   1163  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1164  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1165  1.1  christos     settime(
   1166  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TremN} -r HIDDEN {TremN} -z HIDDEN {TactN1} -d HIDDEN {TremN} {csk1_name}",
   1167  1.1  christos         cwd="ns3",
   1168  1.1  christos     )
   1169  1.1  christos     settime(
   1170  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT {TactN1} -d OMNIPRESENT {TremN} {csk2_name}",
   1171  1.1  christos         cwd="ns3",
   1172  1.1  christos     )
   1173  1.1  christos     # Set key rollover relationship.
   1174  1.1  christos     set_key_relationship(csk1_name, csk2_name)
   1175  1.1  christos     # Signing.
   1176  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
   1177  1.1  christos 
   1178  1.1  christos     # Step 8:
   1179  1.1  christos     # The predecessor DNSKEY can be purged.
   1180  1.1  christos     zonename = f"step8.{zone}"
   1181  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1182  1.1  christos     isctest.log.info(f"setup {zonename}")
   1183  1.1  christos     # Subtract purge-keys interval from all the times (1h).
   1184  1.1  christos     TpubN = "now-5094h"
   1185  1.1  christos     TactN = "now-5069h"
   1186  1.1  christos     TretN = "now-630h"
   1187  1.1  christos     TremN = "now-3h"
   1188  1.1  christos     TpubN1 = "now-633h"
   1189  1.1  christos     TactN1 = TretN
   1190  1.1  christos     TretN1 = "now+3834h"
   1191  1.1  christos     TremN1 = "now+4461h"
   1192  1.1  christos     keytimes = (
   1193  1.1  christos         f"-P {TpubN} -P sync {TactN} -A {TpubN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1194  1.1  christos     )
   1195  1.1  christos     newtimes = f"-P {TpubN1} -P sync {TactN1} -A {TactN1} -I {TretN1} -D {TremN1}"
   1196  1.1  christos     # Key generation.
   1197  1.1  christos     csk1_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1198  1.1  christos     csk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1199  1.1  christos     settime(
   1200  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TremN} -r UNRETENTIVE {TremN} -z HIDDEN now-2295h -d HIDDEN {TremN} {csk1_name}",
   1201  1.1  christos         cwd="ns3",
   1202  1.1  christos     )
   1203  1.1  christos     settime(
   1204  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -z OMNIPRESENT now-2295h -d OMNIPRESENT {TremN} {csk2_name}",
   1205  1.1  christos         cwd="ns3",
   1206  1.1  christos     )
   1207  1.1  christos     # Set key rollover relationship.
   1208  1.1  christos     set_key_relationship(csk1_name, csk2_name)
   1209  1.1  christos     # Signing.
   1210  1.1  christos     render_and_sign_zone(zonename, [csk1_name, csk2_name], extra_options=f"-z -G {cds}")
   1211  1.1  christos 
   1212  1.1  christos     return zones
   1213  1.1  christos 
   1214  1.1  christos 
   1215  1.1  christos def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]:
   1216  1.1  christos     # The zones at enable-dnssec.$tld represent the various steps of the
   1217  1.1  christos     # initial signing of a zone.
   1218  1.1  christos     zones = []
   1219  1.1  christos     zone = f"enable-dnssec.{tld}"
   1220  1.1  christos     keygen = EnvCmd("KEYGEN", f"-k {policy} -l kasp.conf")
   1221  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1222  1.1  christos 
   1223  1.1  christos     # Step 1:
   1224  1.1  christos     # This is an unsigned zone and named should perform the initial steps of
   1225  1.1  christos     # introducing the DNSSEC records in the right order.
   1226  1.1  christos     zonename = f"step1.{zone}"
   1227  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1228  1.1  christos     isctest.log.info(f"setup {zonename}")
   1229  1.1  christos     render_and_sign_zone(zonename, [], signing=False)
   1230  1.1  christos 
   1231  1.1  christos     # Step 2:
   1232  1.1  christos     # The DNSKEY has been published long enough to become OMNIPRESENT.
   1233  1.1  christos     zonename = f"step2.{zone}"
   1234  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1235  1.1  christos     isctest.log.info(f"setup {zonename}")
   1236  1.1  christos     # DNSKEY TTL:             300 seconds
   1237  1.1  christos     # zone-propagation-delay: 5 minutes (300 seconds)
   1238  1.1  christos     # publish-safety:         5 minutes (300 seconds)
   1239  1.1  christos     # Total:                  900 seconds
   1240  1.1  christos     TpubN = "now-900s"
   1241  1.1  christos     keytimes = f"-P {TpubN} -A {TpubN}"
   1242  1.1  christos     # Key generation.
   1243  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1244  1.1  christos     settime(
   1245  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN} -r RUMOURED {TpubN} -z RUMOURED {TpubN} -d HIDDEN {TpubN} {csk_name}",
   1246  1.1  christos         cwd="ns3",
   1247  1.1  christos     )
   1248  1.1  christos     # Signing.
   1249  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
   1250  1.1  christos 
   1251  1.1  christos     # Step 3:
   1252  1.1  christos     # The zone signatures have been published long enough to become OMNIPRESENT.
   1253  1.1  christos     zonename = f"step3.{zone}"
   1254  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1255  1.1  christos     isctest.log.info(f"setup {zonename}")
   1256  1.1  christos     # Passed time since publication:
   1257  1.1  christos     # max-zone-ttl:           12 hours (43200 seconds)
   1258  1.1  christos     # zone-propagation-delay: 5 minutes (300 seconds)
   1259  1.1  christos     # We can submit the DS now.
   1260  1.1  christos     TpubN = "now-43500s"
   1261  1.1  christos     keytimes = f"-P {TpubN} -A {TpubN}"
   1262  1.1  christos     # Key generation.
   1263  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1264  1.1  christos     settime(
   1265  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z RUMOURED {TpubN} -d HIDDEN {TpubN} {csk_name}",
   1266  1.1  christos         cwd="ns3",
   1267  1.1  christos     )
   1268  1.1  christos     # Signing.
   1269  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
   1270  1.1  christos 
   1271  1.1  christos     # Step 4:
   1272  1.1  christos     # The DS has been submitted long enough ago to become OMNIPRESENT.
   1273  1.1  christos     zonename = f"step4.{zone}"
   1274  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1275  1.1  christos     isctest.log.info(f"setup {zonename}")
   1276  1.1  christos     # DS TTL:                    2 hour (7200 seconds)
   1277  1.1  christos     # parent-propagation-delay:  1 hour (3600 seconds)
   1278  1.1  christos     # Total aditional time:      10800 seconds
   1279  1.1  christos     # 43500 + 10800 = 54300
   1280  1.1  christos     TpubN = "now-54300s"
   1281  1.1  christos     TsbmN = "now-10800s"
   1282  1.1  christos     keytimes = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}"
   1283  1.1  christos     # Key generation.
   1284  1.1  christos     csk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1285  1.1  christos     settime(
   1286  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TsbmN} -d RUMOURED {TpubN} -P ds {TsbmN} {csk_name}",
   1287  1.1  christos         cwd="ns3",
   1288  1.1  christos     )
   1289  1.1  christos     # Signing.
   1290  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
   1291  1.1  christos 
   1292  1.1  christos     return zones
   1293  1.1  christos 
   1294  1.1  christos 
   1295  1.1  christos def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]:
   1296  1.1  christos     zones = []
   1297  1.1  christos     keygen = EnvCmd("KEYGEN", "-a ECDSA256 -L 7200")
   1298  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1299  1.1  christos 
   1300  1.1  christos     # The child zones (step1, step2) beneath these zones represent the various
   1301  1.1  christos     # steps of unsigning a zone.
   1302  1.1  christos     for zone in [f"going-insecure.{tld}", f"going-insecure-dynamic.{tld}"]:
   1303  1.1  christos         # Set up a zone with dnssec-policy that is going insecure.
   1304  1.1  christos 
   1305  1.1  christos         # Step 1:
   1306  1.1  christos         zonename = f"step1.{zone}"
   1307  1.1  christos         zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1308  1.1  christos         isctest.log.info(f"setup {zonename}")
   1309  1.1  christos         # Timing metadata.
   1310  1.1  christos         TpubN = "now-10d"
   1311  1.1  christos         TsbmN = "now-12955mi"
   1312  1.1  christos         keytimes = f"-P {TpubN} -A {TpubN}"
   1313  1.1  christos         cdstimes = f"-P sync {TsbmN}"
   1314  1.1  christos         # Key generation.
   1315  1.1  christos         ksk_name = keygen(
   1316  1.1  christos             f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3"
   1317  1.1  christos         ).out.strip()
   1318  1.1  christos         zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1319  1.1  christos         settime(
   1320  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {ksk_name}",
   1321  1.1  christos             cwd="ns3",
   1322  1.1  christos         )
   1323  1.1  christos         settime(
   1324  1.1  christos             f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
   1325  1.1  christos             cwd="ns3",
   1326  1.1  christos         )
   1327  1.1  christos         # Signing.
   1328  1.1  christos         render_and_sign_zone(zonename, [ksk_name, zsk_name])
   1329  1.1  christos 
   1330  1.1  christos         if reconfig:
   1331  1.1  christos             # Step 2:
   1332  1.1  christos             zonename = f"step2.{zone}"
   1333  1.1  christos             zones.append(
   1334  1.1  christos                 Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))
   1335  1.1  christos             )
   1336  1.1  christos             isctest.log.info(f"setup {zonename}")
   1337  1.1  christos             # The DS was withdrawn from the parent zone 26 hours ago.
   1338  1.1  christos             TremN = "now-26h"
   1339  1.1  christos             keytimes = f"-P {TpubN} -A {TpubN} -I {TremN} -D now"
   1340  1.1  christos             cdstimes = f"-P sync {TsbmN} -D sync {TremN}"
   1341  1.1  christos             # Key generation.
   1342  1.1  christos             ksk_name = keygen(
   1343  1.1  christos                 f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3"
   1344  1.1  christos             ).out.strip()
   1345  1.1  christos             zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1346  1.1  christos             settime(
   1347  1.1  christos                 f"-g HIDDEN -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d UNRETENTIVE {TremN} -D ds {TremN} {ksk_name}",
   1348  1.1  christos                 cwd="ns3",
   1349  1.1  christos             )
   1350  1.1  christos             settime(
   1351  1.1  christos                 f"-g HIDDEN -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
   1352  1.1  christos                 cwd="ns3",
   1353  1.1  christos             )
   1354  1.1  christos             # Fake lifetime of old algorithm keys.
   1355  1.1  christos             fake_lifetime(ksk_name, 0)
   1356  1.1  christos             fake_lifetime(zsk_name, 5184000)
   1357  1.1  christos             # Signing.
   1358  1.1  christos             render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options="-P")
   1359  1.1  christos 
   1360  1.1  christos     return zones
   1361  1.1  christos 
   1362  1.1  christos 
   1363  1.1  christos def configure_straight2none(tld: str) -> List[Zone]:
   1364  1.1  christos     # These zones are going straight to "none" policy. This is undefined behavior.
   1365  1.1  christos     zones = []
   1366  1.1  christos     keygen = EnvCmd("KEYGEN", "-k default")
   1367  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1368  1.1  christos 
   1369  1.1  christos     TpubN = "now-10d"
   1370  1.1  christos     TsbmN = "now-12955mi"
   1371  1.1  christos     keytimes = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}"
   1372  1.1  christos 
   1373  1.1  christos     zonename = f"going-straight-to-none.{tld}"
   1374  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1375  1.1  christos     isctest.log.info(f"setup {zonename}")
   1376  1.1  christos     # Key generation.
   1377  1.1  christos     csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1378  1.1  christos     settime(
   1379  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {csk_name}",
   1380  1.1  christos         cwd="ns3",
   1381  1.1  christos     )
   1382  1.1  christos     # Signing.
   1383  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
   1384  1.1  christos 
   1385  1.1  christos     zonename = f"going-straight-to-none-dynamic.{tld}"
   1386  1.1  christos     zones.append(
   1387  1.1  christos         Zone(zonename, f"{zonename}.db.signed", Nameserver("ns3", "10.53.0.3"))
   1388  1.1  christos     )
   1389  1.1  christos     isctest.log.info(f"setup {zonename}")
   1390  1.1  christos     # Key generation.
   1391  1.1  christos     csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1392  1.1  christos     settime(
   1393  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {csk_name}",
   1394  1.1  christos         cwd="ns3",
   1395  1.1  christos     )
   1396  1.1  christos     # Signing.
   1397  1.1  christos     render_and_sign_zone(zonename, [csk_name], extra_options="-z -O full")
   1398  1.1  christos 
   1399  1.1  christos     return zones
   1400  1.1  christos 
   1401  1.1  christos 
   1402  1.1  christos def configure_ksk_doubleksk(tld: str) -> List[Zone]:
   1403  1.1  christos     # The zones at ksk-doubleksk.$tld represent the various steps of a KSK
   1404  1.1  christos     # Double-KSK rollover.
   1405  1.1  christos     zones = []
   1406  1.1  christos     zone = f"ksk-doubleksk.{tld}"
   1407  1.1  christos     cds = "cds:sha-256"
   1408  1.1  christos     keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 7200")
   1409  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1410  1.1  christos 
   1411  1.1  christos     # Step 1:
   1412  1.1  christos     # Introduce the first key. This will immediately be active.
   1413  1.1  christos     zonename = f"step1.{zone}"
   1414  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1415  1.1  christos     isctest.log.info(f"setup {zonename}")
   1416  1.1  christos     # Timing metadata.
   1417  1.1  christos     TactN = "now-7d"
   1418  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1419  1.1  christos     # Key generation.
   1420  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1421  1.1  christos     zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1422  1.1  christos     settime(
   1423  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1424  1.1  christos         cwd="ns3",
   1425  1.1  christos     )
   1426  1.1  christos     settime(
   1427  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1428  1.1  christos         cwd="ns3",
   1429  1.1  christos     )
   1430  1.1  christos     # Signing.
   1431  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}")
   1432  1.1  christos 
   1433  1.1  christos     # Step 2:
   1434  1.1  christos     # It is time to introduce the new KSK.
   1435  1.1  christos     zonename = f"step2.{zone}"
   1436  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1437  1.1  christos     isctest.log.info(f"setup {zonename}")
   1438  1.1  christos     # Lksk:           60d
   1439  1.1  christos     # Dreg:           n/a
   1440  1.1  christos     # DprpC:          1h
   1441  1.1  christos     # TTLds:          1d
   1442  1.1  christos     # TTLkey:         2h
   1443  1.1  christos     # publish-safety: 1d
   1444  1.1  christos     # retire-safety:  2d
   1445  1.1  christos     #
   1446  1.1  christos     # According to RFC 7583:
   1447  1.1  christos     # Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
   1448  1.1  christos     # IpubC = DprpC + TTLkey (+publish-safety)
   1449  1.1  christos     #
   1450  1.1  christos     # IpubC   = 27h
   1451  1.1  christos     # Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h
   1452  1.1  christos     #         = now - 1440h + 27h = now - 1413h
   1453  1.1  christos     TactN = "now-1413h"
   1454  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1455  1.1  christos     # Key generation.
   1456  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1457  1.1  christos     zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1458  1.1  christos     settime(
   1459  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1460  1.1  christos         cwd="ns3",
   1461  1.1  christos     )
   1462  1.1  christos     settime(
   1463  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1464  1.1  christos         cwd="ns3",
   1465  1.1  christos     )
   1466  1.1  christos     # Signing.
   1467  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options=f"-G {cds}")
   1468  1.1  christos 
   1469  1.1  christos     # Step 3:
   1470  1.1  christos     # It is time to submit the DS.
   1471  1.1  christos     zonename = f"step3.{zone}"
   1472  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1473  1.1  christos     isctest.log.info(f"setup {zonename}")
   1474  1.1  christos     # According to RFC 7583:
   1475  1.1  christos     # Iret = DprpP + TTLds (+retire-safety)
   1476  1.1  christos     #
   1477  1.1  christos     # Iret       = 50h
   1478  1.1  christos     # Tpub(N)    = now - Lksk = now - 60d = now - 60d
   1479  1.1  christos     # Tact(N)    = now - 1413h
   1480  1.1  christos     # Tret(N)    = now
   1481  1.1  christos     # Trem(N)    = now + Iret = now + 50h
   1482  1.1  christos     # Tpub(N+1)  = now - IpubC = now - 27h
   1483  1.1  christos     # Tact(N+1)  = now
   1484  1.1  christos     # Tret(N+1)  = now + Lksk = now + 60d
   1485  1.1  christos     # Trem(N+1)  = now + Lksk + Iret = now + 60d + 50h
   1486  1.1  christos     #            = now + 1440h + 50h = 1490h
   1487  1.1  christos     TpubN = "now-60d"
   1488  1.1  christos     TactN = "now-1413h"
   1489  1.1  christos     TretN = "now"
   1490  1.1  christos     TremN = "now+50h"
   1491  1.1  christos     TpubN1 = "now-27h"
   1492  1.1  christos     TactN1 = "now"
   1493  1.1  christos     TretN1 = "now+60d"
   1494  1.1  christos     TremN1 = "now+1490h"
   1495  1.1  christos     ksktimes = (
   1496  1.1  christos         f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1497  1.1  christos     )
   1498  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
   1499  1.1  christos     zsktimes = f"-P {TpubN}  -A {TpubN}"
   1500  1.1  christos     # Key generation.
   1501  1.1  christos     ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").out.strip()
   1502  1.1  christos     ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip()
   1503  1.1  christos     zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.strip()
   1504  1.1  christos     settime(
   1505  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}",
   1506  1.1  christos         cwd="ns3",
   1507  1.1  christos     )
   1508  1.1  christos     settime(
   1509  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}",
   1510  1.1  christos         cwd="ns3",
   1511  1.1  christos     )
   1512  1.1  christos     settime(
   1513  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
   1514  1.1  christos         cwd="ns3",
   1515  1.1  christos     )
   1516  1.1  christos     # Set key rollover relationship.
   1517  1.1  christos     set_key_relationship(ksk1_name, ksk2_name)
   1518  1.1  christos     # Signing.
   1519  1.1  christos     render_and_sign_zone(
   1520  1.1  christos         zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
   1521  1.1  christos     )
   1522  1.1  christos 
   1523  1.1  christos     # Step 4:
   1524  1.1  christos     # The DS should be swapped now.
   1525  1.1  christos     zonename = f"step4.{zone}"
   1526  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1527  1.1  christos     isctest.log.info(f"setup {zonename}")
   1528  1.1  christos     # Tpub(N)    = now - Lksk - Iret = now - 60d - 50h
   1529  1.1  christos     #            = now - 1440h - 50h = now - 1490h
   1530  1.1  christos     # Tact(N)    = now - 1490h + 27h = now - 1463h
   1531  1.1  christos     # Tret(N)    = now - Iret = now - 50h
   1532  1.1  christos     # Trem(N)    = now
   1533  1.1  christos     # Tpub(N+1)  = now - Iret - IpubC = now - 50h - 27h
   1534  1.1  christos     #            = now - 77h
   1535  1.1  christos     # Tact(N+1)  = Tret(N)
   1536  1.1  christos     # Tret(N+1)  = now + Lksk - Iret = now + 60d - 50h = now + 1390h
   1537  1.1  christos     # Trem(N+1)  = now + Lksk = now + 60d
   1538  1.1  christos     TpubN = "now-1490h"
   1539  1.1  christos     TactN = "now-1463h"
   1540  1.1  christos     TretN = "now-50h"
   1541  1.1  christos     TremN = "now"
   1542  1.1  christos     TpubN1 = "now-77h"
   1543  1.1  christos     TactN1 = TretN
   1544  1.1  christos     TretN1 = "now+1390h"
   1545  1.1  christos     TremN1 = "now+60d"
   1546  1.1  christos     ksktimes = (
   1547  1.1  christos         f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1548  1.1  christos     )
   1549  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
   1550  1.1  christos     zsktimes = f"-P {TpubN} -A {TpubN}"
   1551  1.1  christos     # Key generation.
   1552  1.1  christos     ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").out.strip()
   1553  1.1  christos     ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip()
   1554  1.1  christos     zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.strip()
   1555  1.1  christos     settime(
   1556  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d UNRETENTIVE {TretN} -D ds {TretN} {ksk1_name}",
   1557  1.1  christos         cwd="ns3",
   1558  1.1  christos     )
   1559  1.1  christos     settime(
   1560  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d RUMOURED {TactN1} -P ds {TactN1} {ksk2_name}",
   1561  1.1  christos         cwd="ns3",
   1562  1.1  christos     )
   1563  1.1  christos     settime(
   1564  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1565  1.1  christos         cwd="ns3",
   1566  1.1  christos     )
   1567  1.1  christos     # Set key rollover relationship.
   1568  1.1  christos     set_key_relationship(ksk1_name, ksk2_name)
   1569  1.1  christos     # Signing.
   1570  1.1  christos     render_and_sign_zone(
   1571  1.1  christos         zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
   1572  1.1  christos     )
   1573  1.1  christos 
   1574  1.1  christos     # Step 5:
   1575  1.1  christos     # The predecessor DNSKEY is removed long enough that is has become HIDDEN.
   1576  1.1  christos     zonename = f"step5.{zone}"
   1577  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1578  1.1  christos     isctest.log.info(f"setup {zonename}")
   1579  1.1  christos     # Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
   1580  1.1  christos     # Tpub(N)    = now - 1490h - 3h = now - 1493h
   1581  1.1  christos     # Tact(N)    = now - 1463h - 3h = now - 1466h
   1582  1.1  christos     # Tret(N)    = now - 50h - 3h = now - 53h
   1583  1.1  christos     # Trem(N)    = now - 3h
   1584  1.1  christos     # Tpub(N+1)  = now - 77h - 3h = now - 80h
   1585  1.1  christos     # Tact(N+1)  = Tret(N)
   1586  1.1  christos     # Tret(N+1)  = now + 1390h - 3h = now + 1387h
   1587  1.1  christos     # Trem(N+1)  = now + 60d - 3h = now + 1441h
   1588  1.1  christos     TpubN = "now-1493h"
   1589  1.1  christos     TactN = "now-1466h"
   1590  1.1  christos     TretN = "now-53h"
   1591  1.1  christos     TremN = "now-3h"
   1592  1.1  christos     TpubN1 = "now-80h"
   1593  1.1  christos     TactN1 = TretN
   1594  1.1  christos     TretN1 = "now+1387h"
   1595  1.1  christos     TremN1 = "now+1441h"
   1596  1.1  christos     ksktimes = (
   1597  1.1  christos         f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1598  1.1  christos     )
   1599  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
   1600  1.1  christos     zsktimes = f"-P {TpubN} -A {TpubN}"
   1601  1.1  christos     # Key generation.
   1602  1.1  christos     ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").out.strip()
   1603  1.1  christos     ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip()
   1604  1.1  christos     zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.strip()
   1605  1.1  christos     settime(
   1606  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TretN} -r UNRETENTIVE {TretN} -d HIDDEN {TretN} {ksk1_name}",
   1607  1.1  christos         cwd="ns3",
   1608  1.1  christos     )
   1609  1.1  christos     settime(
   1610  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}",
   1611  1.1  christos         cwd="ns3",
   1612  1.1  christos     )
   1613  1.1  christos     settime(
   1614  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1615  1.1  christos         cwd="ns3",
   1616  1.1  christos     )
   1617  1.1  christos     # Set key rollover relationship.
   1618  1.1  christos     set_key_relationship(ksk1_name, ksk2_name)
   1619  1.1  christos     # Signing.
   1620  1.1  christos     render_and_sign_zone(
   1621  1.1  christos         zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
   1622  1.1  christos     )
   1623  1.1  christos 
   1624  1.1  christos     # Step 6:
   1625  1.1  christos     # The predecessor DNSKEY can be purged.
   1626  1.1  christos     zonename = f"step6.{zone}"
   1627  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1628  1.1  christos     isctest.log.info(f"setup {zonename}")
   1629  1.1  christos     # Subtract purge-keys interval from all the times (1h).
   1630  1.1  christos     TpubN = "now-1494h"
   1631  1.1  christos     TactN = "now-1467h"
   1632  1.1  christos     TretN = "now-54h"
   1633  1.1  christos     TremN = "now-4h"
   1634  1.1  christos     TpubN1 = "now-81h"
   1635  1.1  christos     TactN1 = TretN
   1636  1.1  christos     TretN1 = "now+1386h"
   1637  1.1  christos     TremN1 = "now+1440h"
   1638  1.1  christos     ksktimes = (
   1639  1.1  christos         f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1640  1.1  christos     )
   1641  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
   1642  1.1  christos     zsktimes = f"-P {TpubN} -A {TpubN}"
   1643  1.1  christos     # Key generation.
   1644  1.1  christos     ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").out.strip()
   1645  1.1  christos     ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip()
   1646  1.1  christos     zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.strip()
   1647  1.1  christos     settime(
   1648  1.1  christos         f"-g HIDDEN -k HIDDEN {TretN} -r HIDDEN {TretN} -d HIDDEN {TretN} {ksk1_name}",
   1649  1.1  christos         cwd="ns3",
   1650  1.1  christos     )
   1651  1.1  christos     settime(
   1652  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -r OMNIPRESENT {TactN1} -d OMNIPRESENT {TactN1} {ksk2_name}",
   1653  1.1  christos         cwd="ns3",
   1654  1.1  christos     )
   1655  1.1  christos     settime(
   1656  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1657  1.1  christos         cwd="ns3",
   1658  1.1  christos     )
   1659  1.1  christos     # Set key rollover relationship.
   1660  1.1  christos     set_key_relationship(ksk1_name, ksk2_name)
   1661  1.1  christos     # Signing.
   1662  1.1  christos     render_and_sign_zone(
   1663  1.1  christos         zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
   1664  1.1  christos     )
   1665  1.1  christos 
   1666  1.1  christos     return zones
   1667  1.1  christos 
   1668  1.1  christos 
   1669  1.1  christos def configure_ksk_3crowd(tld: str) -> List[Zone]:
   1670  1.1  christos     # Test #2375, the "three is a crowd" bug, where a new key is introduced but the
   1671  1.1  christos     # previous rollover has not finished yet. In other words, we have a key KEY2
   1672  1.1  christos     # that is the successor of key KEY1, and we introduce a new key KEY3 that is
   1673  1.1  christos     # the successor of key KEY2:
   1674  1.1  christos     #
   1675  1.1  christos     #     KEY1 < KEY2 < KEY3.
   1676  1.1  christos     #
   1677  1.1  christos     # The expected behavior is that all three keys remain in the zone, and not
   1678  1.1  christos     # the bug behavior where KEY2 is removed and immediately replaced with KEY3.
   1679  1.1  christos     #
   1680  1.1  christos     zones = []
   1681  1.1  christos     cds = "cds:sha-256"
   1682  1.1  christos     keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 7200")
   1683  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1684  1.1  christos 
   1685  1.1  christos     # Set up a zone that has a KSK (KEY1) and have the successor key (KEY2)
   1686  1.1  christos     # published as well.
   1687  1.1  christos     zonename = f"three-is-a-crowd.{tld}"
   1688  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1689  1.1  christos     isctest.log.info(f"setup {zonename}")
   1690  1.1  christos     # These times are the same as step3.ksk-doubleksk.autosign.
   1691  1.1  christos     TpubN = "now-60d"
   1692  1.1  christos     TactN = "now-1413h"
   1693  1.1  christos     TretN = "now"
   1694  1.1  christos     TremN = "now+50h"
   1695  1.1  christos     TpubN1 = "now-27h"
   1696  1.1  christos     TactN1 = TretN
   1697  1.1  christos     TretN1 = "now+60d"
   1698  1.1  christos     TremN1 = "now+1490h"
   1699  1.1  christos     ksktimes = (
   1700  1.1  christos         f"-P {TpubN} -A {TpubN} -P sync {TactN} -I {TretN} -D {TremN} -D sync {TactN1}"
   1701  1.1  christos     )
   1702  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1} -P sync {TactN1} -I {TretN1} -D {TremN1}"
   1703  1.1  christos     zsktimes = f"-P {TpubN}  -A {TpubN}"
   1704  1.1  christos     # Key generation.
   1705  1.1  christos     ksk1_name = keygen(f"-f KSK {ksktimes} {zonename}", cwd="ns3").out.strip()
   1706  1.1  christos     ksk2_name = keygen(f"-f KSK {newtimes} {zonename}", cwd="ns3").out.strip()
   1707  1.1  christos     zsk_name = keygen(f"{zsktimes} {zonename}", cwd="ns3").out.strip()
   1708  1.1  christos     settime(
   1709  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk1_name}",
   1710  1.1  christos         cwd="ns3",
   1711  1.1  christos     )
   1712  1.1  christos     settime(
   1713  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN1} -r RUMOURED {TpubN1} -d HIDDEN {TpubN1} {ksk2_name}",
   1714  1.1  christos         cwd="ns3",
   1715  1.1  christos     )
   1716  1.1  christos     settime(
   1717  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
   1718  1.1  christos         cwd="ns3",
   1719  1.1  christos     )
   1720  1.1  christos     # Set key rollover relationship.
   1721  1.1  christos     set_key_relationship(ksk1_name, ksk2_name)
   1722  1.1  christos     # Signing.
   1723  1.1  christos     render_and_sign_zone(
   1724  1.1  christos         zonename, [ksk1_name, ksk2_name, zsk_name], extra_options=f"-G {cds}"
   1725  1.1  christos     )
   1726  1.1  christos 
   1727  1.1  christos     return zones
   1728  1.1  christos 
   1729  1.1  christos 
   1730  1.1  christos def configure_zsk_prepub(tld: str) -> List[Zone]:
   1731  1.1  christos     # The zones at zsk-prepub.$tld represent the various steps of a ZSK
   1732  1.1  christos     # Pre-Publication rollover.
   1733  1.1  christos     zones = []
   1734  1.1  christos     zone = f"zsk-prepub.{tld}"
   1735  1.1  christos     keygen = EnvCmd("KEYGEN", "-a ECDSAP256SHA256 -L 3600")
   1736  1.1  christos     settime = EnvCmd("SETTIME", "-s")
   1737  1.1  christos 
   1738  1.1  christos     # Step 1:
   1739  1.1  christos     # Introduce the first key. This will immediately be active.
   1740  1.1  christos     zonename = f"step1.{zone}"
   1741  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1742  1.1  christos     isctest.log.info(f"setup {zonename}")
   1743  1.1  christos     # Timing metadata.
   1744  1.1  christos     TactN = "now-7d"
   1745  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1746  1.1  christos     # Key generation.
   1747  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1748  1.1  christos     zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1749  1.1  christos     settime(
   1750  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1751  1.1  christos         cwd="ns3",
   1752  1.1  christos     )
   1753  1.1  christos     settime(
   1754  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1755  1.1  christos         cwd="ns3",
   1756  1.1  christos     )
   1757  1.1  christos     # Signing.
   1758  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk_name])
   1759  1.1  christos 
   1760  1.1  christos     # Step 2:
   1761  1.1  christos     # It is time to pre-publish the successor ZSK.
   1762  1.1  christos     zonename = f"step2.{zone}"
   1763  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1764  1.1  christos     isctest.log.info(f"setup {zonename}")
   1765  1.1  christos     # According to RFC 7583:
   1766  1.1  christos     # Tact(N) = now + Ipub - Lzsk = now + 26h - 30d
   1767  1.1  christos     #         = now + 26h - 30d = now  694h
   1768  1.1  christos     TactN = "now-694h"
   1769  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1770  1.1  christos     # Key generation.
   1771  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1772  1.1  christos     zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").out.strip()
   1773  1.1  christos     settime(
   1774  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1775  1.1  christos         cwd="ns3",
   1776  1.1  christos     )
   1777  1.1  christos     settime(
   1778  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk_name}",
   1779  1.1  christos         cwd="ns3",
   1780  1.1  christos     )
   1781  1.1  christos     # Signing.
   1782  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk_name])
   1783  1.1  christos 
   1784  1.1  christos     # Step 3:
   1785  1.1  christos     # After the publication interval has passed the DNSKEY of the successor ZSK
   1786  1.1  christos     # is OMNIPRESENT and the zone can thus be signed with the successor ZSK.
   1787  1.1  christos     zonename = f"step3.{zone}"
   1788  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1789  1.1  christos     isctest.log.info(f"setup {zonename}")
   1790  1.1  christos     # According to RFC 7583:
   1791  1.1  christos     # Tpub(N+1) <= Tact(N) + Lzsk - Ipub
   1792  1.1  christos     # Tact(N+1) = Tact(N) + Lzsk
   1793  1.1  christos     #
   1794  1.1  christos     # Tact(N)   = now - Lzsk = now - 30d
   1795  1.1  christos     # Tpub(N+1) = now - Ipub = now - 26h
   1796  1.1  christos     # Tact(N+1) = now
   1797  1.1  christos     # Tret(N) = now
   1798  1.1  christos     # Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h
   1799  1.1  christos     TactN = "now-30d"
   1800  1.1  christos     TpubN1 = "now-26h"
   1801  1.1  christos     TactN1 = "now"
   1802  1.1  christos     TremN = "now+241h"
   1803  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1804  1.1  christos     oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}"
   1805  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1}"
   1806  1.1  christos     # Key generation.
   1807  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1808  1.1  christos     zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip()
   1809  1.1  christos     zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1810  1.1  christos     settime(
   1811  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1812  1.1  christos         cwd="ns3",
   1813  1.1  christos     )
   1814  1.1  christos     settime(
   1815  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -z OMNIPRESENT {TactN} {zsk1_name}",
   1816  1.1  christos         cwd="ns3",
   1817  1.1  christos     )
   1818  1.1  christos     settime(
   1819  1.1  christos         f"-g OMNIPRESENT -k RUMOURED {TpubN1} -z HIDDEN {TpubN1} {zsk2_name}", cwd="ns3"
   1820  1.1  christos     )
   1821  1.1  christos     # Set key rollover relationship.
   1822  1.1  christos     set_key_relationship(zsk1_name, zsk2_name)
   1823  1.1  christos     # Signing.
   1824  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name])
   1825  1.1  christos 
   1826  1.1  christos     # Step 4:
   1827  1.1  christos     # After the retire interval has passed the predecessor DNSKEY can be
   1828  1.1  christos     # removed from the zone.
   1829  1.1  christos     zonename = f"step4.{zone}"
   1830  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1831  1.1  christos     isctest.log.info(f"setup {zonename}")
   1832  1.1  christos     # Lzsk:          30d
   1833  1.1  christos     # Ipub:          26h
   1834  1.1  christos     # Dsgn:          1w
   1835  1.1  christos     # Dprp:          1h
   1836  1.1  christos     # TTLsig:        1d
   1837  1.1  christos     # retire-safety: 2d
   1838  1.1  christos     #
   1839  1.1  christos     # According to RFC 7583:
   1840  1.1  christos     # Iret      = Dsgn + Dprp + TTLsig (+retire-safety)
   1841  1.1  christos     # Iret      = 1w + 1h + 1d + 2d = 10d1h = 241h
   1842  1.1  christos     #
   1843  1.1  christos     # Tact(N)   = now - Iret - Lzsk
   1844  1.1  christos     #           = now - 241h - 30d = now - 241h - 720h
   1845  1.1  christos     #           = now - 961h
   1846  1.1  christos     # Tpub(N+1) = now - Iret - Ipub
   1847  1.1  christos     #           = now - 241h - 26h
   1848  1.1  christos     #           = now - 267h
   1849  1.1  christos     # Tact(N+1) = now - Iret = now - 241h
   1850  1.1  christos     TactN = "now-961h"
   1851  1.1  christos     TpubN1 = "now-267h"
   1852  1.1  christos     TactN1 = "now-241h"
   1853  1.1  christos     TremN = "now"
   1854  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1855  1.1  christos     oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}"
   1856  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1}"
   1857  1.1  christos     # Key generation.
   1858  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1859  1.1  christos     zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip()
   1860  1.1  christos     zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1861  1.1  christos     settime(
   1862  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1863  1.1  christos         cwd="ns3",
   1864  1.1  christos     )
   1865  1.1  christos     settime(
   1866  1.1  christos         f"-g HIDDEN -k OMNIPRESENT {TactN} -z UNRETENTIVE {TactN1} {zsk1_name}",
   1867  1.1  christos         cwd="ns3",
   1868  1.1  christos     )
   1869  1.1  christos     settime(
   1870  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z RUMOURED {TactN1} {zsk2_name}",
   1871  1.1  christos         cwd="ns3",
   1872  1.1  christos     )
   1873  1.1  christos     # Set key rollover relationship.
   1874  1.1  christos     set_key_relationship(zsk1_name, zsk2_name)
   1875  1.1  christos     # Signing.
   1876  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name])
   1877  1.1  christos 
   1878  1.1  christos     # Step 5:
   1879  1.1  christos     # The predecessor DNSKEY is removed long enough that is has become HIDDEN.
   1880  1.1  christos     zonename = f"step5.{zone}"
   1881  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1882  1.1  christos     isctest.log.info(f"setup {zonename}")
   1883  1.1  christos     # Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h).
   1884  1.1  christos     # Tact(N)   = now - 961h - 2h = now - 963h
   1885  1.1  christos     # Tpub(N+1) = now - 267h - 2h = now - 269h
   1886  1.1  christos     # Tact(N+1) = now - 241h - 2h = now - 243h
   1887  1.1  christos     # Trem(N)   = Tact(N+1) + Iret = now -2h
   1888  1.1  christos     TactN = "now-963h"
   1889  1.1  christos     TremN = "now-2h"
   1890  1.1  christos     TpubN1 = "now-269h"
   1891  1.1  christos     TactN1 = "now-243h"
   1892  1.1  christos     TremN = "now-2h"
   1893  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1894  1.1  christos     oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}"
   1895  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1}"
   1896  1.1  christos     # Key generation.
   1897  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1898  1.1  christos     zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip()
   1899  1.1  christos     zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1900  1.1  christos     settime(
   1901  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1902  1.1  christos         cwd="ns3",
   1903  1.1  christos     )
   1904  1.1  christos     settime(
   1905  1.1  christos         f"-g HIDDEN -k UNRETENTIVE {TremN} -z HIDDEN {TremN} {zsk1_name}", cwd="ns3"
   1906  1.1  christos     )
   1907  1.1  christos     settime(
   1908  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z OMNIPRESENT {TremN} {zsk2_name}",
   1909  1.1  christos         cwd="ns3",
   1910  1.1  christos     )
   1911  1.1  christos     # Set key rollover relationship.
   1912  1.1  christos     set_key_relationship(zsk1_name, zsk2_name)
   1913  1.1  christos     # Signing.
   1914  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name])
   1915  1.1  christos 
   1916  1.1  christos     # Step 6:
   1917  1.1  christos     # The predecessor DNSKEY can be purged.
   1918  1.1  christos     zonename = f"step6.{zone}"
   1919  1.1  christos     zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
   1920  1.1  christos     isctest.log.info(f"setup {zonename}")
   1921  1.1  christos     # Subtract purge-keys interval from all the times (1h).
   1922  1.1  christos     TactN = "now-964h"
   1923  1.1  christos     TremN = "now-3h"
   1924  1.1  christos     TpubN1 = "now-270h"
   1925  1.1  christos     TactN1 = "now-244h"
   1926  1.1  christos     TremN = "now-3h"
   1927  1.1  christos     keytimes = f"-P {TactN} -A {TactN}"
   1928  1.1  christos     oldtimes = f"-P {TactN} -A {TactN} -I {TactN1} -D {TremN}"
   1929  1.1  christos     newtimes = f"-P {TpubN1} -A {TactN1}"
   1930  1.1  christos     # Key generation.
   1931  1.1  christos     ksk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
   1932  1.1  christos     zsk1_name = keygen(f"{oldtimes} {zonename}", cwd="ns3").out.strip()
   1933  1.1  christos     zsk2_name = keygen(f"{newtimes} {zonename}", cwd="ns3").out.strip()
   1934  1.1  christos     settime(
   1935  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN} -r OMNIPRESENT {TactN} -d OMNIPRESENT {TactN} {ksk_name}",
   1936  1.1  christos         cwd="ns3",
   1937  1.1  christos     )
   1938  1.1  christos     settime(f"-g HIDDEN -k HIDDEN {TremN} -z HIDDEN {TremN} {zsk1_name}", cwd="ns3")
   1939  1.1  christos     settime(
   1940  1.1  christos         f"-g OMNIPRESENT -k OMNIPRESENT {TactN1} -z OMNIPRESENT {TremN} {zsk2_name}",
   1941  1.1  christos         cwd="ns3",
   1942  1.1  christos     )
   1943  1.1  christos     # Set key rollover relationship.
   1944  1.1  christos     set_key_relationship(zsk1_name, zsk2_name)
   1945  1.1  christos     # Signing.
   1946  1.1  christos     render_and_sign_zone(zonename, [ksk_name, zsk1_name, zsk2_name])
   1947  1.1  christos 
   1948  1.1  christos     return zones
   1949