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 }