dns/dnssec.go

740 lines
18 KiB
Go
Raw Normal View History

// DNSSEC
//
// DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It
2012-12-01 11:44:57 +00:00
// uses public key cryptography to sign resource records. The
// public keys are stored in DNSKEY records and the signatures in RRSIG records.
//
// Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
// to an request.
2013-05-11 19:02:17 +00:00
//
// m := new(dns.Msg)
// m.SetEdns0(4096, true)
2012-08-27 06:41:14 +00:00
//
// Signature generation, signature verification and key generation are all supported.
package dns
import (
2011-09-07 20:38:34 +00:00
"bytes"
2011-02-24 15:22:14 +00:00
"crypto"
2012-04-17 09:39:58 +00:00
"crypto/dsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"hash"
2011-12-16 14:06:24 +00:00
"io"
"math/big"
"sort"
"strings"
"time"
)
// DNSSEC encryption algorithm codes.
const (
RSAMD5 = 1
DH = 2
DSA = 3
ECC = 4
RSASHA1 = 5
DSANSEC3SHA1 = 6
RSASHA1NSEC3SHA1 = 7
RSASHA256 = 8
RSASHA512 = 10
ECCGOST = 12
2012-04-11 12:37:51 +00:00
ECDSAP256SHA256 = 13
ECDSAP384SHA384 = 14
2012-04-16 07:09:32 +00:00
INDIRECT = 252
2011-12-09 20:45:57 +00:00
PRIVATEDNS = 253 // Private (experimental keys)
PRIVATEOID = 254
)
// DNSSEC hashing algorithm codes.
const (
2011-07-23 21:43:43 +00:00
_ = iota
SHA1 // RFC 4034
2013-05-11 19:02:17 +00:00
SHA256 // RFC 4509
2011-07-23 21:43:43 +00:00
GOST94 // RFC 5933
SHA384 // Experimental
2012-04-11 12:32:44 +00:00
SHA512 // Experimental
)
// DNSKEY flag values.
2011-03-03 10:45:33 +00:00
const (
2012-01-08 15:49:54 +00:00
SEP = 1
REVOKE = 1 << 7
ZONE = 1 << 8
2011-03-03 10:45:33 +00:00
)
// The RRSIG needs to be converted to wireformat with some of
// the rdata (the signature) missing. Use this struct to easy
2011-02-11 21:21:41 +00:00
// the conversion (and re-use the pack/unpack functions).
type rrsigWireFmt struct {
TypeCovered uint16
Algorithm uint8
Labels uint8
OrigTtl uint32
Expiration uint32
Inception uint32
KeyTag uint16
SignerName string `dns:"domain-name"`
/* No Signature */
}
// Used for converting DNSKEY's rdata to wirefmt.
type dnskeyWireFmt struct {
Flags uint16
Protocol uint8
Algorithm uint8
PublicKey string `dns:"base64"`
2011-01-18 10:34:48 +00:00
/* Nothing is left out */
}
2012-01-15 15:14:22 +00:00
// KeyTag calculates the keytag (or key-id) of the DNSKEY.
func (k *DNSKEY) KeyTag() uint16 {
if k == nil {
return 0
}
var keytag int
switch k.Algorithm {
2011-07-08 15:27:44 +00:00
case RSAMD5:
2012-04-17 08:55:02 +00:00
// Look at the bottom two bytes of the modules, which the last
// item in the pubkey. We could do this faster by looking directly
// at the base64 values. But I'm lazy.
modulus, _ := packBase64([]byte(k.PublicKey))
2012-05-05 15:37:48 +00:00
if len(modulus) > 1 {
2012-04-17 08:55:02 +00:00
x, _ := unpackUint16(modulus, len(modulus)-2)
keytag = int(x)
}
default:
keywire := new(dnskeyWireFmt)
keywire.Flags = k.Flags
keywire.Protocol = k.Protocol
keywire.Algorithm = k.Algorithm
keywire.PublicKey = k.PublicKey
2011-01-27 19:43:55 +00:00
wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(keywire, wire, 0)
if err != nil {
return 0
}
wire = wire[:n]
for i, v := range wire {
if i&1 != 0 {
keytag += int(v) // must be larger than uint32
} else {
keytag += int(v) << 8
}
}
keytag += (keytag >> 16) & 0xFFFF
keytag &= 0xFFFF
}
return uint16(keytag)
}
2011-09-08 17:25:45 +00:00
// ToDS converts a DNSKEY record to a DS record.
func (k *DNSKEY) ToDS(h int) *DS {
if k == nil {
return nil
}
ds := new(DS)
ds.Hdr.Name = k.Hdr.Name
ds.Hdr.Class = k.Hdr.Class
2011-03-24 08:24:24 +00:00
ds.Hdr.Rrtype = TypeDS
ds.Hdr.Ttl = k.Hdr.Ttl
ds.Algorithm = k.Algorithm
ds.DigestType = uint8(h)
ds.KeyTag = k.KeyTag()
keywire := new(dnskeyWireFmt)
keywire.Flags = k.Flags
keywire.Protocol = k.Protocol
keywire.Algorithm = k.Algorithm
keywire.PublicKey = k.PublicKey
2011-01-27 19:43:55 +00:00
wire := make([]byte, DefaultMsgSize)
n, err := PackStruct(keywire, wire, 0)
if err != nil {
2012-03-19 19:00:40 +00:00
return nil
}
wire = wire[:n]
owner := make([]byte, 255)
off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false)
2012-10-10 20:17:50 +00:00
if err1 != nil {
2012-03-19 19:00:40 +00:00
return nil
}
owner = owner[:off]
2011-03-15 18:41:28 +00:00
// RFC4034:
// digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
// "|" denotes concatenation
// DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
// digest buffer
digest := append(owner, wire...) // another copy
switch h {
2011-07-08 15:27:44 +00:00
case SHA1:
s := sha1.New()
2011-12-16 14:06:24 +00:00
io.WriteString(s, string(digest))
ds.Digest = hex.EncodeToString(s.Sum(nil))
2011-07-08 15:27:44 +00:00
case SHA256:
s := sha256.New()
2011-12-16 14:06:24 +00:00
io.WriteString(s, string(digest))
ds.Digest = hex.EncodeToString(s.Sum(nil))
2011-07-23 21:43:43 +00:00
case SHA384:
s := sha512.New384()
2011-12-16 14:06:24 +00:00
io.WriteString(s, string(digest))
ds.Digest = hex.EncodeToString(s.Sum(nil))
2011-07-08 15:27:44 +00:00
case GOST94:
2011-01-18 10:34:48 +00:00
/* I have no clue */
default:
return nil
}
return ds
}
2011-09-08 06:30:17 +00:00
// Sign signs an RRSet. The signature needs to be filled in with
2014-02-02 20:30:52 +00:00
// the values: Inception, Expiration, KeyTag, SignerName and Algorithm.
2011-09-08 17:25:45 +00:00
// The rest is copied from the RRset. Sign returns true when the signing went OK,
// otherwise false.
2011-03-30 13:44:28 +00:00
// There is no check if RRSet is a proper (RFC 2181) RRSet.
2014-02-02 20:30:52 +00:00
// If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset
// is used as the OrigTTL.
func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
if k == nil {
return ErrPrivKey
}
// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
2012-09-03 06:35:21 +00:00
if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
return ErrKey
2011-02-24 15:22:14 +00:00
}
2012-09-03 06:35:21 +00:00
rr.Hdr.Rrtype = TypeRRSIG
rr.Hdr.Name = rrset[0].Header().Name
rr.Hdr.Class = rrset[0].Header().Class
2014-01-26 20:22:19 +00:00
if rr.OrigTtl == 0 { // If set don't override
rr.OrigTtl = rrset[0].Header().Ttl
}
2012-09-03 06:35:21 +00:00
rr.TypeCovered = rrset[0].Header().Rrtype
rr.Labels = uint8(CountLabel(rrset[0].Header().Name))
2012-04-06 18:12:00 +00:00
2011-02-24 15:22:14 +00:00
if strings.HasPrefix(rrset[0].Header().Name, "*") {
2012-09-03 06:35:21 +00:00
rr.Labels-- // wildcard, remove from label count
2011-02-24 15:22:14 +00:00
}
sigwire := new(rrsigWireFmt)
2012-09-03 06:35:21 +00:00
sigwire.TypeCovered = rr.TypeCovered
sigwire.Algorithm = rr.Algorithm
sigwire.Labels = rr.Labels
sigwire.OrigTtl = rr.OrigTtl
sigwire.Expiration = rr.Expiration
sigwire.Inception = rr.Inception
sigwire.KeyTag = rr.KeyTag
2012-02-28 18:25:09 +00:00
// For signing, lowercase this name
2012-09-03 06:35:21 +00:00
sigwire.SignerName = strings.ToLower(rr.SignerName)
// Create the desired binary blob
2011-01-27 08:38:52 +00:00
signdata := make([]byte, DefaultMsgSize)
n, err := PackStruct(sigwire, signdata, 0)
if err != nil {
return err
}
signdata = signdata[:n]
wire, err := rawSignatureData(rrset, rr)
if err != nil {
return err
2011-02-24 15:22:14 +00:00
}
signdata = append(signdata, wire...)
2011-07-23 21:43:43 +00:00
var sighash []byte
var h hash.Hash
var ch crypto.Hash // Only need for RSA
2012-09-03 06:35:21 +00:00
switch rr.Algorithm {
2012-04-19 12:39:50 +00:00
case DSA, DSANSEC3SHA1:
2012-04-18 09:57:32 +00:00
// Implicit in the ParameterSizes
case RSASHA1, RSASHA1NSEC3SHA1:
2011-07-23 21:43:43 +00:00
h = sha1.New()
ch = crypto.SHA1
2012-04-11 12:37:51 +00:00
case RSASHA256, ECDSAP256SHA256:
2011-07-23 21:43:43 +00:00
h = sha256.New()
ch = crypto.SHA256
2012-04-11 12:37:51 +00:00
case ECDSAP384SHA384:
2011-07-23 21:43:43 +00:00
h = sha512.New384()
case RSASHA512:
h = sha512.New()
ch = crypto.SHA512
2012-09-14 07:11:19 +00:00
case RSAMD5:
2012-10-10 20:17:50 +00:00
fallthrough // Deprecated in RFC 6725
2011-07-23 21:43:43 +00:00
default:
return ErrAlg
2011-07-23 21:43:43 +00:00
}
2011-12-16 14:06:24 +00:00
io.WriteString(h, string(signdata))
sighash = h.Sum(nil)
2011-07-23 21:43:43 +00:00
switch p := k.(type) {
case *dsa.PrivateKey:
2012-04-18 09:57:32 +00:00
r1, s1, err := dsa.Sign(rand.Reader, p, sighash)
if err != nil {
return err
}
2012-05-05 15:37:48 +00:00
signature := []byte{0x4D} // T value, here the ASCII M for Miek (not used in DNSSEC)
signature = append(signature, r1.Bytes()...)
2012-04-18 09:57:32 +00:00
signature = append(signature, s1.Bytes()...)
2012-09-03 06:35:21 +00:00
rr.Signature = unpackBase64(signature)
2011-07-23 21:43:43 +00:00
case *rsa.PrivateKey:
2012-09-16 08:28:53 +00:00
// We can use nil as rand.Reader here (says AGL)
signature, err := rsa.SignPKCS1v15(nil, p, ch, sighash)
2011-07-23 21:43:43 +00:00
if err != nil {
return err
2011-07-23 21:43:43 +00:00
}
2012-09-03 06:35:21 +00:00
rr.Signature = unpackBase64(signature)
2011-07-23 21:43:43 +00:00
case *ecdsa.PrivateKey:
r1, s1, err := ecdsa.Sign(rand.Reader, p, sighash)
if err != nil {
return err
2011-07-23 21:43:43 +00:00
}
signature := r1.Bytes()
signature = append(signature, s1.Bytes()...)
2012-09-03 06:35:21 +00:00
rr.Signature = unpackBase64(signature)
2011-07-23 21:43:43 +00:00
default:
// Not given the correct key
return ErrKeyAlg
2011-07-23 21:43:43 +00:00
}
return nil
2011-01-13 16:14:14 +00:00
}
2011-09-08 17:25:45 +00:00
// Verify validates an RRSet with the signature and key. This is only the
2012-01-28 23:34:59 +00:00
// cryptographic test, the signature validity period must be checked separately.
2013-05-11 19:02:17 +00:00
// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
2012-02-10 08:19:23 +00:00
// First the easy checks
2012-02-28 18:25:09 +00:00
if len(rrset) == 0 {
2012-08-27 06:41:14 +00:00
return ErrRRset
2012-02-28 18:25:09 +00:00
}
2012-09-03 06:37:16 +00:00
if rr.KeyTag != k.KeyTag() {
return ErrKey
}
2012-09-03 06:37:16 +00:00
if rr.Hdr.Class != k.Hdr.Class {
return ErrKey
}
2012-09-03 06:37:16 +00:00
if rr.Algorithm != k.Algorithm {
return ErrKey
}
2012-09-03 06:37:16 +00:00
if strings.ToLower(rr.SignerName) != strings.ToLower(k.Hdr.Name) {
return ErrKey
}
2012-02-23 09:47:50 +00:00
if k.Protocol != 3 {
return ErrKey
}
for _, r := range rrset {
2012-09-03 06:37:16 +00:00
if r.Header().Class != rr.Hdr.Class {
return ErrRRset
}
2012-09-03 06:37:16 +00:00
if r.Header().Rrtype != rr.TypeCovered {
return ErrRRset
}
}
// RFC 4035 5.3.2. Reconstructing the Signed Data
// Copy the sig, except the rrsig data
sigwire := new(rrsigWireFmt)
2012-09-03 06:37:16 +00:00
sigwire.TypeCovered = rr.TypeCovered
sigwire.Algorithm = rr.Algorithm
sigwire.Labels = rr.Labels
sigwire.OrigTtl = rr.OrigTtl
sigwire.Expiration = rr.Expiration
sigwire.Inception = rr.Inception
sigwire.KeyTag = rr.KeyTag
sigwire.SignerName = strings.ToLower(rr.SignerName)
// Create the desired binary blob
2011-01-27 08:38:52 +00:00
signeddata := make([]byte, DefaultMsgSize)
n, err := PackStruct(sigwire, signeddata, 0)
if err != nil {
return err
}
signeddata = signeddata[:n]
wire, err := rawSignatureData(rrset, rr)
if err != nil {
return err
2011-02-24 15:22:14 +00:00
}
signeddata = append(signeddata, wire...)
2012-09-03 06:37:16 +00:00
sigbuf := rr.sigBuf() // Get the binary signature data
if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
2012-04-15 19:37:00 +00:00
// TODO(mg)
2011-12-09 20:45:57 +00:00
// remove the domain name and assume its our
}
2012-09-03 06:37:16 +00:00
switch rr.Algorithm {
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
2012-04-15 19:37:00 +00:00
// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
2012-04-11 14:09:40 +00:00
pubkey := k.publicKeyRSA() // Get the key
2012-02-29 20:11:45 +00:00
if pubkey == nil {
return ErrKey
}
// Setup the hash as defined for this alg.
var h hash.Hash
2011-02-02 08:05:25 +00:00
var ch crypto.Hash
2012-09-03 06:37:16 +00:00
switch rr.Algorithm {
2011-07-08 15:27:44 +00:00
case RSAMD5:
h = md5.New()
2011-02-02 08:05:25 +00:00
ch = crypto.MD5
case RSASHA1, RSASHA1NSEC3SHA1:
h = sha1.New()
2011-02-02 08:05:25 +00:00
ch = crypto.SHA1
2011-07-08 15:27:44 +00:00
case RSASHA256:
h = sha256.New()
2011-02-02 08:05:25 +00:00
ch = crypto.SHA256
2011-07-08 15:27:44 +00:00
case RSASHA512:
h = sha512.New()
2011-02-02 08:05:25 +00:00
ch = crypto.SHA512
}
2011-12-16 14:06:24 +00:00
io.WriteString(h, string(signeddata))
sighash := h.Sum(nil)
return rsa.VerifyPKCS1v15(pubkey, ch, sighash, sigbuf)
2012-04-11 14:20:29 +00:00
case ECDSAP256SHA256, ECDSAP384SHA384:
pubkey := k.publicKeyCurve()
if pubkey == nil {
return ErrKey
}
2012-04-15 19:37:00 +00:00
var h hash.Hash
2012-09-03 06:37:16 +00:00
switch rr.Algorithm {
2012-04-15 19:37:00 +00:00
case ECDSAP256SHA256:
h = sha256.New()
case ECDSAP384SHA384:
h = sha512.New384()
2012-04-15 19:37:00 +00:00
}
io.WriteString(h, string(signeddata))
sighash := h.Sum(nil)
// Split sigbuf into the r and s coordinates
r := big.NewInt(0)
r.SetBytes(sigbuf[:len(sigbuf)/2])
s := big.NewInt(0)
s.SetBytes(sigbuf[len(sigbuf)/2:])
if ecdsa.Verify(pubkey, sighash, r, s) {
return nil
2012-04-15 19:37:00 +00:00
}
return ErrSig
}
// Unknown alg
2011-11-02 22:06:54 +00:00
return ErrAlg
}
2013-05-11 19:02:17 +00:00
// ValidityPeriod uses RFC1982 serial arithmetic to calculate
// if a signature period is valid. If t is the zero time, the
// current time is taken other t is.
2014-01-27 14:45:34 +00:00
func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
var utc int64
2014-01-27 14:45:34 +00:00
if t.IsZero() {
utc = time.Now().UTC().Unix()
} else {
2014-01-27 14:45:34 +00:00
utc = t.UTC().Unix()
}
2012-09-03 06:37:16 +00:00
modi := (int64(rr.Inception) - utc) / year68
mode := (int64(rr.Expiration) - utc) / year68
ti := int64(rr.Inception) + (modi * year68)
te := int64(rr.Expiration) + (mode * year68)
return ti <= utc && utc <= te
}
// Return the signatures base64 encodedig sigdata as a byte slice.
func (s *RRSIG) sigBuf() []byte {
sigbuf, err := packBase64([]byte(s.Signature))
if err != nil {
return nil
}
return sigbuf
}
2013-05-11 19:02:17 +00:00
// setPublicKeyInPrivate sets the public key in the private key.
func (k *DNSKEY) setPublicKeyInPrivate(p PrivateKey) bool {
2012-04-11 14:09:40 +00:00
switch t := p.(type) {
2012-04-17 09:39:58 +00:00
case *dsa.PrivateKey:
x := k.publicKeyDSA()
if x == nil {
return false
}
t.PublicKey = *x
2012-04-11 14:09:40 +00:00
case *rsa.PrivateKey:
2012-04-17 09:39:58 +00:00
x := k.publicKeyRSA()
if x == nil {
return false
}
t.PublicKey = *x
2012-04-11 14:09:40 +00:00
case *ecdsa.PrivateKey:
x := k.publicKeyCurve()
if x == nil {
return false
}
t.PublicKey = *x
}
return true
}
// publicKeyRSA returns the RSA public key from a DNSKEY record.
func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
// RFC 2537/3110, section 2. RSA Public KEY Resource Records
// Length is in the 0th byte, unless its zero, then it
// it in bytes 1 and 2 and its a 16 bit number
explen := uint16(keybuf[0])
keyoff := 1
if explen == 0 {
explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
keyoff = 3
}
pubkey := new(rsa.PublicKey)
2012-02-29 20:11:45 +00:00
pubkey.N = big.NewInt(0)
2012-02-29 20:11:45 +00:00
shift := uint64((explen - 1) * 8)
expo := uint64(0)
for i := int(explen - 1); i > 0; i-- {
expo += uint64(keybuf[keyoff+i]) << shift
shift -= 8
}
2012-02-29 20:11:45 +00:00
// Remainder
expo += uint64(keybuf[keyoff])
if expo > 2<<31 {
// Larger expo than supported.
// println("dns: F5 primes (or larger) are not supported")
2012-02-29 20:11:45 +00:00
return nil
}
pubkey.E = int(expo)
pubkey.N.SetBytes(keybuf[keyoff+int(explen):])
return pubkey
}
2012-04-11 14:09:40 +00:00
// publicKeyCurve returns the Curve public key from the DNSKEY record.
func (k *DNSKEY) publicKeyCurve() *ecdsa.PublicKey {
2011-07-23 21:43:43 +00:00
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
2012-04-11 12:32:44 +00:00
pubkey := new(ecdsa.PublicKey)
2011-07-23 21:43:43 +00:00
switch k.Algorithm {
2012-04-11 12:37:51 +00:00
case ECDSAP256SHA256:
2012-04-11 12:32:44 +00:00
pubkey.Curve = elliptic.P256()
2012-04-12 13:39:54 +00:00
if len(keybuf) != 64 {
// wrongly encoded key
return nil
}
2012-04-11 12:37:51 +00:00
case ECDSAP384SHA384:
2012-04-11 12:32:44 +00:00
pubkey.Curve = elliptic.P384()
2012-04-12 13:39:54 +00:00
if len(keybuf) != 96 {
// Wrongly encoded key
return nil
}
2011-07-23 21:43:43 +00:00
}
2012-04-11 12:32:44 +00:00
pubkey.X = big.NewInt(0)
pubkey.X.SetBytes(keybuf[:len(keybuf)/2])
pubkey.Y = big.NewInt(0)
2012-04-12 13:39:54 +00:00
pubkey.Y.SetBytes(keybuf[len(keybuf)/2:])
2011-07-23 21:43:43 +00:00
return pubkey
2011-07-08 09:08:31 +00:00
}
func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
2012-04-17 09:39:58 +00:00
keybuf, err := packBase64([]byte(k.PublicKey))
if err != nil {
return nil
}
if len(keybuf) < 22 { // TODO: check
return nil
}
t := int(keybuf[0])
size := 64 + t*8
pubkey := new(dsa.PublicKey)
pubkey.Parameters.Q = big.NewInt(0)
pubkey.Parameters.Q.SetBytes(keybuf[1:21]) // +/- 1 ?
pubkey.Parameters.P = big.NewInt(0)
2012-05-05 15:37:48 +00:00
pubkey.Parameters.P.SetBytes(keybuf[22 : 22+size])
2012-04-17 09:39:58 +00:00
pubkey.Parameters.G = big.NewInt(0)
2012-05-05 15:37:48 +00:00
pubkey.Parameters.G.SetBytes(keybuf[22+size+1 : 22+size*2])
2012-04-17 09:39:58 +00:00
pubkey.Y = big.NewInt(0)
2012-05-05 15:37:48 +00:00
pubkey.Y.SetBytes(keybuf[22+size*2+1 : 22+size*3])
2012-04-17 09:39:58 +00:00
return pubkey
}
// Set the public key (the value E and N)
func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
2011-07-07 09:19:57 +00:00
if _E == 0 || _N == nil {
2011-03-24 08:24:24 +00:00
return false
}
2011-01-17 19:29:40 +00:00
buf := exponentToBuf(_E)
buf = append(buf, _N.Bytes()...)
k.PublicKey = unpackBase64(buf)
2011-03-24 08:02:19 +00:00
return true
2011-01-17 17:13:52 +00:00
}
2011-07-08 08:41:07 +00:00
// Set the public key for Elliptic Curves
func (k *DNSKEY) setPublicKeyCurve(_X, _Y *big.Int) bool {
2011-07-23 21:43:43 +00:00
if _X == nil || _Y == nil {
return false
}
buf := curveToBuf(_X, _Y)
2012-04-12 13:39:54 +00:00
// Check the length of the buffer, either 64 or 92 bytes
2011-07-23 21:43:43 +00:00
k.PublicKey = unpackBase64(buf)
return true
2012-04-17 09:39:58 +00:00
}
// Set the public key for DSA
func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
if _Q == nil || _P == nil || _G == nil || _Y == nil {
2012-04-17 09:39:58 +00:00
return false
}
buf := dsaToBuf(_Q, _P, _G, _Y)
k.PublicKey = unpackBase64(buf)
2012-04-17 09:39:58 +00:00
return true
2011-07-08 08:41:07 +00:00
}
2011-07-07 09:19:57 +00:00
// Set the public key (the values E and N) for RSA
2011-01-17 19:18:51 +00:00
// RFC 3110: Section 2. RSA Public KEY Resource Records
2011-01-17 17:13:52 +00:00
func exponentToBuf(_E int) []byte {
2011-01-17 19:29:40 +00:00
var buf []byte
i := big.NewInt(int64(_E))
if len(i.Bytes()) < 256 {
buf = make([]byte, 1)
buf[0] = uint8(len(i.Bytes()))
} else {
buf = make([]byte, 3)
buf[0] = 0
buf[1] = uint8(len(i.Bytes()) >> 8)
buf[2] = uint8(len(i.Bytes()))
}
buf = append(buf, i.Bytes()...)
return buf
}
2013-05-11 19:02:17 +00:00
// Set the public key for X and Y for Curve. The two
2012-04-11 12:32:44 +00:00
// values are just concatenated.
func curveToBuf(_X, _Y *big.Int) []byte {
2011-07-23 21:43:43 +00:00
buf := _X.Bytes()
buf = append(buf, _Y.Bytes()...)
return buf
2011-07-08 08:41:07 +00:00
}
2013-05-11 19:02:17 +00:00
// Set the public key for X and Y for Curve. The two
// values are just concatenated.
func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
2012-04-18 10:55:48 +00:00
t := byte((len(_G.Bytes()) - 64) / 8)
buf := []byte{t}
buf = append(buf, _Q.Bytes()...)
buf = append(buf, _P.Bytes()...)
buf = append(buf, _G.Bytes()...)
buf = append(buf, _Y.Bytes()...)
return buf
}
2011-09-07 20:38:34 +00:00
type wireSlice [][]byte
func (p wireSlice) Len() int { return len(p) }
func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
2011-09-07 20:38:34 +00:00
func (p wireSlice) Less(i, j int) bool {
2011-10-06 18:16:23 +00:00
_, ioff, _ := UnpackDomainName(p[i], 0)
_, joff, _ := UnpackDomainName(p[j], 0)
2011-09-07 20:38:34 +00:00
return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
}
// Return the raw signature data.
func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
2011-09-07 20:38:34 +00:00
wires := make(wireSlice, len(rrset))
for i, r := range rrset {
r1 := r.copy()
r1.Header().Ttl = s.OrigTtl
labels := SplitDomainName(r1.Header().Name)
// 6.2. Canonical RR Form. (4) - wildcards
if len(labels) > int(s.Labels) {
// Wildcard
r1.Header().Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
}
// RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
r1.Header().Name = strings.ToLower(r1.Header().Name)
2012-02-23 09:47:50 +00:00
// 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
// NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
// HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
// SRV, DNAME, A6
switch x := r1.(type) {
case *NS:
2012-02-23 09:47:50 +00:00
x.Ns = strings.ToLower(x.Ns)
case *CNAME:
x.Target = strings.ToLower(x.Target)
case *SOA:
2012-02-23 09:47:50 +00:00
x.Ns = strings.ToLower(x.Ns)
x.Mbox = strings.ToLower(x.Mbox)
case *MB:
2012-02-23 09:47:50 +00:00
x.Mb = strings.ToLower(x.Mb)
case *MG:
2012-02-23 09:47:50 +00:00
x.Mg = strings.ToLower(x.Mg)
case *MR:
2012-02-23 09:47:50 +00:00
x.Mr = strings.ToLower(x.Mr)
case *PTR:
2012-02-23 09:47:50 +00:00
x.Ptr = strings.ToLower(x.Ptr)
case *MINFO:
2012-02-23 09:47:50 +00:00
x.Rmail = strings.ToLower(x.Rmail)
x.Email = strings.ToLower(x.Email)
case *MX:
2012-02-23 09:47:50 +00:00
x.Mx = strings.ToLower(x.Mx)
case *NAPTR:
2012-02-23 09:47:50 +00:00
x.Replacement = strings.ToLower(x.Replacement)
case *KX:
2012-02-23 09:47:50 +00:00
x.Exchanger = strings.ToLower(x.Exchanger)
case *SRV:
2012-02-23 09:47:50 +00:00
x.Target = strings.ToLower(x.Target)
case *DNAME:
2012-02-23 09:47:50 +00:00
x.Target = strings.ToLower(x.Target)
}
// 6.2. Canonical RR Form. (5) - origTTL
wire := make([]byte, r1.len()+1) // +1 to be safe(r)
off, err1 := PackRR(r1, wire, 0, nil, false)
if err1 != nil {
return nil, err1
}
2012-01-21 10:58:26 +00:00
wire = wire[:off]
2011-09-07 20:38:34 +00:00
wires[i] = wire
}
sort.Sort(wires)
for _, wire := range wires {
2011-02-24 15:22:14 +00:00
buf = append(buf, wire...)
}
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",
2012-04-11 12:37:51 +00:00
ECDSAP256SHA256: "ECDSAP256SHA256",
ECDSAP384SHA384: "ECDSAP384SHA384",
2012-04-16 07:09:32 +00:00
INDIRECT: "INDIRECT",
2011-12-09 20:45:57 +00:00
PRIVATEDNS: "PRIVATEDNS",
PRIVATEOID: "PRIVATEOID",
}
// Map of algorithm strings.
var StringToAlgorithm = reverseInt8(AlgorithmToString)
2013-05-11 19:02:17 +00:00
// 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)