Skip to content

Commit

Permalink
Merge pull request #66 from smlx/lazy-keyfile-decryption
Browse files Browse the repository at this point in the history
Lazy decryption for keyfiles
  • Loading branch information
smlx authored Sep 23, 2021
2 parents a8c7be8 + d0c4af9 commit f964f11
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 21 deletions.
4 changes: 2 additions & 2 deletions internal/assuan/assuan.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func New(rw io.ReadWriter, log *zap.Logger, ks ...KeyService) *Assuan {
}
keyFound, _, err = haveKey(ks, keygrips)
if err != nil {
_, _ = io.WriteString(rw, "ERR 1 couldn't check for keygrip\n")
return fmt.Errorf("couldn't check keygrips: %v", err)
_, err = io.WriteString(rw, "ERR 1 couldn't check for keygrip\n")
return err
}
if keyFound {
_, err = io.WriteString(rw, "OK\n")
Expand Down
41 changes: 41 additions & 0 deletions internal/keyservice/gpg/havekey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package gpg

import (
"bytes"
"crypto/ecdsa"
"crypto/rsa"
)

// HaveKey takes a list of keygrips, and returns a boolean indicating if any of
// the given keygrips were found, the found keygrip, and an error, if any.
func (g *KeyService) HaveKey(keygrips [][]byte) (bool, []byte, error) {
for _, keyfile := range g.privKeys {
for _, privKey := range keyfile.keys {
pubKeyRSA, ok := privKey.PublicKey.PublicKey.(*rsa.PublicKey)
if ok {
for _, kg := range keygrips {
rsaKG, err := keygripRSA(pubKeyRSA)
if err != nil {
return false, nil, err
}
if bytes.Equal(kg, rsaKG) {
return true, kg, nil
}
}
}
pubKeyECDSA, ok := privKey.PublicKey.PublicKey.(*ecdsa.PublicKey)
if ok {
for _, kg := range keygrips {
ecdsaKG, err := KeygripECDSA(pubKeyECDSA)
if err != nil {
return false, nil, err
}
if bytes.Equal(kg, ecdsaKG) {
return true, kg, nil
}
}
}
}
}
return false, nil, nil
}
7 changes: 5 additions & 2 deletions internal/keyservice/gpg/keygrip.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ func compute(parts []part) ([]byte, error) {
}

// keygripRSA calculates a keygrip for an RSA public key.
func keygripRSA(pubKey *rsa.PublicKey) []byte {
func keygripRSA(pubKey *rsa.PublicKey) ([]byte, error) {
if pubKey == nil {
return nil, fmt.Errorf("nil key")
}
keygrip := sha1.New()
keygrip.Write([]byte{0})
keygrip.Write(pubKey.N.Bytes())
return keygrip.Sum(nil)
return keygrip.Sum(nil), nil
}
22 changes: 5 additions & 17 deletions internal/keyservice/gpg/keyservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,6 @@ func (*KeyService) Name() string {
return "GPG Keyfile"
}

// HaveKey takes a list of keygrips, and returns a boolean indicating if any of
// the given keygrips were found, the found keygrip, and an error, if any.
func (g *KeyService) HaveKey(keygrips [][]byte) (bool, []byte, error) {
for _, kg := range keygrips {
key, err := g.getRSAKey(kg)
if err != nil {
return false, nil, err
}
if key != nil {
return true, kg, nil
}
}
return false, nil, nil
}

// doDecrypt prompts for a passphrase via pinentry and uses the passphrase to
// decrypt the given private key
func (g *KeyService) doDecrypt(k *packet.PrivateKey, uid string) error {
Expand Down Expand Up @@ -120,14 +105,17 @@ func (g *KeyService) decryptPrivateKey(k *packet.PrivateKey, uid string) error {
// getRSAKey returns a matching private RSA key if the keygrip matches. If a key
// is returned err will be nil. If no key is found, both values may be nil.
func (g *KeyService) getRSAKey(keygrip []byte) (*rsa.PrivateKey, error) {
var err error
for _, pk := range g.privKeys {
for _, k := range pk.keys {
pubKey, ok := k.PublicKey.PublicKey.(*rsa.PublicKey)
if !ok {
continue
}
if !bytes.Equal(keygrip, keygripRSA(pubKey)) {
pubKeygrip, err := keygripRSA(pubKey)
if err != nil {
return nil, fmt.Errorf("couldn't get RSA keygrip: %v", err)
}
if !bytes.Equal(keygrip, pubKeygrip) {
continue
}
err = g.decryptPrivateKey(k,
Expand Down

0 comments on commit f964f11

Please sign in to comment.