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