forked from flynn/flynn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gen_ssh_key_action.go
73 lines (60 loc) · 1.53 KB
/
gen_ssh_key_action.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package bootstrap
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"github.com/flynn/flynn/Godeps/_workspace/src/code.google.com/p/go.crypto/ssh"
)
type GenSSHKeyAction struct {
ID string `json:"id"`
}
type SSHKey struct {
PrivateKeys string `json:"-"`
RSAPublic string `json:"rsa_public"`
ECDSAPublic string `json:"ecdsa_public"`
}
func init() {
Register("gen-ssh-key", &GenSSHKeyAction{})
}
// This action generates two SSH keys using the same key strength as Ubuntu
// defaults:
// - RSA (2048-bit)
// - ECDSA (256-bit prime256v1)
func (a *GenSSHKeyAction) Run(s *State) error {
data := &SSHKey{}
s.StepData[a.ID] = data
var pemBuf bytes.Buffer
rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return err
}
pem.Encode(&pemBuf, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(rsaKey),
})
rsaPubKey, err := ssh.NewPublicKey(&rsaKey.PublicKey)
if err != nil {
return err
}
data.RSAPublic = string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(rsaPubKey)))
ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
ecBytes, err := x509.MarshalECPrivateKey(ecKey)
if err != nil {
return err
}
pem.Encode(&pemBuf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: ecBytes})
ecPubKey, err := ssh.NewPublicKey(&ecKey.PublicKey)
if err != nil {
return err
}
data.ECDSAPublic = string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(ecPubKey)))
data.PrivateKeys = pemBuf.String()
return nil
}