-
Notifications
You must be signed in to change notification settings - Fork 1
/
cert.go
56 lines (45 loc) · 1.33 KB
/
cert.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
package sshcert
import (
"crypto/ed25519"
"crypto/rand"
"encoding/pem"
"fmt"
"github.com/mikesmitty/edkey"
"golang.org/x/crypto/ssh"
)
// RawPrivateKey is a private key in the on-disk private key format
type RawPrivateKey string
// RawCertificate is a cert in the on-disk certificate format
type RawCertificate string
// RawPublicKey is a public key in the on-disk format
type RawPublicKey string
// Parse parses a certificate
func Parse(raw RawCertificate) (*ssh.Certificate, error) {
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(raw))
if err != nil {
return nil, fmt.Errorf("error parsing certificate: %w", err)
}
cert, ok := pk.(*ssh.Certificate)
if !ok {
return nil, fmt.Errorf("error certificate is not a certificate: %w", err)
}
return cert, nil
}
// GenerateKeys generates a ed25519 keypair in on-disk format
func GenerateKeys() (RawPublicKey, RawPrivateKey, error) {
pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return "", "", err
}
publicKey, err := ssh.NewPublicKey(pubKey)
if err != nil {
return "", "", err
}
pemKey := &pem.Block{
Type: "OPENSSH PRIVATE KEY",
Bytes: edkey.MarshalED25519PrivateKey(privKey),
}
privateKey := pem.EncodeToMemory(pemKey)
authorizedKey := ssh.MarshalAuthorizedKey(publicKey)
return RawPublicKey(authorizedKey), RawPrivateKey(privateKey), nil
}