Skip to content

Instantly share code, notes, and snippets.

@Mic92
Last active August 9, 2021 14:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mic92/24c40996cd97cb8edd53fd688c60ab6f to your computer and use it in GitHub Desktop.
Save Mic92/24c40996cd97cb8edd53fd688c60ab6f to your computer and use it in GitHub Desktop.
Convert ssh private keys i.e. /etc/ssh/ssh_host_rsa_key to gpg
package main
import (
"crypto"
"crypto/rsa"
"fmt"
"io/ioutil"
"os"
"reflect"
"time"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"golang.org/x/crypto/ssh"
)
func loadSSHPrivateKey(path string) (*rsa.PrivateKey, error) {
content, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("Error reading %s: %s", path, err)
}
privateKey, err := ssh.ParseRawPrivateKey(content)
if err != nil {
panic(err)
}
rsaKey, ok := privateKey.(*rsa.PrivateKey)
if !ok {
return nil, fmt.Errorf("Only RSA keys are supported right now, got: %s", reflect.TypeOf(privateKey))
}
return rsaKey, nil
}
func gpgFromPrivateKey(key *rsa.PrivateKey) (*openpgp.Entity, error) {
name, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("Failed to get hostname(): %s", err)
}
uid := packet.NewUserId("root", "Imported from ssh key", fmt.Sprintf("root@%s", name))
// Let's make keys reproducible
timeNull := time.Unix(0, 0)
e := &openpgp.Entity{
PrimaryKey: packet.NewRSAPublicKey(timeNull, &key.PublicKey),
PrivateKey: packet.NewRSAPrivateKey(timeNull, key),
Identities: make(map[string]*openpgp.Identity),
}
isPrimaryId := true
e.Identities[uid.Id] = &openpgp.Identity{
Name: uid.Id,
UserId: uid,
SelfSignature: &packet.Signature{
CreationTime: timeNull,
SigType: packet.SigTypePositiveCert,
PubKeyAlgo: packet.PubKeyAlgoRSA,
Hash: crypto.SHA256,
IsPrimaryId: &isPrimaryId,
FlagsValid: true,
// TODO what flags do we actually need here?
FlagSign: true,
FlagCertify: true,
FlagEncryptStorage: true,
FlagEncryptCommunications: true,
IssuerKeyId: &e.PrimaryKey.KeyId,
},
}
return e, nil
}
func main() {
if len(os.Args) < 3 {
fmt.Printf("USAGE: %s /etc/ssh/ssh_host_rsa_key gpg-key\n", os.Args[0])
os.Exit(1)
}
privateKeyPath := os.Args[1]
gpgKeyPath := os.Args[2]
key, err := loadSSHPrivateKey(privateKeyPath)
if err != nil {
panic(err)
}
gpgKey, err := gpgFromPrivateKey(key)
if err != nil {
panic(err)
}
f, err := os.Create(gpgKeyPath)
defer f.Close()
if err := gpgKey.SerializePrivate(f, nil); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment