gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

dnssec.go (18761B)


      1 package dns
      2 
      3 import (
      4 	"bytes"
      5 	"crypto"
      6 	"crypto/ecdsa"
      7 	"crypto/ed25519"
      8 	"crypto/elliptic"
      9 	"crypto/rand"
     10 	"crypto/rsa"
     11 	_ "crypto/sha1"   // need its init function
     12 	_ "crypto/sha256" // need its init function
     13 	_ "crypto/sha512" // need its init function
     14 	"encoding/asn1"
     15 	"encoding/binary"
     16 	"encoding/hex"
     17 	"math/big"
     18 	"sort"
     19 	"strings"
     20 	"time"
     21 )
     22 
     23 // DNSSEC encryption algorithm codes.
     24 const (
     25 	_ uint8 = iota
     26 	RSAMD5
     27 	DH
     28 	DSA
     29 	_ // Skip 4, RFC 6725, section 2.1
     30 	RSASHA1
     31 	DSANSEC3SHA1
     32 	RSASHA1NSEC3SHA1
     33 	RSASHA256
     34 	_ // Skip 9, RFC 6725, section 2.1
     35 	RSASHA512
     36 	_ // Skip 11, RFC 6725, section 2.1
     37 	ECCGOST
     38 	ECDSAP256SHA256
     39 	ECDSAP384SHA384
     40 	ED25519
     41 	ED448
     42 	INDIRECT   uint8 = 252
     43 	PRIVATEDNS uint8 = 253 // Private (experimental keys)
     44 	PRIVATEOID uint8 = 254
     45 )
     46 
     47 // AlgorithmToString is a map of algorithm IDs to algorithm names.
     48 var AlgorithmToString = map[uint8]string{
     49 	RSAMD5:           "RSAMD5",
     50 	DH:               "DH",
     51 	DSA:              "DSA",
     52 	RSASHA1:          "RSASHA1",
     53 	DSANSEC3SHA1:     "DSA-NSEC3-SHA1",
     54 	RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
     55 	RSASHA256:        "RSASHA256",
     56 	RSASHA512:        "RSASHA512",
     57 	ECCGOST:          "ECC-GOST",
     58 	ECDSAP256SHA256:  "ECDSAP256SHA256",
     59 	ECDSAP384SHA384:  "ECDSAP384SHA384",
     60 	ED25519:          "ED25519",
     61 	ED448:            "ED448",
     62 	INDIRECT:         "INDIRECT",
     63 	PRIVATEDNS:       "PRIVATEDNS",
     64 	PRIVATEOID:       "PRIVATEOID",
     65 }
     66 
     67 // AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
     68 // For newer algorithm that do their own hashing (i.e. ED25519) the returned value
     69 // is 0, implying no (external) hashing should occur. The non-exported identityHash is then
     70 // used.
     71 var AlgorithmToHash = map[uint8]crypto.Hash{
     72 	RSAMD5:           crypto.MD5, // Deprecated in RFC 6725
     73 	DSA:              crypto.SHA1,
     74 	RSASHA1:          crypto.SHA1,
     75 	RSASHA1NSEC3SHA1: crypto.SHA1,
     76 	RSASHA256:        crypto.SHA256,
     77 	ECDSAP256SHA256:  crypto.SHA256,
     78 	ECDSAP384SHA384:  crypto.SHA384,
     79 	RSASHA512:        crypto.SHA512,
     80 	ED25519:          0,
     81 }
     82 
     83 // DNSSEC hashing algorithm codes.
     84 const (
     85 	_      uint8 = iota
     86 	SHA1         // RFC 4034
     87 	SHA256       // RFC 4509
     88 	GOST94       // RFC 5933
     89 	SHA384       // Experimental
     90 	SHA512       // Experimental
     91 )
     92 
     93 // HashToString is a map of hash IDs to names.
     94 var HashToString = map[uint8]string{
     95 	SHA1:   "SHA1",
     96 	SHA256: "SHA256",
     97 	GOST94: "GOST94",
     98 	SHA384: "SHA384",
     99 	SHA512: "SHA512",
    100 }
    101 
    102 // DNSKEY flag values.
    103 const (
    104 	SEP    = 1
    105 	REVOKE = 1 << 7
    106 	ZONE   = 1 << 8
    107 )
    108 
    109 // The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing.
    110 type rrsigWireFmt struct {
    111 	TypeCovered uint16
    112 	Algorithm   uint8
    113 	Labels      uint8
    114 	OrigTtl     uint32
    115 	Expiration  uint32
    116 	Inception   uint32
    117 	KeyTag      uint16
    118 	SignerName  string `dns:"domain-name"`
    119 	/* No Signature */
    120 }
    121 
    122 // Used for converting DNSKEY's rdata to wirefmt.
    123 type dnskeyWireFmt struct {
    124 	Flags     uint16
    125 	Protocol  uint8
    126 	Algorithm uint8
    127 	PublicKey string `dns:"base64"`
    128 	/* Nothing is left out */
    129 }
    130 
    131 // KeyTag calculates the keytag (or key-id) of the DNSKEY.
    132 func (k *DNSKEY) KeyTag() uint16 {
    133 	if k == nil {
    134 		return 0
    135 	}
    136 	var keytag int
    137 	switch k.Algorithm {
    138 	case RSAMD5:
    139 		// This algorithm has been deprecated, but keep this key-tag calculation.
    140 		// Look at the bottom two bytes of the modules, which the last item in the pubkey.
    141 		// See https://www.rfc-editor.org/errata/eid193 .
    142 		modulus, _ := fromBase64([]byte(k.PublicKey))
    143 		if len(modulus) > 1 {
    144 			x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
    145 			keytag = int(x)
    146 		}
    147 	default:
    148 		keywire := new(dnskeyWireFmt)
    149 		keywire.Flags = k.Flags
    150 		keywire.Protocol = k.Protocol
    151 		keywire.Algorithm = k.Algorithm
    152 		keywire.PublicKey = k.PublicKey
    153 		wire := make([]byte, DefaultMsgSize)
    154 		n, err := packKeyWire(keywire, wire)
    155 		if err != nil {
    156 			return 0
    157 		}
    158 		wire = wire[:n]
    159 		for i, v := range wire {
    160 			if i&1 != 0 {
    161 				keytag += int(v) // must be larger than uint32
    162 			} else {
    163 				keytag += int(v) << 8
    164 			}
    165 		}
    166 		keytag += keytag >> 16 & 0xFFFF
    167 		keytag &= 0xFFFF
    168 	}
    169 	return uint16(keytag)
    170 }
    171 
    172 // ToDS converts a DNSKEY record to a DS record.
    173 func (k *DNSKEY) ToDS(h uint8) *DS {
    174 	if k == nil {
    175 		return nil
    176 	}
    177 	ds := new(DS)
    178 	ds.Hdr.Name = k.Hdr.Name
    179 	ds.Hdr.Class = k.Hdr.Class
    180 	ds.Hdr.Rrtype = TypeDS
    181 	ds.Hdr.Ttl = k.Hdr.Ttl
    182 	ds.Algorithm = k.Algorithm
    183 	ds.DigestType = h
    184 	ds.KeyTag = k.KeyTag()
    185 
    186 	keywire := new(dnskeyWireFmt)
    187 	keywire.Flags = k.Flags
    188 	keywire.Protocol = k.Protocol
    189 	keywire.Algorithm = k.Algorithm
    190 	keywire.PublicKey = k.PublicKey
    191 	wire := make([]byte, DefaultMsgSize)
    192 	n, err := packKeyWire(keywire, wire)
    193 	if err != nil {
    194 		return nil
    195 	}
    196 	wire = wire[:n]
    197 
    198 	owner := make([]byte, 255)
    199 	off, err1 := PackDomainName(CanonicalName(k.Hdr.Name), owner, 0, nil, false)
    200 	if err1 != nil {
    201 		return nil
    202 	}
    203 	owner = owner[:off]
    204 	// RFC4034:
    205 	// digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
    206 	// "|" denotes concatenation
    207 	// DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
    208 
    209 	var hash crypto.Hash
    210 	switch h {
    211 	case SHA1:
    212 		hash = crypto.SHA1
    213 	case SHA256:
    214 		hash = crypto.SHA256
    215 	case SHA384:
    216 		hash = crypto.SHA384
    217 	case SHA512:
    218 		hash = crypto.SHA512
    219 	default:
    220 		return nil
    221 	}
    222 
    223 	s := hash.New()
    224 	s.Write(owner)
    225 	s.Write(wire)
    226 	ds.Digest = hex.EncodeToString(s.Sum(nil))
    227 	return ds
    228 }
    229 
    230 // ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
    231 func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
    232 	c := &CDNSKEY{DNSKEY: *k}
    233 	c.Hdr = k.Hdr
    234 	c.Hdr.Rrtype = TypeCDNSKEY
    235 	return c
    236 }
    237 
    238 // ToCDS converts a DS record to a CDS record.
    239 func (d *DS) ToCDS() *CDS {
    240 	c := &CDS{DS: *d}
    241 	c.Hdr = d.Hdr
    242 	c.Hdr.Rrtype = TypeCDS
    243 	return c
    244 }
    245 
    246 // Sign signs an RRSet. The signature needs to be filled in with the values:
    247 // Inception, Expiration, KeyTag, SignerName and Algorithm.  The rest is copied
    248 // from the RRset. Sign returns a non-nill error when the signing went OK.
    249 // There is no check if RRSet is a proper (RFC 2181) RRSet.  If OrigTTL is non
    250 // zero, it is used as-is, otherwise the TTL of the RRset is used as the
    251 // OrigTTL.
    252 func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
    253 	if k == nil {
    254 		return ErrPrivKey
    255 	}
    256 	// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
    257 	if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
    258 		return ErrKey
    259 	}
    260 
    261 	h0 := rrset[0].Header()
    262 	rr.Hdr.Rrtype = TypeRRSIG
    263 	rr.Hdr.Name = h0.Name
    264 	rr.Hdr.Class = h0.Class
    265 	if rr.OrigTtl == 0 { // If set don't override
    266 		rr.OrigTtl = h0.Ttl
    267 	}
    268 	rr.TypeCovered = h0.Rrtype
    269 	rr.Labels = uint8(CountLabel(h0.Name))
    270 
    271 	if strings.HasPrefix(h0.Name, "*") {
    272 		rr.Labels-- // wildcard, remove from label count
    273 	}
    274 
    275 	sigwire := new(rrsigWireFmt)
    276 	sigwire.TypeCovered = rr.TypeCovered
    277 	sigwire.Algorithm = rr.Algorithm
    278 	sigwire.Labels = rr.Labels
    279 	sigwire.OrigTtl = rr.OrigTtl
    280 	sigwire.Expiration = rr.Expiration
    281 	sigwire.Inception = rr.Inception
    282 	sigwire.KeyTag = rr.KeyTag
    283 	// For signing, lowercase this name
    284 	sigwire.SignerName = CanonicalName(rr.SignerName)
    285 
    286 	// Create the desired binary blob
    287 	signdata := make([]byte, DefaultMsgSize)
    288 	n, err := packSigWire(sigwire, signdata)
    289 	if err != nil {
    290 		return err
    291 	}
    292 	signdata = signdata[:n]
    293 	wire, err := rawSignatureData(rrset, rr)
    294 	if err != nil {
    295 		return err
    296 	}
    297 
    298 	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
    299 	if err != nil {
    300 		return err
    301 	}
    302 
    303 	switch rr.Algorithm {
    304 	case RSAMD5, DSA, DSANSEC3SHA1:
    305 		// See RFC 6944.
    306 		return ErrAlg
    307 	default:
    308 		h.Write(signdata)
    309 		h.Write(wire)
    310 
    311 		signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
    312 		if err != nil {
    313 			return err
    314 		}
    315 
    316 		rr.Signature = toBase64(signature)
    317 		return nil
    318 	}
    319 }
    320 
    321 func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
    322 	signature, err := k.Sign(rand.Reader, hashed, hash)
    323 	if err != nil {
    324 		return nil, err
    325 	}
    326 
    327 	switch alg {
    328 	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
    329 		return signature, nil
    330 	case ECDSAP256SHA256, ECDSAP384SHA384:
    331 		ecdsaSignature := &struct {
    332 			R, S *big.Int
    333 		}{}
    334 		if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
    335 			return nil, err
    336 		}
    337 
    338 		var intlen int
    339 		switch alg {
    340 		case ECDSAP256SHA256:
    341 			intlen = 32
    342 		case ECDSAP384SHA384:
    343 			intlen = 48
    344 		}
    345 
    346 		signature := intToBytes(ecdsaSignature.R, intlen)
    347 		signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
    348 		return signature, nil
    349 	default:
    350 		return nil, ErrAlg
    351 	}
    352 }
    353 
    354 // Verify validates an RRSet with the signature and key. This is only the
    355 // cryptographic test, the signature validity period must be checked separately.
    356 // This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
    357 // It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY
    358 // and that the Protocol field is set to 3 (RFC 4034 2.1.2).
    359 func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
    360 	// First the easy checks
    361 	if !IsRRset(rrset) {
    362 		return ErrRRset
    363 	}
    364 	if rr.KeyTag != k.KeyTag() {
    365 		return ErrKey
    366 	}
    367 	if rr.Hdr.Class != k.Hdr.Class {
    368 		return ErrKey
    369 	}
    370 	if rr.Algorithm != k.Algorithm {
    371 		return ErrKey
    372 	}
    373 	if !strings.EqualFold(rr.SignerName, k.Hdr.Name) {
    374 		return ErrKey
    375 	}
    376 	if k.Protocol != 3 {
    377 		return ErrKey
    378 	}
    379 	// RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some
    380 	// other type of DNS public key and MUST NOT be used to verify RRSIGs that
    381 	// cover RRsets.
    382 	if k.Flags&ZONE == 0 {
    383 		return ErrKey
    384 	}
    385 
    386 	// IsRRset checked that we have at least one RR and that the RRs in
    387 	// the set have consistent type, class, and name. Also check that type and
    388 	// class matches the RRSIG record.
    389 	if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered {
    390 		return ErrRRset
    391 	}
    392 
    393 	// RFC 4035 5.3.2.  Reconstructing the Signed Data
    394 	// Copy the sig, except the rrsig data
    395 	sigwire := new(rrsigWireFmt)
    396 	sigwire.TypeCovered = rr.TypeCovered
    397 	sigwire.Algorithm = rr.Algorithm
    398 	sigwire.Labels = rr.Labels
    399 	sigwire.OrigTtl = rr.OrigTtl
    400 	sigwire.Expiration = rr.Expiration
    401 	sigwire.Inception = rr.Inception
    402 	sigwire.KeyTag = rr.KeyTag
    403 	sigwire.SignerName = CanonicalName(rr.SignerName)
    404 	// Create the desired binary blob
    405 	signeddata := make([]byte, DefaultMsgSize)
    406 	n, err := packSigWire(sigwire, signeddata)
    407 	if err != nil {
    408 		return err
    409 	}
    410 	signeddata = signeddata[:n]
    411 	wire, err := rawSignatureData(rrset, rr)
    412 	if err != nil {
    413 		return err
    414 	}
    415 
    416 	sigbuf := rr.sigBuf() // Get the binary signature data
    417 	// TODO(miek)
    418 	// remove the domain name and assume its ours?
    419 	// if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
    420 	// }
    421 
    422 	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
    423 	if err != nil {
    424 		return err
    425 	}
    426 
    427 	switch rr.Algorithm {
    428 	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
    429 		// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
    430 		pubkey := k.publicKeyRSA() // Get the key
    431 		if pubkey == nil {
    432 			return ErrKey
    433 		}
    434 
    435 		h.Write(signeddata)
    436 		h.Write(wire)
    437 		return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
    438 
    439 	case ECDSAP256SHA256, ECDSAP384SHA384:
    440 		pubkey := k.publicKeyECDSA()
    441 		if pubkey == nil {
    442 			return ErrKey
    443 		}
    444 
    445 		// Split sigbuf into the r and s coordinates
    446 		r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
    447 		s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
    448 
    449 		h.Write(signeddata)
    450 		h.Write(wire)
    451 		if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
    452 			return nil
    453 		}
    454 		return ErrSig
    455 
    456 	case ED25519:
    457 		pubkey := k.publicKeyED25519()
    458 		if pubkey == nil {
    459 			return ErrKey
    460 		}
    461 
    462 		if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) {
    463 			return nil
    464 		}
    465 		return ErrSig
    466 
    467 	default:
    468 		return ErrAlg
    469 	}
    470 }
    471 
    472 // ValidityPeriod uses RFC1982 serial arithmetic to calculate
    473 // if a signature period is valid. If t is the zero time, the
    474 // current time is taken other t is. Returns true if the signature
    475 // is valid at the given time, otherwise returns false.
    476 func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
    477 	var utc int64
    478 	if t.IsZero() {
    479 		utc = time.Now().UTC().Unix()
    480 	} else {
    481 		utc = t.UTC().Unix()
    482 	}
    483 	modi := (int64(rr.Inception) - utc) / year68
    484 	mode := (int64(rr.Expiration) - utc) / year68
    485 	ti := int64(rr.Inception) + modi*year68
    486 	te := int64(rr.Expiration) + mode*year68
    487 	return ti <= utc && utc <= te
    488 }
    489 
    490 // Return the signatures base64 encoding sigdata as a byte slice.
    491 func (rr *RRSIG) sigBuf() []byte {
    492 	sigbuf, err := fromBase64([]byte(rr.Signature))
    493 	if err != nil {
    494 		return nil
    495 	}
    496 	return sigbuf
    497 }
    498 
    499 // publicKeyRSA returns the RSA public key from a DNSKEY record.
    500 func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
    501 	keybuf, err := fromBase64([]byte(k.PublicKey))
    502 	if err != nil {
    503 		return nil
    504 	}
    505 
    506 	if len(keybuf) < 1+1+64 {
    507 		// Exponent must be at least 1 byte and modulus at least 64
    508 		return nil
    509 	}
    510 
    511 	// RFC 2537/3110, section 2. RSA Public KEY Resource Records
    512 	// Length is in the 0th byte, unless its zero, then it
    513 	// it in bytes 1 and 2 and its a 16 bit number
    514 	explen := uint16(keybuf[0])
    515 	keyoff := 1
    516 	if explen == 0 {
    517 		explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
    518 		keyoff = 3
    519 	}
    520 
    521 	if explen > 4 || explen == 0 || keybuf[keyoff] == 0 {
    522 		// Exponent larger than supported by the crypto package,
    523 		// empty, or contains prohibited leading zero.
    524 		return nil
    525 	}
    526 
    527 	modoff := keyoff + int(explen)
    528 	modlen := len(keybuf) - modoff
    529 	if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 {
    530 		// Modulus is too small, large, or contains prohibited leading zero.
    531 		return nil
    532 	}
    533 
    534 	pubkey := new(rsa.PublicKey)
    535 
    536 	var expo uint64
    537 	// The exponent of length explen is between keyoff and modoff.
    538 	for _, v := range keybuf[keyoff:modoff] {
    539 		expo <<= 8
    540 		expo |= uint64(v)
    541 	}
    542 	if expo > 1<<31-1 {
    543 		// Larger exponent than supported by the crypto package.
    544 		return nil
    545 	}
    546 
    547 	pubkey.E = int(expo)
    548 	pubkey.N = new(big.Int).SetBytes(keybuf[modoff:])
    549 	return pubkey
    550 }
    551 
    552 // publicKeyECDSA returns the Curve public key from the DNSKEY record.
    553 func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
    554 	keybuf, err := fromBase64([]byte(k.PublicKey))
    555 	if err != nil {
    556 		return nil
    557 	}
    558 	pubkey := new(ecdsa.PublicKey)
    559 	switch k.Algorithm {
    560 	case ECDSAP256SHA256:
    561 		pubkey.Curve = elliptic.P256()
    562 		if len(keybuf) != 64 {
    563 			// wrongly encoded key
    564 			return nil
    565 		}
    566 	case ECDSAP384SHA384:
    567 		pubkey.Curve = elliptic.P384()
    568 		if len(keybuf) != 96 {
    569 			// Wrongly encoded key
    570 			return nil
    571 		}
    572 	}
    573 	pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2])
    574 	pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:])
    575 	return pubkey
    576 }
    577 
    578 func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
    579 	keybuf, err := fromBase64([]byte(k.PublicKey))
    580 	if err != nil {
    581 		return nil
    582 	}
    583 	if len(keybuf) != ed25519.PublicKeySize {
    584 		return nil
    585 	}
    586 	return keybuf
    587 }
    588 
    589 type wireSlice [][]byte
    590 
    591 func (p wireSlice) Len() int      { return len(p) }
    592 func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
    593 func (p wireSlice) Less(i, j int) bool {
    594 	_, ioff, _ := UnpackDomainName(p[i], 0)
    595 	_, joff, _ := UnpackDomainName(p[j], 0)
    596 	return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
    597 }
    598 
    599 // Return the raw signature data.
    600 func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
    601 	wires := make(wireSlice, len(rrset))
    602 	for i, r := range rrset {
    603 		r1 := r.copy()
    604 		h := r1.Header()
    605 		h.Ttl = s.OrigTtl
    606 		labels := SplitDomainName(h.Name)
    607 		// 6.2. Canonical RR Form. (4) - wildcards
    608 		if len(labels) > int(s.Labels) {
    609 			// Wildcard
    610 			h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
    611 		}
    612 		// RFC 4034: 6.2.  Canonical RR Form. (2) - domain name to lowercase
    613 		h.Name = CanonicalName(h.Name)
    614 		// 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
    615 		//   NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
    616 		//   HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
    617 		//   SRV, DNAME, A6
    618 		//
    619 		// RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC):
    620 		//	Section 6.2 of [RFC4034] also erroneously lists HINFO as a record
    621 		//	that needs conversion to lowercase, and twice at that.  Since HINFO
    622 		//	records contain no domain names, they are not subject to case
    623 		//	conversion.
    624 		switch x := r1.(type) {
    625 		case *NS:
    626 			x.Ns = CanonicalName(x.Ns)
    627 		case *MD:
    628 			x.Md = CanonicalName(x.Md)
    629 		case *MF:
    630 			x.Mf = CanonicalName(x.Mf)
    631 		case *CNAME:
    632 			x.Target = CanonicalName(x.Target)
    633 		case *SOA:
    634 			x.Ns = CanonicalName(x.Ns)
    635 			x.Mbox = CanonicalName(x.Mbox)
    636 		case *MB:
    637 			x.Mb = CanonicalName(x.Mb)
    638 		case *MG:
    639 			x.Mg = CanonicalName(x.Mg)
    640 		case *MR:
    641 			x.Mr = CanonicalName(x.Mr)
    642 		case *PTR:
    643 			x.Ptr = CanonicalName(x.Ptr)
    644 		case *MINFO:
    645 			x.Rmail = CanonicalName(x.Rmail)
    646 			x.Email = CanonicalName(x.Email)
    647 		case *MX:
    648 			x.Mx = CanonicalName(x.Mx)
    649 		case *RP:
    650 			x.Mbox = CanonicalName(x.Mbox)
    651 			x.Txt = CanonicalName(x.Txt)
    652 		case *AFSDB:
    653 			x.Hostname = CanonicalName(x.Hostname)
    654 		case *RT:
    655 			x.Host = CanonicalName(x.Host)
    656 		case *SIG:
    657 			x.SignerName = CanonicalName(x.SignerName)
    658 		case *PX:
    659 			x.Map822 = CanonicalName(x.Map822)
    660 			x.Mapx400 = CanonicalName(x.Mapx400)
    661 		case *NAPTR:
    662 			x.Replacement = CanonicalName(x.Replacement)
    663 		case *KX:
    664 			x.Exchanger = CanonicalName(x.Exchanger)
    665 		case *SRV:
    666 			x.Target = CanonicalName(x.Target)
    667 		case *DNAME:
    668 			x.Target = CanonicalName(x.Target)
    669 		}
    670 		// 6.2. Canonical RR Form. (5) - origTTL
    671 		wire := make([]byte, Len(r1)+1) // +1 to be safe(r)
    672 		off, err1 := PackRR(r1, wire, 0, nil, false)
    673 		if err1 != nil {
    674 			return nil, err1
    675 		}
    676 		wire = wire[:off]
    677 		wires[i] = wire
    678 	}
    679 	sort.Sort(wires)
    680 	for i, wire := range wires {
    681 		if i > 0 && bytes.Equal(wire, wires[i-1]) {
    682 			continue
    683 		}
    684 		buf = append(buf, wire...)
    685 	}
    686 	return buf, nil
    687 }
    688 
    689 func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
    690 	// copied from zmsg.go RRSIG packing
    691 	off, err := packUint16(sw.TypeCovered, msg, 0)
    692 	if err != nil {
    693 		return off, err
    694 	}
    695 	off, err = packUint8(sw.Algorithm, msg, off)
    696 	if err != nil {
    697 		return off, err
    698 	}
    699 	off, err = packUint8(sw.Labels, msg, off)
    700 	if err != nil {
    701 		return off, err
    702 	}
    703 	off, err = packUint32(sw.OrigTtl, msg, off)
    704 	if err != nil {
    705 		return off, err
    706 	}
    707 	off, err = packUint32(sw.Expiration, msg, off)
    708 	if err != nil {
    709 		return off, err
    710 	}
    711 	off, err = packUint32(sw.Inception, msg, off)
    712 	if err != nil {
    713 		return off, err
    714 	}
    715 	off, err = packUint16(sw.KeyTag, msg, off)
    716 	if err != nil {
    717 		return off, err
    718 	}
    719 	off, err = PackDomainName(sw.SignerName, msg, off, nil, false)
    720 	if err != nil {
    721 		return off, err
    722 	}
    723 	return off, nil
    724 }
    725 
    726 func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {
    727 	// copied from zmsg.go DNSKEY packing
    728 	off, err := packUint16(dw.Flags, msg, 0)
    729 	if err != nil {
    730 		return off, err
    731 	}
    732 	off, err = packUint8(dw.Protocol, msg, off)
    733 	if err != nil {
    734 		return off, err
    735 	}
    736 	off, err = packUint8(dw.Algorithm, msg, off)
    737 	if err != nil {
    738 		return off, err
    739 	}
    740 	off, err = packStringBase64(dw.PublicKey, msg, off)
    741 	if err != nil {
    742 		return off, err
    743 	}
    744 	return off, nil
    745 }