2018-09-11 11:09:28 +02:00
|
|
|
package crypto
|
2018-06-04 16:05:14 -07:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
|
|
|
|
|
"golang.org/x/crypto/openpgp/packet"
|
|
|
|
|
)
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
// RandomToken generated a random token of the same size of the keysize of the default cipher.
|
2019-05-14 18:05:01 +02:00
|
|
|
func (pgp *GopenPGP) RandomToken() ([]byte, error) {
|
2018-06-04 16:05:14 -07:00
|
|
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
2019-06-03 17:00:01 +02:00
|
|
|
return pgp.RandomTokenSize(config.DefaultCipher.KeySize())
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
// RandomTokenSize generates a random token with the specified key size
|
|
|
|
|
func (pgp *GopenPGP) RandomTokenSize(size int) ([]byte, error) {
|
2018-06-04 16:05:14 -07:00
|
|
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
|
|
|
|
symKey := make([]byte, size)
|
|
|
|
|
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return symKey, nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
// DecryptSessionKey returns the decrypted session key from a binary encrypted session key packet.
|
|
|
|
|
func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SymmetricKey, error) {
|
2019-05-15 13:40:19 +02:00
|
|
|
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, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ek := p.(*packet.EncryptedKey)
|
|
|
|
|
var decryptErr error
|
2019-06-03 17:00:01 +02:00
|
|
|
for _, key := range keyRing.entities.DecryptionKeys() {
|
2018-06-04 16:05:14 -07:00
|
|
|
priv := key.PrivateKey
|
|
|
|
|
if priv.Encrypted {
|
2019-06-03 17:00:01 +02:00
|
|
|
continue
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if decryptErr != nil {
|
2019-03-07 14:08:17 +01:00
|
|
|
return nil, decryptErr
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
if ek == nil {
|
|
|
|
|
return nil, errors.New("gopenpgp: unable to decrypt session key")
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
2019-06-03 17:00:01 +02:00
|
|
|
|
|
|
|
|
return newSymmetricKeyFromEncrypted(ek)
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
// EncryptSessionKey encrypts the session key with the unarmored
|
2019-05-15 13:40:19 +02:00
|
|
|
// publicKey and returns a binary public-key encrypted session key packet.
|
2019-06-03 17:00:01 +02:00
|
|
|
func (keyRing *KeyRing) EncryptSessionKey(sessionSplit *SymmetricKey) ([]byte, error) {
|
2018-06-04 16:05:14 -07:00
|
|
|
outbuf := &bytes.Buffer{}
|
|
|
|
|
|
2018-11-05 22:55:45 +01:00
|
|
|
cf := sessionSplit.GetCipherFunc()
|
2018-06-04 16:05:14 -07:00
|
|
|
|
|
|
|
|
var pub *packet.PublicKey
|
2019-06-03 17:00:01 +02:00
|
|
|
for _, e := range keyRing.GetEntities() {
|
2019-05-23 16:36:24 +02:00
|
|
|
if encryptionKey, ok := e.EncryptionKey(pgp.getNow()); ok {
|
|
|
|
|
pub = encryptionKey.PublicKey
|
2018-06-04 16:05:14 -07:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if pub == nil {
|
|
|
|
|
return nil, errors.New("cannot set key: no public key available")
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
if err := packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Key, nil); err != nil {
|
2019-05-15 13:40:19 +02:00
|
|
|
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
2019-05-14 14:42:38 +00:00
|
|
|
return nil, err
|
2018-06-04 16:05:14 -07:00
|
|
|
}
|
|
|
|
|
return outbuf.Bytes(), nil
|
|
|
|
|
}
|