diff --git a/crypto/attachment.go b/crypto/attachment.go index d578e52..21e0dda 100644 --- a/crypto/attachment.go +++ b/crypto/attachment.go @@ -65,19 +65,7 @@ func (pm *PmCrypto) DecryptAttachment(keyPacket []byte, dataPacket []byte, kr *K privKeyEntries := kr.entities - rawPwd := []byte(passphrase) - for _, e := range privKeyEntries { - - if e.PrivateKey != nil && e.PrivateKey.Encrypted { - e.PrivateKey.Decrypt(rawPwd) - } - - for _, sub := range e.Subkeys { - if sub.PrivateKey != nil && sub.PrivateKey.Encrypted { - sub.PrivateKey.Decrypt(rawPwd) - } - } - } + kr.Unlock([]byte(passphrase)) keyReader := bytes.NewReader(keyPacket) dataReader := bytes.NewReader(dataPacket) diff --git a/crypto/keyring.go b/crypto/keyring.go index a72833b..687e9c1 100644 --- a/crypto/keyring.go +++ b/crypto/keyring.go @@ -105,6 +105,25 @@ func (kr *KeyRing) GetEntities() openpgp.EntityList { return kr.entities } +func (kr *KeyRing) GetSigningEntity(passphrase string) *openpgp.Entity { + + var signEntity *openpgp.Entity + + for _, e := range kr.entities { + // Entity.PrivateKey must be a signing key + if e.PrivateKey != nil { + if e.PrivateKey.Encrypted { + e.PrivateKey.Decrypt([]byte(passphrase)) + } + if !e.PrivateKey.Encrypted { + signEntity = e + break + } + } + } + return signEntity +} + // Encrypt encrypts data to this keyring's owner. If sign is not nil, it also // signs data with it. sign must be unlock to be able to sign data, if it's not // the case an error will be returned. @@ -347,7 +366,7 @@ func (kr *KeyRing) Unlock(passphrase []byte) error { } if len(keys) == 0 { - return errors.New("pmapi: cannot unlock key ring, no private key available") + return errors.New("go-pm-crypto: cannot unlock key ring, no private key available") } var err error diff --git a/crypto/message.go b/crypto/message.go index 3f69868..4f26f45 100644 --- a/crypto/message.go +++ b/crypto/message.go @@ -40,7 +40,7 @@ func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey str // passphrase : match with private key to decrypt message func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) { - md, err := decryptCore(encryptedText, nil, privateKey.entities, passphrase, pm.getTimeGenerator()) + md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator()) if err != nil { return "", err } @@ -55,20 +55,14 @@ func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, pa return string(b), nil } -func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, privKeyEntries openpgp.EntityList, passphrase string, timeFunc func() time.Time) (*openpgp.MessageDetails, error) { +func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, privKey *KeyRing, passphrase string, timeFunc func() time.Time) (*openpgp.MessageDetails, error) { rawPwd := []byte(passphrase) - for _, e := range privKeyEntries { + privKey.Unlock(rawPwd) - if e.PrivateKey != nil && e.PrivateKey.Encrypted { - e.PrivateKey.Decrypt(rawPwd) - } - - for _, sub := range e.Subkeys { - if sub.PrivateKey != nil && sub.PrivateKey.Encrypted { - sub.PrivateKey.Decrypt(rawPwd) - } - } + privKeyEntries := privKey.entities + for _, entity := range privKey.entities { + privKeyEntries = append(privKeyEntries, entity) } if additionalEntries != nil { @@ -101,7 +95,7 @@ func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey *KeyR out.Verify = noVerifier } - md, err := decryptCore(encryptedText, verifierEntries, privateKeyRing.entities, passphrase, func() time.Time { return time.Unix(0, 0) }) // TODO: I doubt this time is correct + md, err := decryptCore(encryptedText, verifierEntries, privateKeyRing, passphrase, func() time.Time { return time.Unix(0, 0) }) // TODO: I doubt this time is correct decrypted := md.UnverifiedBody b, err := ioutil.ReadAll(decrypted) @@ -205,18 +199,7 @@ func (pm *PmCrypto) EncryptMessage(plainText string, publicKey *KeyRing, private if len(passphrase) > 0 && len(privateKey.entities) > 0 { - for _, e := range privateKey.entities { - // Entity.PrivateKey must be a signing key - if e.PrivateKey != nil { - if e.PrivateKey.Encrypted { - e.PrivateKey.Decrypt([]byte(passphrase)) - } - if !e.PrivateKey.Encrypted { - signEntity = e - break - } - } - } + signEntity := privateKey.GetSigningEntity(passphrase) if signEntity == nil { return "", errors.New("cannot sign message, signer key is not unlocked") diff --git a/crypto/sign_detached.go b/crypto/sign_detached.go index d97485d..982c8b2 100644 --- a/crypto/sign_detached.go +++ b/crypto/sign_detached.go @@ -16,24 +16,11 @@ import ( // SignTextDetached sign detached text type func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, passphrase string, trim bool) (string, error) { //sign with 0x01 text - var signEntity *openpgp.Entity - if trim { plainText = internal.TrimNewlines(plainText) } - for _, e := range privateKey.entities { - // Entity.PrivateKey must be a signing key - if e.PrivateKey != nil { - if e.PrivateKey.Encrypted { - e.PrivateKey.Decrypt([]byte(passphrase)) - } - if !e.PrivateKey.Encrypted { - signEntity = e - break - } - } - } + signEntity := privateKey.GetSigningEntity(passphrase) if signEntity == nil { return "", errors.New("cannot sign message, signer key is not unlocked") @@ -55,20 +42,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, pass // Sign detached bin data using string key func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) { //sign with 0x00 - var signEntity *openpgp.Entity - - for _, e := range privateKey.entities { - // Entity.PrivateKey must be a signing key - if e.PrivateKey != nil { - if e.PrivateKey.Encrypted { - e.PrivateKey.Decrypt([]byte(passphrase)) - } - if !e.PrivateKey.Encrypted { - signEntity = e - break - } - } - } + signEntity := privateKey.GetSigningEntity(passphrase) if signEntity == nil { return "", errors.New("cannot sign message, singer key is not unlocked")