dnssec.go raw

   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  	h0 := rrset[0].Header()
 254  	rr.Hdr.Rrtype = TypeRRSIG
 255  	rr.Hdr.Name = h0.Name
 256  	rr.Hdr.Class = h0.Class
 257  	if rr.OrigTtl == 0 { // If set don't override
 258  		rr.OrigTtl = h0.Ttl
 259  	}
 260  	rr.TypeCovered = h0.Rrtype
 261  	rr.Labels = uint8(CountLabel(h0.Name))
 262  
 263  	if strings.HasPrefix(h0.Name, "*") {
 264  		rr.Labels-- // wildcard, remove from label count
 265  	}
 266  
 267  	return rr.signAsIs(k, rrset)
 268  }
 269  
 270  func (rr *RRSIG) signAsIs(k crypto.Signer, rrset []RR) error {
 271  	if k == nil {
 272  		return ErrPrivKey
 273  	}
 274  	// s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
 275  	if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
 276  		return ErrKey
 277  	}
 278  
 279  	sigwire := new(rrsigWireFmt)
 280  	sigwire.TypeCovered = rr.TypeCovered
 281  	sigwire.Algorithm = rr.Algorithm
 282  	sigwire.Labels = rr.Labels
 283  	sigwire.OrigTtl = rr.OrigTtl
 284  	sigwire.Expiration = rr.Expiration
 285  	sigwire.Inception = rr.Inception
 286  	sigwire.KeyTag = rr.KeyTag
 287  	// For signing, lowercase this name
 288  	sigwire.SignerName = CanonicalName(rr.SignerName)
 289  
 290  	// Create the desired binary blob
 291  	signdata := make([]byte, DefaultMsgSize)
 292  	n, err := packSigWire(sigwire, signdata)
 293  	if err != nil {
 294  		return err
 295  	}
 296  	signdata = signdata[:n]
 297  	wire, err := rawSignatureData(rrset, rr)
 298  	if err != nil {
 299  		return err
 300  	}
 301  
 302  	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
 303  	if err != nil {
 304  		return err
 305  	}
 306  
 307  	switch rr.Algorithm {
 308  	case RSAMD5, DSA, DSANSEC3SHA1:
 309  		// See RFC 6944.
 310  		return ErrAlg
 311  	default:
 312  		h.Write(signdata)
 313  		h.Write(wire)
 314  
 315  		signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
 316  		if err != nil {
 317  			return err
 318  		}
 319  
 320  		rr.Signature = toBase64(signature)
 321  		return nil
 322  	}
 323  }
 324  
 325  func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) {
 326  	signature, err := k.Sign(rand.Reader, hashed, hash)
 327  	if err != nil {
 328  		return nil, err
 329  	}
 330  
 331  	switch alg {
 332  	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
 333  		return signature, nil
 334  	case ECDSAP256SHA256, ECDSAP384SHA384:
 335  		ecdsaSignature := &struct {
 336  			R, S *big.Int
 337  		}{}
 338  		if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil {
 339  			return nil, err
 340  		}
 341  
 342  		var intlen int
 343  		switch alg {
 344  		case ECDSAP256SHA256:
 345  			intlen = 32
 346  		case ECDSAP384SHA384:
 347  			intlen = 48
 348  		}
 349  
 350  		signature := intToBytes(ecdsaSignature.R, intlen)
 351  		signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
 352  		return signature, nil
 353  	default:
 354  		return nil, ErrAlg
 355  	}
 356  }
 357  
 358  // Verify validates an RRSet with the signature and key. This is only the
 359  // cryptographic test, the signature validity period must be checked separately.
 360  // This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
 361  // It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY
 362  // and that the Protocol field is set to 3 (RFC 4034 2.1.2).
 363  func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
 364  	// First the easy checks
 365  	if !IsRRset(rrset) {
 366  		return ErrRRset
 367  	}
 368  	if rr.KeyTag != k.KeyTag() {
 369  		return ErrKey
 370  	}
 371  	if rr.Hdr.Class != k.Hdr.Class {
 372  		return ErrKey
 373  	}
 374  	if rr.Algorithm != k.Algorithm {
 375  		return ErrKey
 376  	}
 377  
 378  	signerName := CanonicalName(rr.SignerName)
 379  	if !equal(signerName, k.Hdr.Name) {
 380  		return ErrKey
 381  	}
 382  
 383  	if k.Protocol != 3 {
 384  		return ErrKey
 385  	}
 386  	// RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some
 387  	// other type of DNS public key and MUST NOT be used to verify RRSIGs that
 388  	// cover RRsets.
 389  	if k.Flags&ZONE == 0 {
 390  		return ErrKey
 391  	}
 392  
 393  	// IsRRset checked that we have at least one RR and that the RRs in
 394  	// the set have consistent type, class, and name. Also check that type,
 395  	// class and name matches the RRSIG record.
 396  	// Also checks RFC 4035 5.3.1 the number of labels in the RRset owner
 397  	// name MUST be greater than or equal to the value in the RRSIG RR's Labels field.
 398  	// RFC 4035 5.3.1 Signer's Name MUST be the name of the zone that [contains the RRset].
 399  	// Since we don't have SOA info, checking suffix may be the best we can do...?
 400  	if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class ||
 401  		h0.Rrtype != rr.TypeCovered ||
 402  		uint8(CountLabel(h0.Name)) < rr.Labels ||
 403  		!equal(h0.Name, rr.Hdr.Name) ||
 404  		!strings.HasSuffix(CanonicalName(h0.Name), signerName) {
 405  
 406  		return ErrRRset
 407  	}
 408  
 409  	// RFC 4035 5.3.2.  Reconstructing the Signed Data
 410  	// Copy the sig, except the rrsig data
 411  	sigwire := new(rrsigWireFmt)
 412  	sigwire.TypeCovered = rr.TypeCovered
 413  	sigwire.Algorithm = rr.Algorithm
 414  	sigwire.Labels = rr.Labels
 415  	sigwire.OrigTtl = rr.OrigTtl
 416  	sigwire.Expiration = rr.Expiration
 417  	sigwire.Inception = rr.Inception
 418  	sigwire.KeyTag = rr.KeyTag
 419  	sigwire.SignerName = signerName
 420  	// Create the desired binary blob
 421  	signeddata := make([]byte, DefaultMsgSize)
 422  	n, err := packSigWire(sigwire, signeddata)
 423  	if err != nil {
 424  		return err
 425  	}
 426  	signeddata = signeddata[:n]
 427  	wire, err := rawSignatureData(rrset, rr)
 428  	if err != nil {
 429  		return err
 430  	}
 431  
 432  	sigbuf := rr.sigBuf() // Get the binary signature data
 433  	// TODO(miek)
 434  	// remove the domain name and assume its ours?
 435  	// if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
 436  	// }
 437  
 438  	h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
 439  	if err != nil {
 440  		return err
 441  	}
 442  
 443  	switch rr.Algorithm {
 444  	case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
 445  		// TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
 446  		pubkey := k.publicKeyRSA() // Get the key
 447  		if pubkey == nil {
 448  			return ErrKey
 449  		}
 450  
 451  		h.Write(signeddata)
 452  		h.Write(wire)
 453  		return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
 454  
 455  	case ECDSAP256SHA256, ECDSAP384SHA384:
 456  		pubkey := k.publicKeyECDSA()
 457  		if pubkey == nil {
 458  			return ErrKey
 459  		}
 460  
 461  		// Split sigbuf into the r and s coordinates
 462  		r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
 463  		s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
 464  
 465  		h.Write(signeddata)
 466  		h.Write(wire)
 467  		if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
 468  			return nil
 469  		}
 470  		return ErrSig
 471  
 472  	case ED25519:
 473  		pubkey := k.publicKeyED25519()
 474  		if pubkey == nil {
 475  			return ErrKey
 476  		}
 477  
 478  		if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) {
 479  			return nil
 480  		}
 481  		return ErrSig
 482  
 483  	default:
 484  		return ErrAlg
 485  	}
 486  }
 487  
 488  // ValidityPeriod uses RFC1982 serial arithmetic to calculate
 489  // if a signature period is valid. If t is the zero time, the
 490  // current time is taken other t is. Returns true if the signature
 491  // is valid at the given time, otherwise returns false.
 492  func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
 493  	var utc int64
 494  	if t.IsZero() {
 495  		utc = time.Now().UTC().Unix()
 496  	} else {
 497  		utc = t.UTC().Unix()
 498  	}
 499  	modi := (int64(rr.Inception) - utc) / year68
 500  	mode := (int64(rr.Expiration) - utc) / year68
 501  	ti := int64(rr.Inception) + modi*year68
 502  	te := int64(rr.Expiration) + mode*year68
 503  	return ti <= utc && utc <= te
 504  }
 505  
 506  // Return the signatures base64 encoding sigdata as a byte slice.
 507  func (rr *RRSIG) sigBuf() []byte {
 508  	sigbuf, err := fromBase64([]byte(rr.Signature))
 509  	if err != nil {
 510  		return nil
 511  	}
 512  	return sigbuf
 513  }
 514  
 515  // publicKeyRSA returns the RSA public key from a DNSKEY record.
 516  func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
 517  	keybuf, err := fromBase64([]byte(k.PublicKey))
 518  	if err != nil {
 519  		return nil
 520  	}
 521  
 522  	if len(keybuf) < 1+1+64 {
 523  		// Exponent must be at least 1 byte and modulus at least 64
 524  		return nil
 525  	}
 526  
 527  	// RFC 2537/3110, section 2. RSA Public KEY Resource Records
 528  	// Length is in the 0th byte, unless its zero, then it
 529  	// it in bytes 1 and 2 and its a 16 bit number
 530  	explen := uint16(keybuf[0])
 531  	keyoff := 1
 532  	if explen == 0 {
 533  		explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
 534  		keyoff = 3
 535  	}
 536  
 537  	if explen > 4 || explen == 0 || keybuf[keyoff] == 0 {
 538  		// Exponent larger than supported by the crypto package,
 539  		// empty, or contains prohibited leading zero.
 540  		return nil
 541  	}
 542  
 543  	modoff := keyoff + int(explen)
 544  	modlen := len(keybuf) - modoff
 545  	if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 {
 546  		// Modulus is too small, large, or contains prohibited leading zero.
 547  		return nil
 548  	}
 549  
 550  	pubkey := new(rsa.PublicKey)
 551  
 552  	var expo uint64
 553  	// The exponent of length explen is between keyoff and modoff.
 554  	for _, v := range keybuf[keyoff:modoff] {
 555  		expo <<= 8
 556  		expo |= uint64(v)
 557  	}
 558  	if expo > 1<<31-1 {
 559  		// Larger exponent than supported by the crypto package.
 560  		return nil
 561  	}
 562  
 563  	pubkey.E = int(expo)
 564  	pubkey.N = new(big.Int).SetBytes(keybuf[modoff:])
 565  	return pubkey
 566  }
 567  
 568  // publicKeyECDSA returns the Curve public key from the DNSKEY record.
 569  func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
 570  	keybuf, err := fromBase64([]byte(k.PublicKey))
 571  	if err != nil {
 572  		return nil
 573  	}
 574  	pubkey := new(ecdsa.PublicKey)
 575  	switch k.Algorithm {
 576  	case ECDSAP256SHA256:
 577  		pubkey.Curve = elliptic.P256()
 578  		if len(keybuf) != 64 {
 579  			// wrongly encoded key
 580  			return nil
 581  		}
 582  	case ECDSAP384SHA384:
 583  		pubkey.Curve = elliptic.P384()
 584  		if len(keybuf) != 96 {
 585  			// Wrongly encoded key
 586  			return nil
 587  		}
 588  	}
 589  	pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2])
 590  	pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:])
 591  	return pubkey
 592  }
 593  
 594  func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey {
 595  	keybuf, err := fromBase64([]byte(k.PublicKey))
 596  	if err != nil {
 597  		return nil
 598  	}
 599  	if len(keybuf) != ed25519.PublicKeySize {
 600  		return nil
 601  	}
 602  	return keybuf
 603  }
 604  
 605  type wireSlice [][]byte
 606  
 607  func (p wireSlice) Len() int      { return len(p) }
 608  func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
 609  func (p wireSlice) Less(i, j int) bool {
 610  	_, ioff, _ := UnpackDomainName(p[i], 0)
 611  	_, joff, _ := UnpackDomainName(p[j], 0)
 612  	return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
 613  }
 614  
 615  // Return the raw signature data.
 616  func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
 617  	wires := make(wireSlice, len(rrset))
 618  	for i, r := range rrset {
 619  		r1 := r.copy()
 620  		h := r1.Header()
 621  		h.Ttl = s.OrigTtl
 622  		labels := SplitDomainName(h.Name)
 623  		// 6.2. Canonical RR Form. (4) - wildcards
 624  		if len(labels) > int(s.Labels) {
 625  			// Wildcard
 626  			h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
 627  		}
 628  		// RFC 4034: 6.2.  Canonical RR Form. (2) - domain name to lowercase
 629  		h.Name = CanonicalName(h.Name)
 630  		// 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
 631  		//   NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
 632  		//   HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
 633  		//   SRV, DNAME, A6
 634  		//
 635  		// RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC):
 636  		//	Section 6.2 of [RFC4034] also erroneously lists HINFO as a record
 637  		//	that needs conversion to lowercase, and twice at that.  Since HINFO
 638  		//	records contain no domain names, they are not subject to case
 639  		//	conversion.
 640  		switch x := r1.(type) {
 641  		case *NS:
 642  			x.Ns = CanonicalName(x.Ns)
 643  		case *MD:
 644  			x.Md = CanonicalName(x.Md)
 645  		case *MF:
 646  			x.Mf = CanonicalName(x.Mf)
 647  		case *CNAME:
 648  			x.Target = CanonicalName(x.Target)
 649  		case *SOA:
 650  			x.Ns = CanonicalName(x.Ns)
 651  			x.Mbox = CanonicalName(x.Mbox)
 652  		case *MB:
 653  			x.Mb = CanonicalName(x.Mb)
 654  		case *MG:
 655  			x.Mg = CanonicalName(x.Mg)
 656  		case *MR:
 657  			x.Mr = CanonicalName(x.Mr)
 658  		case *PTR:
 659  			x.Ptr = CanonicalName(x.Ptr)
 660  		case *MINFO:
 661  			x.Rmail = CanonicalName(x.Rmail)
 662  			x.Email = CanonicalName(x.Email)
 663  		case *MX:
 664  			x.Mx = CanonicalName(x.Mx)
 665  		case *RP:
 666  			x.Mbox = CanonicalName(x.Mbox)
 667  			x.Txt = CanonicalName(x.Txt)
 668  		case *AFSDB:
 669  			x.Hostname = CanonicalName(x.Hostname)
 670  		case *RT:
 671  			x.Host = CanonicalName(x.Host)
 672  		case *SIG:
 673  			x.SignerName = CanonicalName(x.SignerName)
 674  		case *PX:
 675  			x.Map822 = CanonicalName(x.Map822)
 676  			x.Mapx400 = CanonicalName(x.Mapx400)
 677  		case *NAPTR:
 678  			x.Replacement = CanonicalName(x.Replacement)
 679  		case *KX:
 680  			x.Exchanger = CanonicalName(x.Exchanger)
 681  		case *SRV:
 682  			x.Target = CanonicalName(x.Target)
 683  		case *DNAME:
 684  			x.Target = CanonicalName(x.Target)
 685  		}
 686  		// 6.2. Canonical RR Form. (5) - origTTL
 687  		wire := make([]byte, Len(r1)+1) // +1 to be safe(r)
 688  		off, err1 := PackRR(r1, wire, 0, nil, false)
 689  		if err1 != nil {
 690  			return nil, err1
 691  		}
 692  		wire = wire[:off]
 693  		wires[i] = wire
 694  	}
 695  	sort.Sort(wires)
 696  	for i, wire := range wires {
 697  		if i > 0 && bytes.Equal(wire, wires[i-1]) {
 698  			continue
 699  		}
 700  		buf = append(buf, wire...)
 701  	}
 702  	return buf, nil
 703  }
 704  
 705  func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) {
 706  	// copied from zmsg.go RRSIG packing
 707  	off, err := packUint16(sw.TypeCovered, msg, 0)
 708  	if err != nil {
 709  		return off, err
 710  	}
 711  	off, err = packUint8(sw.Algorithm, msg, off)
 712  	if err != nil {
 713  		return off, err
 714  	}
 715  	off, err = packUint8(sw.Labels, msg, off)
 716  	if err != nil {
 717  		return off, err
 718  	}
 719  	off, err = packUint32(sw.OrigTtl, msg, off)
 720  	if err != nil {
 721  		return off, err
 722  	}
 723  	off, err = packUint32(sw.Expiration, msg, off)
 724  	if err != nil {
 725  		return off, err
 726  	}
 727  	off, err = packUint32(sw.Inception, msg, off)
 728  	if err != nil {
 729  		return off, err
 730  	}
 731  	off, err = packUint16(sw.KeyTag, msg, off)
 732  	if err != nil {
 733  		return off, err
 734  	}
 735  	off, err = PackDomainName(sw.SignerName, msg, off, nil, false)
 736  	if err != nil {
 737  		return off, err
 738  	}
 739  	return off, nil
 740  }
 741  
 742  func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) {
 743  	// copied from zmsg.go DNSKEY packing
 744  	off, err := packUint16(dw.Flags, msg, 0)
 745  	if err != nil {
 746  		return off, err
 747  	}
 748  	off, err = packUint8(dw.Protocol, msg, off)
 749  	if err != nil {
 750  		return off, err
 751  	}
 752  	off, err = packUint8(dw.Algorithm, msg, off)
 753  	if err != nil {
 754  		return off, err
 755  	}
 756  	off, err = packStringBase64(dw.PublicKey, msg, off)
 757  	if err != nil {
 758  		return off, err
 759  	}
 760  	return off, nil
 761  }
 762