From cbad1f0b8be7c1e678d57dd4b07d2ddcc2998da3 Mon Sep 17 00:00:00 2001 From: Scott Leggett Date: Fri, 24 Mar 2023 22:40:37 +0800 Subject: [PATCH] fix: correctly convert to openpgp ecdsa key representation --- internal/keyservice/gpg/keyservice.go | 43 ------------------- internal/keyservice/gpg/openpgpecdsa.go | 57 +++++++++++++++++++++++++ internal/securitykey/decryptingkey.go | 3 +- internal/securitykey/openpgpecdsa.go | 16 +++++++ internal/securitykey/signingkey.go | 3 +- 5 files changed, 75 insertions(+), 47 deletions(-) create mode 100644 internal/keyservice/gpg/openpgpecdsa.go create mode 100644 internal/securitykey/openpgpecdsa.go diff --git a/internal/keyservice/gpg/keyservice.go b/internal/keyservice/gpg/keyservice.go index 3bbb77f..833ae35 100644 --- a/internal/keyservice/gpg/keyservice.go +++ b/internal/keyservice/gpg/keyservice.go @@ -6,7 +6,6 @@ import ( "bytes" "crypto" "crypto/ecdsa" - "crypto/elliptic" "crypto/rsa" "fmt" @@ -137,48 +136,6 @@ func (g *KeyService) getRSAKey(keygrip []byte) (*rsa.PrivateKey, error) { return nil, nil } -func nameToCurve(name string) (elliptic.Curve, error) { - switch name { - case elliptic.P224().Params().Name: - return elliptic.P224(), nil - case elliptic.P256().Params().Name: - return elliptic.P256(), nil - case elliptic.P384().Params().Name: - return elliptic.P384(), nil - case elliptic.P521().Params().Name: - return elliptic.P521(), nil - default: - return nil, fmt.Errorf("unknown curve name: %s", name) - } -} - -func ecdsaPublicKey(k *openpgpecdsa.PublicKey) (*ecdsa.PublicKey, error) { - curve, err := nameToCurve(k.GetCurve().GetCurveName()) - if err != nil { - return nil, err - } - return &ecdsa.PublicKey{ - Curve: curve, - X: k.X, - Y: k.Y, - }, nil -} - -func ecdsaPrivateKey(k *openpgpecdsa.PrivateKey) (*ecdsa.PrivateKey, error) { - curve, err := nameToCurve(k.GetCurve().GetCurveName()) - if err != nil { - return nil, err - } - return &ecdsa.PrivateKey{ - D: k.D, - PublicKey: ecdsa.PublicKey{ - Curve: curve, - X: k.X, - Y: k.Y, - }, - }, nil -} - // getECDSAKey returns a matching private ECDSA key if the keygrip matches. If // a key is returned err will be nil. If no key is found, both values will be // nil. diff --git a/internal/keyservice/gpg/openpgpecdsa.go b/internal/keyservice/gpg/openpgpecdsa.go new file mode 100644 index 0000000..4f6aca7 --- /dev/null +++ b/internal/keyservice/gpg/openpgpecdsa.go @@ -0,0 +1,57 @@ +package gpg + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "fmt" + + openpgpecdsa "github.com/ProtonMail/go-crypto/openpgp/ecdsa" +) + +// nameToCurve takes a given curve name and returns the associated +// elliptic.Curve. +func nameToCurve(name string) (elliptic.Curve, error) { + switch name { + case elliptic.P224().Params().Name: + return elliptic.P224(), nil + case elliptic.P256().Params().Name: + return elliptic.P256(), nil + case elliptic.P384().Params().Name: + return elliptic.P384(), nil + case elliptic.P521().Params().Name: + return elliptic.P521(), nil + default: + return nil, fmt.Errorf("unknown curve name: %s", name) + } +} + +// ecdsaPublicKey converts the given ECDSA Key in go-crypto/openpgp +// representation, to standard library crypto/ecdsa representation. +func ecdsaPublicKey(k *openpgpecdsa.PublicKey) (*ecdsa.PublicKey, error) { + curve, err := nameToCurve(k.GetCurve().GetCurveName()) + if err != nil { + return nil, err + } + return &ecdsa.PublicKey{ + Curve: curve, + X: k.X, + Y: k.Y, + }, nil +} + +// ecdsaPrivateKey converts the given ECDSA Key in go-crypto/openpgp +// representation, to standard library crypto/ecdsa representation. +func ecdsaPrivateKey(k *openpgpecdsa.PrivateKey) (*ecdsa.PrivateKey, error) { + curve, err := nameToCurve(k.GetCurve().GetCurveName()) + if err != nil { + return nil, err + } + return &ecdsa.PrivateKey{ + D: k.D, + PublicKey: ecdsa.PublicKey{ + Curve: curve, + X: k.X, + Y: k.Y, + }, + }, nil +} diff --git a/internal/securitykey/decryptingkey.go b/internal/securitykey/decryptingkey.go index 8c870bc..b62f3cf 100644 --- a/internal/securitykey/decryptingkey.go +++ b/internal/securitykey/decryptingkey.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" - openpgpecdsa "github.com/ProtonMail/go-crypto/openpgp/ecdsa" "github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/go-piv/piv-go/piv" ) @@ -39,7 +38,7 @@ func decryptingKeys(yk *piv.YubiKey) ([]DecryptingKey, error) { SlotSpec: s, }, PubPGP: packet.NewECDSAPublicKey(cert.NotBefore, - openpgpecdsa.NewPublicKeyFromCurve(pubKey.Curve)), + openpgpECDSAPublicKey(pubKey)), }) } return decryptingKeys, nil diff --git a/internal/securitykey/openpgpecdsa.go b/internal/securitykey/openpgpecdsa.go new file mode 100644 index 0000000..b200cdb --- /dev/null +++ b/internal/securitykey/openpgpecdsa.go @@ -0,0 +1,16 @@ +package securitykey + +import ( + "crypto/ecdsa" + + openpgpecdsa "github.com/ProtonMail/go-crypto/openpgp/ecdsa" +) + +// openpgpECDSAPublicKey converts the given ECDSA Key in crypto/ecdsa +// representation, to go-crypto/openpgp representation. +func openpgpECDSAPublicKey(k *ecdsa.PublicKey) *openpgpecdsa.PublicKey { + openpgpPubKey := openpgpecdsa.NewPublicKeyFromCurve(k.Curve) + openpgpPubKey.X = k.X + openpgpPubKey.Y = k.Y + return openpgpPubKey +} diff --git a/internal/securitykey/signingkey.go b/internal/securitykey/signingkey.go index b8866b4..c8f4819 100644 --- a/internal/securitykey/signingkey.go +++ b/internal/securitykey/signingkey.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" - openpgpecdsa "github.com/ProtonMail/go-crypto/openpgp/ecdsa" "github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/go-piv/piv-go/piv" "golang.org/x/crypto/ssh" @@ -45,7 +44,7 @@ func signingKeys(yk *piv.YubiKey) ([]SigningKey, error) { }, PubSSH: pubSSH, PubPGP: packet.NewECDSAPublicKey(cert.NotBefore, - openpgpecdsa.NewPublicKeyFromCurve(pubKey.Curve)), + openpgpECDSAPublicKey(pubKey)), }) } return signingKeys, nil