11// Copyright 2014 The Gogs Authors. All rights reserved.
2+ // Copyright 2017 The Gitea Authors. All rights reserved.
23// Use of this source code is governed by a MIT-style
34// license that can be found in the LICENSE file.
45
56package ssh
67
78import (
9+ "crypto/rand"
10+ "crypto/rsa"
11+ "crypto/x509"
12+ "encoding/pem"
813 "io"
914 "io/ioutil"
1015 "net"
@@ -176,9 +181,9 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
176181 log .Error (4 , "Failed to create dir %s: %v" , filePath , err )
177182 }
178183
179- _ , stderr , err := com . ExecCmd ( "ssh-keygen" , "-f" , keyPath , "-t" , "rsa" , "-N" , "" )
184+ err := GenKeyPair ( keyPath )
180185 if err != nil {
181- log .Fatal (4 , "Failed to generate private key: %v - %s " , err , stderr )
186+ log .Fatal (4 , "Failed to generate private key: %v" , err )
182187 }
183188 log .Trace ("SSH: New private key is generateed: %s" , keyPath )
184189 }
@@ -195,3 +200,39 @@ func Listen(host string, port int, ciphers []string, keyExchanges []string, macs
195200
196201 go listen (config , host , port )
197202}
203+
204+ // GenKeyPair make a pair of public and private keys for SSH access.
205+ // Public key is encoded in the format for inclusion in an OpenSSH authorized_keys file.
206+ // Private Key generated is PEM encoded
207+ func GenKeyPair (keyPath string ) error {
208+ privateKey , err := rsa .GenerateKey (rand .Reader , 2048 )
209+ if err != nil {
210+ return err
211+ }
212+
213+ privateKeyPEM := & pem.Block {Type : "RSA PRIVATE KEY" , Bytes : x509 .MarshalPKCS1PrivateKey (privateKey )}
214+ f , err := os .OpenFile (keyPath , os .O_RDWR | os .O_CREATE | os .O_TRUNC , 0600 )
215+ if err != nil {
216+ return err
217+ }
218+ defer f .Close ()
219+
220+ if err := pem .Encode (f , privateKeyPEM ); err != nil {
221+ return err
222+ }
223+
224+ // generate public key
225+ pub , err := ssh .NewPublicKey (& privateKey .PublicKey )
226+ if err != nil {
227+ return err
228+ }
229+
230+ public := ssh .MarshalAuthorizedKey (pub )
231+ p , err := os .OpenFile (keyPath + ".pub" , os .O_RDWR | os .O_CREATE | os .O_TRUNC , 0600 )
232+ if err != nil {
233+ return err
234+ }
235+ defer p .Close ()
236+ _ , err = p .Write (public )
237+ return err
238+ }
0 commit comments