Fix package header
This commit is contained in:
commit
26e298191a
42
sig0.go
42
sig0.go
|
@ -8,6 +8,11 @@
|
||||||
//
|
//
|
||||||
// It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
|
// It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
|
||||||
// secret approach in TSIG.
|
// secret approach in TSIG.
|
||||||
|
// Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and
|
||||||
|
// RSASHA512.
|
||||||
|
//
|
||||||
|
// Signing subsequent messages in multi-message sessions is not implemented.
|
||||||
|
//
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -16,7 +21,6 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"fmt"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -160,29 +164,34 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||||
adc, offset := unpackUint16(buf, 10)
|
adc, offset := unpackUint16(buf, 10)
|
||||||
var err error
|
var err error
|
||||||
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
||||||
// decode a name
|
|
||||||
_, offset, err = UnpackDomainName(buf, offset)
|
_, offset, err = UnpackDomainName(buf, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// skip past Type and Class
|
// Skip past Type and Class
|
||||||
offset += 2 + 2
|
offset += 2 + 2
|
||||||
}
|
}
|
||||||
for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
|
for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
|
||||||
// decode a name
|
|
||||||
_, offset, err = UnpackDomainName(buf, offset)
|
_, offset, err = UnpackDomainName(buf, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// skip past Type, Class and TTL
|
// Skip past Type, Class and TTL
|
||||||
offset += 2 + 2 + 4
|
offset += 2 + 2 + 4
|
||||||
|
if offset+1 >= buflen {
|
||||||
|
continue
|
||||||
|
}
|
||||||
var rdlen uint16
|
var rdlen uint16
|
||||||
rdlen, offset = unpackUint16(buf, offset)
|
rdlen, offset = unpackUint16(buf, offset)
|
||||||
offset += int(rdlen)
|
offset += int(rdlen)
|
||||||
}
|
}
|
||||||
|
if offset >= buflen {
|
||||||
|
return &Error{err: "overflowing unpacking signed message"}
|
||||||
|
}
|
||||||
|
|
||||||
// offset should be just prior to SIG
|
// offset should be just prior to SIG
|
||||||
bodyend := offset
|
bodyend := offset
|
||||||
// Owner name SHOULD be root
|
// owner name SHOULD be root
|
||||||
_, offset, err = UnpackDomainName(buf, offset)
|
_, offset, err = UnpackDomainName(buf, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -190,20 +199,21 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||||
// Skip Type, Class, TTL, RDLen
|
// Skip Type, Class, TTL, RDLen
|
||||||
offset += 2 + 2 + 4 + 2
|
offset += 2 + 2 + 4 + 2
|
||||||
sigstart := offset
|
sigstart := offset
|
||||||
offset += 2 + 1 + 1 + 4 // skip Type Covered, Algorithm, Labels, Original TTL
|
// Skip Type Covered, Algorithm, Labels, Original TTL
|
||||||
// TODO: This should be moved out and used elsewhere
|
offset += 2 + 1 + 1 + 4
|
||||||
unpackUint32 := func(buf []byte, off int) (uint32, int) {
|
if offset+4+4 >= buflen {
|
||||||
r := uint32(buf[off])<<24 | uint32(buf[off+1])<<16 | uint32(buf[off+2])<<8 | uint32(buf[off+3])
|
return &Error{err: "overflow unpacking signed message"}
|
||||||
return r, off + 4
|
|
||||||
}
|
}
|
||||||
var expire, incept uint32
|
expire := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3])
|
||||||
expire, offset = unpackUint32(buf, offset)
|
offset += 4
|
||||||
incept, offset = unpackUint32(buf, offset)
|
incept := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3])
|
||||||
|
offset += 4
|
||||||
now := uint32(time.Now().Unix())
|
now := uint32(time.Now().Unix())
|
||||||
if now < incept || now > expire {
|
if now < incept || now > expire {
|
||||||
return ErrTime
|
return ErrTime
|
||||||
}
|
}
|
||||||
offset += 2 // skip key tag
|
// Skip key tag
|
||||||
|
offset += 2
|
||||||
var signername string
|
var signername string
|
||||||
signername, offset, err = UnpackDomainName(buf, offset)
|
signername, offset, err = UnpackDomainName(buf, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -212,7 +222,7 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||||
// If key has come from the DNS name compression might
|
// If key has come from the DNS name compression might
|
||||||
// have mangled the case of the name
|
// have mangled the case of the name
|
||||||
if strings.ToLower(signername) != strings.ToLower(k.Header().Name) {
|
if strings.ToLower(signername) != strings.ToLower(k.Header().Name) {
|
||||||
return fmt.Errorf("Signer name doesn't match key name")
|
return &Error{err: "signer name doesn't match key name"}
|
||||||
}
|
}
|
||||||
sigend := offset
|
sigend := offset
|
||||||
hasher.Write(buf[sigstart:sigend])
|
hasher.Write(buf[sigstart:sigend])
|
||||||
|
|
52
sig0_test.go
52
sig0_test.go
|
@ -6,51 +6,39 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSIG0(t *testing.T) {
|
func TestSIG0(t *testing.T) {
|
||||||
keys := []struct {
|
m := new(Msg)
|
||||||
alg uint8
|
m.SetQuestion("example.org.", TypeSOA)
|
||||||
rr *KEY
|
for _, alg := range []uint8{DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
|
||||||
pk PrivateKey
|
algstr := AlgorithmToString[alg]
|
||||||
}{{alg: DSA}, {alg: ECDSAP256SHA256}, {alg: ECDSAP384SHA384}, {alg: RSASHA1}, {alg: RSASHA256}, {alg: RSASHA512}}
|
keyrr := new(KEY)
|
||||||
for i := range keys {
|
keyrr.Hdr.Name = algstr + "."
|
||||||
keys[i].rr = new(KEY)
|
keyrr.Hdr.Rrtype = TypeKEY
|
||||||
keys[i].rr.Hdr.Name = AlgorithmToString[keys[i].alg] + "."
|
keyrr.Hdr.Class = ClassINET
|
||||||
keys[i].rr.Hdr.Rrtype = TypeKEY
|
keyrr.Algorithm = alg
|
||||||
keys[i].rr.Hdr.Class = ClassINET
|
|
||||||
keys[i].rr.Algorithm = keys[i].alg
|
|
||||||
keysize := 1024
|
keysize := 1024
|
||||||
switch keys[i].alg {
|
switch alg {
|
||||||
case ECDSAP256SHA256:
|
case ECDSAP256SHA256:
|
||||||
keysize = 256
|
keysize = 256
|
||||||
case ECDSAP384SHA384:
|
case ECDSAP384SHA384:
|
||||||
keysize = 384
|
keysize = 384
|
||||||
}
|
}
|
||||||
pk, err := keys[i].rr.Generate(keysize)
|
pk, err := keyrr.Generate(keysize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("Failed to generate key for “%s”: %v", AlgorithmToString[keys[i].alg], err)
|
t.Logf("Failed to generate key for “%s”: %v", algstr, err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
keys[i].pk = pk
|
|
||||||
}
|
|
||||||
|
|
||||||
m := new(Msg)
|
|
||||||
m.SetQuestion("example.org.", TypeSOA)
|
|
||||||
for _, key := range keys {
|
|
||||||
if key.pk == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
algstr := AlgorithmToString[key.alg]
|
|
||||||
now := uint32(time.Now().Unix())
|
now := uint32(time.Now().Unix())
|
||||||
sigrr := new(SIG)
|
sigrr := new(SIG)
|
||||||
sigrr.Hdr.Name = "."
|
sigrr.Hdr.Name = "."
|
||||||
sigrr.Hdr.Rrtype = TypeSIG
|
sigrr.Hdr.Rrtype = TypeSIG
|
||||||
sigrr.Hdr.Class = ClassANY
|
sigrr.Hdr.Class = ClassANY
|
||||||
sigrr.Algorithm = key.rr.Algorithm
|
sigrr.Algorithm = alg
|
||||||
sigrr.Expiration = now + 300
|
sigrr.Expiration = now + 300
|
||||||
sigrr.Inception = now - 300
|
sigrr.Inception = now - 300
|
||||||
sigrr.KeyTag = key.rr.KeyTag()
|
sigrr.KeyTag = keyrr.KeyTag()
|
||||||
sigrr.SignerName = key.rr.Hdr.Name
|
sigrr.SignerName = keyrr.Hdr.Name
|
||||||
mb, err := sigrr.Sign(key.pk, m)
|
mb, err := sigrr.Sign(pk, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("Failed to sign message using “%s”: %v", algstr, err)
|
t.Logf("Failed to sign message using “%s”: %v", algstr, err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
|
@ -81,22 +69,22 @@ func TestSIG0(t *testing.T) {
|
||||||
if rr == sigrrwire {
|
if rr == sigrrwire {
|
||||||
id = "sigrrwire"
|
id = "sigrrwire"
|
||||||
}
|
}
|
||||||
if err := rr.Verify(key.rr, mb); err != nil {
|
if err := rr.Verify(keyrr, mb); err != nil {
|
||||||
t.Logf("Failed to verify “%s” signed SIG(%s): %v", algstr, id, err)
|
t.Logf("Failed to verify “%s” signed SIG(%s): %v", algstr, id, err)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mb[13]++
|
mb[13]++
|
||||||
if err := sigrr.Verify(key.rr, mb); err == nil {
|
if err := sigrr.Verify(keyrr, mb); err == nil {
|
||||||
t.Logf("Verify succeeded on an altered message using “%s”", algstr)
|
t.Logf("Verify succeeded on an altered message using “%s”", algstr)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sigrr.Expiration = 2
|
sigrr.Expiration = 2
|
||||||
sigrr.Inception = 1
|
sigrr.Inception = 1
|
||||||
mb, _ = sigrr.Sign(key.pk, m)
|
mb, _ = sigrr.Sign(pk, m)
|
||||||
if err := sigrr.Verify(key.rr, mb); err == nil {
|
if err := sigrr.Verify(keyrr, mb); err == nil {
|
||||||
t.Logf("Verify succeeded on an expired message using “%s”", algstr)
|
t.Logf("Verify succeeded on an expired message using “%s”", algstr)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue