mirror of
https://github.com/Mic92/sops-nix.git
synced 2024-12-14 11:57:52 +00:00
fix public gpg key import
This commit is contained in:
parent
23ffb7df4e
commit
6286c5cc75
5 changed files with 38 additions and 64 deletions
22
README.md
22
README.md
|
@ -33,7 +33,10 @@ conversion tool to convert an existing ssh key (we only support RSA keys right n
|
|||
|
||||
```
|
||||
$ nix-shell -p ssh-to-pgp
|
||||
$ ssh-to-pgp -privkey $HOME/.ssh/id_rsa | gpg --import --quiet
|
||||
$ ssh-to-pgp -private-key -i $HOME/.ssh/id_rsa | gpg --import --quiet
|
||||
2504791468b153b8a3963cc97ba53d1919c5dfd4
|
||||
# This exports the public key
|
||||
$ ssh-to-pgp -i $HOME/.ssh/id_rsa -o $USER.asc
|
||||
2504791468b153b8a3963cc97ba53d1919c5dfd4
|
||||
```
|
||||
|
||||
|
@ -48,7 +51,7 @@ then your ssh key is encrypted with your password and you need to create a encry
|
|||
```
|
||||
$ cp $HOME/.ssh/id_rsa /tmp/id_rsa
|
||||
$ ssh-keygen -p -N "" -f /tmp/id_rsa
|
||||
$ ssh-to-pgp -privkey /tmp/id_rsa | gpg --import --quiet
|
||||
$ ssh-to-pgp -private-key -i /tmp/id_rsa | gpg --import --quiet
|
||||
```
|
||||
|
||||
The hex string printed here is your GPG fingerprint that can be exported to `SOPS_PGP_FP`.
|
||||
|
@ -71,23 +74,20 @@ uid [ unknown] root <root@localhost>
|
|||
The fingerprint here is `9F89 C5F6 9A10 281A 8350 14B0 9C3D C61F 7520 87EF`, you
|
||||
need to remove the space in-between manually.
|
||||
|
||||
### 3. Get a GPG key for your machine
|
||||
### 3. Get a PGP Public key for your machine
|
||||
|
||||
The easiest way to add new hosts is using ssh host keys (requires openssh to be enabled).
|
||||
Since sops does not natively supports ssh keys yet, nix-sops supports a conversion tool
|
||||
to store them as gpg keys.
|
||||
|
||||
```
|
||||
$ nix-shell -p ssh-to-gpg
|
||||
# One can use ssh-keyscan over the network
|
||||
$ ssh-keyscan -t rsa server01 | ssh-to-pgp -pubkey - > server01.asc
|
||||
# server01:22 SSH-2.0-OpenSSH_8.2
|
||||
0fd60c8c3b664aceb1796ce02b318df330331003
|
||||
# via ssh command:
|
||||
$ ssh server01 "cat /etc/ssh/ssh_host_rsa_key.pub" | ssh-to-gpg -pubkey - > hosts/server01.asc
|
||||
$ nix-shell -p ssh-to-pgp
|
||||
$ ssh root@server01 "cat /etc/ssh/ssh_host_rsa_key" | ssh-to-pgp -o server01.asc
|
||||
# or with sudo
|
||||
$ ssh youruser@server01 "sudo cat /etc/ssh/ssh_host_rsa_key" | ssh-to-pgp -o server01.asc
|
||||
0fd60c8c3b664aceb1796ce02b318df330331003
|
||||
# Or just read them locally (or in a ssh session)
|
||||
$ ssh-to-pgp -pubkey /etc/ssh/ssh_host_rsa_key.pub > server01.asc
|
||||
$ ssh-to-pgp -i /etc/ssh/ssh_host_rsa_key -o server01.asc
|
||||
0fd60c8c3b664aceb1796ce02b318df330331003
|
||||
```
|
||||
|
||||
|
|
|
@ -14,28 +14,19 @@ import (
|
|||
)
|
||||
|
||||
type options struct {
|
||||
publicKey, privateKey, format, out string
|
||||
format, out, in string
|
||||
privateKey bool
|
||||
}
|
||||
|
||||
func parseFlags(args []string) options {
|
||||
var opts options
|
||||
f := flag.NewFlagSet(args[0], flag.ExitOnError)
|
||||
f.StringVar(&opts.publicKey, "pubkey", "", "Path to public key. Reads from standard input if equal to '-'")
|
||||
f.StringVar(&opts.privateKey, "privkey", "", "Path to private key. Reads from standard input if equal to '-'")
|
||||
f.BoolVar(&opts.privateKey, "private-key", false, "Export private key instead of public key")
|
||||
f.StringVar(&opts.format, "format", "armor", "GPG format encoding (binary|armor)")
|
||||
f.StringVar(&opts.in, "i", "-", "Input path. Reads by default from standard output")
|
||||
f.StringVar(&opts.out, "o", "-", "Output path. Prints by default to standard output")
|
||||
f.Parse(args[1:])
|
||||
|
||||
if opts.publicKey != "" && opts.privateKey != "" {
|
||||
fmt.Fprintln(os.Stderr, "-pubkey and -privkey are mutual exclusive")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if opts.publicKey == "" && opts.privateKey == "" {
|
||||
fmt.Fprintln(os.Stderr, "Either -pubkey and -privkey must be specified")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
|
@ -43,19 +34,15 @@ func convertKeys(args []string) error {
|
|||
opts := parseFlags(args)
|
||||
var err error
|
||||
var sshKey []byte
|
||||
keyPath := opts.privateKey
|
||||
if opts.publicKey != "" {
|
||||
keyPath = opts.publicKey
|
||||
}
|
||||
if keyPath == "-" {
|
||||
if opts.in == "-" {
|
||||
sshKey, _ = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading stdin: %s", err)
|
||||
}
|
||||
} else {
|
||||
sshKey, err = ioutil.ReadFile(keyPath)
|
||||
sshKey, err = ioutil.ReadFile(opts.in)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading %s: %s", opts.privateKey, err)
|
||||
return fmt.Errorf("error reading %s: %s", opts.in, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,9 +56,9 @@ func convertKeys(args []string) error {
|
|||
}
|
||||
|
||||
if opts.format == "armor" {
|
||||
keyType := openpgp.PrivateKeyType
|
||||
if opts.publicKey != "" {
|
||||
keyType = openpgp.PublicKeyType
|
||||
keyType := openpgp.PublicKeyType
|
||||
if opts.privateKey {
|
||||
keyType = openpgp.PrivateKeyType
|
||||
}
|
||||
writer, err = armor.Encode(writer, keyType, make(map[string]string))
|
||||
if err != nil {
|
||||
|
@ -79,28 +66,21 @@ func convertKeys(args []string) error {
|
|||
}
|
||||
}
|
||||
|
||||
var fingerprint [20]byte
|
||||
gpgKey, err := sshkeys.SSHPrivateKeyToPGP(sshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.publicKey != "" {
|
||||
gpgKey, err := sshkeys.SSHPublicKeyToPGP(sshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = gpgKey.Serialize(writer)
|
||||
fingerprint = gpgKey.Fingerprint
|
||||
} else {
|
||||
gpgKey, err := sshkeys.SSHPrivateKeyToPGP(sshKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.privateKey {
|
||||
err = gpgKey.SerializePrivate(writer, nil)
|
||||
fingerprint = gpgKey.PrimaryKey.Fingerprint
|
||||
} else {
|
||||
err = gpgKey.Serialize(writer)
|
||||
}
|
||||
if err == nil {
|
||||
if opts.format == "armor" {
|
||||
writer.Close()
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%s\n", hex.EncodeToString(fingerprint[:]))
|
||||
fmt.Fprintf(os.Stderr, "%s\n", hex.EncodeToString(gpgKey.PrimaryKey.Fingerprint[:]))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -28,13 +28,12 @@ func TestCli(t *testing.T) {
|
|||
defer os.RemoveAll(tempdir)
|
||||
|
||||
out := path.Join(tempdir, "out")
|
||||
pubKey := path.Join(assets, "id_rsa.pub")
|
||||
privKey := path.Join(assets, "id_rsa")
|
||||
cmds := [][]string{
|
||||
{"ssh-to-pgp", "-pubkey", pubKey, "-o", out},
|
||||
{"ssh-to-pgp", "-format=armor", "-pubkey", pubKey, "-o", out},
|
||||
{"ssh-to-pgp", "-privkey", privKey, "-o", out},
|
||||
{"ssh-to-pgp", "-format=armor", "-privkey", privKey, "-o", out},
|
||||
{"ssh-to-pgp", "-i", privKey, "-o", out},
|
||||
{"ssh-to-pgp", "-format=binary", "-i", privKey, "-o", out},
|
||||
{"ssh-to-pgp", "-private-key", "-i", privKey, "-o", out},
|
||||
{"ssh-to-pgp", "-format=binary", "-private-key", "-i", privKey, "-o", out},
|
||||
}
|
||||
for _, cmd := range cmds {
|
||||
err = convertKeys(cmd)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDSeS6SEputIOi2mQhLeIEJnMAink+KcUv38HnaLak3nnLmUsYJnXYB5KZGxaxVtIjr59J8TndmwniZ+wc0rql6Dkif9CsTXgAjxrPiknZNQ7JQbgWUr0pk4jx/K3zLD6i/XAS8QWySNJmY5aJWySbF/K687kUMJ5ql0BX4Tt0RiWL4pIwzZZlLzH4rRySy4z1kbiuOZf8htVRtlGoDGqGViJRpuybSKrmXbevRI7aWjiml2BVTMktPekAPx+MA3t/8EM/uJxtWp7g3BsneHQdKIjR0WEKAITTmuDLEEtIXXEUbgBW0WjbD62nRft/A6/iyWykPJmkLA4WnSLS03caeUxCKoEthZ1xfBPCRNw7xbysQF8CHJz8cAMjZGgBGlOin8EKDhmlma6FZ94cAB5Tr4G3R0h4ky77bPk2/6vvZtyU/AFnDP2HfGaRCDNF+Q7+fR9YmKwcW/vCa2ItIEXgMmBjS+yl0p+4fVaY6Q7bCTbrd6znb6gTGo7nD9Kj/CGU= joerg@turingmachine
|
|
@ -33,14 +33,6 @@ func parsePublicKey(publicKey []byte) (*rsa.PublicKey, error) {
|
|||
return rsaKey, nil
|
||||
}
|
||||
|
||||
func SSHPublicKeyToPGP(sshPublicKey []byte) (*packet.PublicKey, error) {
|
||||
rsaKey, err := parsePublicKey(sshPublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return packet.NewRSAPublicKey(time.Unix(0, 0), rsaKey), nil
|
||||
}
|
||||
|
||||
func parsePrivateKey(sshPrivateKey []byte) (*rsa.PrivateKey, error) {
|
||||
privateKey, err := ssh.ParseRawPrivateKey(sshPrivateKey)
|
||||
if err != nil {
|
||||
|
@ -70,7 +62,7 @@ func SSHPrivateKeyToPGP(sshPrivateKey []byte) (*openpgp.Entity, error) {
|
|||
PrivateKey: packet.NewRSAPrivateKey(timeNull, key),
|
||||
Identities: make(map[string]*openpgp.Identity),
|
||||
}
|
||||
uid := packet.NewUserId("root", "", "root@localhost")
|
||||
uid := packet.NewUserId("root", "Imported from SSH", "root@localhost")
|
||||
isPrimaryID := true
|
||||
gpgKey.Identities[uid.Id] = &openpgp.Identity{
|
||||
Name: uid.Id,
|
||||
|
@ -89,6 +81,10 @@ func SSHPrivateKeyToPGP(sshPrivateKey []byte) (*openpgp.Entity, error) {
|
|||
IssuerKeyId: &gpgKey.PrimaryKey.KeyId,
|
||||
},
|
||||
}
|
||||
err = gpgKey.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, gpgKey.PrimaryKey, gpgKey.PrivateKey, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gpgKey, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue