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