dnssec.go (18761B)
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 if k == nil { 254 return ErrPrivKey 255 } 256 // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set 257 if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { 258 return ErrKey 259 } 260 261 h0 := rrset[0].Header() 262 rr.Hdr.Rrtype = TypeRRSIG 263 rr.Hdr.Name = h0.Name 264 rr.Hdr.Class = h0.Class 265 if rr.OrigTtl == 0 { // If set don't override 266 rr.OrigTtl = h0.Ttl 267 } 268 rr.TypeCovered = h0.Rrtype 269 rr.Labels = uint8(CountLabel(h0.Name)) 270 271 if strings.HasPrefix(h0.Name, "*") { 272 rr.Labels-- // wildcard, remove from label count 273 } 274 275 sigwire := new(rrsigWireFmt) 276 sigwire.TypeCovered = rr.TypeCovered 277 sigwire.Algorithm = rr.Algorithm 278 sigwire.Labels = rr.Labels 279 sigwire.OrigTtl = rr.OrigTtl 280 sigwire.Expiration = rr.Expiration 281 sigwire.Inception = rr.Inception 282 sigwire.KeyTag = rr.KeyTag 283 // For signing, lowercase this name 284 sigwire.SignerName = CanonicalName(rr.SignerName) 285 286 // Create the desired binary blob 287 signdata := make([]byte, DefaultMsgSize) 288 n, err := packSigWire(sigwire, signdata) 289 if err != nil { 290 return err 291 } 292 signdata = signdata[:n] 293 wire, err := rawSignatureData(rrset, rr) 294 if err != nil { 295 return err 296 } 297 298 h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) 299 if err != nil { 300 return err 301 } 302 303 switch rr.Algorithm { 304 case RSAMD5, DSA, DSANSEC3SHA1: 305 // See RFC 6944. 306 return ErrAlg 307 default: 308 h.Write(signdata) 309 h.Write(wire) 310 311 signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm) 312 if err != nil { 313 return err 314 } 315 316 rr.Signature = toBase64(signature) 317 return nil 318 } 319 } 320 321 func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) { 322 signature, err := k.Sign(rand.Reader, hashed, hash) 323 if err != nil { 324 return nil, err 325 } 326 327 switch alg { 328 case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519: 329 return signature, nil 330 case ECDSAP256SHA256, ECDSAP384SHA384: 331 ecdsaSignature := &struct { 332 R, S *big.Int 333 }{} 334 if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil { 335 return nil, err 336 } 337 338 var intlen int 339 switch alg { 340 case ECDSAP256SHA256: 341 intlen = 32 342 case ECDSAP384SHA384: 343 intlen = 48 344 } 345 346 signature := intToBytes(ecdsaSignature.R, intlen) 347 signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...) 348 return signature, nil 349 default: 350 return nil, ErrAlg 351 } 352 } 353 354 // Verify validates an RRSet with the signature and key. This is only the 355 // cryptographic test, the signature validity period must be checked separately. 356 // This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. 357 // It also checks that the Zone Key bit (RFC 4034 2.1.1) is set on the DNSKEY 358 // and that the Protocol field is set to 3 (RFC 4034 2.1.2). 359 func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { 360 // First the easy checks 361 if !IsRRset(rrset) { 362 return ErrRRset 363 } 364 if rr.KeyTag != k.KeyTag() { 365 return ErrKey 366 } 367 if rr.Hdr.Class != k.Hdr.Class { 368 return ErrKey 369 } 370 if rr.Algorithm != k.Algorithm { 371 return ErrKey 372 } 373 if !strings.EqualFold(rr.SignerName, k.Hdr.Name) { 374 return ErrKey 375 } 376 if k.Protocol != 3 { 377 return ErrKey 378 } 379 // RFC 4034 2.1.1 If bit 7 has value 0, then the DNSKEY record holds some 380 // other type of DNS public key and MUST NOT be used to verify RRSIGs that 381 // cover RRsets. 382 if k.Flags&ZONE == 0 { 383 return ErrKey 384 } 385 386 // IsRRset checked that we have at least one RR and that the RRs in 387 // the set have consistent type, class, and name. Also check that type and 388 // class matches the RRSIG record. 389 if h0 := rrset[0].Header(); h0.Class != rr.Hdr.Class || h0.Rrtype != rr.TypeCovered { 390 return ErrRRset 391 } 392 393 // RFC 4035 5.3.2. Reconstructing the Signed Data 394 // Copy the sig, except the rrsig data 395 sigwire := new(rrsigWireFmt) 396 sigwire.TypeCovered = rr.TypeCovered 397 sigwire.Algorithm = rr.Algorithm 398 sigwire.Labels = rr.Labels 399 sigwire.OrigTtl = rr.OrigTtl 400 sigwire.Expiration = rr.Expiration 401 sigwire.Inception = rr.Inception 402 sigwire.KeyTag = rr.KeyTag 403 sigwire.SignerName = CanonicalName(rr.SignerName) 404 // Create the desired binary blob 405 signeddata := make([]byte, DefaultMsgSize) 406 n, err := packSigWire(sigwire, signeddata) 407 if err != nil { 408 return err 409 } 410 signeddata = signeddata[:n] 411 wire, err := rawSignatureData(rrset, rr) 412 if err != nil { 413 return err 414 } 415 416 sigbuf := rr.sigBuf() // Get the binary signature data 417 // TODO(miek) 418 // remove the domain name and assume its ours? 419 // if rr.Algorithm == PRIVATEDNS { // PRIVATEOID 420 // } 421 422 h, cryptohash, err := hashFromAlgorithm(rr.Algorithm) 423 if err != nil { 424 return err 425 } 426 427 switch rr.Algorithm { 428 case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: 429 // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere?? 430 pubkey := k.publicKeyRSA() // Get the key 431 if pubkey == nil { 432 return ErrKey 433 } 434 435 h.Write(signeddata) 436 h.Write(wire) 437 return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf) 438 439 case ECDSAP256SHA256, ECDSAP384SHA384: 440 pubkey := k.publicKeyECDSA() 441 if pubkey == nil { 442 return ErrKey 443 } 444 445 // Split sigbuf into the r and s coordinates 446 r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2]) 447 s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:]) 448 449 h.Write(signeddata) 450 h.Write(wire) 451 if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { 452 return nil 453 } 454 return ErrSig 455 456 case ED25519: 457 pubkey := k.publicKeyED25519() 458 if pubkey == nil { 459 return ErrKey 460 } 461 462 if ed25519.Verify(pubkey, append(signeddata, wire...), sigbuf) { 463 return nil 464 } 465 return ErrSig 466 467 default: 468 return ErrAlg 469 } 470 } 471 472 // ValidityPeriod uses RFC1982 serial arithmetic to calculate 473 // if a signature period is valid. If t is the zero time, the 474 // current time is taken other t is. Returns true if the signature 475 // is valid at the given time, otherwise returns false. 476 func (rr *RRSIG) ValidityPeriod(t time.Time) bool { 477 var utc int64 478 if t.IsZero() { 479 utc = time.Now().UTC().Unix() 480 } else { 481 utc = t.UTC().Unix() 482 } 483 modi := (int64(rr.Inception) - utc) / year68 484 mode := (int64(rr.Expiration) - utc) / year68 485 ti := int64(rr.Inception) + modi*year68 486 te := int64(rr.Expiration) + mode*year68 487 return ti <= utc && utc <= te 488 } 489 490 // Return the signatures base64 encoding sigdata as a byte slice. 491 func (rr *RRSIG) sigBuf() []byte { 492 sigbuf, err := fromBase64([]byte(rr.Signature)) 493 if err != nil { 494 return nil 495 } 496 return sigbuf 497 } 498 499 // publicKeyRSA returns the RSA public key from a DNSKEY record. 500 func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey { 501 keybuf, err := fromBase64([]byte(k.PublicKey)) 502 if err != nil { 503 return nil 504 } 505 506 if len(keybuf) < 1+1+64 { 507 // Exponent must be at least 1 byte and modulus at least 64 508 return nil 509 } 510 511 // RFC 2537/3110, section 2. RSA Public KEY Resource Records 512 // Length is in the 0th byte, unless its zero, then it 513 // it in bytes 1 and 2 and its a 16 bit number 514 explen := uint16(keybuf[0]) 515 keyoff := 1 516 if explen == 0 { 517 explen = uint16(keybuf[1])<<8 | uint16(keybuf[2]) 518 keyoff = 3 519 } 520 521 if explen > 4 || explen == 0 || keybuf[keyoff] == 0 { 522 // Exponent larger than supported by the crypto package, 523 // empty, or contains prohibited leading zero. 524 return nil 525 } 526 527 modoff := keyoff + int(explen) 528 modlen := len(keybuf) - modoff 529 if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 { 530 // Modulus is too small, large, or contains prohibited leading zero. 531 return nil 532 } 533 534 pubkey := new(rsa.PublicKey) 535 536 var expo uint64 537 // The exponent of length explen is between keyoff and modoff. 538 for _, v := range keybuf[keyoff:modoff] { 539 expo <<= 8 540 expo |= uint64(v) 541 } 542 if expo > 1<<31-1 { 543 // Larger exponent than supported by the crypto package. 544 return nil 545 } 546 547 pubkey.E = int(expo) 548 pubkey.N = new(big.Int).SetBytes(keybuf[modoff:]) 549 return pubkey 550 } 551 552 // publicKeyECDSA returns the Curve public key from the DNSKEY record. 553 func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey { 554 keybuf, err := fromBase64([]byte(k.PublicKey)) 555 if err != nil { 556 return nil 557 } 558 pubkey := new(ecdsa.PublicKey) 559 switch k.Algorithm { 560 case ECDSAP256SHA256: 561 pubkey.Curve = elliptic.P256() 562 if len(keybuf) != 64 { 563 // wrongly encoded key 564 return nil 565 } 566 case ECDSAP384SHA384: 567 pubkey.Curve = elliptic.P384() 568 if len(keybuf) != 96 { 569 // Wrongly encoded key 570 return nil 571 } 572 } 573 pubkey.X = new(big.Int).SetBytes(keybuf[:len(keybuf)/2]) 574 pubkey.Y = new(big.Int).SetBytes(keybuf[len(keybuf)/2:]) 575 return pubkey 576 } 577 578 func (k *DNSKEY) publicKeyED25519() ed25519.PublicKey { 579 keybuf, err := fromBase64([]byte(k.PublicKey)) 580 if err != nil { 581 return nil 582 } 583 if len(keybuf) != ed25519.PublicKeySize { 584 return nil 585 } 586 return keybuf 587 } 588 589 type wireSlice [][]byte 590 591 func (p wireSlice) Len() int { return len(p) } 592 func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 593 func (p wireSlice) Less(i, j int) bool { 594 _, ioff, _ := UnpackDomainName(p[i], 0) 595 _, joff, _ := UnpackDomainName(p[j], 0) 596 return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0 597 } 598 599 // Return the raw signature data. 600 func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) { 601 wires := make(wireSlice, len(rrset)) 602 for i, r := range rrset { 603 r1 := r.copy() 604 h := r1.Header() 605 h.Ttl = s.OrigTtl 606 labels := SplitDomainName(h.Name) 607 // 6.2. Canonical RR Form. (4) - wildcards 608 if len(labels) > int(s.Labels) { 609 // Wildcard 610 h.Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "." 611 } 612 // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase 613 h.Name = CanonicalName(h.Name) 614 // 6.2. Canonical RR Form. (3) - domain rdata to lowercase. 615 // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR, 616 // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX, 617 // SRV, DNAME, A6 618 // 619 // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC): 620 // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record 621 // that needs conversion to lowercase, and twice at that. Since HINFO 622 // records contain no domain names, they are not subject to case 623 // conversion. 624 switch x := r1.(type) { 625 case *NS: 626 x.Ns = CanonicalName(x.Ns) 627 case *MD: 628 x.Md = CanonicalName(x.Md) 629 case *MF: 630 x.Mf = CanonicalName(x.Mf) 631 case *CNAME: 632 x.Target = CanonicalName(x.Target) 633 case *SOA: 634 x.Ns = CanonicalName(x.Ns) 635 x.Mbox = CanonicalName(x.Mbox) 636 case *MB: 637 x.Mb = CanonicalName(x.Mb) 638 case *MG: 639 x.Mg = CanonicalName(x.Mg) 640 case *MR: 641 x.Mr = CanonicalName(x.Mr) 642 case *PTR: 643 x.Ptr = CanonicalName(x.Ptr) 644 case *MINFO: 645 x.Rmail = CanonicalName(x.Rmail) 646 x.Email = CanonicalName(x.Email) 647 case *MX: 648 x.Mx = CanonicalName(x.Mx) 649 case *RP: 650 x.Mbox = CanonicalName(x.Mbox) 651 x.Txt = CanonicalName(x.Txt) 652 case *AFSDB: 653 x.Hostname = CanonicalName(x.Hostname) 654 case *RT: 655 x.Host = CanonicalName(x.Host) 656 case *SIG: 657 x.SignerName = CanonicalName(x.SignerName) 658 case *PX: 659 x.Map822 = CanonicalName(x.Map822) 660 x.Mapx400 = CanonicalName(x.Mapx400) 661 case *NAPTR: 662 x.Replacement = CanonicalName(x.Replacement) 663 case *KX: 664 x.Exchanger = CanonicalName(x.Exchanger) 665 case *SRV: 666 x.Target = CanonicalName(x.Target) 667 case *DNAME: 668 x.Target = CanonicalName(x.Target) 669 } 670 // 6.2. Canonical RR Form. (5) - origTTL 671 wire := make([]byte, Len(r1)+1) // +1 to be safe(r) 672 off, err1 := PackRR(r1, wire, 0, nil, false) 673 if err1 != nil { 674 return nil, err1 675 } 676 wire = wire[:off] 677 wires[i] = wire 678 } 679 sort.Sort(wires) 680 for i, wire := range wires { 681 if i > 0 && bytes.Equal(wire, wires[i-1]) { 682 continue 683 } 684 buf = append(buf, wire...) 685 } 686 return buf, nil 687 } 688 689 func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) { 690 // copied from zmsg.go RRSIG packing 691 off, err := packUint16(sw.TypeCovered, msg, 0) 692 if err != nil { 693 return off, err 694 } 695 off, err = packUint8(sw.Algorithm, msg, off) 696 if err != nil { 697 return off, err 698 } 699 off, err = packUint8(sw.Labels, msg, off) 700 if err != nil { 701 return off, err 702 } 703 off, err = packUint32(sw.OrigTtl, msg, off) 704 if err != nil { 705 return off, err 706 } 707 off, err = packUint32(sw.Expiration, msg, off) 708 if err != nil { 709 return off, err 710 } 711 off, err = packUint32(sw.Inception, msg, off) 712 if err != nil { 713 return off, err 714 } 715 off, err = packUint16(sw.KeyTag, msg, off) 716 if err != nil { 717 return off, err 718 } 719 off, err = PackDomainName(sw.SignerName, msg, off, nil, false) 720 if err != nil { 721 return off, err 722 } 723 return off, nil 724 } 725 726 func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) { 727 // copied from zmsg.go DNSKEY packing 728 off, err := packUint16(dw.Flags, msg, 0) 729 if err != nil { 730 return off, err 731 } 732 off, err = packUint8(dw.Protocol, msg, off) 733 if err != nil { 734 return off, err 735 } 736 off, err = packUint8(dw.Algorithm, msg, off) 737 if err != nil { 738 return off, err 739 } 740 off, err = packStringBase64(dw.PublicKey, msg, off) 741 if err != nil { 742 return off, err 743 } 744 return off, nil 745 }