mirror of
https://github.com/Mic92/sops-nix.git
synced 2025-03-06 08:37:21 +00:00
95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
|
package sshkeys
|
||
|
|
||
|
import (
|
||
|
"crypto"
|
||
|
"crypto/rsa"
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"time"
|
||
|
|
||
|
"golang.org/x/crypto/openpgp"
|
||
|
"golang.org/x/crypto/openpgp/packet"
|
||
|
"golang.org/x/crypto/ssh"
|
||
|
)
|
||
|
|
||
|
func parsePublicKey(publicKey []byte) (*rsa.PublicKey, error) {
|
||
|
key, _, _, _, err := ssh.ParseAuthorizedKey(publicKey)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to parse public ssh key: %s", err)
|
||
|
}
|
||
|
|
||
|
cryptoPublicKey, ok := key.(ssh.CryptoPublicKey)
|
||
|
|
||
|
if !ok {
|
||
|
return nil, fmt.Errorf("Unsupported public key algo: %s", key.Type())
|
||
|
}
|
||
|
|
||
|
rsaKey, ok := cryptoPublicKey.CryptoPublicKey().(*rsa.PublicKey)
|
||
|
|
||
|
if !ok {
|
||
|
return nil, fmt.Errorf("Unsupported public key algo: %s", key.Type())
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
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 SSHPrivateKeyToPGP(sshPrivateKey []byte) (*openpgp.Entity, error) {
|
||
|
key, err := parsePrivateKey(sshPrivateKey)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to parse private ssh key: %s", err)
|
||
|
}
|
||
|
|
||
|
// Let's make keys reproducible
|
||
|
timeNull := time.Unix(0, 0)
|
||
|
|
||
|
gpgKey := &openpgp.Entity{
|
||
|
PrimaryKey: packet.NewRSAPublicKey(timeNull, &key.PublicKey),
|
||
|
PrivateKey: packet.NewRSAPrivateKey(timeNull, key),
|
||
|
Identities: make(map[string]*openpgp.Identity),
|
||
|
}
|
||
|
uid := packet.NewUserId("root", "", "root@localhost")
|
||
|
isPrimaryID := true
|
||
|
gpgKey.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,
|
||
|
FlagSign: true,
|
||
|
FlagCertify: true,
|
||
|
FlagEncryptStorage: true,
|
||
|
FlagEncryptCommunications: true,
|
||
|
IssuerKeyId: &gpgKey.PrimaryKey.KeyId,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
return gpgKey, nil
|
||
|
}
|