From de1def76d8f39593ca0eec37d4039796c2ef31e7 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Tue, 21 Jul 2020 21:29:04 -0700 Subject: [PATCH] Add support for HMAC-SHA224 and HMAC-SHA384 TSIG algorithms (#1139) --- tsig.go | 10 ++++++++++ tsig_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/tsig.go b/tsig.go index 86d11b6f..c207d616 100644 --- a/tsig.go +++ b/tsig.go @@ -18,7 +18,9 @@ import ( const ( HmacMD5 = "hmac-md5.sig-alg.reg.int." HmacSHA1 = "hmac-sha1." + HmacSHA224 = "hmac-sha224." HmacSHA256 = "hmac-sha256." + HmacSHA384 = "hmac-sha384." HmacSHA512 = "hmac-sha512." ) @@ -123,8 +125,12 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s h = hmac.New(md5.New, rawsecret) case HmacSHA1: h = hmac.New(sha1.New, rawsecret) + case HmacSHA224: + h = hmac.New(sha256.New224, rawsecret) case HmacSHA256: h = hmac.New(sha256.New, rawsecret) + case HmacSHA384: + h = hmac.New(sha512.New384, rawsecret) case HmacSHA512: h = hmac.New(sha512.New, rawsecret) default: @@ -183,8 +189,12 @@ func tsigVerify(msg []byte, secret, requestMAC string, timersOnly bool, now uint h = hmac.New(md5.New, rawsecret) case HmacSHA1: h = hmac.New(sha1.New, rawsecret) + case HmacSHA224: + h = hmac.New(sha256.New224, rawsecret) case HmacSHA256: h = hmac.New(sha256.New, rawsecret) + case HmacSHA384: + h = hmac.New(sha512.New384, rawsecret) case HmacSHA512: h = hmac.New(sha512.New, rawsecret) default: diff --git a/tsig_test.go b/tsig_test.go index c74b20a5..5b63fd9f 100644 --- a/tsig_test.go +++ b/tsig_test.go @@ -192,3 +192,48 @@ func TestTsigGenerate(t *testing.T) { }) } } + +func TestTSIGHMAC224And384(t *testing.T) { + tests := []struct { + algorithm string // TSIG algorithm, also used as test description + secret string // (arbitrarily chosen) secret suitable for the algorithm in base64 format + expectedMAC string // pre-computed expected (correct) MAC in hex form + }{ + {HmacSHA224, "hVEkQuAqnTmBuRrT9KF1Udr91gOMGWPw9LaTtw==", + "d6daf9ea189e48bc38f9aed63d6cc4140cdfa38a7a333ee2eefdbd31", + }, + {HmacSHA384, "Qjer2TL2lAdpq9w6Gjs98/ClCQx/L3vtgVHCmrZ8l/oKEPjqUUMFO18gMCRwd5H4", + "89a48936d29187870c325cbdba5ad71609bd038d0459d6010c844d659c570e881d3650e4fe7310be53ebe5178d0d1001", + }, + } + for _, tc := range tests { + tc := tc + t.Run(tc.algorithm, func(t *testing.T) { + // Build a DNS message with TSIG for the test scenario + tsig := TSIG{ + Hdr: RR_Header{Name: "testkey.", Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}, + Algorithm: tc.algorithm, + TimeSigned: timeSigned, + Fudge: 300, + OrigId: 42, + } + req := &Msg{ + MsgHdr: MsgHdr{Opcode: OpcodeUpdate}, + Question: []Question{Question{Name: "example.com.", Qtype: TypeSOA, Qclass: ClassINET}}, + Extra: []RR{&tsig}, + } + + // Confirm both Generate and Verify recognize the algorithm and handle it correctly + msgData, mac, err := TsigGenerate(req, tc.secret, "", false) + if err != nil { + t.Error(err) + } + if mac != tc.expectedMAC { + t.Fatalf("MAC doesn't match: expected '%s' but got '%s'", tc.expectedMAC, mac) + } + if err = tsigVerify(msgData, tc.secret, "", false, timeSigned); err != nil { + t.Error(err) + } + }) + } +}