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