{-|
Module      : Net.DNSBase.RData.Dnssec
Description : DNSSEC chain-of-trust records (DS, DNSKEY, RRSIG, plus IPSECKEY and ZONEMD)
Copyright   : (c) Viktor Dukhovni, 2026
License     : BSD-3-Clause
Maintainer  : ietf-dane@dukhovni.org
Stability   : unstable

The DNSSEC chain-of-trust RR types from RFC 4034 — 'T_ds',
'T_dnskey', 'T_rrsig' — plus their parent\/child mirror
announcements: 'T_cds' and 'T_cdnskey' (RFC 7344) carry the
child-side signalling of which DS and DNSKEY records the parent
should publish.  The legacy 'T_key' and 'T_sig' records, still
used by SIG(0) transaction authentication (RFC 2535, RFC 2931),
share a codec with their DNSSEC successors.

The three groups DS\/CDS, DNSKEY\/CDNSKEY\/KEY, and SIG\/RRSIG
each have a single underlying data type ('X_ds', 'X_key',
'X_sig') with the RR type carried at the type level.  DS and
KEY have the @phantom@ type role on @n@, so values are
mutually coercible; the SIG family has @nominal@, since SIG(0)
signs a single transaction while RRSIG signs an RRSet, and
conflating them at the type level would be unsafe.

'T_ipseckey' (RFC 4025) and 'T_zonemd' (RFC 8976) live here
too, alongside the re-export of "Net.DNSBase.RData.NSEC" for
the denial-of-existence records.
-}
{-# OPTIONS_GHC -Wno-duplicate-exports #-}
{-# LANGUAGE
    MagicHash
  , RecordWildCards
  , UndecidableInstances
  #-}
module Net.DNSBase.RData.Dnssec
    ( -- * DS, DNSKEY and RRSIG
      -- ** DS resource records
      X_ds(.., T_DS, T_CDS
          , dsKtag, dsKalg, dsHalg, dsHval
          , cdsKtag, cdsKalg, cdsHalg, cdsHval)
    , type XdsConName
      -- **** @T_DS@ record pattern synonym fields
    , T_ds
    , dsKtag, dsKalg, dsHalg, dsHval
      -- **** @T_CDS@ record pattern synonym fields
    , T_cds
    , cdsKtag, cdsKalg, cdsHalg, cdsHval
      -- ** DNSKEY resource records
    , X_key(.., T_DNSKEY, T_CDNSKEY, T_KEY
           , dnskeyFlags, dnskeyProto, dnskeyAlgor, dnskeyValue
           , cdnskeyFlags, cdnskeyProto, cdnskeyAlgor, cdnskeyValue
           , keyFlags, keyProto, keyAlgor, keyValue)
    , type XkeyConName
      -- *** @DNSKEY@ record pattern synonym fields
    , T_dnskey
    , dnskeyFlags, dnskeyProto, dnskeyAlgor, dnskeyValue
      -- **** Compute a DNSKey tag
    , keytag
      -- *** @CDNSKEY@ record pattern synonym fields
    , T_cdnskey
    , cdnskeyFlags, cdnskeyProto, cdnskeyAlgor, cdnskeyValue
      -- *** @KEY@ record pattern synonym fields
    , T_key
    , keyFlags, keyProto, keyAlgor, keyValue
      -- ** RRSIG resource records
    , X_sig(.., T_RRSIG, T_SIG
           , rrsigType, rrsigKeyAlg, rrsigNumLabels, rrsigTTL
           , rrsigExpiration, rrsigInception, rrsigKeyTag, rrsigZone, rrsigValue
           , sigType, sigKeyAlg, sigNumLabels, sigTTL
           , sigExpiration, sigInception, sigKeyTag, sigZone, sigValue)
    , type XsigConName
      -- *** @RRSIG@ record pattern synonym fields
    , T_rrsig
    , rrsigType, rrsigKeyAlg, rrsigNumLabels, rrsigTTL
    , rrsigExpiration, rrsigInception, rrsigKeyTag, rrsigZone, rrsigValue
      -- *** @SIG@ record pattern synonym fields
    , T_sig
    , sigType, sigKeyAlg, sigNumLabels, sigTTL
    , sigExpiration, sigInception, sigKeyTag, sigZone, sigValue
      -- * IPSECKEY resource records
    , T_ipseckey(IPSecKey), IPSecKeyGateway(..)
      -- * Zone digest
    , T_zonemd(..)
    , module Net.DNSBase.RData.NSEC
    ) where

import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Short as SB
import GHC.Exts (proxy#)
import GHC.TypeLits as TL (TypeError, ErrorMessage(..))
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal')

import Net.DNSBase.Internal.Util

import Net.DNSBase.Bytes
import Net.DNSBase.Decode.Domain
import Net.DNSBase.Decode.State
import Net.DNSBase.Domain
import Net.DNSBase.Encode.Metric
import Net.DNSBase.Encode.State
import Net.DNSBase.Nat16
import Net.DNSBase.Present
import Net.DNSBase.RData
import Net.DNSBase.RData.NSEC
import Net.DNSBase.RRTYPE
import Net.DNSBase.Secalgs

type XdsConName :: Nat -> Symbol
type family XdsConName n where
    XdsConName N_ds  = "T_DS"
    XdsConName N_cds = "T_CDS"
    XdsConName n     = TypeError
                     ( ShowType n
                       :<>: TL.Text " is not a DS or CDS RRTYPE" )

type XkeyConName :: Nat -> Symbol
type family XkeyConName n where
    XkeyConName N_dnskey  = "T_DNSKEY"
    XkeyConName N_cdnskey = "T_CDNSKEY"
    XkeyConName N_key     = "T_KEY"
    XkeyConName n         = TypeError
                            ( ShowType n
                              :<>: TL.Text " is not a DNSSEC key RRTYPE" )

type XsigConName :: Nat -> Symbol
type family XsigConName n where
    XsigConName N_rrsig  = "T_RRSIG"
    XsigConName N_sig    = "T_SIG"
    XsigConName n        = TypeError
                           ( ShowType n
                             :<>: TL.Text " is not a SIG or RRSIG RRTYPE" )

-- | X_ds specialised to @DS@ records.
--
-- Note that @T_ds@ is just a type alias!  The 'T_DS' record pattern
-- synonym and its fields are bundled with the underlying 'X_ds'
-- data type.  In many cases it is sufficient to import just
-- @X_ds(..)@, but if you also need the type alias, it needs to be
-- imported separately:
--
-- > import Net.DNSBase (X_ds(..), T_ds)
--
type T_ds      = X_ds N_ds

-- | X_ds specialised to @CDS@ records.
--
-- Note that @T_cds@ is just a type alias!  The 'T_CDS' record pattern
-- synonym and its fields are bundled with the underlying 'X_ds'
-- data type.  In many cases it is sufficient to import just
-- @X_ds(..)@, but if you also need the type alias it needs to be
-- imported separately:
--
-- > import Net.DNSBase (X_ds(..), T_cds)
--
type T_cds     = X_ds N_cds

-- | Record pattern synonym viewing the shared 'X_ds' record as a
-- parent-side @DS@ record (RFC 4034, section 5).  Fields: 'dsKtag',
-- 'dsKalg', 'dsHalg', 'dsHval'.  Coercible to/from 'T_CDS'.
pattern T_DS :: Word16 -- ^ Key Tag
             -> DNSKEYAlg -- ^ Algorithm
             -> DSHashAlg -- ^ Digest-algorithm /selector/ (a 'DSHashAlg' code), distinct from the digest bytes below
             -> ShortByteString -- ^ Digest
             -> T_ds
pattern $bT_DS :: Word16 -> DNSKEYAlg -> DSHashAlg -> ShortByteString -> T_ds
$mT_DS :: forall {r}.
T_ds
-> (Word16 -> DNSKEYAlg -> DSHashAlg -> ShortByteString -> r)
-> ((# #) -> r)
-> r
T_DS { T_ds -> Word16
dsKtag, T_ds -> DNSKEYAlg
dsKalg, T_ds -> DSHashAlg
dsHalg, T_ds -> ShortByteString
dsHval }
      = (X_DS dsKtag dsKalg dsHalg dsHval :: T_ds)
{-# COMPLETE T_DS #-}

-- | Record pattern synonym viewing the shared 'X_ds' record as a
-- child-side @CDS@ announcement (RFC 7344).  Fields: 'cdsKtag',
-- 'cdsKalg', 'cdsHalg', 'cdsHval'.  Coercible to/from 'T_DS'.
pattern T_CDS :: Word16 -- ^ Key Tag
              -> DNSKEYAlg -- ^ Algorithm
              -> DSHashAlg -- ^ Digest-algorithm /selector/ (a 'DSHashAlg' code), distinct from the digest bytes below
              -> ShortByteString -- ^ Digest
              -> T_cds
pattern $bT_CDS :: Word16 -> DNSKEYAlg -> DSHashAlg -> ShortByteString -> T_cds
$mT_CDS :: forall {r}.
T_cds
-> (Word16 -> DNSKEYAlg -> DSHashAlg -> ShortByteString -> r)
-> ((# #) -> r)
-> r
T_CDS { T_cds -> Word16
cdsKtag, T_cds -> DNSKEYAlg
cdsKalg, T_cds -> DSHashAlg
cdsHalg, T_cds -> ShortByteString
cdsHval }
      = (X_DS cdsKtag cdsKalg cdsHalg cdsHval :: T_cds)
{-# COMPLETE T_CDS #-}

-- | X_key specialised to @DNSKEY@ records.
--
-- Note that @T_dnskey@ is just a type alias!  The 'T_DNSKEY'
-- record pattern synonym and its fields are bundled with the
-- underlying 'X_key' data type.  In many cases it is sufficient
-- to import just @X_key(..)@, but if you also need the type
-- alias, it needs to be imported separately:
--
-- > import Net.DNSBase (X_key(..), T_dnskey)
--
type T_dnskey  = X_key N_dnskey

-- | X_key specialised to @CDNSKEY@ records.
--
-- Note that @T_cdnskey@ is just a type alias!  The 'T_CDNSKEY'
-- record pattern synonym and its fields are bundled with the
-- underlying 'X_key' data type.  In many cases it is sufficient
-- to import just @X_key(..)@, but if you also need the type
-- alias, it needs to be imported separately:
--
-- > import Net.DNSBase (X_key(..), T_cdnskey)
--
type T_cdnskey = X_key N_cdnskey

-- | X_key specialised to @KEY@ records.
--
-- Note that @T_key@ is just a type alias!  The 'T_KEY' record
-- pattern synonym and its fields are bundled with the underlying
-- 'X_key' data type.  In many cases it is sufficient to import
-- just @X_key(..)@, but if you also need the type alias, it needs
-- to be imported separately:
--
-- > import Net.DNSBase (X_key(..), T_key)
--
type T_key     = X_key N_key

-- | Record pattern synonym viewing the shared 'X_key' record as a
-- DNSSEC @DNSKEY@ (RFC 4034, section 2).  Fields: 'dnskeyFlags',
-- 'dnskeyProto', 'dnskeyAlgor', 'dnskeyValue'.  Coercible to/from
-- 'T_cdnskey'; CDNSKEY is the child-side announcement of which DNSKEY
-- KSKs the parent should reference as sources for future DS records.
pattern T_DNSKEY :: Word16 -- ^ Flags
                 -> Word8 -- ^ Protocol selector; MUST be 3 for DNSKEY (RFC 4034 section 2.1.2)
                 -> DNSKEYAlg -- ^ Algorithm
                 -> ShortByteString -- ^ Public Key
                 -> T_dnskey
pattern $bT_DNSKEY :: Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> T_dnskey
$mT_DNSKEY :: forall {r}.
T_dnskey
-> (Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> r)
-> ((# #) -> r)
-> r
T_DNSKEY { T_dnskey -> Word16
dnskeyFlags, T_dnskey -> Word8
dnskeyProto, T_dnskey -> DNSKEYAlg
dnskeyAlgor, T_dnskey -> ShortByteString
dnskeyValue }
      = (X_KEY dnskeyFlags dnskeyProto dnskeyAlgor dnskeyValue :: T_dnskey)
{-# COMPLETE T_DNSKEY #-}

-- | Record pattern synonym viewing the shared 'X_key' record as a
-- child-side @CDNSKEY@ announcement (RFC 7344).  Fields:
-- 'cdnskeyFlags', 'cdnskeyProto', 'cdnskeyAlgor', 'cdnskeyValue'.
-- Coercible to/from 'T_dnskey'.
pattern T_CDNSKEY :: Word16 -- ^ Flags
                  -> Word8 -- ^ Protocol selector; MUST be 3 for CDNSKEY (RFC 4034 section 2.1.2, via RFC 7344)
                  -> DNSKEYAlg -- ^ Algorithm
                  -> ShortByteString -- ^ Public Key
                  -> T_cdnskey
pattern $bT_CDNSKEY :: Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> T_cdnskey
$mT_CDNSKEY :: forall {r}.
T_cdnskey
-> (Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> r)
-> ((# #) -> r)
-> r
T_CDNSKEY { T_cdnskey -> Word16
cdnskeyFlags, T_cdnskey -> Word8
cdnskeyProto, T_cdnskey -> DNSKEYAlg
cdnskeyAlgor, T_cdnskey -> ShortByteString
cdnskeyValue }
      = (X_KEY cdnskeyFlags cdnskeyProto cdnskeyAlgor cdnskeyValue :: T_cdnskey)
{-# COMPLETE T_CDNSKEY #-}

-- | Record pattern synonym viewing the shared 'X_key' record as a
-- legacy @KEY@ record (RFC 2535, section 3), still used by SIG(0)
-- transaction authentication.  Fields: 'keyFlags', 'keyProto',
-- 'keyAlgor', 'keyValue'.  Coercible to/from 'T_dnskey' and
-- 'T_cdnskey'.
pattern T_KEY :: Word16 -- ^ Flags
              -> Word8 -- ^ Protocol selector;
                       -- for DNSKEY the only valid value is 3
                       -- (RFC 4034 section 2.1.2), other values
                       -- appear in legacy KEY records
              -> DNSKEYAlg -- ^ Algorithm
              -> ShortByteString -- ^ Public Key
              -> T_key
pattern $bT_KEY :: Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> T_key
$mT_KEY :: forall {r}.
T_key
-> (Word16 -> Word8 -> DNSKEYAlg -> ShortByteString -> r)
-> ((# #) -> r)
-> r
T_KEY { T_key -> Word16
keyFlags, T_key -> Word8
keyProto, T_key -> DNSKEYAlg
keyAlgor, T_key -> ShortByteString
keyValue }
      = (X_KEY keyFlags keyProto keyAlgor keyValue :: T_key)
{-# COMPLETE T_KEY #-}

-- | X_sig specialised to @RRSIG@ records.
--
-- Note that @T_rrsig@ is just a type alias!  The 'T_RRSIG' record
-- pattern synonym and its fields are bundled with the underlying
-- 'X_sig' data type.  In many cases it is sufficient to import
-- just @X_sig(..)@, but if you also need the type alias, it needs
-- to be imported separately:
--
-- > import Net.DNSBase (X_sig(..), T_rrsig)
--
type T_rrsig = X_sig N_rrsig

-- | X_sig specialised to @SIG@ / @SIG(0)@ records.
--
-- Note that @T_sig@ is just a type alias!  The 'T_SIG' record
-- pattern synonym and its fields are bundled with the underlying
-- 'X_sig' data type.  In many cases it is sufficient to import
-- just @X_sig(..)@, but if you also need the type alias, it needs
-- to be imported separately:
--
-- > import Net.DNSBase (X_sig(..), T_sig)
--
type T_sig   = X_sig N_sig

-- | Record pattern synonym viewing the shared 'X_sig' record as a
-- DNSSEC @RRSIG@ (RFC 4034, section 3).  Fields: 'rrsigType',
-- 'rrsigKeyAlg', 'rrsigNumLabels', 'rrsigTTL', 'rrsigExpiration',
-- 'rrsigInception', 'rrsigKeyTag', 'rrsigZone', 'rrsigValue'.
-- 'Eq' and 'Ord' compare the signer name in canonical wire form
-- (via 'equalWireHost' / 'compareWireHost'); canonical RR
-- ordering does not meaningfully apply to RRSIG (see 'X_sig').
pattern T_RRSIG :: RRTYPE -- ^ Type Covered
                -> DNSKEYAlg -- ^ Algorithm
                -> Word8 -- ^ Number of labels in the signed owner name, excluding any leading wildcard ('*') and the trailing root (RFC 4034 section 3.1.3)
                -> Word32 -- ^ Original TTL
                -> Int64 -- ^ Signature expiration as absolute 'Int64' time; 32-bit serial-number arithmetic on the wire (see 'X_sig' for the conversion)
                -> Int64 -- ^ Signature inception as absolute 'Int64' time; same serial-number caveat as 'rrsigExpiration'
                -> Word16 -- ^ Key Tag
                -> Domain -- ^ Signer's Name
                -> ShortByteString -- ^ Signature
                -> T_rrsig
pattern $bT_RRSIG :: RRTYPE
-> DNSKEYAlg
-> Word8
-> Word32
-> Int64
-> Int64
-> Word16
-> Domain
-> ShortByteString
-> T_rrsig
$mT_RRSIG :: forall {r}.
T_rrsig
-> (RRTYPE
    -> DNSKEYAlg
    -> Word8
    -> Word32
    -> Int64
    -> Int64
    -> Word16
    -> Domain
    -> ShortByteString
    -> r)
-> ((# #) -> r)
-> r
T_RRSIG
    { T_rrsig -> RRTYPE
rrsigType, T_rrsig -> DNSKEYAlg
rrsigKeyAlg, T_rrsig -> Word8
rrsigNumLabels, T_rrsig -> Word32
rrsigTTL
    , T_rrsig -> Int64
rrsigExpiration, T_rrsig -> Int64
rrsigInception, T_rrsig -> Word16
rrsigKeyTag, T_rrsig -> Domain
rrsigZone, T_rrsig -> ShortByteString
rrsigValue
    } = ( X_SIG rrsigType rrsigKeyAlg rrsigNumLabels rrsigTTL
                rrsigExpiration rrsigInception rrsigKeyTag rrsigZone rrsigValue
        :: T_rrsig )
{-# COMPLETE T_RRSIG #-}

-- | Record pattern synonym viewing the shared 'X_sig' record as a
-- legacy @SIG@ record (RFC 2535, section 4.1) or @SIG(0)@
-- transaction authenticator (RFC 2931).  Fields: 'sigType',
-- 'sigKeyAlg', 'sigNumLabels', 'sigTTL', 'sigExpiration',
-- 'sigInception', 'sigKeyTag', 'sigZone', 'sigValue'.  'Eq' and
-- 'Ord' compare the signer name in canonical wire form
-- (via 'equalWireHost' / 'compareWireHost'); see 'X_sig' for why
-- 'T_sig' and 'T_rrsig' are not coercible.
pattern T_SIG :: RRTYPE -- ^ Type Covered
              -> DNSKEYAlg -- ^ Algorithm
              -> Word8 -- ^ Number of labels in the signed owner name, excluding any leading wildcard ('*') and the trailing root (RFC 4034 section 3.1.3)
              -> Word32 -- ^ Original TTL
              -> Int64 -- ^ Signature expiration as absolute 'Int64' time; 32-bit serial-number arithmetic on the wire (see 'X_sig' for the conversion)
              -> Int64 -- ^ Signature inception as absolute 'Int64' time; same serial-number caveat as 'sigExpiration'
              -> Word16 -- ^ Key Tag
              -> Domain -- ^ Signer's Name
              -> ShortByteString -- ^ Signature
              -> T_sig
pattern $bT_SIG :: RRTYPE
-> DNSKEYAlg
-> Word8
-> Word32
-> Int64
-> Int64
-> Word16
-> Domain
-> ShortByteString
-> T_sig
$mT_SIG :: forall {r}.
T_sig
-> (RRTYPE
    -> DNSKEYAlg
    -> Word8
    -> Word32
    -> Int64
    -> Int64
    -> Word16
    -> Domain
    -> ShortByteString
    -> r)
-> ((# #) -> r)
-> r
T_SIG
    { T_sig -> RRTYPE
sigType, T_sig -> DNSKEYAlg
sigKeyAlg, T_sig -> Word8
sigNumLabels, T_sig -> Word32
sigTTL
    , T_sig -> Int64
sigExpiration, T_sig -> Int64
sigInception, T_sig -> Word16
sigKeyTag, T_sig -> Domain
sigZone, T_sig -> ShortByteString
sigValue
    } = ( X_SIG sigType sigKeyAlg sigNumLabels sigTTL
                sigExpiration sigInception sigKeyTag sigZone sigValue
        :: T_sig )
{-# COMPLETE T_SIG #-}

-------------------
-- RData structure Definitions

-- | Shared wire-format representation for DNSSEC delegation-signer
-- records: the parent-side @DS@ record
-- ([RFC 4034 section 5.1](https://datatracker.ietf.org/doc/html/rfc4034#section-5.1))
-- and the child-side @CDS@ announcement
-- ([RFC 7344 section 3.1](https://www.rfc-editor.org/rfc/rfc7344.html#section-3.1)).
--
-- >                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
-- >  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |           Key Tag             |  Algorithm    |  Digest Type  |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > /                                                               /
-- > /                            Digest                             /
-- > /                                                               /
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--
-- The type parameter @n@ (either 'N_ds' or 'N_cds') determines
-- the RR type.  Each has its own type synonym ('T_ds', 'T_cds')
-- and matching record pattern synonym ('T_DS', 'T_CDS') with the
-- corresponding field-name prefix (@ds@, @cds@).
--
-- The wire format is identical and the type role of @n@ is
-- @phantom@, so 'T_ds' and 'T_cds' are mutually coercible —
-- useful for promoting a child-side CDS announcement into a
-- parent-side DS without rebuilding the value.
--
-- Note that @T_ds@ and @T_cds@ are just type aliases!  The 'T_DS'
-- and 'T_CDS' record pattern synonyms and their fields are
-- bundled with the underlying 'X_ds' data type.  In many cases it
-- is sufficient to import just @X_ds(..)@, but if you also need
-- the type aliases, they need to be imported separately:
--
-- > import Net.DNSBase (X_ds(..), T_ds, T_cds)
--
-- No embedded domain field, so derived 'Ord' agrees with the
-- canonical wire-form octet ordering
-- ([RFC 4034 section 6.2](https://datatracker.ietf.org/doc/html/rfc4034#section-6.2)).
--
-- The record pattern synonyms 'T_DS' and 'T_CDS' build the
-- corresponding 'T_ds' or 'T_cds' value directly, with their own
-- field-name prefixes (@ds@ and @cds@):
--
-- > :set -XOverloadedStrings
-- > let ds  = T_DS  { dsKtag  = 12345
-- >                 , dsKalg  = 13
-- >                 , dsHalg  = 2
-- >                 , dsHval  = coerce @Bytes16 "0001...1e1f" }
-- >     cds = T_CDS { cdsKtag = 12345
-- >                 , cdsKalg = 13
-- >                 , cdsHalg = 2
-- >                 , cdsHval = coerce @Bytes16 "0001...1e1f" }
-- >  in RData ds : RData cds : []
--
-- Functions that work on either RR type can use the
-- underscore-prefixed selectors on the shared 'X_ds' record:
--
-- > hashTypeVal :: forall n. X_ds n -> (Word8, ShortByteString)
-- > hashTypeVal = (,) <$> x_dsHalg <*> x_dsHval
--
type X_ds :: Nat -> Type
data X_ds n = X_DS
    { forall (n :: Nat). X_ds n -> Word16
x_dsKtag :: Word16 -- ^ Key Tag
    , forall (n :: Nat). X_ds n -> DNSKEYAlg
x_dsKalg :: DNSKEYAlg -- ^ Algorithm
    , forall (n :: Nat). X_ds n -> DSHashAlg
x_dsHalg :: DSHashAlg -- ^ Digest Type
    , forall (n :: Nat). X_ds n -> ShortByteString
x_dsHval :: ShortByteString -- ^ Digest
    }
deriving instance (KnownSymbol (XdsConName n)) => Eq (X_ds n)
deriving instance (KnownSymbol (XdsConName n)) => Ord (X_ds n)

instance (Nat16 n, KnownSymbol (XdsConName n)) => Show (X_ds n) where
    showsPrec :: Int -> X_ds n -> ShowS
showsPrec Int
p X_DS{Word16
ShortByteString
DNSKEYAlg
DSHashAlg
x_dsKtag :: forall (n :: Nat). X_ds n -> Word16
x_dsKalg :: forall (n :: Nat). X_ds n -> DNSKEYAlg
x_dsHalg :: forall (n :: Nat). X_ds n -> DSHashAlg
x_dsHval :: forall (n :: Nat). X_ds n -> ShortByteString
x_dsKtag :: Word16
x_dsKalg :: DNSKEYAlg
x_dsHalg :: DSHashAlg
x_dsHval :: ShortByteString
..} = Int -> ShowS -> ShowS
showsP Int
p (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString (Proxy# (XdsConName n) -> String
forall (n :: Symbol). KnownSymbol n => Proxy# n -> String
symbolVal' (forall {k} (a :: k). Proxy# a
forall (a :: Symbol). Proxy# a
proxy# @(XdsConName n))) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> ShowS
forall a. Show a => a -> ShowS
shows' Word16
x_dsKtag     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> ShowS
forall a. Show a => a -> ShowS
shows' DNSKEYAlg
x_dsKalg     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DSHashAlg -> ShowS
forall a. Show a => a -> ShowS
shows' DSHashAlg
x_dsHalg     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ShowS
showHv ShortByteString
x_dsHval
      where
        showHv :: ShortByteString -> ShowS
showHv = forall a. Show a => a -> ShowS
shows @Bytes16 (Bytes16 -> ShowS)
-> (ShortByteString -> Bytes16) -> ShortByteString -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes16
forall a b. Coercible a b => a -> b
coerce

instance (KnownSymbol (XdsConName n)) => Presentable (X_ds n) where
    present :: X_ds n -> Builder -> Builder
present X_DS{Word16
ShortByteString
DNSKEYAlg
DSHashAlg
x_dsKtag :: forall (n :: Nat). X_ds n -> Word16
x_dsKalg :: forall (n :: Nat). X_ds n -> DNSKEYAlg
x_dsHalg :: forall (n :: Nat). X_ds n -> DSHashAlg
x_dsHval :: forall (n :: Nat). X_ds n -> ShortByteString
x_dsKtag :: Word16
x_dsKalg :: DNSKEYAlg
x_dsHalg :: DSHashAlg
x_dsHval :: ShortByteString
..} =
        Word16 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present     Word16
x_dsKtag
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp DNSKEYAlg
x_dsKalg
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DSHashAlg -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp DSHashAlg
x_dsHalg
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Builder -> Builder
presentHv ShortByteString
x_dsHval
      where
        presentHv :: ShortByteString -> Builder -> Builder
presentHv = forall a. Presentable a => a -> Builder -> Builder
presentSp @Bytes16 (Bytes16 -> Builder -> Builder)
-> (ShortByteString -> Bytes16)
-> ShortByteString
-> Builder
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes16
forall a b. Coercible a b => a -> b
coerce

instance (Nat16 n, KnownSymbol (XdsConName n)) => KnownRData (X_ds n) where
    rdType :: forall b -> (b ~ X_ds n) => RRTYPE
rdType _ = Word16 -> RRTYPE
RRTYPE (Word16 -> RRTYPE) -> Word16 -> RRTYPE
forall a b. (a -> b) -> a -> b
$ natToWord16 n
    {-# INLINE rdType #-}
    rdEncode :: forall s. X_ds n -> SPut s RData
rdEncode X_DS{Word16
ShortByteString
DNSKEYAlg
DSHashAlg
x_dsKtag :: forall (n :: Nat). X_ds n -> Word16
x_dsKalg :: forall (n :: Nat). X_ds n -> DNSKEYAlg
x_dsHalg :: forall (n :: Nat). X_ds n -> DSHashAlg
x_dsHval :: forall (n :: Nat). X_ds n -> ShortByteString
x_dsKtag :: Word16
x_dsKalg :: DNSKEYAlg
x_dsHalg :: DSHashAlg
x_dsHval :: ShortByteString
..} = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$!
           Word16 -> SizedBuilder
mbWord16       Word16
x_dsKtag
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Word8 -> SizedBuilder) -> DNSKEYAlg -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word8 -> SizedBuilder
mbWord8 DNSKEYAlg
x_dsKalg
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Word8 -> SizedBuilder) -> DSHashAlg -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word8 -> SizedBuilder
mbWord8 DSHashAlg
x_dsHalg
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
x_dsHval
    rdDecode :: forall b ->
(b ~ X_ds n) => RDataExtensionVal (X_ds n) -> Int -> SGet RData
rdDecode _ RDataExtensionVal (X_ds n)
_ = SGet RData -> Int -> SGet RData
forall a b. a -> b -> a
const do
        x_dsKtag <- SGet Word16
get16
        x_dsKalg <- DNSKEYAlg <$> get8
        x_dsHalg <- DSHashAlg <$> get8
        x_dsHval <- getShortByteString
        pure $ RData (X_DS{..} :: X_ds n)

-- | Shared wire-format representation for DNSSEC signing-key
-- records: the @DNSKEY@ record
-- ([RFC 4034 section 2](https://datatracker.ietf.org/doc/html/rfc4034#section-2))
-- published at the child zone apex, the @CDNSKEY@ child-side
-- announcement
-- ([RFC 7344 section 3.2](https://www.rfc-editor.org/rfc/rfc7344.html#section-3.2))
-- of which KSKs the parent should reference, and the legacy
-- @KEY@ record
-- ([RFC 2535 section 3.1](https://datatracker.ietf.org/doc/html/rfc2535#section-3.1))
-- still used by SIG(0) transaction authentication and otherwise
-- effectively unused in modern deployments.
--
-- >                       1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
-- >   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- >  |              Flags            |    Protocol   |   Algorithm   |
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- >  /                                                               /
-- >  /                            Public Key                         /
-- >  /                                                               /
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--
-- The type parameter @n@ (one of 'N_dnskey', 'N_cdnskey',
-- 'N_key') determines the RR type.  Each has its own type synonym
-- ('T_dnskey', 'T_cdnskey', 'T_key') and matching record pattern
-- synonym ('T_DNSKEY', 'T_CDNSKEY', 'T_KEY') with the
-- corresponding field-name prefix (@dnskey@, @cdnskey@, @key@).
-- The wire format is identical across all three and the type role
-- of @n@ is @phantom@, so the types are mutually coercible; the
-- practical pairing is DNSKEY \<-\> CDNSKEY (mirroring DS \<-\>
-- CDS).
--
-- Note that @T_dnskey@, @T_cdnskey@ and @T_key@ are just type
-- aliases!  The 'T_DNSKEY', 'T_CDNSKEY' and 'T_KEY' record
-- pattern synonyms and their fields are bundled with the
-- underlying 'X_key' data type.  In many cases it is sufficient
-- to import just @X_key(..)@, but if you also need the type
-- aliases, they need to be imported separately:
--
-- > import Net.DNSBase (X_key(..), T_dnskey, T_cdnskey, T_key)
--
-- No embedded domain field, so derived 'Ord' agrees with the
-- canonical wire-form octet ordering
-- ([RFC 4034 section 6.2](https://datatracker.ietf.org/doc/html/rfc4034#section-6.2)).
--
-- The record pattern synonyms build the corresponding type
-- directly, with their own field-name prefixes:
--
-- > :set -XOverloadedStrings
-- > let dk  = T_DNSKEY  { dnskeyFlags  = 257
-- >                     , dnskeyProto  = 3
-- >                     , dnskeyAlgor  = 13
-- >                     , dnskeyValue  = coerce @Bytes64 "3FOs...Kw==" }
-- >     cdk = T_CDNSKEY { cdnskeyFlags = 257
-- >                     , cdnskeyProto = 3
-- >                     , cdnskeyAlgor = 13
-- >                     , cdnskeyValue = coerce @Bytes64 "3FOs...Kw==" }
-- >  in RData dk : RData cdk : []
--
-- Functions that work on any of the three RR types can use the
-- underscore-prefixed selectors on the shared 'X_key' record:
--
-- > keyAlgVal :: forall n. X_key n -> (DNSKEYAlg, ShortByteString)
-- > keyAlgVal = (,) <$> x_keyAlgor <*> x_keyValue
type role X_key phantom
type X_key :: Nat -> Type
data X_key n = X_KEY
    { forall (n :: Nat). X_key n -> Word16
x_keyFlags :: Word16          -- ^ Flags
    , forall (n :: Nat). X_key n -> Word8
x_keyProto :: Word8           -- ^ Protocol
    , forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyAlgor :: DNSKEYAlg       -- ^ Algorithm
    , forall (n :: Nat). X_key n -> ShortByteString
x_keyValue :: ShortByteString -- ^ Public Key
    }
deriving instance (KnownSymbol (XkeyConName n)) => Eq (X_key n)
deriving instance (KnownSymbol (XkeyConName n)) => Ord (X_key n)

instance (Nat16 n, KnownSymbol (XkeyConName n)) => Show (X_key n) where
    showsPrec :: Int -> X_key n -> ShowS
showsPrec Int
p X_KEY{Word8
Word16
ShortByteString
DNSKEYAlg
x_keyFlags :: forall (n :: Nat). X_key n -> Word16
x_keyProto :: forall (n :: Nat). X_key n -> Word8
x_keyAlgor :: forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyValue :: forall (n :: Nat). X_key n -> ShortByteString
x_keyFlags :: Word16
x_keyProto :: Word8
x_keyAlgor :: DNSKEYAlg
x_keyValue :: ShortByteString
..} = Int -> ShowS -> ShowS
showsP Int
p (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString (Proxy# (XkeyConName n) -> String
forall (n :: Symbol). KnownSymbol n => Proxy# n -> String
symbolVal' (forall {k} (a :: k). Proxy# a
forall (a :: Symbol). Proxy# a
proxy# @(XkeyConName n))) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> ShowS
forall a. Show a => a -> ShowS
shows' Word16
x_keyFlags    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall a. Show a => a -> ShowS
shows' Word8
x_keyProto    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> ShowS
forall a. Show a => a -> ShowS
shows' DNSKEYAlg
x_keyAlgor    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ShowS
showKv ShortByteString
x_keyValue
      where
        showKv :: ShortByteString -> ShowS
showKv = forall a. Show a => a -> ShowS
shows @Bytes64 (Bytes64 -> ShowS)
-> (ShortByteString -> Bytes64) -> ShortByteString -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes64
forall a b. Coercible a b => a -> b
coerce

instance (KnownSymbol (XkeyConName n)) => Presentable (X_key n) where
    present :: X_key n -> Builder -> Builder
present X_KEY{Word8
Word16
ShortByteString
DNSKEYAlg
x_keyFlags :: forall (n :: Nat). X_key n -> Word16
x_keyProto :: forall (n :: Nat). X_key n -> Word8
x_keyAlgor :: forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyValue :: forall (n :: Nat). X_key n -> ShortByteString
x_keyFlags :: Word16
x_keyProto :: Word8
x_keyAlgor :: DNSKEYAlg
x_keyValue :: ShortByteString
..} =
        Word16 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present     Word16
x_keyFlags
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
x_keyProto
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp DNSKEYAlg
x_keyAlgor
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Builder -> Builder
presentKv ShortByteString
x_keyValue
      where
        presentKv :: ShortByteString -> Builder -> Builder
presentKv = forall a. Presentable a => a -> Builder -> Builder
presentSp @Bytes64 (Bytes64 -> Builder -> Builder)
-> (ShortByteString -> Bytes64)
-> ShortByteString
-> Builder
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes64
forall a b. Coercible a b => a -> b
coerce

instance (Nat16 n, KnownSymbol (XkeyConName n)) => KnownRData (X_key n) where
    rdType :: forall b -> (b ~ X_key n) => RRTYPE
rdType _ = Word16 -> RRTYPE
RRTYPE (Word16 -> RRTYPE) -> Word16 -> RRTYPE
forall a b. (a -> b) -> a -> b
$ natToWord16 n
    {-# INLINE rdType #-}
    rdEncode :: forall s. X_key n -> SPut s RData
rdEncode X_KEY{Word8
Word16
ShortByteString
DNSKEYAlg
x_keyFlags :: forall (n :: Nat). X_key n -> Word16
x_keyProto :: forall (n :: Nat). X_key n -> Word8
x_keyAlgor :: forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyValue :: forall (n :: Nat). X_key n -> ShortByteString
x_keyFlags :: Word16
x_keyProto :: Word8
x_keyAlgor :: DNSKEYAlg
x_keyValue :: ShortByteString
..} = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$!
        Word16 -> SizedBuilder
mbWord16   Word16
x_keyFlags
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8 Word8
x_keyProto
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Word8 -> SizedBuilder) -> DNSKEYAlg -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word8 -> SizedBuilder
mbWord8 DNSKEYAlg
x_keyAlgor
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
x_keyValue
    rdDecode :: forall b ->
(b ~ X_key n) => RDataExtensionVal (X_key n) -> Int -> SGet RData
rdDecode _ RDataExtensionVal (X_key n)
_ = SGet RData -> Int -> SGet RData
forall a b. a -> b -> a
const do
        x_keyFlags <- SGet Word16
get16
        x_keyProto <- get8
        x_keyAlgor <- DNSKEYAlg <$> get8
        x_keyValue <- getShortByteString
        pure $ RData (X_KEY{..} :: X_key n)

-- | Shared wire-format representation for DNSSEC signature
-- records: the @RRSIG@ record
-- ([RFC 4034 section 3](https://datatracker.ietf.org/doc/html/rfc4034#section-3))
-- that signs an RRSet, and the legacy @SIG@ record
-- ([RFC 2535 section 4.1](https://datatracker.ietf.org/doc/html/rfc2535#section-4.1))
-- and its @SIG(0)@ transaction-authentication use
-- ([RFC 2931 section 3](https://datatracker.ietf.org/doc/html/rfc2931#section-3)).
--
-- >                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
-- >  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |        Type Covered           |  Algorithm    |     Labels    |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |                         Original TTL                          |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |                      Signature Expiration                     |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |                      Signature Inception                      |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |            Key Tag            |                               |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         Signer's Name         +
-- > |                                                               /
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-/
-- > /                                                               /
-- > /                            Signature                          /
-- > /                                                               /
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--
-- The type parameter @n@ (either 'N_rrsig' or 'N_sig') determines
-- the RR type.  Each has its own type synonym ('T_rrsig', 'T_sig')
-- and matching record pattern synonym ('T_RRSIG', 'T_SIG') with
-- the corresponding field-name prefix (@rrsig@, @sig@).  The
-- wire format is shared, but the type role of @n@ is @nominal@:
-- a 'T_sig' value cannot be used where a 'T_rrsig' is expected.
-- This is deliberate — SIG(0) signs a single transaction while
-- RRSIG signs an RRSet, and conflating them at the type level
-- would be unsafe.
--
-- Note that @T_rrsig@ and @T_sig@ are just type aliases!  The 'T_RRSIG' and
-- 'T_SIG' record pattern synonyms and their fields are bundled
-- with the underlying 'X_sig' data type.  In many cases it is
-- sufficient to import just @X_sig(..)@, but if you also need the
-- type aliases, they need to be imported separately:
--
-- > import Net.DNSBase (X_sig(..), T_rrsig, T_sig)
--
-- As noted in
-- [Section 3.1.5 of RFC 4034](https://tools.ietf.org/html/rfc4034#section-3.1.5)
-- the RRsig inception and expiration times use serial number arithmetic.  As a
-- result these timestamps /are not/ pure values, their meaning is
-- time-dependent!  They depend on the present time and are both at most
-- approximately +\/-68 years from the present.  This ambiguity is not a
-- problem because cached RRSIG records should only persist a few days,
-- signature lifetimes should be *much* shorter than 68 years, and key rotation
-- should cause any misconstrued 136-year-old signatures to fail to validate.
-- This also means that the interpretation of a time that is exactly half-way
-- around the clock at @now +\/-0x80000000@ is not important, the signature
-- should never be valid.
--
-- To avoid ambiguity, these *impure* relative values are converted to pure
-- absolute times as they are received from from the network, and converted
-- back to 32-bit values when encoding.  Therefore, the constructor takes
-- absolute 64-bit representations of the inception and expiration times.
--
-- The signer zone name is not subject to wire-form name
-- compression
-- ([RFC 3597 section 4](https://datatracker.ietf.org/doc/html/rfc3597#section-4))
-- and canonicalises to lower case
-- ([RFC 4034 section 6.2](https://datatracker.ietf.org/doc/html/rfc4034#section-6.2),
-- confirmed by
-- [RFC 6840 section 5.1](https://datatracker.ietf.org/doc/html/rfc6840#section-5.1)).
-- The 'Eq' and 'Ord' instances compare the signer name in
-- canonical wire form (via 'equalWireHost' / 'compareWireHost'),
-- giving stable comparison semantics for general use in ordered
-- collections.  Canonical RR ordering is not a meaningful concept
-- for RRSIG records — they are never themselves signed — so the
-- canonical-ordering machinery from RFC 4034 §6.2 does not apply
-- to them in practice.
--
type role X_sig nominal
type X_sig :: Nat -> Type
data X_sig n = X_SIG
    { forall (n :: Nat). X_sig n -> RRTYPE
x_sigType       :: RRTYPE          -- ^ Type Covered
    , forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigKeyAlg     :: DNSKEYAlg       -- ^ Algorithm
    , forall (n :: Nat). X_sig n -> Word8
x_sigNumLabels  :: Word8           -- ^ Labels
    , forall (n :: Nat). X_sig n -> Word32
x_sigTTL        :: Word32          -- ^ Original TTL
    , forall (n :: Nat). X_sig n -> Int64
x_sigExpiration :: Int64           -- ^ Signature Expiration
    , forall (n :: Nat). X_sig n -> Int64
x_sigInception  :: Int64           -- ^ Signature Inception
    , forall (n :: Nat). X_sig n -> Word16
x_sigKeyTag     :: Word16          -- ^ Key Tag
    , forall (n :: Nat). X_sig n -> Domain
x_sigZone       :: Domain          -- ^ Signer's Name
    , forall (n :: Nat). X_sig n -> ShortByteString
x_sigValue      :: ShortByteString -- ^ Signature
    }

instance (Nat16 n, KnownSymbol (XsigConName n)) => Show (X_sig n) where
    showsPrec :: Int -> X_sig n -> ShowS
showsPrec Int
p X_SIG{Int64
Word8
Word16
Word32
ShortByteString
RRTYPE
Domain
DNSKEYAlg
x_sigType :: forall (n :: Nat). X_sig n -> RRTYPE
x_sigKeyAlg :: forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigNumLabels :: forall (n :: Nat). X_sig n -> Word8
x_sigTTL :: forall (n :: Nat). X_sig n -> Word32
x_sigExpiration :: forall (n :: Nat). X_sig n -> Int64
x_sigInception :: forall (n :: Nat). X_sig n -> Int64
x_sigKeyTag :: forall (n :: Nat). X_sig n -> Word16
x_sigZone :: forall (n :: Nat). X_sig n -> Domain
x_sigValue :: forall (n :: Nat). X_sig n -> ShortByteString
x_sigType :: RRTYPE
x_sigKeyAlg :: DNSKEYAlg
x_sigNumLabels :: Word8
x_sigTTL :: Word32
x_sigExpiration :: Int64
x_sigInception :: Int64
x_sigKeyTag :: Word16
x_sigZone :: Domain
x_sigValue :: ShortByteString
..} = Int -> ShowS -> ShowS
showsP Int
p (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString (Proxy# (XsigConName n) -> String
forall (n :: Symbol). KnownSymbol n => Proxy# n -> String
symbolVal' (forall {k} (a :: k). Proxy# a
forall (a :: Symbol). Proxy# a
proxy# @(XsigConName n))) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RRTYPE -> ShowS
forall a. Show a => a -> ShowS
shows' RRTYPE
x_sigType       ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> ShowS
forall a. Show a => a -> ShowS
shows' DNSKEYAlg
x_sigKeyAlg     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall a. Show a => a -> ShowS
shows' Word8
x_sigNumLabels  ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> ShowS
forall a. Show a => a -> ShowS
shows' Word32
x_sigTTL        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ShowS
forall a. Show a => a -> ShowS
shows' Int64
x_sigExpiration ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> ShowS
forall a. Show a => a -> ShowS
shows' Int64
x_sigInception  ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> ShowS
forall a. Show a => a -> ShowS
shows' Word16
x_sigKeyTag     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Domain -> ShowS
forall a. Show a => a -> ShowS
shows' Domain
x_sigZone       ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ShowS
showSv ShortByteString
x_sigValue
      where
        showSv :: ShortByteString -> ShowS
showSv = forall a. Show a => a -> ShowS
shows @Bytes64 (Bytes64 -> ShowS)
-> (ShortByteString -> Bytes64) -> ShortByteString -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes64
forall a b. Coercible a b => a -> b
coerce

-- | Equality of signer names is case-insensitive.
instance (KnownSymbol (XsigConName n)) => Eq  (X_sig n) where
    X_sig n
a == :: X_sig n -> X_sig n -> Bool
== X_sig n
b = (X_sig n -> RRTYPE
forall (n :: Nat). X_sig n -> RRTYPE
x_sigType       X_sig n
a) RRTYPE -> RRTYPE -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> RRTYPE
forall (n :: Nat). X_sig n -> RRTYPE
x_sigType       X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> DNSKEYAlg
forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigKeyAlg     X_sig n
a) DNSKEYAlg -> DNSKEYAlg -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> DNSKEYAlg
forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigKeyAlg     X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Word8
forall (n :: Nat). X_sig n -> Word8
x_sigNumLabels  X_sig n
a) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> Word8
forall (n :: Nat). X_sig n -> Word8
x_sigNumLabels  X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Word32
forall (n :: Nat). X_sig n -> Word32
x_sigTTL        X_sig n
a) Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> Word32
forall (n :: Nat). X_sig n -> Word32
x_sigTTL        X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigExpiration X_sig n
a) Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigExpiration X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigInception  X_sig n
a) Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigInception  X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Word16
forall (n :: Nat). X_sig n -> Word16
x_sigKeyTag     X_sig n
a) Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> Word16
forall (n :: Nat). X_sig n -> Word16
x_sigKeyTag     X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> Domain
forall (n :: Nat). X_sig n -> Domain
x_sigZone X_sig n
a) Domain -> Domain -> Bool
`equalWireHost` (X_sig n -> Domain
forall (n :: Nat). X_sig n -> Domain
x_sigZone X_sig n
b)
          Bool -> Bool -> Bool
&& (X_sig n -> ShortByteString
forall (n :: Nat). X_sig n -> ShortByteString
x_sigValue      X_sig n
a) ShortByteString -> ShortByteString -> Bool
forall a. Eq a => a -> a -> Bool
== (X_sig n -> ShortByteString
forall (n :: Nat). X_sig n -> ShortByteString
x_sigValue      X_sig n
b)

-- | Comparison of signer names is case-insensitive.
instance (KnownSymbol (XsigConName n)) => Ord (X_sig n) where
    X_sig n
a compare :: X_sig n -> X_sig n -> Ordering
`compare` X_sig n
b = (X_sig n -> RRTYPE
forall (n :: Nat). X_sig n -> RRTYPE
x_sigType       X_sig n
a) RRTYPE -> RRTYPE -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> RRTYPE
forall (n :: Nat). X_sig n -> RRTYPE
x_sigType       X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> DNSKEYAlg
forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigKeyAlg     X_sig n
a) DNSKEYAlg -> DNSKEYAlg -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> DNSKEYAlg
forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigKeyAlg     X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Word8
forall (n :: Nat). X_sig n -> Word8
x_sigNumLabels  X_sig n
a) Word8 -> Word8 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> Word8
forall (n :: Nat). X_sig n -> Word8
x_sigNumLabels  X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Word32
forall (n :: Nat). X_sig n -> Word32
x_sigTTL        X_sig n
a) Word32 -> Word32 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> Word32
forall (n :: Nat). X_sig n -> Word32
x_sigTTL        X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigExpiration X_sig n
a) Int64 -> Int64 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigExpiration X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigInception  X_sig n
a) Int64 -> Int64 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> Int64
forall (n :: Nat). X_sig n -> Int64
x_sigInception  X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Word16
forall (n :: Nat). X_sig n -> Word16
x_sigKeyTag     X_sig n
a) Word16 -> Word16 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> Word16
forall (n :: Nat). X_sig n -> Word16
x_sigKeyTag     X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> Domain
forall (n :: Nat). X_sig n -> Domain
x_sigZone X_sig n
a) Domain -> Domain -> Ordering
`compareWireHost` (X_sig n -> Domain
forall (n :: Nat). X_sig n -> Domain
x_sigZone     X_sig n
b)
                 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (X_sig n -> ShortByteString
forall (n :: Nat). X_sig n -> ShortByteString
x_sigValue      X_sig n
a) ShortByteString -> ShortByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (X_sig n -> ShortByteString
forall (n :: Nat). X_sig n -> ShortByteString
x_sigValue      X_sig n
b)

instance (KnownSymbol (XsigConName n)) => Presentable (X_sig n) where
    present :: X_sig n -> Builder -> Builder
present X_SIG{Int64
Word8
Word16
Word32
ShortByteString
RRTYPE
Domain
DNSKEYAlg
x_sigType :: forall (n :: Nat). X_sig n -> RRTYPE
x_sigKeyAlg :: forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigNumLabels :: forall (n :: Nat). X_sig n -> Word8
x_sigTTL :: forall (n :: Nat). X_sig n -> Word32
x_sigExpiration :: forall (n :: Nat). X_sig n -> Int64
x_sigInception :: forall (n :: Nat). X_sig n -> Int64
x_sigKeyTag :: forall (n :: Nat). X_sig n -> Word16
x_sigZone :: forall (n :: Nat). X_sig n -> Domain
x_sigValue :: forall (n :: Nat). X_sig n -> ShortByteString
x_sigType :: RRTYPE
x_sigKeyAlg :: DNSKEYAlg
x_sigNumLabels :: Word8
x_sigTTL :: Word32
x_sigExpiration :: Int64
x_sigInception :: Int64
x_sigKeyTag :: Word16
x_sigZone :: Domain
x_sigValue :: ShortByteString
..} =
        RRTYPE -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present     RRTYPE
x_sigType
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DNSKEYAlg -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp DNSKEYAlg
x_sigKeyAlg
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
x_sigNumLabels
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word32
x_sigTTL
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder -> Builder
presentEp Int64
x_sigExpiration
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder -> Builder
presentEp Int64
x_sigInception
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word16
x_sigKeyTag
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Domain -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Domain
x_sigZone
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Builder -> Builder
presentSv ShortByteString
x_sigValue
      where
        presentEp :: Int64 -> Builder -> Builder
presentEp = forall a. Presentable a => a -> Builder -> Builder
presentSp @Epoch64 (Epoch64 -> Builder -> Builder)
-> (Int64 -> Epoch64) -> Int64 -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Epoch64
forall a b. Coercible a b => a -> b
coerce
        presentSv :: ShortByteString -> Builder -> Builder
presentSv = forall a. Presentable a => a -> Builder -> Builder
presentSp @Bytes64 (Bytes64 -> Builder -> Builder)
-> (ShortByteString -> Bytes64)
-> ShortByteString
-> Builder
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes64
forall a b. Coercible a b => a -> b
coerce

instance (Nat16 n, KnownSymbol (XsigConName n)) => KnownRData (X_sig n) where
    rdType :: forall b -> (b ~ X_sig n) => RRTYPE
rdType _ = Word16 -> RRTYPE
RRTYPE (Word16 -> RRTYPE) -> Word16 -> RRTYPE
forall a b. (a -> b) -> a -> b
$ natToWord16 n
    {-# INLINE rdType #-}
    rdEncode :: forall s. X_sig n -> SPut s RData
rdEncode X_SIG{Int64
Word8
Word16
Word32
ShortByteString
RRTYPE
Domain
DNSKEYAlg
x_sigType :: forall (n :: Nat). X_sig n -> RRTYPE
x_sigKeyAlg :: forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigNumLabels :: forall (n :: Nat). X_sig n -> Word8
x_sigTTL :: forall (n :: Nat). X_sig n -> Word32
x_sigExpiration :: forall (n :: Nat). X_sig n -> Int64
x_sigInception :: forall (n :: Nat). X_sig n -> Int64
x_sigKeyTag :: forall (n :: Nat). X_sig n -> Word16
x_sigZone :: forall (n :: Nat). X_sig n -> Domain
x_sigValue :: forall (n :: Nat). X_sig n -> ShortByteString
x_sigType :: RRTYPE
x_sigKeyAlg :: DNSKEYAlg
x_sigNumLabels :: Word8
x_sigTTL :: Word32
x_sigExpiration :: Int64
x_sigInception :: Int64
x_sigKeyTag :: Word16
x_sigZone :: Domain
x_sigValue :: ShortByteString
..} = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$
        (Word16 -> SizedBuilder) -> RRTYPE -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word16 -> SizedBuilder
mbWord16     RRTYPE
x_sigType
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Word8 -> SizedBuilder) -> DNSKEYAlg -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word8 -> SizedBuilder
mbWord8   DNSKEYAlg
x_sigKeyAlg
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8          Word8
x_sigNumLabels
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word32 -> SizedBuilder
mbWord32         Word32
x_sigTTL
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> SizedBuilder) -> Int64 -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Int64 -> SizedBuilder
clock     Int64
x_sigExpiration
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> SizedBuilder) -> Int64 -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Int64 -> SizedBuilder
clock     Int64
x_sigInception
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word16 -> SizedBuilder
mbWord16         Word16
x_sigKeyTag
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Domain -> SizedBuilder
mbWireForm       Domain
x_sigZone
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
x_sigValue
      where
        clock :: Int64 -> SizedBuilder
        clock :: Int64 -> SizedBuilder
clock = Word32 -> SizedBuilder
mbWord32 (Word32 -> SizedBuilder)
-> (Int64 -> Word32) -> Int64 -> SizedBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    cnEncode :: forall s. X_sig n -> SPut s RData
cnEncode X_SIG{Int64
Word8
Word16
Word32
ShortByteString
RRTYPE
Domain
DNSKEYAlg
x_sigType :: forall (n :: Nat). X_sig n -> RRTYPE
x_sigKeyAlg :: forall (n :: Nat). X_sig n -> DNSKEYAlg
x_sigNumLabels :: forall (n :: Nat). X_sig n -> Word8
x_sigTTL :: forall (n :: Nat). X_sig n -> Word32
x_sigExpiration :: forall (n :: Nat). X_sig n -> Int64
x_sigInception :: forall (n :: Nat). X_sig n -> Int64
x_sigKeyTag :: forall (n :: Nat). X_sig n -> Word16
x_sigZone :: forall (n :: Nat). X_sig n -> Domain
x_sigValue :: forall (n :: Nat). X_sig n -> ShortByteString
x_sigType :: RRTYPE
x_sigKeyAlg :: DNSKEYAlg
x_sigNumLabels :: Word8
x_sigTTL :: Word32
x_sigExpiration :: Int64
x_sigInception :: Int64
x_sigKeyTag :: Word16
x_sigZone :: Domain
x_sigValue :: ShortByteString
..} = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$
        (Word16 -> SizedBuilder) -> RRTYPE -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word16 -> SizedBuilder
mbWord16     RRTYPE
x_sigType
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Word8 -> SizedBuilder) -> DNSKEYAlg -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Word8 -> SizedBuilder
mbWord8   DNSKEYAlg
x_sigKeyAlg
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8          Word8
x_sigNumLabels
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word32 -> SizedBuilder
mbWord32         Word32
x_sigTTL
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> SizedBuilder) -> Int64 -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Int64 -> SizedBuilder
clock     Int64
x_sigExpiration
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> SizedBuilder) -> Int64 -> SizedBuilder
forall a b. Coercible a b => a -> b
coerce Int64 -> SizedBuilder
clock     Int64
x_sigInception
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word16 -> SizedBuilder
mbWord16         Word16
x_sigKeyTag
        SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Domain -> SizedBuilder
mbWireForm (Domain -> Domain
canonicalise Domain
x_sigZone)
        -- | Canonical encoding of the RRSIG omits the signature value.
      where
        clock :: Int64 -> SizedBuilder
        clock :: Int64 -> SizedBuilder
clock = Word32 -> SizedBuilder
mbWord32 (Word32 -> SizedBuilder)
-> (Int64 -> Word32) -> Int64 -> SizedBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    rdDecode :: forall b ->
(b ~ X_sig n) => RDataExtensionVal (X_sig n) -> Int -> SGet RData
rdDecode _ RDataExtensionVal (X_sig n)
_ = SGet RData -> Int -> SGet RData
forall a b. a -> b -> a
const do
        x_sigType       <- Word16 -> RRTYPE
RRTYPE (Word16 -> RRTYPE) -> SGet Word16 -> SGet RRTYPE
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet Word16
get16
        x_sigKeyAlg     <- DNSKEYAlg <$> get8
        x_sigNumLabels  <- get8
        x_sigTTL        <- get32
        x_sigExpiration <- getDnsTime
        x_sigInception  <- getDnsTime
        x_sigKeyTag     <- get16
        x_sigZone       <- getDomainNC
        x_sigValue      <- getShortByteString
        pure $ RData (X_SIG{..} :: X_sig n)

-- | The @ZONEMD@ resource record
-- ([RFC 8976 section 2.2](https://www.rfc-editor.org/rfc/rfc8976#section-2.2))
-- — a digest of the zone contents, used by recipients of zone
-- transfers to verify zone integrity end-to-end.  Four fields:
-- a 32-bit serial number matching the SOA, an 8-bit scheme
-- selector, an 8-bit hash-algorithm selector, and the digest
-- bytes.
--
-- >                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
-- >  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |                             Serial                            |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- > |    Scheme     |Hash Algorithm |                               |
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
-- > |                             Digest                            |
-- > /                                                               /
-- > /                                                               /
-- > +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--
-- No embedded domain field, so derived 'Ord' agrees with the
-- canonical wire-form octet ordering.
data T_zonemd = T_ZONEMD
    { T_zonemd -> Word32
zonemdSerial  :: Word32 -- ^ Serial
    , T_zonemd -> Word8
zonemdScheme  :: Word8  -- ^ Scheme
    , T_zonemd -> Word8
zonemdHashAlg :: Word8  -- ^ Hash Algorithm
    , T_zonemd -> ShortByteString
zonemdDigest  :: ShortByteString -- ^ Digest
    } deriving (T_zonemd -> T_zonemd -> Bool
(T_zonemd -> T_zonemd -> Bool)
-> (T_zonemd -> T_zonemd -> Bool) -> Eq T_zonemd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: T_zonemd -> T_zonemd -> Bool
== :: T_zonemd -> T_zonemd -> Bool
$c/= :: T_zonemd -> T_zonemd -> Bool
/= :: T_zonemd -> T_zonemd -> Bool
Eq, Eq T_zonemd
Eq T_zonemd =>
(T_zonemd -> T_zonemd -> Ordering)
-> (T_zonemd -> T_zonemd -> Bool)
-> (T_zonemd -> T_zonemd -> Bool)
-> (T_zonemd -> T_zonemd -> Bool)
-> (T_zonemd -> T_zonemd -> Bool)
-> (T_zonemd -> T_zonemd -> T_zonemd)
-> (T_zonemd -> T_zonemd -> T_zonemd)
-> Ord T_zonemd
T_zonemd -> T_zonemd -> Bool
T_zonemd -> T_zonemd -> Ordering
T_zonemd -> T_zonemd -> T_zonemd
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: T_zonemd -> T_zonemd -> Ordering
compare :: T_zonemd -> T_zonemd -> Ordering
$c< :: T_zonemd -> T_zonemd -> Bool
< :: T_zonemd -> T_zonemd -> Bool
$c<= :: T_zonemd -> T_zonemd -> Bool
<= :: T_zonemd -> T_zonemd -> Bool
$c> :: T_zonemd -> T_zonemd -> Bool
> :: T_zonemd -> T_zonemd -> Bool
$c>= :: T_zonemd -> T_zonemd -> Bool
>= :: T_zonemd -> T_zonemd -> Bool
$cmax :: T_zonemd -> T_zonemd -> T_zonemd
max :: T_zonemd -> T_zonemd -> T_zonemd
$cmin :: T_zonemd -> T_zonemd -> T_zonemd
min :: T_zonemd -> T_zonemd -> T_zonemd
Ord)

instance Show T_zonemd where
    showsPrec :: Int -> T_zonemd -> ShowS
showsPrec Int
p T_ZONEMD{Word8
Word32
ShortByteString
zonemdSerial :: T_zonemd -> Word32
zonemdScheme :: T_zonemd -> Word8
zonemdHashAlg :: T_zonemd -> Word8
zonemdDigest :: T_zonemd -> ShortByteString
zonemdSerial :: Word32
zonemdScheme :: Word8
zonemdHashAlg :: Word8
zonemdDigest :: ShortByteString
..} = Int -> ShowS -> ShowS
showsP Int
p (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
        String -> ShowS
showString String
"X_SIG"     ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> ShowS
forall a. Show a => a -> ShowS
shows' Word32
zonemdSerial  ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall a. Show a => a -> ShowS
shows' Word8
zonemdScheme  ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall a. Show a => a -> ShowS
shows' Word8
zonemdHashAlg ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> ShowS
showMd ShortByteString
zonemdDigest
      where
        showMd :: ShortByteString -> ShowS
showMd = forall a. Show a => a -> ShowS
shows @Bytes16 (Bytes16 -> ShowS)
-> (ShortByteString -> Bytes16) -> ShortByteString -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Bytes16
forall a b. Coercible a b => a -> b
coerce

instance Presentable T_zonemd where
    present :: T_zonemd -> Builder -> Builder
present T_ZONEMD{Word8
Word32
ShortByteString
zonemdSerial :: T_zonemd -> Word32
zonemdScheme :: T_zonemd -> Word8
zonemdHashAlg :: T_zonemd -> Word8
zonemdDigest :: T_zonemd -> ShortByteString
zonemdSerial :: Word32
zonemdScheme :: Word8
zonemdHashAlg :: Word8
zonemdDigest :: ShortByteString
..} =
        Word32 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present   Word32
zonemdSerial
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
zonemdScheme
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
zonemdHashAlg
        (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortByteString -> Builder -> Builder
presentMd ShortByteString
zonemdDigest
      where
        presentMd :: ShortByteString -> Builder -> Builder
presentMd ShortByteString
d | ShortByteString -> Bool
SB.null ShortByteString
d = forall a. Presentable a => a -> Builder -> Builder
present @String String
" ( )"
                    | Bool
otherwise = forall a. Presentable a => a -> Builder -> Builder
presentSp @Bytes16 (ShortByteString -> Bytes16
forall a b. Coercible a b => a -> b
coerce ShortByteString
d)

instance KnownRData T_zonemd where
    rdType :: forall b -> (b ~ T_zonemd) => RRTYPE
rdType _ = RRTYPE
ZONEMD
    {-# INLINE rdType #-}
    rdEncode :: forall s. T_zonemd -> SPut s RData
rdEncode T_ZONEMD{Word8
Word32
ShortByteString
zonemdSerial :: T_zonemd -> Word32
zonemdScheme :: T_zonemd -> Word8
zonemdHashAlg :: T_zonemd -> Word8
zonemdDigest :: T_zonemd -> ShortByteString
zonemdSerial :: Word32
zonemdScheme :: Word8
zonemdHashAlg :: Word8
zonemdDigest :: ShortByteString
..}
        | ShortByteString -> Int
SB.length (ShortByteString -> ShortByteString
forall a b. Coercible a b => a -> b
coerce ShortByteString
zonemdDigest) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
12
        = (forall a. ErrorContext a => a -> EncodeErr a) -> SPut s RData
forall r s.
ErrorContext r =>
(forall a. ErrorContext a => a -> EncodeErr a) -> SPut s r
failWith a -> EncodeErr a
forall r. (Typeable r, Show r, Eq r) => r -> EncodeErr r
forall a. ErrorContext a => a -> EncodeErr a
CantEncode
        | Bool
otherwise
        = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$
            Word32 -> SizedBuilder
mbWord32 Word32
zonemdSerial
            SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8 Word8
zonemdScheme
            SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8 Word8
zonemdHashAlg
            SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
zonemdDigest
    rdDecode :: forall b ->
(b ~ T_zonemd) => RDataExtensionVal T_zonemd -> Int -> SGet RData
rdDecode _ RDataExtensionVal T_zonemd
_ Int
len
        | Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
18 = String -> SGet RData
forall a. String -> SGet a
failSGet String
"ZONEMD digest too short"
        | Bool
otherwise = do
            zonemdSerial    <- SGet Word32
get32
            zonemdScheme    <- get8
            zonemdHashAlg   <- get8
            zonemdDigest    <- getShortByteString
            pure $ RData T_ZONEMD{..}

-- | The @IPSECKEY@ resource record
-- ([RFC 4025 section 2.1](https://datatracker.ietf.org/doc/html/rfc4025#section-2.1))
-- — IPsec keying material for a host or subnet.
--
-- >   0                   1                   2                   3
-- >   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- >  |  precedence   | gateway type  |  algorithm    |   gateway     |
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---------------+               +
-- >  ~                            gateway                            ~
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- >  |                                                               /
-- >  /                          public key                           /
-- >  /                                                               /
-- >  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
--
-- The /gateway type/ byte selects one of four defined gateway shapes
-- (none, IPv4, IPv6, or FQDN); the /gateway/ field carries the
-- corresponding value, and the trailing /public key/ holds the key
-- bytes.
--
-- For future or otherwise unrecognised gateway types (any value
-- outside 0..3) the wire-form boundary between the gateway and the
-- public key is unknown to the parser, so both are kept together as
-- a single opaque blob inside 'IPSecKeyGWG', and the @key@ component
-- below is then empty.
--
-- The constructors are not exported; the only public view is the
-- 'IPSecKey' bidirectional pattern synonym, which exposes a uniform
-- five-argument tuple @(precedence, gateway type, algorithm,
-- gateway, public key)@ regardless of the gateway shape.
--
type T_ipseckey :: Type
data T_ipseckey
    = IPSecX_ Word8 Word8 ShortByteString        -- ^ No gateway (type 0); fields: precedence, algorithm, public key.
    | IPSec4_ Word8 Word8 IPv4 ShortByteString   -- ^ IPv4 gateway (type 1); fields: precedence, algorithm, gateway, public key.
    | IPSec6_ Word8 Word8 IPv6 ShortByteString   -- ^ IPv6 gateway (type 2); fields: precedence, algorithm, gateway, public key.
    | IPSecD_ Word8 Word8 Domain ShortByteString -- ^ FQDN gateway (type 3); fields: precedence, algorithm, gateway, public key.
    | IPSecG_ Word8 Word8 Word8 ShortByteString  -- ^ Future or unrecognised gateway type (\>3); fields: precedence, gateway type, algorithm, opaque (gateway+key) blob.
   deriving (T_ipseckey -> T_ipseckey -> Bool
(T_ipseckey -> T_ipseckey -> Bool)
-> (T_ipseckey -> T_ipseckey -> Bool) -> Eq T_ipseckey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: T_ipseckey -> T_ipseckey -> Bool
== :: T_ipseckey -> T_ipseckey -> Bool
$c/= :: T_ipseckey -> T_ipseckey -> Bool
/= :: T_ipseckey -> T_ipseckey -> Bool
Eq, Int -> T_ipseckey -> ShowS
[T_ipseckey] -> ShowS
T_ipseckey -> String
(Int -> T_ipseckey -> ShowS)
-> (T_ipseckey -> String)
-> ([T_ipseckey] -> ShowS)
-> Show T_ipseckey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> T_ipseckey -> ShowS
showsPrec :: Int -> T_ipseckey -> ShowS
$cshow :: T_ipseckey -> String
show :: T_ipseckey -> String
$cshowList :: [T_ipseckey] -> ShowS
showList :: [T_ipseckey] -> ShowS
Show)

instance Ord T_ipseckey where
    (IPSecKey Word8
pa Word8
ta Word8
aa IPSecKeyGateway
ga ShortByteString
ka) compare :: T_ipseckey -> T_ipseckey -> Ordering
`compare` (IPSecKey Word8
pb Word8
tb Word8
ab IPSecKeyGateway
gb ShortByteString
kb) =
        Word8
pa Word8 -> Word8 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Word8
pb
        Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Word8
ta Word8 -> Word8 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Word8
tb
        Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Word8
aa Word8 -> Word8 -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Word8
ab
        Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> IPSecKeyGateway
ga IPSecKeyGateway -> IPSecKeyGateway -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` IPSecKeyGateway
gb
        Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> ShortByteString
ka ShortByteString -> ShortByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` ShortByteString
kb

instance Presentable T_ipseckey where
    present :: T_ipseckey -> Builder -> Builder
present (IPSecKey Word8
p Word8
t Word8
a IPSecKeyGateway
g ShortByteString
k)
        | IPSecKeyGWG ShortByteString
bytes <- IPSecKeyGateway
g = \Builder
kont -> String -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present String
"\\#"
            (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$ Int -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ShortByteString -> Int
SB.length ShortByteString
bytes)
            (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$ Char -> Builder
B.char8 Char
' ' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
B.word8HexFixed Word8
p Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
B.word8HexFixed Word8
t Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Word8 -> Builder
B.word8HexFixed Word8
a
              Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> forall a. Presentable a => a -> Builder -> Builder
present @Bytes16 (ShortByteString -> Bytes16
forall a b. Coercible a b => a -> b
coerce ShortByteString
bytes) Builder
kont
        | Bool
otherwise = Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Word8
p
                    (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
t
                    (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp Word8
a
                    (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IPSecKeyGateway -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
presentSp IPSecKeyGateway
g
                    (Builder -> Builder) -> (Builder -> Builder) -> Builder -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Presentable a => a -> Builder -> Builder
presentSp @Bytes64 (ShortByteString -> Bytes64
forall a b. Coercible a b => a -> b
coerce ShortByteString
k)

instance KnownRData T_ipseckey where
    rdType :: forall b -> (b ~ T_ipseckey) => RRTYPE
rdType _ = RRTYPE
IPSECKEY
    {-# INLINE rdType #-}
    rdEncode :: forall s. T_ipseckey -> SPut s RData
rdEncode (IPSecKey Word8
p Word8
t Word8
a IPSecKeyGateway
g ShortByteString
k) = SizedBuilder -> SPut s RData
forall r s. ErrorContext r => SizedBuilder -> SPut s r
putSizedBuilder (SizedBuilder -> SPut s RData) -> SizedBuilder -> SPut s RData
forall a b. (a -> b) -> a -> b
$
        Word8 -> SizedBuilder
mbWord8 Word8
p SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8 Word8
t SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> Word8 -> SizedBuilder
mbWord8 Word8
a SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> IPSecKeyGateway -> SizedBuilder
mbgk IPSecKeyGateway
g
      where
        mbgk :: IPSecKeyGateway -> SizedBuilder
mbgk IPSecKeyGateway
IPSecKeyGWX      = ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
k
        mbgk (IPSecKeyGW4 IPv4
ip) = IPv4 -> SizedBuilder
mbIPv4 IPv4
ip SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
k
        mbgk (IPSecKeyGW6 IPv6
ip) = IPv6 -> SizedBuilder
mbIPv6 IPv6
ip SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
k
        mbgk (IPSecKeyGWD Domain
dn) = Domain -> SizedBuilder
mbWireForm Domain
dn SizedBuilder -> SizedBuilder -> SizedBuilder
forall a. Semigroup a => a -> a -> a
<> ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
k
        mbgk (IPSecKeyGWG ShortByteString
gk)  = ShortByteString -> SizedBuilder
mbShortByteString ShortByteString
gk
    rdDecode :: forall b ->
(b ~ T_ipseckey) =>
RDataExtensionVal T_ipseckey -> Int -> SGet RData
rdDecode _ RDataExtensionVal T_ipseckey
_ = SGet RData -> Int -> SGet RData
forall a b. a -> b -> a
const do
        p <- SGet Word8
get8
        t <- get8
        a <- get8
        case t of
            Word8
0 -> T_ipseckey -> RData
forall a. KnownRData a => a -> RData
RData (T_ipseckey -> RData)
-> (ShortByteString -> T_ipseckey) -> ShortByteString -> RData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word8 -> ShortByteString -> T_ipseckey
IPSecX_ Word8
p Word8
a (ShortByteString -> RData) -> SGet ShortByteString -> SGet RData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet ShortByteString
getShortByteString
            Word8
1 -> T_ipseckey -> RData
forall a. KnownRData a => a -> RData
RData (T_ipseckey -> RData) -> SGet T_ipseckey -> SGet RData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$.> Word8 -> Word8 -> IPv4 -> ShortByteString -> T_ipseckey
IPSec4_ Word8
p Word8
a (IPv4 -> ShortByteString -> T_ipseckey)
-> SGet IPv4 -> SGet (ShortByteString -> T_ipseckey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet IPv4
getIPv4 SGet (ShortByteString -> T_ipseckey)
-> SGet ShortByteString -> SGet T_ipseckey
forall a b. SGet (a -> b) -> SGet a -> SGet b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SGet ShortByteString
getShortByteString
            Word8
2 -> T_ipseckey -> RData
forall a. KnownRData a => a -> RData
RData (T_ipseckey -> RData) -> SGet T_ipseckey -> SGet RData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$.> Word8 -> Word8 -> IPv6 -> ShortByteString -> T_ipseckey
IPSec6_ Word8
p Word8
a (IPv6 -> ShortByteString -> T_ipseckey)
-> SGet IPv6 -> SGet (ShortByteString -> T_ipseckey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet IPv6
getIPv6 SGet (ShortByteString -> T_ipseckey)
-> SGet ShortByteString -> SGet T_ipseckey
forall a b. SGet (a -> b) -> SGet a -> SGet b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SGet ShortByteString
getShortByteString
            Word8
3 -> T_ipseckey -> RData
forall a. KnownRData a => a -> RData
RData (T_ipseckey -> RData) -> SGet T_ipseckey -> SGet RData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$.> Word8 -> Word8 -> Domain -> ShortByteString -> T_ipseckey
IPSecD_ Word8
p Word8
a (Domain -> ShortByteString -> T_ipseckey)
-> SGet Domain -> SGet (ShortByteString -> T_ipseckey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet Domain
getDomain SGet (ShortByteString -> T_ipseckey)
-> SGet ShortByteString -> SGet T_ipseckey
forall a b. SGet (a -> b) -> SGet a -> SGet b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SGet ShortByteString
getShortByteString
            Word8
_ -> T_ipseckey -> RData
forall a. KnownRData a => a -> RData
RData (T_ipseckey -> RData)
-> (ShortByteString -> T_ipseckey) -> ShortByteString -> RData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word8 -> Word8 -> ShortByteString -> T_ipseckey
IPSecG_ Word8
p Word8
t Word8
a (ShortByteString -> RData) -> SGet ShortByteString -> SGet RData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SGet ShortByteString
getShortByteString

-- | Uniform five-argument view of an 'T_ipseckey' record.
--
-- When matching against an existing record, /gateway type/ and
-- /gateway/ are always consistent (an 'IPSecKeyGW4' value implies
-- @gateway type == 1@, and so on).
--
-- When /constructing/ a record, the /gateway type/ and /gateway/
-- arguments must agree, and for unrecognised gateway types
-- (anything outside 0..3) the /public key/ argument must be empty
-- (the parser cannot find the boundary, so the gateway-and-key
-- bytes live together inside the 'IPSecKeyGWG' payload).  Valid
-- combinations are:
--
-- * @0@ with 'IPSecKeyGWX' — no gateway
-- * @1@ with 'IPSecKeyGW4' — IPv4 gateway
-- * @2@ with 'IPSecKeyGW6' — IPv6 gateway
-- * @3@ with 'IPSecKeyGWD' — FQDN gateway
-- * any other type byte with 'IPSecKeyGWG' and empty key
--
-- Any other combination raises a runtime error.
pattern IPSecKey :: Word8 -- ^ precedence
                 -> Word8 -- ^ gateway type
                 -> Word8 -- ^ algorithm
                 -> IPSecKeyGateway -- ^ gateway
                 -> ShortByteString -- ^ public key
                 -> T_ipseckey
pattern $bIPSecKey :: Word8
-> Word8
-> Word8
-> IPSecKeyGateway
-> ShortByteString
-> T_ipseckey
$mIPSecKey :: forall {r}.
T_ipseckey
-> (Word8
    -> Word8 -> Word8 -> IPSecKeyGateway -> ShortByteString -> r)
-> ((# #) -> r)
-> r
IPSecKey p t a g k <- (ipSecDecon -> (p, t, a, g, k)) where
    IPSecKey Word8
p Word8
0 Word8
a IPSecKeyGateway
IPSecKeyGWX ShortByteString
k      = Word8 -> Word8 -> ShortByteString -> T_ipseckey
IPSecX_ Word8
p Word8
a ShortByteString
k
    IPSecKey Word8
p Word8
1 Word8
a (IPSecKeyGW4 IPv4
ip) ShortByteString
k = Word8 -> Word8 -> IPv4 -> ShortByteString -> T_ipseckey
IPSec4_ Word8
p Word8
a IPv4
ip ShortByteString
k
    IPSecKey Word8
p Word8
2 Word8
a (IPSecKeyGW6 IPv6
ip) ShortByteString
k = Word8 -> Word8 -> IPv6 -> ShortByteString -> T_ipseckey
IPSec6_ Word8
p Word8
a IPv6
ip ShortByteString
k
    IPSecKey Word8
p Word8
3 Word8
a (IPSecKeyGWD Domain
dn) ShortByteString
k = Word8 -> Word8 -> Domain -> ShortByteString -> T_ipseckey
IPSecD_ Word8
p Word8
a Domain
dn ShortByteString
k
    IPSecKey Word8
p Word8
t Word8
a (IPSecKeyGWG ShortByteString
gk) (ShortByteString -> Bool
SB.null -> Bool
True) = Word8 -> Word8 -> Word8 -> ShortByteString -> T_ipseckey
IPSecG_ Word8
p Word8
t Word8
a ShortByteString
gk
    IPSecKey Word8
_ Word8
_ Word8
_ IPSecKeyGateway
_ ShortByteString
_ = String -> T_ipseckey
forall a. HasCallStack => String -> a
error String
"Invalid IPSECKEY parameters"
{-# COMPLETE IPSecKey #-}

ipSecDecon :: T_ipseckey
           -> (Word8, Word8, Word8, IPSecKeyGateway, ShortByteString)
ipSecDecon :: T_ipseckey
-> (Word8, Word8, Word8, IPSecKeyGateway, ShortByteString)
ipSecDecon (IPSecX_ Word8
p Word8
a ShortByteString
k)    = (Word8
p, Word8
0, Word8
a, IPSecKeyGateway
IPSecKeyGWX,    ShortByteString
k)
ipSecDecon (IPSec4_ Word8
p Word8
a IPv4
ip ShortByteString
k) = (Word8
p, Word8
1, Word8
a, IPv4 -> IPSecKeyGateway
IPSecKeyGW4 IPv4
ip, ShortByteString
k)
ipSecDecon (IPSec6_ Word8
p Word8
a IPv6
ip ShortByteString
k) = (Word8
p, Word8
2, Word8
a, IPv6 -> IPSecKeyGateway
IPSecKeyGW6 IPv6
ip, ShortByteString
k)
ipSecDecon (IPSecD_ Word8
p Word8
a Domain
dn ShortByteString
k) = (Word8
p, Word8
3, Word8
a, Domain -> IPSecKeyGateway
IPSecKeyGWD Domain
dn, ShortByteString
k)
ipSecDecon (IPSecG_ Word8
p Word8
t Word8
a ShortByteString
gk) = (Word8
p, Word8
t, Word8
a, ShortByteString -> IPSecKeyGateway
IPSecKeyGWG ShortByteString
gk, ShortByteString
forall a. Monoid a => a
mempty)
{-# INLINE ipSecDecon #-}

-- | Shape of an 'IPSECKEY' record's /gateway/ field.  Four cases
-- match the four gateway types defined by RFC 4025; the catchall
-- 'IPSecKeyGWG' covers any future or otherwise unrecognised gateway
-- type byte and holds the gateway and public-key bytes together as
-- a single opaque blob (the parser has no way to find the boundary
-- between them when the shape is unknown).
data IPSecKeyGateway
    = IPSecKeyGWX                 -- ^ No gateway (gateway type 0).
    | IPSecKeyGW4 IPv4            -- ^ IPv4 gateway address (gateway type 1).
    | IPSecKeyGW6 IPv6            -- ^ IPv6 gateway address (gateway type 2).
    | IPSecKeyGWD Domain          -- ^ FQDN gateway (gateway type 3); not subject to name compression.
    | IPSecKeyGWG ShortByteString -- ^ Future or unrecognised gateway type (\>3); opaque gateway-and-key blob.
  deriving (IPSecKeyGateway -> IPSecKeyGateway -> Bool
(IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> (IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> Eq IPSecKeyGateway
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
== :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
$c/= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
/= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
Eq, Eq IPSecKeyGateway
Eq IPSecKeyGateway =>
(IPSecKeyGateway -> IPSecKeyGateway -> Ordering)
-> (IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> (IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> (IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> (IPSecKeyGateway -> IPSecKeyGateway -> Bool)
-> (IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway)
-> (IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway)
-> Ord IPSecKeyGateway
IPSecKeyGateway -> IPSecKeyGateway -> Bool
IPSecKeyGateway -> IPSecKeyGateway -> Ordering
IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IPSecKeyGateway -> IPSecKeyGateway -> Ordering
compare :: IPSecKeyGateway -> IPSecKeyGateway -> Ordering
$c< :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
< :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
$c<= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
<= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
$c> :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
> :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
$c>= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
>= :: IPSecKeyGateway -> IPSecKeyGateway -> Bool
$cmax :: IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway
max :: IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway
$cmin :: IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway
min :: IPSecKeyGateway -> IPSecKeyGateway -> IPSecKeyGateway
Ord, Int -> IPSecKeyGateway -> ShowS
[IPSecKeyGateway] -> ShowS
IPSecKeyGateway -> String
(Int -> IPSecKeyGateway -> ShowS)
-> (IPSecKeyGateway -> String)
-> ([IPSecKeyGateway] -> ShowS)
-> Show IPSecKeyGateway
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IPSecKeyGateway -> ShowS
showsPrec :: Int -> IPSecKeyGateway -> ShowS
$cshow :: IPSecKeyGateway -> String
show :: IPSecKeyGateway -> String
$cshowList :: [IPSecKeyGateway] -> ShowS
showList :: [IPSecKeyGateway] -> ShowS
Show)

instance Presentable IPSecKeyGateway where
    present :: IPSecKeyGateway -> Builder -> Builder
present IPSecKeyGateway
IPSecKeyGWX      = Char -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Char
'.'
    present (IPSecKeyGW4 IPv4
ip) = IPv4 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present IPv4
ip
    present (IPSecKeyGW6 IPv6
ip) = IPv6 -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present IPv6
ip
    present (IPSecKeyGWD Domain
dn) = Domain -> Builder -> Builder
forall a. Presentable a => a -> Builder -> Builder
present Domain
dn
    present IPSecKeyGateway
_                = Builder -> Builder
forall a. a -> a
id

-- | Compute RFC 4034, Appendix B key tag over the DNSKEY RData: 16 bit flags,
-- 8 bit proto, 8 bit alg and key octets.
--
-- With the obsolete algorithm 1 we assign key tag 0 to truncated keys, but
-- RSAMD5 keys are no longer seen in the wild.  We check that the modulus
-- actually has at least 3 octets.
--
keytag :: X_key n -> Word16
keytag :: forall (n :: Nat). X_key n -> Word16
keytag = Word32 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word16) -> (X_key n -> Word32) -> X_key n -> Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. X_key n -> Word32
forall (n :: Nat). X_key n -> Word32
go
  where
    go :: X_key n -> Word32
    go :: forall (n :: Nat). X_key n -> Word32
go X_KEY{Word8
Word16
ShortByteString
DNSKEYAlg
x_keyFlags :: forall (n :: Nat). X_key n -> Word16
x_keyProto :: forall (n :: Nat). X_key n -> Word8
x_keyAlgor :: forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyValue :: forall (n :: Nat). X_key n -> ShortByteString
x_keyFlags :: Word16
x_keyProto :: Word8
x_keyAlgor :: DNSKEYAlg
x_keyValue :: ShortByteString
..} | Word8
alg Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
1 = Word32
tag
      where
        (DNSKEYAlg Word8
alg) = DNSKEYAlg
x_keyAlgor
        !z :: Word32
z   = Word16 -> Word32
forall a. Integral a => a -> Word32
lo Word16
x_keyFlags Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word8 -> Word32
forall a. Integral a => a -> Word32
hi Word8
x_keyProto Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word8 -> Word32
forall a. Integral a => a -> Word32
lo Word8
alg
        ws32 :: [Word32]
ws32 = ((Word8 -> Word32) -> Word8 -> Word32)
-> [Word8 -> Word32] -> [Word8] -> [Word32]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Word8 -> Word32) -> Word8 -> Word32
forall a b. (a -> b) -> a -> b
($) ([Word8 -> Word32] -> [Word8 -> Word32]
forall a. HasCallStack => [a] -> [a]
cycle [Word8 -> Word32
forall a. Integral a => a -> Word32
hi, Word8 -> Word32
forall a. Integral a => a -> Word32
lo]) ([Word8] -> [Word32]) -> [Word8] -> [Word32]
forall a b. (a -> b) -> a -> b
$ ShortByteString -> [Word8]
SB.unpack ShortByteString
x_keyValue
        !raw :: Word32
raw = (Word32 -> Word32 -> Word32) -> Word32 -> [Word32] -> Word32
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(+) Word32
z [Word32]
ws32
        !tag :: Word32
tag = (Word32
raw Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ (Word32
raw Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
16)) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xffff
    go X_KEY{Word8
Word16
ShortByteString
DNSKEYAlg
x_keyFlags :: forall (n :: Nat). X_key n -> Word16
x_keyProto :: forall (n :: Nat). X_key n -> Word8
x_keyAlgor :: forall (n :: Nat). X_key n -> DNSKEYAlg
x_keyValue :: forall (n :: Nat). X_key n -> ShortByteString
x_keyFlags :: Word16
x_keyProto :: Word8
x_keyAlgor :: DNSKEYAlg
x_keyValue :: ShortByteString
..} | Just !Word32
tag <- Maybe Word32
c32 = Word32
tag
                    | Bool
otherwise = Word32
0
      where
        len :: Int
len = ShortByteString -> Int
SB.length ShortByteString
x_keyValue
        c32 :: Maybe Word32
c32 = Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(+) (Word32 -> Word32 -> Word32)
-> Maybe Word32 -> Maybe (Word32 -> Word32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Word32
forall a. Integral a => a -> Word32
hi (Word8 -> Word32) -> Maybe Word8 -> Maybe Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$.> ShortByteString -> Int -> Maybe Word8
SB.indexMaybe ShortByteString
x_keyValue (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3))
                  Maybe (Word32 -> Word32) -> Maybe Word32 -> Maybe Word32
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Word8 -> Word32
forall a. Integral a => a -> Word32
lo (Word8 -> Word32) -> Maybe Word8 -> Maybe Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$.> ShortByteString -> Int -> Maybe Word8
SB.indexMaybe ShortByteString
x_keyValue (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2))

    hi, lo :: Integral a => a -> Word32
    lo :: forall a. Integral a => a -> Word32
lo = a -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral
    hi :: forall a. Integral a => a -> Word32
hi = (Word32 -> Int -> Word32) -> Int -> Word32 -> Word32
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftL Int
8 (Word32 -> Word32) -> (a -> Word32) -> a -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Word32
forall a. Integral a => a -> Word32
lo