...

Source file src/github.com/miekg/dns/dnssec.go

Documentation: github.com/miekg/dns

     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  }
   746  

View as plain text