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