Refactor DNSSEC to use crypto.{PrivateKey,Signer}
This will allow RRSIG.Sign to use generic crypto.Signer implementations. This is a interface breaking change, even if the required changes are most likely just type asserions from crypto.PrivateKey to the underlying type or crypto.Signer.
This commit is contained in:
parent
c50a9fc91d
commit
034c247229
237
dnssec.go
237
dnssec.go
|
@ -6,14 +6,14 @@ import (
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/md5"
|
_ "crypto/md5"
|
||||||
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha1"
|
_ "crypto/sha1"
|
||||||
"crypto/sha256"
|
_ "crypto/sha256"
|
||||||
"crypto/sha512"
|
_ "crypto/sha512"
|
||||||
|
"encoding/asn1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"hash"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -42,6 +42,38 @@ const (
|
||||||
PRIVATEOID uint8 = 254
|
PRIVATEOID uint8 = 254
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Map for algorithm names.
|
||||||
|
var AlgorithmToString = map[uint8]string{
|
||||||
|
RSAMD5: "RSAMD5",
|
||||||
|
DH: "DH",
|
||||||
|
DSA: "DSA",
|
||||||
|
RSASHA1: "RSASHA1",
|
||||||
|
DSANSEC3SHA1: "DSA-NSEC3-SHA1",
|
||||||
|
RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
|
||||||
|
RSASHA256: "RSASHA256",
|
||||||
|
RSASHA512: "RSASHA512",
|
||||||
|
ECCGOST: "ECC-GOST",
|
||||||
|
ECDSAP256SHA256: "ECDSAP256SHA256",
|
||||||
|
ECDSAP384SHA384: "ECDSAP384SHA384",
|
||||||
|
INDIRECT: "INDIRECT",
|
||||||
|
PRIVATEDNS: "PRIVATEDNS",
|
||||||
|
PRIVATEOID: "PRIVATEOID",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map of algorithm strings.
|
||||||
|
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
||||||
|
|
||||||
|
// Map of algorithm crypto hashes.
|
||||||
|
var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||||
|
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
||||||
|
RSASHA1: crypto.SHA1,
|
||||||
|
RSASHA1NSEC3SHA1: crypto.SHA1,
|
||||||
|
RSASHA256: crypto.SHA256,
|
||||||
|
ECDSAP256SHA256: crypto.SHA256,
|
||||||
|
ECDSAP384SHA384: crypto.SHA384,
|
||||||
|
RSASHA512: crypto.SHA512,
|
||||||
|
}
|
||||||
|
|
||||||
// DNSSEC hashing algorithm codes.
|
// DNSSEC hashing algorithm codes.
|
||||||
const (
|
const (
|
||||||
_ uint8 = iota
|
_ uint8 = iota
|
||||||
|
@ -52,6 +84,18 @@ const (
|
||||||
SHA512 // Experimental
|
SHA512 // Experimental
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Map for hash names.
|
||||||
|
var HashToString = map[uint8]string{
|
||||||
|
SHA1: "SHA1",
|
||||||
|
SHA256: "SHA256",
|
||||||
|
GOST94: "GOST94",
|
||||||
|
SHA384: "SHA384",
|
||||||
|
SHA512: "SHA512",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map of hash strings.
|
||||||
|
var StringToHash = reverseInt8(HashToString)
|
||||||
|
|
||||||
// DNSKEY flag values.
|
// DNSKEY flag values.
|
||||||
const (
|
const (
|
||||||
SEP = 1
|
SEP = 1
|
||||||
|
@ -168,24 +212,23 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
|
||||||
// digest buffer
|
// digest buffer
|
||||||
digest := append(owner, wire...) // another copy
|
digest := append(owner, wire...) // another copy
|
||||||
|
|
||||||
|
var hash crypto.Hash
|
||||||
switch h {
|
switch h {
|
||||||
case SHA1:
|
case SHA1:
|
||||||
s := sha1.New()
|
hash = crypto.SHA1
|
||||||
io.WriteString(s, string(digest))
|
|
||||||
ds.Digest = hex.EncodeToString(s.Sum(nil))
|
|
||||||
case SHA256:
|
case SHA256:
|
||||||
s := sha256.New()
|
hash = crypto.SHA256
|
||||||
io.WriteString(s, string(digest))
|
|
||||||
ds.Digest = hex.EncodeToString(s.Sum(nil))
|
|
||||||
case SHA384:
|
case SHA384:
|
||||||
s := sha512.New384()
|
hash = crypto.SHA384
|
||||||
io.WriteString(s, string(digest))
|
case SHA512:
|
||||||
ds.Digest = hex.EncodeToString(s.Sum(nil))
|
hash = crypto.SHA512
|
||||||
case GOST94:
|
|
||||||
/* I have no clue */
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s := hash.New()
|
||||||
|
s.Write(digest)
|
||||||
|
ds.Digest = hex.EncodeToString(s.Sum(nil))
|
||||||
return ds
|
return ds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +255,7 @@ func (d *DS) ToCDS() *CDS {
|
||||||
// There is no check if RRSet is a proper (RFC 2181) RRSet.
|
// There is no check if RRSet is a proper (RFC 2181) RRSet.
|
||||||
// If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset
|
// If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset
|
||||||
// is used as the OrigTTL.
|
// is used as the OrigTTL.
|
||||||
func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||||
if k == nil {
|
if k == nil {
|
||||||
return ErrPrivKey
|
return ErrPrivKey
|
||||||
}
|
}
|
||||||
|
@ -258,39 +301,66 @@ func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
|
||||||
}
|
}
|
||||||
signdata = append(signdata, wire...)
|
signdata = append(signdata, wire...)
|
||||||
|
|
||||||
var h hash.Hash
|
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||||
switch rr.Algorithm {
|
if !ok {
|
||||||
case DSA, DSANSEC3SHA1:
|
|
||||||
// TODO: this seems bugged, will panic
|
|
||||||
case RSASHA1, RSASHA1NSEC3SHA1:
|
|
||||||
h = sha1.New()
|
|
||||||
case RSASHA256, ECDSAP256SHA256:
|
|
||||||
h = sha256.New()
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
h = sha512.New384()
|
|
||||||
case RSASHA512:
|
|
||||||
h = sha512.New()
|
|
||||||
case RSAMD5:
|
|
||||||
fallthrough // Deprecated in RFC 6725
|
|
||||||
default:
|
|
||||||
return ErrAlg
|
return ErrAlg
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = h.Write(signdata)
|
h := hash.New()
|
||||||
if err != nil {
|
h.Write(signdata)
|
||||||
return err
|
|
||||||
}
|
|
||||||
sighash := h.Sum(nil)
|
|
||||||
|
|
||||||
signature, err := k.Sign(sighash, rr.Algorithm)
|
signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
rr.Signature = toBase64(signature)
|
rr.Signature = toBase64(signature)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
|
||||||
|
signature, err := k.Sign(rand.Reader, hashed, hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch alg {
|
||||||
|
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
||||||
|
return signature, nil
|
||||||
|
|
||||||
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
|
ecdsaSignature := &struct {
|
||||||
|
R, S *big.Int
|
||||||
|
}{}
|
||||||
|
if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var intlen int
|
||||||
|
switch alg {
|
||||||
|
case ECDSAP256SHA256:
|
||||||
|
intlen = 32
|
||||||
|
case ECDSAP384SHA384:
|
||||||
|
intlen = 48
|
||||||
|
}
|
||||||
|
|
||||||
|
signature := intToBytes(ecdsaSignature.R, intlen)
|
||||||
|
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
|
||||||
|
return signature, nil
|
||||||
|
|
||||||
|
// There is no defined interface for what a DSA backed crypto.Signer returns
|
||||||
|
case DSA, DSANSEC3SHA1:
|
||||||
|
// t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
|
||||||
|
// signature := []byte{byte(t)}
|
||||||
|
// signature = append(signature, intToBytes(r1, 20)...)
|
||||||
|
// signature = append(signature, intToBytes(s1, 20)...)
|
||||||
|
// rr.Signature = signature
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, ErrAlg
|
||||||
|
}
|
||||||
|
|
||||||
// Verify validates an RRSet with the signature and key. This is only the
|
// Verify validates an RRSet with the signature and key. This is only the
|
||||||
// cryptographic test, the signature validity period must be checked separately.
|
// cryptographic test, the signature validity period must be checked separately.
|
||||||
// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
|
// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
|
||||||
|
@ -355,6 +425,11 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||||
// remove the domain name and assume its our
|
// remove the domain name and assume its our
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||||
|
if !ok {
|
||||||
|
return ErrAlg
|
||||||
|
}
|
||||||
|
|
||||||
switch rr.Algorithm {
|
switch rr.Algorithm {
|
||||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
|
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
|
||||||
// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
|
// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
|
||||||
|
@ -362,52 +437,31 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||||
if pubkey == nil {
|
if pubkey == nil {
|
||||||
return ErrKey
|
return ErrKey
|
||||||
}
|
}
|
||||||
// Setup the hash as defined for this alg.
|
|
||||||
var h hash.Hash
|
h := hash.New()
|
||||||
var ch crypto.Hash
|
h.Write(signeddata)
|
||||||
switch rr.Algorithm {
|
return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
|
||||||
case RSAMD5:
|
|
||||||
h = md5.New()
|
|
||||||
ch = crypto.MD5
|
|
||||||
case RSASHA1, RSASHA1NSEC3SHA1:
|
|
||||||
h = sha1.New()
|
|
||||||
ch = crypto.SHA1
|
|
||||||
case RSASHA256:
|
|
||||||
h = sha256.New()
|
|
||||||
ch = crypto.SHA256
|
|
||||||
case RSASHA512:
|
|
||||||
h = sha512.New()
|
|
||||||
ch = crypto.SHA512
|
|
||||||
}
|
|
||||||
io.WriteString(h, string(signeddata))
|
|
||||||
sighash := h.Sum(nil)
|
|
||||||
return rsa.VerifyPKCS1v15(pubkey, ch, sighash, sigbuf)
|
|
||||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
pubkey := k.publicKeyECDSA()
|
pubkey := k.publicKeyECDSA()
|
||||||
if pubkey == nil {
|
if pubkey == nil {
|
||||||
return ErrKey
|
return ErrKey
|
||||||
}
|
}
|
||||||
var h hash.Hash
|
|
||||||
switch rr.Algorithm {
|
|
||||||
case ECDSAP256SHA256:
|
|
||||||
h = sha256.New()
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
h = sha512.New384()
|
|
||||||
}
|
|
||||||
io.WriteString(h, string(signeddata))
|
|
||||||
sighash := h.Sum(nil)
|
|
||||||
// Split sigbuf into the r and s coordinates
|
// Split sigbuf into the r and s coordinates
|
||||||
r := big.NewInt(0)
|
r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
|
||||||
r.SetBytes(sigbuf[:len(sigbuf)/2])
|
s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
|
||||||
s := big.NewInt(0)
|
|
||||||
s.SetBytes(sigbuf[len(sigbuf)/2:])
|
h := hash.New()
|
||||||
if ecdsa.Verify(pubkey, sighash, r, s) {
|
h.Write(signeddata)
|
||||||
|
if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ErrSig
|
return ErrSig
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ErrAlg
|
||||||
}
|
}
|
||||||
// Unknown alg
|
|
||||||
return ErrAlg
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidityPeriod uses RFC1982 serial arithmetic to calculate
|
// ValidityPeriod uses RFC1982 serial arithmetic to calculate
|
||||||
|
@ -603,36 +657,3 @@ func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
|
||||||
}
|
}
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map for algorithm names.
|
|
||||||
var AlgorithmToString = map[uint8]string{
|
|
||||||
RSAMD5: "RSAMD5",
|
|
||||||
DH: "DH",
|
|
||||||
DSA: "DSA",
|
|
||||||
RSASHA1: "RSASHA1",
|
|
||||||
DSANSEC3SHA1: "DSA-NSEC3-SHA1",
|
|
||||||
RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
|
|
||||||
RSASHA256: "RSASHA256",
|
|
||||||
RSASHA512: "RSASHA512",
|
|
||||||
ECCGOST: "ECC-GOST",
|
|
||||||
ECDSAP256SHA256: "ECDSAP256SHA256",
|
|
||||||
ECDSAP384SHA384: "ECDSAP384SHA384",
|
|
||||||
INDIRECT: "INDIRECT",
|
|
||||||
PRIVATEDNS: "PRIVATEDNS",
|
|
||||||
PRIVATEOID: "PRIVATEOID",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map of algorithm strings.
|
|
||||||
var StringToAlgorithm = reverseInt8(AlgorithmToString)
|
|
||||||
|
|
||||||
// Map for hash names.
|
|
||||||
var HashToString = map[uint8]string{
|
|
||||||
SHA1: "SHA1",
|
|
||||||
SHA256: "SHA256",
|
|
||||||
GOST94: "GOST94",
|
|
||||||
SHA384: "SHA384",
|
|
||||||
SHA512: "SHA512",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map of hash strings.
|
|
||||||
var StringToHash = reverseInt8(HashToString)
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
|
@ -15,7 +16,7 @@ import (
|
||||||
// what kind of DNSKEY will be generated.
|
// what kind of DNSKEY will be generated.
|
||||||
// The ECDSA algorithms imply a fixed keysize, in that case
|
// The ECDSA algorithms imply a fixed keysize, in that case
|
||||||
// bits should be set to the size of the algorithm.
|
// bits should be set to the size of the algorithm.
|
||||||
func (k *DNSKEY) Generate(bits int) (PrivateKey, error) {
|
func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
|
||||||
switch k.Algorithm {
|
switch k.Algorithm {
|
||||||
case DSA, DSANSEC3SHA1:
|
case DSA, DSANSEC3SHA1:
|
||||||
if bits != 1024 {
|
if bits != 1024 {
|
||||||
|
@ -52,14 +53,14 @@ func (k *DNSKEY) Generate(bits int) (PrivateKey, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
k.setPublicKeyDSA(params.Q, params.P, params.G, priv.PublicKey.Y)
|
k.setPublicKeyDSA(params.Q, params.P, params.G, priv.PublicKey.Y)
|
||||||
return (*DSAPrivateKey)(priv), nil
|
return priv, nil
|
||||||
case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
|
case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
|
||||||
priv, err := rsa.GenerateKey(rand.Reader, bits)
|
priv, err := rsa.GenerateKey(rand.Reader, bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
|
k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
|
||||||
return (*RSAPrivateKey)(priv), nil
|
return priv, nil
|
||||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
var c elliptic.Curve
|
var c elliptic.Curve
|
||||||
switch k.Algorithm {
|
switch k.Algorithm {
|
||||||
|
@ -73,7 +74,7 @@ func (k *DNSKEY) Generate(bits int) (PrivateKey, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
|
k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
|
||||||
return (*ECDSAPrivateKey)(priv), nil
|
return priv, nil
|
||||||
default:
|
default:
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
|
|
||||||
// NewPrivateKey returns a PrivateKey by parsing the string s.
|
// NewPrivateKey returns a PrivateKey by parsing the string s.
|
||||||
// s should be in the same form of the BIND private key files.
|
// s should be in the same form of the BIND private key files.
|
||||||
func (k *DNSKEY) NewPrivateKey(s string) (PrivateKey, error) {
|
func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) {
|
||||||
if s[len(s)-1] != '\n' { // We need a closing newline
|
if s[len(s)-1] != '\n' { // We need a closing newline
|
||||||
return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
|
return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
|
||||||
}
|
}
|
||||||
|
@ -23,7 +24,7 @@ func (k *DNSKEY) NewPrivateKey(s string) (PrivateKey, error) {
|
||||||
// only used in error reporting.
|
// only used in error reporting.
|
||||||
// The public key must be known, because some cryptographic algorithms embed
|
// The public key must be known, because some cryptographic algorithms embed
|
||||||
// the public inside the privatekey.
|
// the public inside the privatekey.
|
||||||
func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) {
|
||||||
m, e := parseKey(q, file)
|
m, e := parseKey(q, file)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return nil, e
|
return nil, e
|
||||||
|
@ -50,7 +51,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, ErrKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
priv.PublicKey = *pub
|
priv.PublicKey = *pub
|
||||||
return (*DSAPrivateKey)(priv), e
|
return priv, e
|
||||||
case RSAMD5:
|
case RSAMD5:
|
||||||
fallthrough
|
fallthrough
|
||||||
case RSASHA1:
|
case RSASHA1:
|
||||||
|
@ -69,7 +70,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, ErrKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
priv.PublicKey = *pub
|
priv.PublicKey = *pub
|
||||||
return (*RSAPrivateKey)(priv), e
|
return priv, e
|
||||||
case ECCGOST:
|
case ECCGOST:
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
case ECDSAP256SHA256:
|
case ECDSAP256SHA256:
|
||||||
|
@ -84,7 +85,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
|
||||||
return nil, ErrKey
|
return nil, ErrKey
|
||||||
}
|
}
|
||||||
priv.PublicKey = *pub
|
priv.PublicKey = *pub
|
||||||
return (*ECDSAPrivateKey)(priv), e
|
return priv, e
|
||||||
default:
|
default:
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/dsa"
|
"crypto/dsa"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -12,133 +11,75 @@ import (
|
||||||
|
|
||||||
const format = "Private-key-format: v1.3\n"
|
const format = "Private-key-format: v1.3\n"
|
||||||
|
|
||||||
// PrivateKey ... TODO(miek)
|
|
||||||
type PrivateKey interface {
|
|
||||||
Sign([]byte, uint8) ([]byte, error)
|
|
||||||
String(uint8) string
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrivateKeyString converts a PrivateKey to a string. This string has the same
|
// PrivateKeyString converts a PrivateKey to a string. This string has the same
|
||||||
// format as the private-key-file of BIND9 (Private-key-format: v1.3).
|
// format as the private-key-file of BIND9 (Private-key-format: v1.3).
|
||||||
// It needs some info from the key (the algorithm), so its a method of the
|
// It needs some info from the key (the algorithm), so its a method of the DNSKEY
|
||||||
// DNSKEY and calls PrivateKey.String(alg).
|
// It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey
|
||||||
func (r *DNSKEY) PrivateKeyString(p PrivateKey) string {
|
func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
|
||||||
return p.String(r.Algorithm)
|
algorithm := strconv.Itoa(int(r.Algorithm))
|
||||||
}
|
algorithm += " (" + AlgorithmToString[r.Algorithm] + ")"
|
||||||
|
|
||||||
type RSAPrivateKey rsa.PrivateKey
|
switch p := p.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
modulus := toBase64(p.PublicKey.N.Bytes())
|
||||||
|
e := big.NewInt(int64(p.PublicKey.E))
|
||||||
|
publicExponent := toBase64(e.Bytes())
|
||||||
|
privateExponent := toBase64(p.D.Bytes())
|
||||||
|
prime1 := toBase64(p.Primes[0].Bytes())
|
||||||
|
prime2 := toBase64(p.Primes[1].Bytes())
|
||||||
|
// 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
|
||||||
|
one := big.NewInt(1)
|
||||||
|
p1 := big.NewInt(0).Sub(p.Primes[0], one)
|
||||||
|
q1 := big.NewInt(0).Sub(p.Primes[1], one)
|
||||||
|
exp1 := big.NewInt(0).Mod(p.D, p1)
|
||||||
|
exp2 := big.NewInt(0).Mod(p.D, q1)
|
||||||
|
coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0])
|
||||||
|
|
||||||
|
exponent1 := toBase64(exp1.Bytes())
|
||||||
|
exponent2 := toBase64(exp2.Bytes())
|
||||||
|
coefficient := toBase64(coeff.Bytes())
|
||||||
|
|
||||||
|
return format +
|
||||||
|
"Algorithm: " + algorithm + "\n" +
|
||||||
|
"Modulus: " + modulus + "\n" +
|
||||||
|
"PublicExponent: " + publicExponent + "\n" +
|
||||||
|
"PrivateExponent: " + privateExponent + "\n" +
|
||||||
|
"Prime1: " + prime1 + "\n" +
|
||||||
|
"Prime2: " + prime2 + "\n" +
|
||||||
|
"Exponent1: " + exponent1 + "\n" +
|
||||||
|
"Exponent2: " + exponent2 + "\n" +
|
||||||
|
"Coefficient: " + coefficient + "\n"
|
||||||
|
|
||||||
|
case *ecdsa.PrivateKey:
|
||||||
|
var intlen int
|
||||||
|
switch r.Algorithm {
|
||||||
|
case ECDSAP256SHA256:
|
||||||
|
intlen = 32
|
||||||
|
case ECDSAP384SHA384:
|
||||||
|
intlen = 48
|
||||||
|
}
|
||||||
|
private := toBase64(intToBytes(p.D, intlen))
|
||||||
|
return format +
|
||||||
|
"Algorithm: " + algorithm + "\n" +
|
||||||
|
"PrivateKey: " + private + "\n"
|
||||||
|
|
||||||
|
case *dsa.PrivateKey:
|
||||||
|
T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
|
||||||
|
prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
|
||||||
|
subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
|
||||||
|
base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
|
||||||
|
priv := toBase64(intToBytes(p.X, 20))
|
||||||
|
pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
|
||||||
|
return format +
|
||||||
|
"Algorithm: " + algorithm + "\n" +
|
||||||
|
"Prime(p): " + prime + "\n" +
|
||||||
|
"Subprime(q): " + subprime + "\n" +
|
||||||
|
"Base(g): " + base + "\n" +
|
||||||
|
"Private_value(x): " + priv + "\n" +
|
||||||
|
"Public_value(y): " + pub + "\n"
|
||||||
|
|
||||||
func (p *RSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
|
|
||||||
var hash crypto.Hash
|
|
||||||
switch alg {
|
|
||||||
case RSASHA1, RSASHA1NSEC3SHA1:
|
|
||||||
hash = crypto.SHA1
|
|
||||||
case RSASHA256:
|
|
||||||
hash = crypto.SHA256
|
|
||||||
case RSASHA512:
|
|
||||||
hash = crypto.SHA512
|
|
||||||
default:
|
default:
|
||||||
return nil, ErrAlg
|
return ""
|
||||||
}
|
}
|
||||||
return rsa.SignPKCS1v15(nil, (*rsa.PrivateKey)(p), hash, hashed)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *RSAPrivateKey) String(alg uint8) string {
|
|
||||||
algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
|
|
||||||
modulus := toBase64(p.PublicKey.N.Bytes())
|
|
||||||
e := big.NewInt(int64(p.PublicKey.E))
|
|
||||||
publicExponent := toBase64(e.Bytes())
|
|
||||||
privateExponent := toBase64(p.D.Bytes())
|
|
||||||
prime1 := toBase64(p.Primes[0].Bytes())
|
|
||||||
prime2 := toBase64(p.Primes[1].Bytes())
|
|
||||||
// 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
|
|
||||||
one := big.NewInt(1)
|
|
||||||
p1 := big.NewInt(0).Sub(p.Primes[0], one)
|
|
||||||
q1 := big.NewInt(0).Sub(p.Primes[1], one)
|
|
||||||
exp1 := big.NewInt(0).Mod(p.D, p1)
|
|
||||||
exp2 := big.NewInt(0).Mod(p.D, q1)
|
|
||||||
coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0])
|
|
||||||
|
|
||||||
exponent1 := toBase64(exp1.Bytes())
|
|
||||||
exponent2 := toBase64(exp2.Bytes())
|
|
||||||
coefficient := toBase64(coeff.Bytes())
|
|
||||||
|
|
||||||
return format +
|
|
||||||
"Algorithm: " + algorithm + "\n" +
|
|
||||||
"Modulus: " + modulus + "\n" +
|
|
||||||
"PublicExponent: " + publicExponent + "\n" +
|
|
||||||
"PrivateExponent: " + privateExponent + "\n" +
|
|
||||||
"Prime1: " + prime1 + "\n" +
|
|
||||||
"Prime2: " + prime2 + "\n" +
|
|
||||||
"Exponent1: " + exponent1 + "\n" +
|
|
||||||
"Exponent2: " + exponent2 + "\n" +
|
|
||||||
"Coefficient: " + coefficient + "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
type ECDSAPrivateKey ecdsa.PrivateKey
|
|
||||||
|
|
||||||
func (p *ECDSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
|
|
||||||
var intlen int
|
|
||||||
switch alg {
|
|
||||||
case ECDSAP256SHA256:
|
|
||||||
intlen = 32
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
intlen = 48
|
|
||||||
default:
|
|
||||||
return nil, ErrAlg
|
|
||||||
}
|
|
||||||
r1, s1, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(p), hashed)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
signature := intToBytes(r1, intlen)
|
|
||||||
signature = append(signature, intToBytes(s1, intlen)...)
|
|
||||||
return signature, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ECDSAPrivateKey) String(alg uint8) string {
|
|
||||||
algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
|
|
||||||
var intlen int
|
|
||||||
switch alg {
|
|
||||||
case ECDSAP256SHA256:
|
|
||||||
intlen = 32
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
intlen = 48
|
|
||||||
}
|
|
||||||
private := toBase64(intToBytes(p.D, intlen))
|
|
||||||
return format +
|
|
||||||
"Algorithm: " + algorithm + "\n" +
|
|
||||||
"PrivateKey: " + private + "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
type DSAPrivateKey dsa.PrivateKey
|
|
||||||
|
|
||||||
func (p *DSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
|
|
||||||
r1, s1, err := dsa.Sign(rand.Reader, (*dsa.PrivateKey)(p), hashed)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
|
|
||||||
signature := []byte{byte(t)}
|
|
||||||
signature = append(signature, intToBytes(r1, 20)...)
|
|
||||||
signature = append(signature, intToBytes(s1, 20)...)
|
|
||||||
return signature, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *DSAPrivateKey) String(alg uint8) string {
|
|
||||||
algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
|
|
||||||
T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
|
|
||||||
prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
|
|
||||||
subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
|
|
||||||
base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
|
|
||||||
priv := toBase64(intToBytes(p.X, 20))
|
|
||||||
pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
|
|
||||||
return format +
|
|
||||||
"Algorithm: " + algorithm + "\n" +
|
|
||||||
"Prime(p): " + prime + "\n" +
|
|
||||||
"Subprime(q): " + subprime + "\n" +
|
|
||||||
"Base(g): " + base + "\n" +
|
|
||||||
"Private_value(x): " + priv + "\n" +
|
|
||||||
"Public_value(y): " + pub + "\n"
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/rsa"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -192,7 +195,7 @@ func TestSignVerify(t *testing.T) {
|
||||||
sig.Algorithm = RSASHA256
|
sig.Algorithm = RSASHA256
|
||||||
|
|
||||||
for _, r := range []RR{soa, soa1, srv} {
|
for _, r := range []RR{soa, soa1, srv} {
|
||||||
if sig.Sign(privkey, []RR{r}) != nil {
|
if sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}) != nil {
|
||||||
t.Error("failure to sign the record")
|
t.Error("failure to sign the record")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -228,7 +231,7 @@ func Test65534(t *testing.T) {
|
||||||
sig.KeyTag = key.KeyTag()
|
sig.KeyTag = key.KeyTag()
|
||||||
sig.SignerName = key.Hdr.Name
|
sig.SignerName = key.Hdr.Name
|
||||||
sig.Algorithm = RSASHA256
|
sig.Algorithm = RSASHA256
|
||||||
if err := sig.Sign(privkey, []RR{t6}); err != nil {
|
if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
t.Error("failure to sign the TYPE65534 record")
|
t.Error("failure to sign the TYPE65534 record")
|
||||||
}
|
}
|
||||||
|
@ -324,7 +327,7 @@ func TestKeyRSA(t *testing.T) {
|
||||||
sig.KeyTag = key.KeyTag()
|
sig.KeyTag = key.KeyTag()
|
||||||
sig.SignerName = key.Hdr.Name
|
sig.SignerName = key.Hdr.Name
|
||||||
|
|
||||||
if err := sig.Sign(priv, []RR{soa}); err != nil {
|
if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil {
|
||||||
t.Error("failed to sign")
|
t.Error("failed to sign")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -374,7 +377,7 @@ Activate: 20110302104537`
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
switch priv := p.(type) {
|
switch priv := p.(type) {
|
||||||
case *RSAPrivateKey:
|
case *rsa.PrivateKey:
|
||||||
if 65537 != priv.PublicKey.E {
|
if 65537 != priv.PublicKey.E {
|
||||||
t.Error("exponenent should be 65537")
|
t.Error("exponenent should be 65537")
|
||||||
}
|
}
|
||||||
|
@ -403,7 +406,7 @@ Activate: 20110302104537`
|
||||||
sig.SignerName = k.Hdr.Name
|
sig.SignerName = k.Hdr.Name
|
||||||
sig.Algorithm = k.Algorithm
|
sig.Algorithm = k.Algorithm
|
||||||
|
|
||||||
sig.Sign(p, []RR{soa})
|
sig.Sign(p.(*rsa.PrivateKey), []RR{soa})
|
||||||
if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
|
if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
|
||||||
t.Errorf("signature is not correct: %v", sig)
|
t.Errorf("signature is not correct: %v", sig)
|
||||||
}
|
}
|
||||||
|
@ -443,7 +446,7 @@ PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
|
||||||
sig.SignerName = eckey.(*DNSKEY).Hdr.Name
|
sig.SignerName = eckey.(*DNSKEY).Hdr.Name
|
||||||
sig.Algorithm = eckey.(*DNSKEY).Algorithm
|
sig.Algorithm = eckey.(*DNSKEY).Algorithm
|
||||||
|
|
||||||
if sig.Sign(privkey, []RR{a}) != nil {
|
if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil {
|
||||||
t.Fatal("failure to sign the record")
|
t.Fatal("failure to sign the record")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +494,7 @@ func TestSignVerifyECDSA2(t *testing.T) {
|
||||||
sig.SignerName = key.Hdr.Name
|
sig.SignerName = key.Hdr.Name
|
||||||
sig.Algorithm = ECDSAP256SHA256
|
sig.Algorithm = ECDSAP256SHA256
|
||||||
|
|
||||||
if sig.Sign(privkey, []RR{srv}) != nil {
|
if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil {
|
||||||
t.Fatal("failure to sign the record")
|
t.Fatal("failure to sign the record")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +567,7 @@ PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
|
||||||
}
|
}
|
||||||
ourRRSIG.Expiration, _ = StringToTime("20100909100439")
|
ourRRSIG.Expiration, _ = StringToTime("20100909100439")
|
||||||
ourRRSIG.Inception, _ = StringToTime("20100812100439")
|
ourRRSIG.Inception, _ = StringToTime("20100812100439")
|
||||||
err = ourRRSIG.Sign(priv, []RR{rrA})
|
err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -640,7 +643,7 @@ PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
|
||||||
}
|
}
|
||||||
ourRRSIG.Expiration, _ = StringToTime("20100909102025")
|
ourRRSIG.Expiration, _ = StringToTime("20100909102025")
|
||||||
ourRRSIG.Inception, _ = StringToTime("20100812102025")
|
ourRRSIG.Inception, _ = StringToTime("20100812102025")
|
||||||
err = ourRRSIG.Sign(priv, []RR{rrA})
|
err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -709,7 +712,7 @@ func TestInvalidRRSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign the good record set and then make sure verification fails on the bad record set
|
// Sign the good record set and then make sure verification fails on the bad record set
|
||||||
if err := signature.Sign(privatekey, goodRecords); err != nil {
|
if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil {
|
||||||
t.Fatal("Signing good records failed")
|
t.Fatal("Signing good records failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1237,8 +1237,8 @@ func TestNewPrivateKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch newPrivKey := newPrivKey.(type) {
|
switch newPrivKey := newPrivKey.(type) {
|
||||||
case *RSAPrivateKey:
|
case *rsa.PrivateKey:
|
||||||
(*rsa.PrivateKey)(newPrivKey).Precompute()
|
newPrivKey.Precompute()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(privkey, newPrivKey) {
|
if !reflect.DeepEqual(privkey, newPrivKey) {
|
||||||
|
|
25
sig0.go
25
sig0.go
|
@ -13,7 +13,7 @@ import (
|
||||||
// Sign signs a dns.Msg. It fills the signature with the appropriate data.
|
// Sign signs a dns.Msg. It fills the signature with the appropriate data.
|
||||||
// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
|
// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
|
||||||
// and Expiration set.
|
// and Expiration set.
|
||||||
func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
|
||||||
if k == nil {
|
if k == nil {
|
||||||
return nil, ErrPrivKey
|
return nil, ErrPrivKey
|
||||||
}
|
}
|
||||||
|
@ -41,31 +41,26 @@ func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
buf = buf[:off:cap(buf)]
|
buf = buf[:off:cap(buf)]
|
||||||
var hash crypto.Hash
|
|
||||||
switch rr.Algorithm {
|
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||||
case DSA, RSASHA1:
|
if !ok {
|
||||||
hash = crypto.SHA1
|
|
||||||
case RSASHA256, ECDSAP256SHA256:
|
|
||||||
hash = crypto.SHA256
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
hash = crypto.SHA384
|
|
||||||
case RSASHA512:
|
|
||||||
hash = crypto.SHA512
|
|
||||||
default:
|
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher := hash.New()
|
hasher := hash.New()
|
||||||
// Write SIG rdata
|
// Write SIG rdata
|
||||||
hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
|
hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
|
||||||
// Write message
|
// Write message
|
||||||
hasher.Write(buf[:len(mbuf)])
|
hasher.Write(buf[:len(mbuf)])
|
||||||
hashed := hasher.Sum(nil)
|
|
||||||
|
|
||||||
sig, err := k.Sign(hashed, rr.Algorithm)
|
signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rr.Signature = toBase64(sig)
|
|
||||||
|
rr.Signature = toBase64(signature)
|
||||||
|
sig := string(signature)
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -11,7 +12,7 @@ func TestSIG0(t *testing.T) {
|
||||||
}
|
}
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
m.SetQuestion("example.org.", TypeSOA)
|
m.SetQuestion("example.org.", TypeSOA)
|
||||||
for _, alg := range []uint8{DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
|
for _, alg := range []uint8{ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
|
||||||
algstr := AlgorithmToString[alg]
|
algstr := AlgorithmToString[alg]
|
||||||
keyrr := new(KEY)
|
keyrr := new(KEY)
|
||||||
keyrr.Hdr.Name = algstr + "."
|
keyrr.Hdr.Name = algstr + "."
|
||||||
|
@ -40,7 +41,7 @@ func TestSIG0(t *testing.T) {
|
||||||
sigrr.Inception = now - 300
|
sigrr.Inception = now - 300
|
||||||
sigrr.KeyTag = keyrr.KeyTag()
|
sigrr.KeyTag = keyrr.KeyTag()
|
||||||
sigrr.SignerName = keyrr.Hdr.Name
|
sigrr.SignerName = keyrr.Hdr.Name
|
||||||
mb, err := sigrr.Sign(pk, m)
|
mb, err := sigrr.Sign(pk.(crypto.Signer), m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to sign message using “%s”: %v", algstr, err)
|
t.Errorf("Failed to sign message using “%s”: %v", algstr, err)
|
||||||
continue
|
continue
|
||||||
|
@ -79,7 +80,7 @@ func TestSIG0(t *testing.T) {
|
||||||
}
|
}
|
||||||
sigrr.Expiration = 2
|
sigrr.Expiration = 2
|
||||||
sigrr.Inception = 1
|
sigrr.Inception = 1
|
||||||
mb, _ = sigrr.Sign(pk, m)
|
mb, _ = sigrr.Sign(pk.(crypto.Signer), m)
|
||||||
if err := sigrr.Verify(keyrr, mb); err == nil {
|
if err := sigrr.Verify(keyrr, mb); err == nil {
|
||||||
t.Errorf("Verify succeeded on an expired message using “%s”", algstr)
|
t.Errorf("Verify succeeded on an expired message using “%s”", algstr)
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue