passforios-gopenpgp/crypto/keyring_session.go

75 lines
2 KiB
Go
Raw Normal View History

package crypto
2018-06-04 16:05:14 -07:00
import (
"bytes"
"strconv"
"github.com/pkg/errors"
2018-06-04 16:05:14 -07:00
"golang.org/x/crypto/openpgp/packet"
)
// DecryptSessionKey returns the decrypted session key from a binary encrypted session key packet.
func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SessionKey, error) {
keyReader := bytes.NewReader(keyPacket)
2018-06-04 16:05:14 -07:00
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")
2018-06-04 16:05:14 -07:00
}
ek := p.(*packet.EncryptedKey)
var decryptErr error
for _, key := range keyRing.entities.DecryptionKeys() {
2018-06-04 16:05:14 -07:00
priv := key.PrivateKey
if priv.Encrypted {
continue
2018-06-04 16:05:14 -07:00
}
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
break
}
}
if decryptErr != nil {
return nil, errors.Wrap(decryptErr, "gopenpgp: error in decrypting")
2018-06-04 16:05:14 -07:00
}
if ek == nil {
return nil, errors.New("gopenpgp: unable to decrypt session key")
2018-06-04 16:05:14 -07:00
}
return newSessionKeyFromEncrypted(ek)
2018-06-04 16:05:14 -07:00
}
// EncryptSessionKey encrypts the session key with the unarmored
// publicKey and returns a binary public-key encrypted session key packet.
func (keyRing *KeyRing) EncryptSessionKey(sk *SessionKey) ([]byte, error) {
2018-06-04 16:05:14 -07:00
outbuf := &bytes.Buffer{}
cf, err := sk.GetCipherFunc()
if err != nil {
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt session key")
}
2018-06-04 16:05:14 -07:00
pubKeys := make([]*packet.PublicKey, 0, len(keyRing.entities))
for _, e := range keyRing.entities {
encryptionKey, ok := e.EncryptionKey(getNow())
if !ok {
return nil, errors.New("gopenpgp: encryption key is unavailable for key id " + strconv.FormatUint(e.PrimaryKey.KeyId, 16))
2018-06-04 16:05:14 -07:00
}
pubKeys = append(pubKeys, encryptionKey.PublicKey)
2018-06-04 16:05:14 -07:00
}
if len(pubKeys) == 0 {
2018-06-04 16:05:14 -07:00
return nil, errors.New("cannot set key: no public key available")
}
for _, pub := range pubKeys {
if err := packet.SerializeEncryptedKey(outbuf, pub, cf, sk.Key, nil); err != nil {
return nil, errors.Wrap(err, "gopenpgp: cannot set key")
}
2018-06-04 16:05:14 -07:00
}
return outbuf.Bytes(), nil
}