Repository: miekg/dns
Pull request #1382 (2022-06-20 15:08:53)

Make tsigGenerate/VerifyProvider public
Make it public as TsigGenerateWithProvider and update the docs a little.

Signed-off-by: Miek Gieben <miek@miek.nl>


jelu: This is only for generation, my PR was for verification also.

@miekg can you make `tsigVerifyProvider` public also?

Patch:
diff --git a/client.go b/client.go
index fde5b5e3..9aa65853 100644
--- a/client.go
+++ b/client.go
@@ -280,7 +280,7 @@ func (co *Conn) ReadMsg() (*Msg, error) {
 	}
 	if t := m.IsTsig(); t != nil {
 		// Need to work on the original message p, as that was used to calculate the tsig.
-		err = tsigVerifyProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
+		err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
 	}
 	return m, err
 }
@@ -358,7 +358,7 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
 	var out []byte
 	if t := m.IsTsig(); t != nil {
 		// Set tsigRequestMAC for the next read, although only used in zone transfers.
-		out, co.tsigRequestMAC, err = tsigGenerateProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
+		out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
 	} else {
 		out, err = m.Pack()
 	}
diff --git a/server.go b/server.go
index b962e6f3..4e5a9aa8 100644
--- a/server.go
+++ b/server.go
@@ -646,7 +646,7 @@ func (srv *Server) serveDNS(m []byte, w *response) {
 	w.tsigStatus = nil
 	if w.tsigProvider != nil {
 		if t := req.IsTsig(); t != nil {
-			w.tsigStatus = tsigVerifyProvider(m, w.tsigProvider, "", false)
+			w.tsigStatus = TsigVerifyWithProvider(m, w.tsigProvider, "", false)
 			w.tsigTimersOnly = false
 			w.tsigRequestMAC = t.MAC
 		}
@@ -728,7 +728,7 @@ func (w *response) WriteMsg(m *Msg) (err error) {
 	var data []byte
 	if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
 		if t := m.IsTsig(); t != nil {
-			data, w.tsigRequestMAC, err = tsigGenerateProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
+			data, w.tsigRequestMAC, err = TsigGenerateWithProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
 			if err != nil {
 				return err
 			}
diff --git a/tsig.go b/tsig.go
index 8b37cc84..debfe2dd 100644
--- a/tsig.go
+++ b/tsig.go
@@ -158,18 +158,17 @@ type timerWireFmt struct {
 }
 
 // TsigGenerate fills out the TSIG record attached to the message.
-// The message should contain
-// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
-// time fudge (defaults to 300 seconds) and the current time
-// The TSIG MAC is saved in that Tsig RR.
-// When TsigGenerate is called for the first time requestMAC is set to the empty string and
-// timersOnly is false.
-// If something goes wrong an error is returned, otherwise it is nil.
+// The message should contain a "stub" TSIG RR with the algorithm, key name
+// (owner name of the RR), time fudge (defaults to 300 seconds) and the current
+// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
+// the first time requestMAC should be set to the empty string and timersOnly to
+// false.
 func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
-	return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
+	return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
 }
 
-func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
+// TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider.
+func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
 	if m.IsTsig() == nil {
 		panic("dns: TSIG not last RR in additional")
 	}
@@ -216,14 +215,15 @@ func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, time
 	return mbuf, t.MAC, nil
 }
 
-// TsigVerify verifies the TSIG on a message.
-// If the signature does not validate err contains the
-// error, otherwise it is nil.
+// TsigVerify verifies the TSIG on a message. If the signature does not
+// validate the returned error contains the cause. If the signature is OK, the
+// error is nil.
 func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
 	return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
 }
 
-func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
+// TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider.
+func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
 	return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
 }
 
diff --git a/xfr.go b/xfr.go
index f0dcf61d..1917e91c 100644
--- a/xfr.go
+++ b/xfr.go
@@ -237,7 +237,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
 	}
 	if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
 		// Need to work on the original message p, as that was used to calculate the tsig.
-		err = tsigVerifyProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
+		err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
 		t.tsigRequestMAC = ts.MAC
 	}
 	return m, err
@@ -247,7 +247,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
 func (t *Transfer) WriteMsg(m *Msg) (err error) {
 	var out []byte
 	if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
-		out, t.tsigRequestMAC, err = tsigGenerateProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
+		out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
 	} else {
 		out, err = m.Pack()
 	}


Test patch:
diff --git a/tsig_test.go b/tsig_test.go
index 25a3127b..d886aaef 100644
--- a/tsig_test.go
+++ b/tsig_test.go
@@ -354,7 +354,7 @@ func TestTsigGenerateProvider(t *testing.T) {
 				Extra:    []RR{&tsig},
 			}
 
-			_, mac, err := tsigGenerateProvider(req, new(testProvider), "", false)
+			_, mac, err := TsigGenerateWithProvider(req, new(testProvider), "", false)
 			if err != table.err {
 				t.Fatalf("error doesn't match: expected '%s' but got '%s'", table.err, err)
 			}
@@ -397,7 +397,7 @@ func TestTsigVerifyProvider(t *testing.T) {
 			}
 
 			provider := &testProvider{true}
-			msgData, _, err := tsigGenerateProvider(req, provider, "", false)
+			msgData, _, err := TsigGenerateWithProvider(req, provider, "", false)
 			if err != nil {
 				t.Error(err)
 			}