gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

dnssec_keygen.go (3176B)


      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 }