Allow multiple keypackets in session key decryption (#99)
* Fix session key decryption * Break on all data packets Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
This commit is contained in:
parent
f8d9ba516a
commit
4166d25a63
3 changed files with 47 additions and 17 deletions
|
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Changed
|
||||
- Session key decryption now considers multiple key packets
|
||||
|
||||
|
||||
## [2.1.0] 2020-11-04
|
||||
### Security
|
||||
- Updated underlying crypto library
|
||||
|
|
|
|||
|
|
@ -9,28 +9,53 @@ import (
|
|||
"golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
// DecryptSessionKey returns the decrypted session key from a binary encrypted session key packet.
|
||||
// DecryptSessionKey returns the decrypted session key from one or multiple binary encrypted session key packets.
|
||||
func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SessionKey, error) {
|
||||
var p packet.Packet
|
||||
var ek *packet.EncryptedKey
|
||||
|
||||
var err error
|
||||
var hasPacket = false
|
||||
var decryptErr error
|
||||
|
||||
keyReader := bytes.NewReader(keyPacket)
|
||||
packets := packet.NewReader(keyReader)
|
||||
|
||||
var p packet.Packet
|
||||
var err error
|
||||
if p, err = packets.Next(); err != nil {
|
||||
return nil, errors.Wrap(err, "gopenpgp: error in reading packets")
|
||||
}
|
||||
|
||||
ek := p.(*packet.EncryptedKey)
|
||||
var decryptErr error
|
||||
for _, key := range keyRing.entities.DecryptionKeys() {
|
||||
priv := key.PrivateKey
|
||||
if priv.Encrypted {
|
||||
continue
|
||||
}
|
||||
|
||||
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
|
||||
Loop:
|
||||
for {
|
||||
if p, err = packets.Next(); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
switch p := p.(type) {
|
||||
case *packet.EncryptedKey:
|
||||
hasPacket = true
|
||||
ek = p
|
||||
|
||||
for _, key := range keyRing.entities.DecryptionKeys() {
|
||||
priv := key.PrivateKey
|
||||
if priv.Encrypted {
|
||||
continue
|
||||
}
|
||||
|
||||
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
|
||||
case *packet.SymmetricallyEncrypted,
|
||||
*packet.AEADEncrypted,
|
||||
*packet.Compressed,
|
||||
*packet.LiteralData:
|
||||
break Loop
|
||||
|
||||
default:
|
||||
continue Loop
|
||||
}
|
||||
}
|
||||
|
||||
if !hasPacket {
|
||||
return nil, errors.Wrap(err, "gopenpgp: couldn't find a session key packet that could be decrypted")
|
||||
}
|
||||
|
||||
if decryptErr != nil {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func TestMultipleAsymmetricKeyPacket(t *testing.T) {
|
|||
}
|
||||
|
||||
// Password defined in keyring_test
|
||||
outputSymmetricKey, err := keyRingTestMultiple.DecryptSessionKey(keyPacket)
|
||||
outputSymmetricKey, err := keyRingTestPrivate.DecryptSessionKey(keyPacket)
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while decrypting key packet, got:", err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue