dnssec_keygen.go raw

   1  package dns
   2  
   3  import (
   4  	"crypto"
   5  	"crypto/ecdsa"
   6  	"crypto/ed25519"
   7  	"crypto/elliptic"
   8  	"crypto/rand"
   9  	"crypto/rsa"
  10  	"math/big"
  11  )
  12  
  13  // Generate generates a DNSKEY of the given bit size.
  14  // The public part is put inside the DNSKEY record.
  15  // The Algorithm in the key must be set as this will define
  16  // what kind of DNSKEY will be generated.
  17  // The ECDSA algorithms imply a fixed keysize, in that case
  18  // bits should be set to the size of the algorithm.
  19  func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) {
  20  	switch k.Algorithm {
  21  	case RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
  22  		if bits < 512 || bits > 4096 {
  23  			return nil, ErrKeySize
  24  		}
  25  	case RSASHA512:
  26  		if bits < 1024 || bits > 4096 {
  27  			return nil, ErrKeySize
  28  		}
  29  	case ECDSAP256SHA256:
  30  		if bits != 256 {
  31  			return nil, ErrKeySize
  32  		}
  33  	case ECDSAP384SHA384:
  34  		if bits != 384 {
  35  			return nil, ErrKeySize
  36  		}
  37  	case ED25519:
  38  		if bits != 256 {
  39  			return nil, ErrKeySize
  40  		}
  41  	default:
  42  		return nil, ErrAlg
  43  	}
  44  
  45  	switch k.Algorithm {
  46  	case RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
  47  		priv, err := rsa.GenerateKey(rand.Reader, bits)
  48  		if err != nil {
  49  			return nil, err
  50  		}
  51  		k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
  52  		return priv, nil
  53  	case ECDSAP256SHA256, ECDSAP384SHA384:
  54  		var c elliptic.Curve
  55  		switch k.Algorithm {
  56  		case ECDSAP256SHA256:
  57  			c = elliptic.P256()
  58  		case ECDSAP384SHA384:
  59  			c = elliptic.P384()
  60  		}
  61  		priv, err := ecdsa.GenerateKey(c, rand.Reader)
  62  		if err != nil {
  63  			return nil, err
  64  		}
  65  		k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
  66  		return priv, nil
  67  	case ED25519:
  68  		pub, priv, err := ed25519.GenerateKey(rand.Reader)
  69  		if err != nil {
  70  			return nil, err
  71  		}
  72  		k.setPublicKeyED25519(pub)
  73  		return priv, nil
  74  	default:
  75  		return nil, ErrAlg
  76  	}
  77  }
  78  
  79  // Set the public key (the value E and N)
  80  func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
  81  	if _E == 0 || _N == nil {
  82  		return false
  83  	}
  84  	buf := exponentToBuf(_E)
  85  	buf = append(buf, _N.Bytes()...)
  86  	k.PublicKey = toBase64(buf)
  87  	return true
  88  }
  89  
  90  // Set the public key for Elliptic Curves
  91  func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
  92  	if _X == nil || _Y == nil {
  93  		return false
  94  	}
  95  	var intlen int
  96  	switch k.Algorithm {
  97  	case ECDSAP256SHA256:
  98  		intlen = 32
  99  	case ECDSAP384SHA384:
 100  		intlen = 48
 101  	}
 102  	k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
 103  	return true
 104  }
 105  
 106  // Set the public key for Ed25519
 107  func (k *DNSKEY) setPublicKeyED25519(_K ed25519.PublicKey) bool {
 108  	if _K == nil {
 109  		return false
 110  	}
 111  	k.PublicKey = toBase64(_K)
 112  	return true
 113  }
 114  
 115  // Set the public key (the values E and N) for RSA
 116  // RFC 3110: Section 2. RSA Public KEY Resource Records
 117  func exponentToBuf(_E int) []byte {
 118  	var buf []byte
 119  	i := big.NewInt(int64(_E)).Bytes()
 120  	if len(i) < 256 {
 121  		buf = make([]byte, 1, 1+len(i))
 122  		buf[0] = uint8(len(i))
 123  	} else {
 124  		buf = make([]byte, 3, 3+len(i))
 125  		buf[0] = 0
 126  		buf[1] = uint8(len(i) >> 8)
 127  		buf[2] = uint8(len(i))
 128  	}
 129  	buf = append(buf, i...)
 130  	return buf
 131  }
 132  
 133  // Set the public key for X and Y for Curve. The two
 134  // values are just concatenated.
 135  func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
 136  	buf := intToBytes(_X, intlen)
 137  	buf = append(buf, intToBytes(_Y, intlen)...)
 138  	return buf
 139  }
 140