Implementation of zone digest (ZONEMD) (#1208)
* adding ZONEMD * adding ZONEMD * deleting extra cod * updating constants * updating mod * updating release * Moving ZONEMD Implementation to project structure * re adding indirect tools import * case-insensitive digest * fixing if zone has rfc 3597 RRs * remove .idea folder * restore go.mod imports * gofmt files * pseudo rollback * after go generate... * parsing zonemd in rfc3597 * removing the check for a STRING as HAsh Algorithm in ZONEMD, RFC says only numbers go there * adding ZONEMD constants * Reverting changes in generate.go un-gofmt ing generate.go file * Reverting changes in generate.go un-gofmt ing generate.go file * remove ZoneMD reserved types * remove zonemd RFC3597 branch in ZONEMD parser * revert rfc3597 related modifications * revert rfc3597 related modifications * removing unintentional changes from go.sum and types.go * add line break to go.sum * removing spaces from types.go * Use ZONEMD official RFC link as reference * Add ZONEMD parsing test * Update parse_test.go Co-authored-by: Miek Gieben <miek@miek.nl> Co-authored-by: Eduardo <eriveros@dcc.uchile.cl> Co-authored-by: Eduardo <e.sdfbsadjhgskndwegit@xor.cl> Co-authored-by: Eduardo <e.git@xor.cl> Co-authored-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
parent
883641f4a9
commit
375601dc88
@ -1921,3 +1921,74 @@ func TestUnpackRRWithHeaderInvalidLengths(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseZONEMD(t *testing.T) {
|
||||
// Uses examples from https://tools.ietf.org/html/rfc8976
|
||||
dt := map[string]string{
|
||||
// Simple Zone
|
||||
`example. 86400 IN ZONEMD 2018031900 1 1 (
|
||||
c68090d90a7aed71
|
||||
6bc459f9340e3d7c
|
||||
1370d4d24b7e2fc3
|
||||
a1ddc0b9a87153b9
|
||||
a9713b3c9ae5cc27
|
||||
777f98b8e730044c )
|
||||
`: "example.\t86400\tIN\tZONEMD\t2018031900 1 1 c68090d90a7aed716bc459f9340e3d7c1370d4d24b7e2fc3a1ddc0b9a87153b9a9713b3c9ae5cc27777f98b8e730044c",
|
||||
// Complex Zone
|
||||
`example. 86400 IN ZONEMD 2018031900 1 1 (
|
||||
a3b69bad980a3504
|
||||
e1cffcb0fd6397f9
|
||||
3848071c93151f55
|
||||
2ae2f6b1711d4bd2
|
||||
d8b39808226d7b9d
|
||||
b71e34b72077f8fe )
|
||||
`: "example.\t86400\tIN\tZONEMD\t2018031900 1 1 a3b69bad980a3504e1cffcb0fd6397f93848071c93151f552ae2f6b1711d4bd2d8b39808226d7b9db71e34b72077f8fe",
|
||||
// Multiple Digests Zone
|
||||
`example. 86400 IN ZONEMD 2018031900 1 1 (
|
||||
62e6cf51b02e54b9
|
||||
b5f967d547ce4313
|
||||
6792901f9f88e637
|
||||
493daaf401c92c27
|
||||
9dd10f0edb1c56f8
|
||||
080211f8480ee306 )
|
||||
`: "example.\t86400\tIN\tZONEMD\t2018031900 1 1 62e6cf51b02e54b9b5f967d547ce43136792901f9f88e637493daaf401c92c279dd10f0edb1c56f8080211f8480ee306",
|
||||
`example. 86400 IN ZONEMD 2018031900 1 2 (
|
||||
08cfa1115c7b948c
|
||||
4163a901270395ea
|
||||
226a930cd2cbcf2f
|
||||
a9a5e6eb85f37c8a
|
||||
4e114d884e66f176
|
||||
eab121cb02db7d65
|
||||
2e0cc4827e7a3204
|
||||
f166b47e5613fd27 )
|
||||
`: "example.\t86400\tIN\tZONEMD\t2018031900 1 2 08cfa1115c7b948c4163a901270395ea226a930cd2cbcf2fa9a5e6eb85f37c8a4e114d884e66f176eab121cb02db7d652e0cc4827e7a3204f166b47e5613fd27",
|
||||
`example. 86400 IN ZONEMD 2018031900 1 240 (
|
||||
e2d523f654b9422a
|
||||
96c5a8f44607bbee )
|
||||
`: "example. 86400 IN ZONEMD 2018031900 1 240 e2d523f654b9422a96c5a8f44607bbee",
|
||||
`example. 86400 IN ZONEMD 2018031900 241 1 (
|
||||
e1846540e33a9e41
|
||||
89792d18d5d131f6
|
||||
05fc283e )
|
||||
`: "example. 86400 IN ZONEMD 2018031900 241 1 e1846540e33a9e4189792d18d5d131f605fc283e",
|
||||
// URI.ARPA zone
|
||||
`uri.arpa. 3600 IN ZONEMD 2018100702 1 1 (
|
||||
0dbc3c4dbfd75777c12ca19c337854b1577799901307c482e9d91d5d15
|
||||
cd934d16319d98e30c4201cf25a1d5a0254960 )`: "uri.arpa.\t3600\tIN\tZONEMD\t2018100702 1 1 0dbc3c4dbfd75777c12ca19c337854b1577799901307c482e9d91d5d15cd934d16319d98e30c4201cf25a1d5a0254960",
|
||||
// ROOT-SERVERS.NET Zone
|
||||
`root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 (
|
||||
f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97
|
||||
8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 )
|
||||
`: "root-servers.net.\t3600000\tIN\tZONEMD\t2018091100 1 1 f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a978a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79",
|
||||
}
|
||||
for i, o := range dt {
|
||||
rr, err := NewRR(i)
|
||||
if err != nil {
|
||||
t.Error("failed to parse RR: ", err)
|
||||
continue
|
||||
}
|
||||
if rr.String() != o {
|
||||
t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
32
scan_rr.go
32
scan_rr.go
@ -846,6 +846,38 @@ func (rr *CSYNC) parse(c *zlexer, o string) *ParseError {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rr *ZONEMD) parse(c *zlexer, o string) *ParseError {
|
||||
l, _ := c.Next()
|
||||
i, e := strconv.ParseUint(l.token, 10, 32)
|
||||
if e != nil || l.err {
|
||||
return &ParseError{"", "bad ZONEMD Serial", l}
|
||||
}
|
||||
rr.Serial = uint32(i)
|
||||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
i, e1 := strconv.ParseUint(l.token, 10, 8)
|
||||
if e1 != nil || l.err {
|
||||
return &ParseError{"", "bad ZONEMD Scheme", l}
|
||||
}
|
||||
rr.Scheme = uint8(i)
|
||||
|
||||
c.Next() // zBlank
|
||||
l, _ = c.Next()
|
||||
i, err := strconv.ParseUint(l.token, 10, 8);
|
||||
if err != nil || l.err {
|
||||
return &ParseError{"", "bad ZONEMD Hash Algorithm", l}
|
||||
}
|
||||
rr.Hash = uint8(i)
|
||||
|
||||
s, e2 := endingToString(c, "bad ZONEMD Digest")
|
||||
if e2 != nil {
|
||||
return e2
|
||||
}
|
||||
rr.Digest = s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rr *SIG) parse(c *zlexer, o string) *ParseError { return rr.RRSIG.parse(c, o) }
|
||||
|
||||
func (rr *RRSIG) parse(c *zlexer, o string) *ParseError {
|
||||
|
29
types.go
29
types.go
@ -81,6 +81,7 @@ const (
|
||||
TypeCDNSKEY uint16 = 60
|
||||
TypeOPENPGPKEY uint16 = 61
|
||||
TypeCSYNC uint16 = 62
|
||||
TypeZONEMD uint16 = 63
|
||||
TypeSVCB uint16 = 64
|
||||
TypeHTTPS uint16 = 65
|
||||
TypeSPF uint16 = 99
|
||||
@ -150,6 +151,17 @@ const (
|
||||
OpcodeUpdate = 5
|
||||
)
|
||||
|
||||
// Used in ZONEMD https://tools.ietf.org/html/rfc8976
|
||||
|
||||
const (
|
||||
// ZoneMD Accepted Schemes
|
||||
ZoneMDSchemeSimple = 1
|
||||
|
||||
// ZoneMD Hash Algorithms
|
||||
ZoneMDHashAlgSHA384 = 1
|
||||
ZoneMDHashAlgSHA512 = 2
|
||||
)
|
||||
|
||||
// Header is the wire format for the DNS packet header.
|
||||
type Header struct {
|
||||
Id uint16
|
||||
@ -1361,6 +1373,23 @@ func (rr *CSYNC) len(off int, compression map[string]struct{}) int {
|
||||
return l
|
||||
}
|
||||
|
||||
// ZONEMD RR, from draft-ietf-dnsop-dns-zone-digest
|
||||
type ZONEMD struct {
|
||||
Hdr RR_Header
|
||||
Serial uint32
|
||||
Scheme uint8
|
||||
Hash uint8
|
||||
Digest string `dns:"hex"`
|
||||
}
|
||||
|
||||
func (rr *ZONEMD) String() string {
|
||||
return rr.Hdr.String() +
|
||||
strconv.Itoa(int(rr.Serial)) +
|
||||
" " + strconv.Itoa(int(rr.Scheme)) +
|
||||
" " + strconv.Itoa(int(rr.Hash)) +
|
||||
" " + rr.Digest
|
||||
}
|
||||
|
||||
// APL RR. See RFC 3123.
|
||||
type APL struct {
|
||||
Hdr RR_Header
|
||||
|
@ -1317,3 +1317,24 @@ func (r1 *X25) isDuplicate(_r2 RR) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *ZONEMD) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*ZONEMD)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
if r1.Serial != r2.Serial {
|
||||
return false
|
||||
}
|
||||
if r1.Scheme != r2.Scheme {
|
||||
return false
|
||||
}
|
||||
if r1.Hash != r2.Hash {
|
||||
return false
|
||||
}
|
||||
if r1.Digest != r2.Digest {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
52
zmsg.go
52
zmsg.go
@ -1118,6 +1118,26 @@ func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bo
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *ZONEMD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packUint32(rr.Serial, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packUint8(rr.Scheme, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packUint8(rr.Hash, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
off, err = packStringHex(rr.Digest, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
// unpack*() functions
|
||||
|
||||
func (rr *A) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
@ -2821,3 +2841,35 @@ func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *ZONEMD) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
rr.Serial, off, err = unpackUint32(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Scheme, off, err = unpackUint8(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Hash, off, err = unpackUint8(msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
if off == len(msg) {
|
||||
return off, nil
|
||||
}
|
||||
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
return off, nil
|
||||
}
|
||||
|
14
ztypes.go
14
ztypes.go
@ -82,6 +82,7 @@ var TypeToRR = map[uint16]func() RR{
|
||||
TypeUINFO: func() RR { return new(UINFO) },
|
||||
TypeURI: func() RR { return new(URI) },
|
||||
TypeX25: func() RR { return new(X25) },
|
||||
TypeZONEMD: func() RR { return new(ZONEMD) },
|
||||
}
|
||||
|
||||
// TypeToString is a map of strings for each RR type.
|
||||
@ -168,6 +169,7 @@ var TypeToString = map[uint16]string{
|
||||
TypeUNSPEC: "UNSPEC",
|
||||
TypeURI: "URI",
|
||||
TypeX25: "X25",
|
||||
TypeZONEMD: "ZONEMD",
|
||||
TypeNSAPPTR: "NSAP-PTR",
|
||||
}
|
||||
|
||||
@ -245,6 +247,7 @@ func (rr *UID) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *URI) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *X25) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *ZONEMD) Header() *RR_Header { return &rr.Hdr }
|
||||
|
||||
// len() functions
|
||||
func (rr *A) len(off int, compression map[string]struct{}) int {
|
||||
@ -684,6 +687,14 @@ func (rr *X25) len(off int, compression map[string]struct{}) int {
|
||||
l += len(rr.PSDNAddress) + 1
|
||||
return l
|
||||
}
|
||||
func (rr *ZONEMD) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += 4 // Serial
|
||||
l++ // Scheme
|
||||
l++ // Hash
|
||||
l += len(rr.Digest) / 2
|
||||
return l
|
||||
}
|
||||
|
||||
// copy() functions
|
||||
func (rr *A) copy() RR {
|
||||
@ -936,3 +947,6 @@ func (rr *URI) copy() RR {
|
||||
func (rr *X25) copy() RR {
|
||||
return &X25{rr.Hdr, rr.PSDNAddress}
|
||||
}
|
||||
func (rr *ZONEMD) copy() RR {
|
||||
return &ZONEMD{rr.Hdr, rr.Serial, rr.Scheme, rr.Hash, rr.Digest}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user