github.com/Venafi/vcert/v5@v5.10.2/pkg/util/sshKeyGenerator.go (about) 1 package util 2 3 import ( 4 "crypto/rand" 5 "crypto/rsa" 6 "crypto/x509" 7 "encoding/pem" 8 "fmt" 9 "log" 10 "strings" 11 12 "github.com/youmark/pkcs8" 13 "golang.org/x/crypto/ssh" 14 ) 15 16 const ( 17 RsaPrivKeyType = "RSA PRIVATE KEY" 18 ) 19 20 func generatePrivKey(bitSize int) (*rsa.PrivateKey, error) { 21 22 privKey, err := rsa.GenerateKey(rand.Reader, bitSize) 23 if err != nil { 24 return nil, err 25 } 26 27 err = privKey.Validate() 28 if err != nil { 29 return nil, err 30 } 31 32 log.Println("Private Key was generated") 33 return privKey, nil 34 } 35 36 func encodePrivKeyToPEM(privateKey *rsa.PrivateKey, keyPassword string, format ...string) ([]byte, error) { 37 38 var err error 39 var privBlock *pem.Block 40 var privDER []byte 41 if keyPassword != "" { 42 if format[0] == LegacyPem { 43 privDER := x509.MarshalPKCS1PrivateKey(privateKey) 44 privBlock, err = X509EncryptPEMBlock(rand.Reader, RsaPrivKeyType, privDER, []byte(keyPassword), PEMCipherDES) 45 if err != nil { 46 return nil, err 47 } 48 } else { 49 privDER, err = pkcs8.MarshalPrivateKey(privateKey, []byte(keyPassword), nil) 50 if err != nil { 51 return nil, err 52 } 53 privBlock = &pem.Block{ 54 Type: "ENCRYPTED PRIVATE KEY", 55 Headers: nil, 56 Bytes: privDER, 57 } 58 } 59 } else { 60 if format[0] == LegacyPem { 61 privDER = x509.MarshalPKCS1PrivateKey(privateKey) 62 privBlock = &pem.Block{ 63 Type: RsaPrivKeyType, 64 Headers: nil, 65 Bytes: privDER, 66 } 67 } else { 68 privDER, err := pkcs8.MarshalPrivateKey(privateKey, nil, nil) 69 if err != nil { 70 return nil, err 71 } 72 privBlock = &pem.Block{ 73 Type: "PRIVATE KEY", 74 Headers: nil, 75 Bytes: privDER, 76 } 77 } 78 } 79 80 privatePEM := pem.EncodeToMemory(privBlock) 81 82 return privatePEM, nil 83 } 84 85 func generatePublicKey(key *rsa.PublicKey) ([]byte, error) { 86 87 publicRsaKey, err := ssh.NewPublicKey(key) 88 if err != nil { 89 return nil, err 90 } 91 92 pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey) 93 94 log.Println("Public key was generated") 95 return pubKeyBytes, nil 96 97 } 98 99 func GenerateSshKeyPair(bitSize int, keyPassword, certId string, format ...string) ([]byte, []byte, error) { 100 101 currentFormat := "" 102 if len(format) > 0 && format[0] != "" { 103 currentFormat = format[0] 104 } 105 106 privateKey, err := generatePrivKey(bitSize) 107 108 if err != nil { 109 return nil, nil, err 110 } 111 112 publicKeyBytes, err := generatePublicKey(&privateKey.PublicKey) 113 114 if err != nil { 115 return nil, nil, err 116 } 117 118 privateKeyBytes, err := encodePrivKeyToPEM(privateKey, keyPassword, currentFormat) 119 120 if err != nil { 121 return nil, nil, err 122 } 123 124 sPubKey := string(publicKeyBytes) 125 sPubKey = strings.TrimRight(sPubKey, "\r\n") 126 sPubKey = fmt.Sprint(sPubKey, " ", certId) 127 128 return privateKeyBytes, []byte(sPubKey), nil 129 130 }