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