package dns
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"math/big"
)
func (k *DNSKEY ) Generate (bits int ) (crypto .PrivateKey , error ) {
switch k .Algorithm {
case RSASHA1 , RSASHA256 , RSASHA1NSEC3SHA1 :
if bits < 512 || bits > 4096 {
return nil , ErrKeySize
}
case RSASHA512 :
if bits < 1024 || bits > 4096 {
return nil , ErrKeySize
}
case ECDSAP256SHA256 :
if bits != 256 {
return nil , ErrKeySize
}
case ECDSAP384SHA384 :
if bits != 384 {
return nil , ErrKeySize
}
case ED25519 :
if bits != 256 {
return nil , ErrKeySize
}
default :
return nil , ErrAlg
}
switch k .Algorithm {
case RSASHA1 , RSASHA256 , RSASHA512 , RSASHA1NSEC3SHA1 :
priv , err := rsa .GenerateKey (rand .Reader , bits )
if err != nil {
return nil , err
}
k .setPublicKeyRSA (priv .PublicKey .E , priv .PublicKey .N )
return priv , nil
case ECDSAP256SHA256 , ECDSAP384SHA384 :
var c elliptic .Curve
switch k .Algorithm {
case ECDSAP256SHA256 :
c = elliptic .P256 ()
case ECDSAP384SHA384 :
c = elliptic .P384 ()
}
priv , err := ecdsa .GenerateKey (c , rand .Reader )
if err != nil {
return nil , err
}
k .setPublicKeyECDSA (priv .PublicKey .X , priv .PublicKey .Y )
return priv , nil
case ED25519 :
pub , priv , err := ed25519 .GenerateKey (rand .Reader )
if err != nil {
return nil , err
}
k .setPublicKeyED25519 (pub )
return priv , nil
default :
return nil , ErrAlg
}
}
func (k *DNSKEY ) setPublicKeyRSA (_E int , _N *big .Int ) bool {
if _E == 0 || _N == nil {
return false
}
buf := exponentToBuf (_E )
buf = append (buf , _N .Bytes ()...)
k .PublicKey = toBase64 (buf )
return true
}
func (k *DNSKEY ) setPublicKeyECDSA (_X , _Y *big .Int ) bool {
if _X == nil || _Y == nil {
return false
}
var intlen int
switch k .Algorithm {
case ECDSAP256SHA256 :
intlen = 32
case ECDSAP384SHA384 :
intlen = 48
}
k .PublicKey = toBase64 (curveToBuf (_X , _Y , intlen ))
return true
}
func (k *DNSKEY ) setPublicKeyED25519 (_K ed25519 .PublicKey ) bool {
if _K == nil {
return false
}
k .PublicKey = toBase64 (_K )
return true
}
func exponentToBuf(_E int ) []byte {
var buf []byte
i := big .NewInt (int64 (_E )).Bytes ()
if len (i ) < 256 {
buf = make ([]byte , 1 , 1 +len (i ))
buf [0 ] = uint8 (len (i ))
} else {
buf = make ([]byte , 3 , 3 +len (i ))
buf [0 ] = 0
buf [1 ] = uint8 (len (i ) >> 8 )
buf [2 ] = uint8 (len (i ))
}
buf = append (buf , i ...)
return buf
}
func curveToBuf(_X , _Y *big .Int , intlen int ) []byte {
buf := intToBytes (_X , intlen )
buf = append (buf , intToBytes (_Y , intlen )...)
return buf
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .