Merge pull request #157 from FiloSottile/intermittent_errors
Fix some intermittent errors
This commit is contained in:
commit
877e47b4c3
64
dnssec.go
64
dnssec.go
|
@ -97,6 +97,10 @@ type dnskeyWireFmt struct {
|
||||||
/* Nothing is left out */
|
/* Nothing is left out */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func divRoundUp(a, b int) int {
|
||||||
|
return (a + b - 1) / b
|
||||||
|
}
|
||||||
|
|
||||||
// KeyTag calculates the keytag (or key-id) of the DNSKEY.
|
// KeyTag calculates the keytag (or key-id) of the DNSKEY.
|
||||||
func (k *DNSKEY) KeyTag() uint16 {
|
func (k *DNSKEY) KeyTag() uint16 {
|
||||||
if k == nil {
|
if k == nil {
|
||||||
|
@ -108,7 +112,7 @@ func (k *DNSKEY) KeyTag() uint16 {
|
||||||
// Look at the bottom two bytes of the modules, which the last
|
// Look at the bottom two bytes of the modules, which the last
|
||||||
// item in the pubkey. We could do this faster by looking directly
|
// item in the pubkey. We could do this faster by looking directly
|
||||||
// at the base64 values. But I'm lazy.
|
// at the base64 values. But I'm lazy.
|
||||||
modulus, _ := packBase64([]byte(k.PublicKey))
|
modulus, _ := fromBase64([]byte(k.PublicKey))
|
||||||
if len(modulus) > 1 {
|
if len(modulus) > 1 {
|
||||||
x, _ := unpackUint16(modulus, len(modulus)-2)
|
x, _ := unpackUint16(modulus, len(modulus)-2)
|
||||||
keytag = int(x)
|
keytag = int(x)
|
||||||
|
@ -255,6 +259,7 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
||||||
var sighash []byte
|
var sighash []byte
|
||||||
var h hash.Hash
|
var h hash.Hash
|
||||||
var ch crypto.Hash // Only need for RSA
|
var ch crypto.Hash // Only need for RSA
|
||||||
|
var intlen int
|
||||||
switch rr.Algorithm {
|
switch rr.Algorithm {
|
||||||
case DSA, DSANSEC3SHA1:
|
case DSA, DSANSEC3SHA1:
|
||||||
// Implicit in the ParameterSizes
|
// Implicit in the ParameterSizes
|
||||||
|
@ -264,8 +269,10 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
||||||
case RSASHA256, ECDSAP256SHA256:
|
case RSASHA256, ECDSAP256SHA256:
|
||||||
h = sha256.New()
|
h = sha256.New()
|
||||||
ch = crypto.SHA256
|
ch = crypto.SHA256
|
||||||
|
intlen = 32
|
||||||
case ECDSAP384SHA384:
|
case ECDSAP384SHA384:
|
||||||
h = sha512.New384()
|
h = sha512.New384()
|
||||||
|
intlen = 48
|
||||||
case RSASHA512:
|
case RSASHA512:
|
||||||
h = sha512.New()
|
h = sha512.New()
|
||||||
ch = crypto.SHA512
|
ch = crypto.SHA512
|
||||||
|
@ -284,24 +291,24 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
signature := []byte{0x4D} // T value, here the ASCII M for Miek (not used in DNSSEC)
|
signature := []byte{0x4D} // T value, here the ASCII M for Miek (not used in DNSSEC)
|
||||||
signature = append(signature, r1.Bytes()...)
|
signature = append(signature, intToBytes(r1, 20)...)
|
||||||
signature = append(signature, s1.Bytes()...)
|
signature = append(signature, intToBytes(s1, 20)...)
|
||||||
rr.Signature = unpackBase64(signature)
|
rr.Signature = toBase64(signature)
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
// We can use nil as rand.Reader here (says AGL)
|
// We can use nil as rand.Reader here (says AGL)
|
||||||
signature, err := rsa.SignPKCS1v15(nil, p, ch, sighash)
|
signature, err := rsa.SignPKCS1v15(nil, p, ch, sighash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rr.Signature = unpackBase64(signature)
|
rr.Signature = toBase64(signature)
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
r1, s1, err := ecdsa.Sign(rand.Reader, p, sighash)
|
r1, s1, err := ecdsa.Sign(rand.Reader, p, sighash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
signature := r1.Bytes()
|
signature := intToBytes(r1, intlen)
|
||||||
signature = append(signature, s1.Bytes()...)
|
signature = append(signature, intToBytes(s1, intlen)...)
|
||||||
rr.Signature = unpackBase64(signature)
|
rr.Signature = toBase64(signature)
|
||||||
default:
|
default:
|
||||||
// Not given the correct key
|
// Not given the correct key
|
||||||
return ErrKeyAlg
|
return ErrKeyAlg
|
||||||
|
@ -444,7 +451,7 @@ func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
|
||||||
|
|
||||||
// Return the signatures base64 encodedig sigdata as a byte slice.
|
// Return the signatures base64 encodedig sigdata as a byte slice.
|
||||||
func (s *RRSIG) sigBuf() []byte {
|
func (s *RRSIG) sigBuf() []byte {
|
||||||
sigbuf, err := packBase64([]byte(s.Signature))
|
sigbuf, err := fromBase64([]byte(s.Signature))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -478,7 +485,7 @@ func (k *DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool {
|
||||||
|
|
||||||
// publicKeyRSA returns the RSA public key from a DNSKEY record.
|
// publicKeyRSA returns the RSA public key from a DNSKEY record.
|
||||||
func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
|
func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
|
||||||
keybuf, err := packBase64([]byte(k.PublicKey))
|
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -516,7 +523,7 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
|
||||||
|
|
||||||
// publicKeyCurve returns the Curve public key from the DNSKEY record.
|
// publicKeyCurve returns the Curve public key from the DNSKEY record.
|
||||||
func (k *DNSKEY) publicKeyCurve() *ecdsa.PublicKey {
|
func (k *DNSKEY) publicKeyCurve() *ecdsa.PublicKey {
|
||||||
keybuf, err := packBase64([]byte(k.PublicKey))
|
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -543,7 +550,7 @@ func (k *DNSKEY) publicKeyCurve() *ecdsa.PublicKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
|
func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
|
||||||
keybuf, err := packBase64([]byte(k.PublicKey))
|
keybuf, err := fromBase64([]byte(k.PublicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -573,7 +580,7 @@ func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
|
||||||
}
|
}
|
||||||
buf := exponentToBuf(_E)
|
buf := exponentToBuf(_E)
|
||||||
buf = append(buf, _N.Bytes()...)
|
buf = append(buf, _N.Bytes()...)
|
||||||
k.PublicKey = unpackBase64(buf)
|
k.PublicKey = toBase64(buf)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,9 +589,14 @@ func (k *DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool {
|
||||||
if _X == nil || _Y == nil {
|
if _X == nil || _Y == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
buf := curveToBuf(_X, _Y)
|
var intlen int
|
||||||
// Check the length of the buffer, either 64 or 92 bytes
|
switch k.Algorithm {
|
||||||
k.PublicKey = unpackBase64(buf)
|
case ECDSAP256SHA256:
|
||||||
|
intlen = 32
|
||||||
|
case ECDSAP384SHA384:
|
||||||
|
intlen = 48
|
||||||
|
}
|
||||||
|
k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,7 +606,7 @@ func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
buf := dsaToBuf(_Q, _P, _G, _Y)
|
buf := dsaToBuf(_Q, _P, _G, _Y)
|
||||||
k.PublicKey = unpackBase64(buf)
|
k.PublicKey = toBase64(buf)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,21 +630,21 @@ func exponentToBuf(_E int) []byte {
|
||||||
|
|
||||||
// Set the public key for X and Y for Curve. The two
|
// Set the public key for X and Y for Curve. The two
|
||||||
// values are just concatenated.
|
// values are just concatenated.
|
||||||
func curveToBuf(_X, _Y *big.Int) []byte {
|
func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
|
||||||
buf := _X.Bytes()
|
buf := intToBytes(_X, intlen)
|
||||||
buf = append(buf, _Y.Bytes()...)
|
buf = append(buf, intToBytes(_Y, intlen)...)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the public key for X and Y for Curve. The two
|
// Set the public key for X and Y for Curve. The two
|
||||||
// values are just concatenated.
|
// values are just concatenated.
|
||||||
func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
|
func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
|
||||||
t := byte((len(_G.Bytes()) - 64) / 8)
|
t := divRoundUp(divRoundUp(_G.BitLen(), 8)-64, 8)
|
||||||
buf := []byte{t}
|
buf := []byte{byte(t)}
|
||||||
buf = append(buf, _Q.Bytes()...)
|
buf = append(buf, intToBytes(_Q, 20)...)
|
||||||
buf = append(buf, _P.Bytes()...)
|
buf = append(buf, intToBytes(_P, 64+t*8)...)
|
||||||
buf = append(buf, _G.Bytes()...)
|
buf = append(buf, intToBytes(_G, 64+t*8)...)
|
||||||
buf = append(buf, _Y.Bytes()...)
|
buf = append(buf, intToBytes(_Y, 64+t*8)...)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -455,12 +455,19 @@ PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
|
||||||
sig.SignerName = eckey.(*DNSKEY).Hdr.Name
|
sig.SignerName = eckey.(*DNSKEY).Hdr.Name
|
||||||
sig.Algorithm = eckey.(*DNSKEY).Algorithm
|
sig.Algorithm = eckey.(*DNSKEY).Algorithm
|
||||||
|
|
||||||
sig.Sign(privkey, []RR{a})
|
if sig.Sign(privkey, []RR{a}) != nil {
|
||||||
|
t.Fatal("failure to sign the record")
|
||||||
|
}
|
||||||
|
|
||||||
t.Logf("%s", sig.String())
|
|
||||||
if e := sig.Verify(eckey.(*DNSKEY), []RR{a}); e != nil {
|
if e := sig.Verify(eckey.(*DNSKEY), []RR{a}); e != nil {
|
||||||
t.Logf("failure to validate: %s", e.Error())
|
t.Logf("\n%s\n%s\n%s\n\n%s\n\n",
|
||||||
t.Fail()
|
eckey.(*DNSKEY).String(),
|
||||||
|
a.String(),
|
||||||
|
sig.String(),
|
||||||
|
eckey.(*DNSKEY).PrivateKeyString(privkey),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Fatalf("failure to validate: %s", e.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,6 +510,13 @@ func TestSignVerifyECDSA2(t *testing.T) {
|
||||||
|
|
||||||
err = sig.Verify(key, []RR{srv})
|
err = sig.Verify(key, []RR{srv})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Logf("\n%s\n%s\n%s\n\n%s\n\n",
|
||||||
|
key.String(),
|
||||||
|
srv.String(),
|
||||||
|
sig.String(),
|
||||||
|
key.PrivateKeyString(privkey),
|
||||||
|
)
|
||||||
|
|
||||||
t.Fatal("Failure to validate:", err)
|
t.Fatal("Failure to validate:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
keygen.go
36
keygen.go
|
@ -94,12 +94,12 @@ func (r *DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
||||||
switch t := p.(type) {
|
switch t := p.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||||
modulus := unpackBase64(t.PublicKey.N.Bytes())
|
modulus := toBase64(t.PublicKey.N.Bytes())
|
||||||
e := big.NewInt(int64(t.PublicKey.E))
|
e := big.NewInt(int64(t.PublicKey.E))
|
||||||
publicExponent := unpackBase64(e.Bytes())
|
publicExponent := toBase64(e.Bytes())
|
||||||
privateExponent := unpackBase64(t.D.Bytes())
|
privateExponent := toBase64(t.D.Bytes())
|
||||||
prime1 := unpackBase64(t.Primes[0].Bytes())
|
prime1 := toBase64(t.Primes[0].Bytes())
|
||||||
prime2 := unpackBase64(t.Primes[1].Bytes())
|
prime2 := toBase64(t.Primes[1].Bytes())
|
||||||
// Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
|
// Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
|
||||||
// and from: http://code.google.com/p/go/issues/detail?id=987
|
// and from: http://code.google.com/p/go/issues/detail?id=987
|
||||||
one := big.NewInt(1)
|
one := big.NewInt(1)
|
||||||
|
@ -110,9 +110,9 @@ func (r *DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
||||||
exp2 := big.NewInt(0).Mod(t.D, q_1)
|
exp2 := big.NewInt(0).Mod(t.D, q_1)
|
||||||
coeff := big.NewInt(0).Exp(t.Primes[1], minusone, t.Primes[0])
|
coeff := big.NewInt(0).Exp(t.Primes[1], minusone, t.Primes[0])
|
||||||
|
|
||||||
exponent1 := unpackBase64(exp1.Bytes())
|
exponent1 := toBase64(exp1.Bytes())
|
||||||
exponent2 := unpackBase64(exp2.Bytes())
|
exponent2 := toBase64(exp2.Bytes())
|
||||||
coefficient := unpackBase64(coeff.Bytes())
|
coefficient := toBase64(coeff.Bytes())
|
||||||
|
|
||||||
s = _FORMAT +
|
s = _FORMAT +
|
||||||
"Algorithm: " + algorithm + "\n" +
|
"Algorithm: " + algorithm + "\n" +
|
||||||
|
@ -126,17 +126,25 @@ func (r *DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
|
||||||
"Coefficient: " + coefficient + "\n"
|
"Coefficient: " + coefficient + "\n"
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||||
private := unpackBase64(t.D.Bytes())
|
var intlen int
|
||||||
|
switch r.Algorithm {
|
||||||
|
case ECDSAP256SHA256:
|
||||||
|
intlen = 32
|
||||||
|
case ECDSAP384SHA384:
|
||||||
|
intlen = 48
|
||||||
|
}
|
||||||
|
private := toBase64(intToBytes(t.D, intlen))
|
||||||
s = _FORMAT +
|
s = _FORMAT +
|
||||||
"Algorithm: " + algorithm + "\n" +
|
"Algorithm: " + algorithm + "\n" +
|
||||||
"PrivateKey: " + private + "\n"
|
"PrivateKey: " + private + "\n"
|
||||||
case *dsa.PrivateKey:
|
case *dsa.PrivateKey:
|
||||||
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
algorithm := strconv.Itoa(int(r.Algorithm)) + " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||||
prime := unpackBase64(t.PublicKey.Parameters.P.Bytes())
|
T := divRoundUp(divRoundUp(t.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
|
||||||
subprime := unpackBase64(t.PublicKey.Parameters.Q.Bytes())
|
prime := toBase64(intToBytes(t.PublicKey.Parameters.P, 64+T*8))
|
||||||
base := unpackBase64(t.PublicKey.Parameters.G.Bytes())
|
subprime := toBase64(intToBytes(t.PublicKey.Parameters.Q, 20))
|
||||||
priv := unpackBase64(t.X.Bytes())
|
base := toBase64(intToBytes(t.PublicKey.Parameters.G, 64+T*8))
|
||||||
pub := unpackBase64(t.PublicKey.Y.Bytes())
|
priv := toBase64(intToBytes(t.X, 20))
|
||||||
|
pub := toBase64(intToBytes(t.PublicKey.Y, 64+T*8))
|
||||||
s = _FORMAT +
|
s = _FORMAT +
|
||||||
"Algorithm: " + algorithm + "\n" +
|
"Algorithm: " + algorithm + "\n" +
|
||||||
"Prime(p): " + prime + "\n" +
|
"Prime(p): " + prime + "\n" +
|
||||||
|
|
12
kscan.go
12
kscan.go
|
@ -39,7 +39,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
if !k.setPublicKeyInPrivate(p) {
|
if !k.setPublicKeyInPrivate(p) {
|
||||||
return nil, ErrPrivKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
return p, e
|
return p, e
|
||||||
case "1 (RSAMD5)":
|
case "1 (RSAMD5)":
|
||||||
|
@ -56,7 +56,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
if !k.setPublicKeyInPrivate(p) {
|
if !k.setPublicKeyInPrivate(p) {
|
||||||
return nil, ErrPrivKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
return p, e
|
return p, e
|
||||||
case "12 (ECC-GOST)":
|
case "12 (ECC-GOST)":
|
||||||
|
@ -74,7 +74,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, e
|
return nil, e
|
||||||
}
|
}
|
||||||
if !k.setPublicKeyInPrivate(p) {
|
if !k.setPublicKeyInPrivate(p) {
|
||||||
return nil, ErrPrivKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
return p, e
|
return p, e
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ func readPrivateKeyRSA(m map[string]string) (PrivateKey, error) {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
switch k {
|
switch k {
|
||||||
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
|
case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
|
||||||
v1, err := packBase64([]byte(v))
|
v1, err := fromBase64([]byte(v))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ func readPrivateKeyDSA(m map[string]string) (PrivateKey, error) {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
switch k {
|
switch k {
|
||||||
case "private_value(x)":
|
case "private_value(x)":
|
||||||
v1, err := packBase64([]byte(v))
|
v1, err := fromBase64([]byte(v))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ func readPrivateKeyECDSA(m map[string]string) (PrivateKey, error) {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
switch k {
|
switch k {
|
||||||
case "privatekey":
|
case "privatekey":
|
||||||
v1, err := packBase64([]byte(v))
|
v1, err := fromBase64([]byte(v))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
78
msg.go
78
msg.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -813,7 +814,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
default:
|
default:
|
||||||
return lenmsg, &Error{"bad tag packing string: " + typefield.Tag.Get("dns")}
|
return lenmsg, &Error{"bad tag packing string: " + typefield.Tag.Get("dns")}
|
||||||
case `dns:"base64"`:
|
case `dns:"base64"`:
|
||||||
b64, e := packBase64([]byte(s))
|
b64, e := fromBase64([]byte(s))
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return lenmsg, e
|
return lenmsg, e
|
||||||
}
|
}
|
||||||
|
@ -834,7 +835,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
msg[off-1] = 20
|
msg[off-1] = 20
|
||||||
fallthrough
|
fallthrough
|
||||||
case `dns:"base32"`:
|
case `dns:"base32"`:
|
||||||
b32, e := packBase32([]byte(s))
|
b32, e := fromBase32([]byte(s))
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return lenmsg, e
|
return lenmsg, e
|
||||||
}
|
}
|
||||||
|
@ -1224,7 +1225,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
|
||||||
if b64end > lenrd || b64end > lenmsg {
|
if b64end > lenrd || b64end > lenmsg {
|
||||||
return lenmsg, &Error{err: "overflow unpacking base64"}
|
return lenmsg, &Error{err: "overflow unpacking base64"}
|
||||||
}
|
}
|
||||||
s = unpackBase64(msg[off:b64end])
|
s = toBase64(msg[off:b64end])
|
||||||
off = b64end
|
off = b64end
|
||||||
case `dns:"cdomain-name"`:
|
case `dns:"cdomain-name"`:
|
||||||
fallthrough
|
fallthrough
|
||||||
|
@ -1250,7 +1251,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err er
|
||||||
if off+size > lenmsg {
|
if off+size > lenmsg {
|
||||||
return lenmsg, &Error{err: "overflow unpacking base32"}
|
return lenmsg, &Error{err: "overflow unpacking base32"}
|
||||||
}
|
}
|
||||||
s = unpackBase32(msg[off : off+size])
|
s = toBase32(msg[off : off+size])
|
||||||
off += size
|
off += size
|
||||||
case `dns:"size-hex"`:
|
case `dns:"size-hex"`:
|
||||||
// a "size" string, but it must be encoded in hex in the string
|
// a "size" string, but it must be encoded in hex in the string
|
||||||
|
@ -1298,58 +1299,53 @@ func dddToByte(s []byte) byte {
|
||||||
return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
|
return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for unpacking
|
|
||||||
func unpackUint16(msg []byte, off int) (v uint16, off1 int) {
|
|
||||||
v = uint16(msg[off])<<8 | uint16(msg[off+1])
|
|
||||||
off1 = off + 2
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnpackStruct unpacks a binary message from offset off to the interface
|
// UnpackStruct unpacks a binary message from offset off to the interface
|
||||||
// value given.
|
// value given.
|
||||||
func UnpackStruct(any interface{}, msg []byte, off int) (off1 int, err error) {
|
func UnpackStruct(any interface{}, msg []byte, off int) (int, error) {
|
||||||
off, err = unpackStructValue(structValue(any), msg, off)
|
return unpackStructValue(structValue(any), msg, off)
|
||||||
return off, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackBase32(b []byte) string {
|
// Helper function for packing and unpacking
|
||||||
b32 := make([]byte, base32.HexEncoding.EncodedLen(len(b)))
|
func intToBytes(i *big.Int, length int) []byte {
|
||||||
base32.HexEncoding.Encode(b32, b)
|
buf := i.Bytes()
|
||||||
return string(b32)
|
if len(buf) < length {
|
||||||
|
b := make([]byte, length)
|
||||||
|
copy(b[length-len(buf):], buf)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackBase64(b []byte) string {
|
func unpackUint16(msg []byte, off int) (uint16, int) {
|
||||||
b64 := make([]byte, base64.StdEncoding.EncodedLen(len(b)))
|
return uint16(msg[off])<<8 | uint16(msg[off+1]), off + 2
|
||||||
base64.StdEncoding.Encode(b64, b)
|
|
||||||
return string(b64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for packing
|
|
||||||
func packUint16(i uint16) (byte, byte) {
|
func packUint16(i uint16) (byte, byte) {
|
||||||
return byte(i >> 8), byte(i)
|
return byte(i >> 8), byte(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func packBase64(s []byte) ([]byte, error) {
|
func toBase32(b []byte) string {
|
||||||
b64len := base64.StdEncoding.DecodedLen(len(s))
|
return base32.HexEncoding.EncodeToString(b)
|
||||||
buf := make([]byte, b64len)
|
|
||||||
n, err := base64.StdEncoding.Decode(buf, []byte(s))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
buf = buf[:n]
|
|
||||||
return buf, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for packing, mostly used in dnssec.go
|
func fromBase32(s []byte) (buf []byte, err error) {
|
||||||
func packBase32(s []byte) ([]byte, error) {
|
buflen := base32.HexEncoding.DecodedLen(len(s))
|
||||||
b32len := base32.HexEncoding.DecodedLen(len(s))
|
buf = make([]byte, buflen)
|
||||||
buf := make([]byte, b32len)
|
n, err := base32.HexEncoding.Decode(buf, s)
|
||||||
n, err := base32.HexEncoding.Decode(buf, []byte(s))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
buf = buf[:n]
|
buf = buf[:n]
|
||||||
return buf, nil
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func toBase64(b []byte) string {
|
||||||
|
return base64.StdEncoding.EncodeToString(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromBase64(s []byte) (buf []byte, err error) {
|
||||||
|
buflen := base64.StdEncoding.DecodedLen(len(s))
|
||||||
|
buf = make([]byte, buflen)
|
||||||
|
n, err := base64.StdEncoding.Decode(buf, s)
|
||||||
|
buf = buf[:n]
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackRR packs a resource record rr into msg[off:].
|
// PackRR packs a resource record rr into msg[off:].
|
||||||
|
|
2
nsecx.go
2
nsecx.go
|
@ -47,7 +47,7 @@ func HashName(label string, ha uint8, iter uint16, salt string) string {
|
||||||
io.WriteString(s, string(nsec3))
|
io.WriteString(s, string(nsec3))
|
||||||
nsec3 = s.Sum(nil)
|
nsec3 = s.Sum(nil)
|
||||||
}
|
}
|
||||||
return unpackBase32(nsec3)
|
return toBase32(nsec3)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Denialer interface {
|
type Denialer interface {
|
||||||
|
|
|
@ -1230,7 +1230,7 @@ type algorithm struct {
|
||||||
bits int
|
bits int
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewPrivateKeyECDSA(t *testing.T) {
|
func TestNewPrivateKey(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("skipping test in short mode.")
|
t.Skip("skipping test in short mode.")
|
||||||
}
|
}
|
||||||
|
@ -1239,7 +1239,7 @@ func TestNewPrivateKeyECDSA(t *testing.T) {
|
||||||
algorithm{ECDSAP384SHA384, 384},
|
algorithm{ECDSAP384SHA384, 384},
|
||||||
algorithm{RSASHA1, 1024},
|
algorithm{RSASHA1, 1024},
|
||||||
algorithm{RSASHA256, 2048},
|
algorithm{RSASHA256, 2048},
|
||||||
// algorithm{DSA, 1024}, // TODO: STILL BROKEN!
|
algorithm{DSA, 1024},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, algo := range algorithms {
|
for _, algo := range algorithms {
|
||||||
|
@ -1258,6 +1258,9 @@ func TestNewPrivateKeyECDSA(t *testing.T) {
|
||||||
|
|
||||||
newPrivKey, err := key.NewPrivateKey(key.PrivateKeyString(privkey))
|
newPrivKey, err := key.NewPrivateKey(key.PrivateKeyString(privkey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
t.Log(key.String())
|
||||||
|
t.Log(key.PrivateKeyString(privkey))
|
||||||
|
|
||||||
t.Fatal(err.Error())
|
t.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HelloServer(w ResponseWriter, req *Msg) {
|
func HelloServer(w ResponseWriter, req *Msg) {
|
||||||
|
@ -36,6 +37,25 @@ func RunLocalUDPServer(laddr string) (*Server, string, error) {
|
||||||
server.ActivateAndServe()
|
server.ActivateAndServe()
|
||||||
pc.Close()
|
pc.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
return server, pc.LocalAddr().String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunLocalUDPServerUnsafe(laddr string) (*Server, string, error) {
|
||||||
|
pc, err := net.ListenPacket("udp", laddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
server := &Server{PacketConn: pc, Unsafe: true}
|
||||||
|
go func() {
|
||||||
|
server.ActivateAndServe()
|
||||||
|
pc.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
return server, pc.LocalAddr().String(), nil
|
return server, pc.LocalAddr().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +69,19 @@ func RunLocalTCPServer(laddr string) (*Server, string, error) {
|
||||||
server.ActivateAndServe()
|
server.ActivateAndServe()
|
||||||
l.Close()
|
l.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
for i := 0; ; i++ {
|
||||||
|
conn, err := net.Dial("tcp", l.Addr().String())
|
||||||
|
if err == nil {
|
||||||
|
conn.Close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
if i > 50 {
|
||||||
|
return nil, "", fmt.Errorf("failed to start server: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return server, l.Addr().String(), nil
|
return server, l.Addr().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +344,6 @@ func TestServingResponse(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to run test server: %s", err)
|
t.Fatalf("Unable to run test server: %s", err)
|
||||||
}
|
}
|
||||||
defer s.Shutdown()
|
|
||||||
|
|
||||||
c := new(Client)
|
c := new(Client)
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
|
@ -328,7 +360,14 @@ func TestServingResponse(t *testing.T) {
|
||||||
t.Log("exchanged response message")
|
t.Log("exchanged response message")
|
||||||
t.Fatal()
|
t.Fatal()
|
||||||
}
|
}
|
||||||
s.Unsafe = true
|
|
||||||
|
s.Shutdown()
|
||||||
|
s, addrstr, err = RunLocalUDPServerUnsafe("127.0.0.1:0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to run test server: %s", err)
|
||||||
|
}
|
||||||
|
defer s.Shutdown()
|
||||||
|
|
||||||
m.Response = true
|
m.Response = true
|
||||||
_, _, err = c.Exchange(m, addrstr)
|
_, _, err = c.Exchange(m, addrstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -342,9 +381,6 @@ func TestShutdownTCP(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to run test server: %s", err)
|
t.Fatalf("Unable to run test server: %s", err)
|
||||||
}
|
}
|
||||||
// it normally is too early to shutting down because server
|
|
||||||
// activates in goroutine.
|
|
||||||
runtime.Gosched()
|
|
||||||
err = s.Shutdown()
|
err = s.Shutdown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Could not shutdown test TCP server, %s", err)
|
t.Errorf("Could not shutdown test TCP server, %s", err)
|
||||||
|
@ -356,9 +392,6 @@ func TestShutdownUDP(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to run test server: %s", err)
|
t.Fatalf("Unable to run test server: %s", err)
|
||||||
}
|
}
|
||||||
// it normally is too early to shutting down because server
|
|
||||||
// activates in goroutine.
|
|
||||||
runtime.Gosched()
|
|
||||||
err = s.Shutdown()
|
err = s.Shutdown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Could not shutdown test UDP server, %s", err)
|
t.Errorf("Could not shutdown test UDP server, %s", err)
|
||||||
|
|
31
sig0.go
31
sig0.go
|
@ -44,18 +44,7 @@ func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
||||||
rr.TypeCovered = 0
|
rr.TypeCovered = 0
|
||||||
rr.Labels = 0
|
rr.Labels = 0
|
||||||
|
|
||||||
buflen := m.Len() + rr.len()
|
buf := make([]byte, m.Len()+rr.len())
|
||||||
switch k := k.(type) {
|
|
||||||
case *rsa.PrivateKey:
|
|
||||||
buflen += len(k.N.Bytes())
|
|
||||||
case *dsa.PrivateKey:
|
|
||||||
buflen += 40
|
|
||||||
case *ecdsa.PrivateKey:
|
|
||||||
buflen += 96
|
|
||||||
default:
|
|
||||||
return nil, ErrPrivKey
|
|
||||||
}
|
|
||||||
buf := make([]byte, m.Len()+rr.len()+buflen)
|
|
||||||
mbuf, err := m.PackBuffer(buf)
|
mbuf, err := m.PackBuffer(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -69,13 +58,16 @@ func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
||||||
}
|
}
|
||||||
buf = buf[:off:cap(buf)]
|
buf = buf[:off:cap(buf)]
|
||||||
var hash crypto.Hash
|
var hash crypto.Hash
|
||||||
|
var intlen int
|
||||||
switch rr.Algorithm {
|
switch rr.Algorithm {
|
||||||
case DSA, RSASHA1:
|
case DSA, RSASHA1:
|
||||||
hash = crypto.SHA1
|
hash = crypto.SHA1
|
||||||
case RSASHA256, ECDSAP256SHA256:
|
case RSASHA256, ECDSAP256SHA256:
|
||||||
hash = crypto.SHA256
|
hash = crypto.SHA256
|
||||||
|
intlen = 32
|
||||||
case ECDSAP384SHA384:
|
case ECDSAP384SHA384:
|
||||||
hash = crypto.SHA384
|
hash = crypto.SHA384
|
||||||
|
intlen = 48
|
||||||
case RSASHA512:
|
case RSASHA512:
|
||||||
hash = crypto.SHA512
|
hash = crypto.SHA512
|
||||||
default:
|
default:
|
||||||
|
@ -91,15 +83,14 @@ func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
||||||
var sig []byte
|
var sig []byte
|
||||||
switch p := k.(type) {
|
switch p := k.(type) {
|
||||||
case *dsa.PrivateKey:
|
case *dsa.PrivateKey:
|
||||||
t := byte((len(p.PublicKey.Y.Bytes()) - 64) / 8)
|
t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
|
||||||
r1, s1, err := dsa.Sign(rand.Reader, p, hashed)
|
r1, s1, err := dsa.Sign(rand.Reader, p, hashed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sig = make([]byte, 0, 1+len(r1.Bytes())+len(s1.Bytes()))
|
sig = append(sig, byte(t))
|
||||||
sig = append(sig, t)
|
sig = append(sig, intToBytes(r1, 20)...)
|
||||||
sig = append(sig, r1.Bytes()...)
|
sig = append(sig, intToBytes(s1, 20)...)
|
||||||
sig = append(sig, s1.Bytes()...)
|
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
sig, err = rsa.SignPKCS1v15(rand.Reader, p, hash, hashed)
|
sig, err = rsa.SignPKCS1v15(rand.Reader, p, hash, hashed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -110,12 +101,12 @@ func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sig = r1.Bytes()
|
sig = intToBytes(r1, intlen)
|
||||||
sig = append(sig, s1.Bytes()...)
|
sig = append(sig, intToBytes(s1, intlen)...)
|
||||||
default:
|
default:
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
}
|
}
|
||||||
rr.Signature = unpackBase64(sig)
|
rr.Signature = toBase64(sig)
|
||||||
buf = append(buf, sig...)
|
buf = append(buf, sig...)
|
||||||
if len(buf) > int(^uint16(0)) {
|
if len(buf) > int(^uint16(0)) {
|
||||||
return nil, ErrBuf
|
return nil, ErrBuf
|
||||||
|
|
4
tsig.go
4
tsig.go
|
@ -159,7 +159,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
||||||
panic("dns: TSIG not last RR in additional")
|
panic("dns: TSIG not last RR in additional")
|
||||||
}
|
}
|
||||||
// If we barf here, the caller is to blame
|
// If we barf here, the caller is to blame
|
||||||
rawsecret, err := packBase64([]byte(secret))
|
rawsecret, err := fromBase64([]byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
|
||||||
// If the signature does not validate err contains the
|
// If the signature does not validate err contains the
|
||||||
// error, otherwise it is nil.
|
// error, otherwise it is nil.
|
||||||
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
||||||
rawsecret, err := packBase64([]byte(secret))
|
rawsecret, err := fromBase64([]byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue