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