openpgp: eliminate implicit rand.Reader and time.Now
Fixes golang/go#2501. R=rsc, bradfitz CC=golang-dev https://golang.org/cl/5653067
This commit is contained in:
@@ -17,7 +17,6 @@ import (
|
||||
"io"
|
||||
"net/textproto"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go.crypto/openpgp/armor"
|
||||
"code.google.com/p/go.crypto/openpgp/errors"
|
||||
@@ -179,9 +178,8 @@ type dashEscaper struct {
|
||||
whitespace []byte
|
||||
byteBuf []byte // a one byte buffer to save allocations
|
||||
|
||||
privateKey *packet.PrivateKey
|
||||
signingTime time.Time
|
||||
rand io.Reader
|
||||
privateKey *packet.PrivateKey
|
||||
config *packet.Config
|
||||
}
|
||||
|
||||
func (d *dashEscaper) Write(data []byte) (n int, err error) {
|
||||
@@ -261,10 +259,10 @@ func (d *dashEscaper) Close() (err error) {
|
||||
sig.SigType = packet.SigTypeText
|
||||
sig.PubKeyAlgo = d.privateKey.PubKeyAlgo
|
||||
sig.Hash = d.hashType
|
||||
sig.CreationTime = d.signingTime
|
||||
sig.CreationTime = d.config.Now()
|
||||
sig.IssuerKeyId = &d.privateKey.KeyId
|
||||
|
||||
if err = sig.Sign(d.rand, d.h, d.privateKey); err != nil {
|
||||
if err = sig.Sign(d.h, d.privateKey, d.config); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -334,9 +332,8 @@ func Encode(w io.Writer, privateKey *packet.PrivateKey, config *packet.Config) (
|
||||
|
||||
byteBuf: make([]byte, 1),
|
||||
|
||||
privateKey: privateKey,
|
||||
signingTime: config.Now(),
|
||||
rand: config.Random(),
|
||||
privateKey: privateKey,
|
||||
config: config,
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
+17
-15
@@ -8,11 +8,8 @@ import (
|
||||
"code.google.com/p/go.crypto/openpgp/armor"
|
||||
"code.google.com/p/go.crypto/openpgp/errors"
|
||||
"code.google.com/p/go.crypto/openpgp/packet"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PublicKeyType is the armor type for a PGP public key.
|
||||
@@ -383,16 +380,19 @@ const defaultRSAKeyBits = 2048
|
||||
// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
|
||||
// single identity composed of the given full name, comment and email, any of
|
||||
// which may be empty but must not contain any of "()<>\x00".
|
||||
func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email string) (*Entity, error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
|
||||
currentTime := config.Now()
|
||||
|
||||
uid := packet.NewUserId(name, comment, email)
|
||||
if uid == nil {
|
||||
return nil, errors.InvalidArgumentError("user id field contained invalid characters")
|
||||
}
|
||||
signingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
|
||||
signingPriv, err := rsa.GenerateKey(config.Random(), defaultRSAKeyBits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encryptingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
|
||||
encryptingPriv, err := rsa.GenerateKey(config.Random(), defaultRSAKeyBits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -410,7 +410,7 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
|
||||
CreationTime: currentTime,
|
||||
SigType: packet.SigTypePositiveCert,
|
||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||
Hash: crypto.SHA256,
|
||||
Hash: config.Hash(),
|
||||
IsPrimaryId: &isPrimaryId,
|
||||
FlagsValid: true,
|
||||
FlagSign: true,
|
||||
@@ -427,7 +427,7 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
|
||||
CreationTime: currentTime,
|
||||
SigType: packet.SigTypeSubkeyBinding,
|
||||
PubKeyAlgo: packet.PubKeyAlgoRSA,
|
||||
Hash: crypto.SHA256,
|
||||
Hash: config.Hash(),
|
||||
FlagsValid: true,
|
||||
FlagEncryptStorage: true,
|
||||
FlagEncryptCommunications: true,
|
||||
@@ -443,7 +443,8 @@ func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email strin
|
||||
// SerializePrivate serializes an Entity, including private key material, to
|
||||
// the given Writer. For now, it must only be used on an Entity returned from
|
||||
// NewEntity.
|
||||
func (e *Entity) SerializePrivate(w io.Writer) (err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
|
||||
err = e.PrivateKey.Serialize(w)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -453,7 +454,7 @@ func (e *Entity) SerializePrivate(w io.Writer) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = ident.SelfSignature.SignUserId(rand.Reader, ident.UserId.Id, e.PrimaryKey, e.PrivateKey)
|
||||
err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -467,7 +468,7 @@ func (e *Entity) SerializePrivate(w io.Writer) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = subkey.Sig.SignKey(rand.Reader, subkey.PublicKey, e.PrivateKey)
|
||||
err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -519,7 +520,8 @@ func (e *Entity) Serialize(w io.Writer) error {
|
||||
// associated with e. The provided identity must already be an element of
|
||||
// e.Identities and the private key of signer must have been decrypted if
|
||||
// necessary.
|
||||
func (e *Entity) SignIdentity(identity string, signer *Entity) error {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
|
||||
if signer.PrivateKey == nil {
|
||||
return errors.InvalidArgumentError("signing Entity must have a private key")
|
||||
}
|
||||
@@ -534,11 +536,11 @@ func (e *Entity) SignIdentity(identity string, signer *Entity) error {
|
||||
sig := &packet.Signature{
|
||||
SigType: packet.SigTypeGenericCert,
|
||||
PubKeyAlgo: signer.PrivateKey.PubKeyAlgo,
|
||||
Hash: crypto.SHA256,
|
||||
CreationTime: time.Now(),
|
||||
Hash: config.Hash(),
|
||||
CreationTime: config.Now(),
|
||||
IssuerKeyId: &signer.PrivateKey.KeyId,
|
||||
}
|
||||
if err := sig.SignKey(rand.Reader, e.PrimaryKey, signer.PrivateKey); err != nil {
|
||||
if err := sig.SignKey(e.PrimaryKey, signer.PrivateKey, config); err != nil {
|
||||
return err
|
||||
}
|
||||
ident.Signatures = append(ident.Signatures, sig)
|
||||
|
||||
@@ -7,7 +7,6 @@ package packet
|
||||
import (
|
||||
"code.google.com/p/go.crypto/openpgp/elgamal"
|
||||
"code.google.com/p/go.crypto/openpgp/errors"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
@@ -63,7 +62,8 @@ func checksumKeyMaterial(key []byte) uint16 {
|
||||
|
||||
// Decrypt decrypts an encrypted session key with the given private key. The
|
||||
// private key must have been decrypted first.
|
||||
func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error {
|
||||
var err error
|
||||
var b []byte
|
||||
|
||||
@@ -71,7 +71,7 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
|
||||
// padding oracle attacks.
|
||||
switch priv.PubKeyAlgo {
|
||||
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
|
||||
b, err = rsa.DecryptPKCS1v15(rand.Reader, priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1)
|
||||
b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1)
|
||||
case PubKeyAlgoElGamal:
|
||||
c1 := new(big.Int).SetBytes(e.encryptedMPI1)
|
||||
c2 := new(big.Int).SetBytes(e.encryptedMPI2)
|
||||
@@ -97,7 +97,8 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey) error {
|
||||
|
||||
// SerializeEncryptedKey serializes an encrypted key packet to w that contains
|
||||
// key, encrypted to pub.
|
||||
func SerializeEncryptedKey(w io.Writer, rand io.Reader, pub *PublicKey, cipherFunc CipherFunction, key []byte) error {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error {
|
||||
var buf [10]byte
|
||||
buf[0] = encryptedKeyVersion
|
||||
binary.BigEndian.PutUint64(buf[1:9], pub.KeyId)
|
||||
@@ -112,9 +113,9 @@ func SerializeEncryptedKey(w io.Writer, rand io.Reader, pub *PublicKey, cipherFu
|
||||
|
||||
switch pub.PubKeyAlgo {
|
||||
case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
|
||||
return serializeEncryptedKeyRSA(w, rand, buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
|
||||
return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
|
||||
case PubKeyAlgoElGamal:
|
||||
return serializeEncryptedKeyElGamal(w, rand, buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
|
||||
return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
|
||||
case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
|
||||
return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package packet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@@ -58,7 +57,7 @@ func TestDecryptingEncryptedKey(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = ek.Decrypt(encryptedKeyPriv)
|
||||
err = ek.Decrypt(encryptedKeyPriv, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error from Decrypt: %s", err)
|
||||
return
|
||||
@@ -87,7 +86,7 @@ func TestEncryptingEncryptedKey(t *testing.T) {
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err := SerializeEncryptedKey(buf, rand.Reader, pub, CipherAES128, key)
|
||||
err := SerializeEncryptedKey(buf, pub, CipherAES128, key, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error writing encrypted key packet: %s", err)
|
||||
}
|
||||
@@ -108,7 +107,7 @@ func TestEncryptingEncryptedKey(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = ek.Decrypt(encryptedKeyPriv)
|
||||
err = ek.Decrypt(encryptedKeyPriv, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error from Decrypt: %s", err)
|
||||
return
|
||||
|
||||
@@ -426,7 +426,8 @@ func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
|
||||
// Sign signs a message with a private key. The hash, h, must contain
|
||||
// the hash of the message to be signed and will be mutated by this function.
|
||||
// On success, the signature is stored in sig. Call Serialize to write it out.
|
||||
func (sig *Signature) Sign(rand io.Reader, h hash.Hash, priv *PrivateKey) (err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
|
||||
sig.outSubpackets = sig.buildSubpackets()
|
||||
digest, err := sig.signPrepareHash(h)
|
||||
if err != nil {
|
||||
@@ -435,7 +436,7 @@ func (sig *Signature) Sign(rand io.Reader, h hash.Hash, priv *PrivateKey) (err e
|
||||
|
||||
switch priv.PubKeyAlgo {
|
||||
case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
|
||||
sig.RSASignature.bytes, err = rsa.SignPKCS1v15(rand, priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
|
||||
sig.RSASignature.bytes, err = rsa.SignPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest)
|
||||
sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes))
|
||||
case PubKeyAlgoDSA:
|
||||
dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
|
||||
@@ -445,7 +446,7 @@ func (sig *Signature) Sign(rand io.Reader, h hash.Hash, priv *PrivateKey) (err e
|
||||
if len(digest) > subgroupSize {
|
||||
digest = digest[:subgroupSize]
|
||||
}
|
||||
r, s, err := dsa.Sign(rand, dsaPriv, digest)
|
||||
r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
|
||||
if err == nil {
|
||||
sig.DSASigR.bytes = r.Bytes()
|
||||
sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes))
|
||||
@@ -462,22 +463,24 @@ func (sig *Signature) Sign(rand io.Reader, h hash.Hash, priv *PrivateKey) (err e
|
||||
// SignUserId computes a signature from priv, asserting that pub is a valid
|
||||
// key for the identity id. On success, the signature is stored in sig. Call
|
||||
// Serialize to write it out.
|
||||
func (sig *Signature) SignUserId(rand io.Reader, id string, pub *PublicKey, priv *PrivateKey) error {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
|
||||
h, err := userIdSignatureHash(id, pub, sig)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return sig.Sign(rand, h, priv)
|
||||
return sig.Sign(h, priv, config)
|
||||
}
|
||||
|
||||
// SignKey computes a signature from priv, asserting that pub is a subkey. On
|
||||
// success, the signature is stored in sig. Call Serialize to write it out.
|
||||
func (sig *Signature) SignKey(rand io.Reader, pub *PublicKey, priv *PrivateKey) error {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
|
||||
h, err := keySignatureHash(&priv.PublicKey, pub, sig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sig.Sign(rand, h, priv)
|
||||
return sig.Sign(h, priv, config)
|
||||
}
|
||||
|
||||
// Serialize marshals sig to w. SignRSA or SignDSA must have been called first.
|
||||
|
||||
@@ -107,7 +107,9 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) error {
|
||||
// packet contains a random session key, encrypted by a key derived from the
|
||||
// given passphrase. The session key is returned and must be passed to
|
||||
// SerializeSymmetricallyEncrypted.
|
||||
func SerializeSymmetricKeyEncrypted(w io.Writer, rand io.Reader, passphrase []byte, cipherFunc CipherFunction) (key []byte, err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) {
|
||||
cipherFunc := config.Cipher()
|
||||
keySize := cipherFunc.KeySize()
|
||||
if keySize == 0 {
|
||||
return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc)))
|
||||
@@ -117,7 +119,7 @@ func SerializeSymmetricKeyEncrypted(w io.Writer, rand io.Reader, passphrase []by
|
||||
keyEncryptingKey := make([]byte, keySize)
|
||||
// s2k.Serialize salts and stretches the passphrase, and writes the
|
||||
// resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf.
|
||||
err = s2k.Serialize(s2kBuf, keyEncryptingKey, rand, passphrase)
|
||||
err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -142,7 +144,7 @@ func SerializeSymmetricKeyEncrypted(w io.Writer, rand io.Reader, passphrase []by
|
||||
}
|
||||
|
||||
sessionKey := make([]byte, keySize)
|
||||
_, err = io.ReadFull(rand, sessionKey)
|
||||
_, err = io.ReadFull(config.Random(), sessionKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package packet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -65,9 +64,11 @@ const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a"
|
||||
func TestSerializeSymmetricKeyEncrypted(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
passphrase := []byte("testing")
|
||||
cipherFunc := CipherAES128
|
||||
config := &Config{
|
||||
DefaultCipher: CipherAES128,
|
||||
}
|
||||
|
||||
key, err := SerializeSymmetricKeyEncrypted(buf, rand.Reader, passphrase, cipherFunc)
|
||||
key, err := SerializeSymmetricKeyEncrypted(buf, passphrase, config)
|
||||
if err != nil {
|
||||
t.Errorf("failed to serialize: %s", err)
|
||||
return
|
||||
@@ -87,8 +88,8 @@ func TestSerializeSymmetricKeyEncrypted(t *testing.T) {
|
||||
if !ske.Encrypted {
|
||||
t.Errorf("SKE not encrypted but should be")
|
||||
}
|
||||
if ske.CipherFunc != cipherFunc {
|
||||
t.Errorf("SKE cipher function is %d (expected %d)", ske.CipherFunc, cipherFunc)
|
||||
if ske.CipherFunc != config.DefaultCipher {
|
||||
t.Errorf("SKE cipher function is %d (expected %d)", ske.CipherFunc, config.DefaultCipher)
|
||||
}
|
||||
err = ske.Decrypt(passphrase)
|
||||
if err != nil {
|
||||
|
||||
@@ -252,7 +252,8 @@ func (c noOpCloser) Close() error {
|
||||
// SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet
|
||||
// to w and returns a WriteCloser to which the to-be-encrypted packets can be
|
||||
// written.
|
||||
func SerializeSymmetricallyEncrypted(w io.Writer, rand io.Reader, c CipherFunction, key []byte) (contents io.WriteCloser, err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) {
|
||||
if c.KeySize() != len(key) {
|
||||
return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
|
||||
}
|
||||
@@ -270,7 +271,7 @@ func SerializeSymmetricallyEncrypted(w io.Writer, rand io.Reader, c CipherFuncti
|
||||
block := c.new(key)
|
||||
blockSize := block.BlockSize()
|
||||
iv := make([]byte, blockSize)
|
||||
_, err = rand.Read(iv)
|
||||
_, err = config.Random().Read(iv)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ package packet
|
||||
import (
|
||||
"bytes"
|
||||
"code.google.com/p/go.crypto/openpgp/errors"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
@@ -83,7 +82,7 @@ func TestSerialize(t *testing.T) {
|
||||
c := CipherAES128
|
||||
key := make([]byte, c.KeySize())
|
||||
|
||||
w, err := SerializeSymmetricallyEncrypted(buf, rand.Reader, c, key)
|
||||
w, err := SerializeSymmetricallyEncrypted(buf, c, key, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error from SerializeSymmetricallyEncrypted: %s", err)
|
||||
return
|
||||
|
||||
+3
-2
@@ -80,7 +80,8 @@ type keyEnvelopePair struct {
|
||||
// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
|
||||
// The given KeyRing should contain both public keys (for signature
|
||||
// verification) and, possibly encrypted, private keys for decrypting.
|
||||
func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction) (md *MessageDetails, err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
|
||||
var p packet.Packet
|
||||
|
||||
var symKeys []*packet.SymmetricKeyEncrypted
|
||||
@@ -155,7 +156,7 @@ FindKey:
|
||||
}
|
||||
if !pk.key.PrivateKey.Encrypted {
|
||||
if len(pk.encryptedKey.Key) == 0 {
|
||||
pk.encryptedKey.Decrypt(pk.key.PrivateKey)
|
||||
pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
|
||||
}
|
||||
if len(pk.encryptedKey.Key) == 0 {
|
||||
continue
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestGetKeyById(t *testing.T) {
|
||||
func checkSignedMessage(t *testing.T, signedHex, expected string) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(testKeys1And2Hex))
|
||||
|
||||
md, err := ReadMessage(readerFromHex(signedHex), kring, nil)
|
||||
md, err := ReadMessage(readerFromHex(signedHex), kring, nil, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
@@ -178,7 +178,7 @@ func TestSignedEncryptedMessage(t *testing.T) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
md, err := ReadMessage(readerFromHex(test.messageHex), kring, prompt)
|
||||
md, err := ReadMessage(readerFromHex(test.messageHex), kring, prompt, nil)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: error reading message: %s", i, err)
|
||||
return
|
||||
@@ -206,7 +206,7 @@ func TestUnspecifiedRecipient(t *testing.T) {
|
||||
expected := "Recipient unspecified\n"
|
||||
kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
|
||||
|
||||
md, err := ReadMessage(readerFromHex(recipientUnspecifiedHex), kring, nil)
|
||||
md, err := ReadMessage(readerFromHex(recipientUnspecifiedHex), kring, nil, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error reading message: %s", err)
|
||||
return
|
||||
@@ -236,7 +236,7 @@ func TestSymmetricallyEncrypted(t *testing.T) {
|
||||
return []byte("password"), nil
|
||||
}
|
||||
|
||||
md, err := ReadMessage(readerFromHex(symmetricallyEncryptedCompressedHex), nil, prompt)
|
||||
md, err := ReadMessage(readerFromHex(symmetricallyEncryptedCompressedHex), nil, prompt, nil)
|
||||
if err != nil {
|
||||
t.Errorf("ReadMessage: %s", err)
|
||||
return
|
||||
|
||||
+52
-27
@@ -10,8 +10,6 @@ import (
|
||||
"code.google.com/p/go.crypto/openpgp/packet"
|
||||
"code.google.com/p/go.crypto/openpgp/s2k"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
_ "crypto/sha256"
|
||||
"hash"
|
||||
"io"
|
||||
"strconv"
|
||||
@@ -20,43 +18,47 @@ import (
|
||||
|
||||
// DetachSign signs message with the private key from signer (which must
|
||||
// already have been decrypted) and writes the signature to w.
|
||||
func DetachSign(w io.Writer, signer *Entity, message io.Reader) error {
|
||||
return detachSign(w, signer, message, packet.SigTypeBinary)
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
|
||||
return detachSign(w, signer, message, packet.SigTypeBinary, config)
|
||||
}
|
||||
|
||||
// ArmoredDetachSign signs message with the private key from signer (which
|
||||
// must already have been decrypted) and writes an armored signature to w.
|
||||
func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader) (err error) {
|
||||
return armoredDetachSign(w, signer, message, packet.SigTypeBinary)
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
|
||||
return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
|
||||
}
|
||||
|
||||
// DetachSignText signs message (after canonicalising the line endings) with
|
||||
// the private key from signer (which must already have been decrypted) and
|
||||
// writes the signature to w.
|
||||
func DetachSignText(w io.Writer, signer *Entity, message io.Reader) error {
|
||||
return detachSign(w, signer, message, packet.SigTypeText)
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
|
||||
return detachSign(w, signer, message, packet.SigTypeText, config)
|
||||
}
|
||||
|
||||
// ArmoredDetachSignText signs message (after canonicalising the line endings)
|
||||
// with the private key from signer (which must already have been decrypted)
|
||||
// and writes an armored signature to w.
|
||||
func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader) error {
|
||||
return armoredDetachSign(w, signer, message, packet.SigTypeText)
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
|
||||
return armoredDetachSign(w, signer, message, packet.SigTypeText, config)
|
||||
}
|
||||
|
||||
func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType) (err error) {
|
||||
func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
|
||||
out, err := armor.Encode(w, SignatureType, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = detachSign(out, signer, message, sigType)
|
||||
err = detachSign(out, signer, message, sigType, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType) (err error) {
|
||||
func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) {
|
||||
if signer.PrivateKey == nil {
|
||||
return errors.InvalidArgumentError("signing key doesn't have a private key")
|
||||
}
|
||||
@@ -67,8 +69,8 @@ func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.S
|
||||
sig := new(packet.Signature)
|
||||
sig.SigType = sigType
|
||||
sig.PubKeyAlgo = signer.PrivateKey.PubKeyAlgo
|
||||
sig.Hash = crypto.SHA256
|
||||
sig.CreationTime = time.Now()
|
||||
sig.Hash = config.Hash()
|
||||
sig.CreationTime = config.Now()
|
||||
sig.IssuerKeyId = &signer.PrivateKey.KeyId
|
||||
|
||||
h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
|
||||
@@ -77,7 +79,7 @@ func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.S
|
||||
}
|
||||
io.Copy(wrappedHash, message)
|
||||
|
||||
err = sig.Sign(rand.Reader, h, signer.PrivateKey)
|
||||
err = sig.Sign(h, signer.PrivateKey, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -102,16 +104,17 @@ type FileHints struct {
|
||||
// SymmetricallyEncrypt acts like gpg -c: it encrypts a file with a passphrase.
|
||||
// The resulting WriteCloser must be closed after the contents of the file have
|
||||
// been written.
|
||||
func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints) (plaintext io.WriteCloser, err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
|
||||
if hints == nil {
|
||||
hints = &FileHints{}
|
||||
}
|
||||
|
||||
key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, rand.Reader, passphrase, packet.CipherAES128)
|
||||
key, err := packet.SerializeSymmetricKeyEncrypted(ciphertext, passphrase, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, rand.Reader, packet.CipherAES128, key)
|
||||
w, err := packet.SerializeSymmetricallyEncrypted(ciphertext, config.Cipher(), key, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -151,7 +154,8 @@ func hashToHashId(h crypto.Hash) uint8 {
|
||||
// it. hints contains optional information, that is also encrypted, that aids
|
||||
// the recipients in processing the message. The resulting WriteCloser must
|
||||
// be closed after the contents of the file have been written.
|
||||
func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints) (plaintext io.WriteCloser, err error) {
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) {
|
||||
var signer *packet.PrivateKey
|
||||
if signed != nil {
|
||||
signer = signed.signingKey().PrivateKey
|
||||
@@ -205,19 +209,39 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
|
||||
}
|
||||
|
||||
cipher := packet.CipherFunction(candidateCiphers[0])
|
||||
hash, _ := s2k.HashIdToHash(candidateHashes[0])
|
||||
// If the cipher specifed by config is a candidate, we'll use that.
|
||||
configuredCipher := config.Cipher()
|
||||
for _, c := range candidateCiphers {
|
||||
cipherFunc := packet.CipherFunction(c)
|
||||
if cipherFunc == configuredCipher {
|
||||
cipher = cipherFunc
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
hashFunc := candidateHashes[0]
|
||||
// If the hash specified by config is a candidate, we'll use that.
|
||||
configuredHash := config.Hash()
|
||||
for _, h := range candidateHashes {
|
||||
if h == uint8(configuredHash) {
|
||||
hashFunc = h
|
||||
break
|
||||
}
|
||||
}
|
||||
hash, _ := s2k.HashIdToHash(hashFunc)
|
||||
|
||||
symKey := make([]byte, cipher.KeySize())
|
||||
if _, err := io.ReadFull(rand.Reader, symKey); err != nil {
|
||||
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, key := range encryptKeys {
|
||||
if err := packet.SerializeEncryptedKey(ciphertext, rand.Reader, key.PublicKey, cipher, symKey); err != nil {
|
||||
if err := packet.SerializeEncryptedKey(ciphertext, key.PublicKey, cipher, symKey, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, rand.Reader, cipher, symKey)
|
||||
encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -257,7 +281,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint
|
||||
}
|
||||
|
||||
if signer != nil {
|
||||
return signatureWriter{encryptedData, literalData, hash, hash.New(), signer}, nil
|
||||
return signatureWriter{encryptedData, literalData, hash, hash.New(), signer, config}, nil
|
||||
}
|
||||
return literalData, nil
|
||||
}
|
||||
@@ -271,6 +295,7 @@ type signatureWriter struct {
|
||||
hashType crypto.Hash
|
||||
h hash.Hash
|
||||
signer *packet.PrivateKey
|
||||
config *packet.Config
|
||||
}
|
||||
|
||||
func (s signatureWriter) Write(data []byte) (int, error) {
|
||||
@@ -283,11 +308,11 @@ func (s signatureWriter) Close() error {
|
||||
SigType: packet.SigTypeBinary,
|
||||
PubKeyAlgo: s.signer.PubKeyAlgo,
|
||||
Hash: s.hashType,
|
||||
CreationTime: time.Now(),
|
||||
CreationTime: s.config.Now(),
|
||||
IssuerKeyId: &s.signer.KeyId,
|
||||
}
|
||||
|
||||
if err := sig.Sign(rand.Reader, s.h, s.signer); err != nil {
|
||||
if err := sig.Sign(s.h, s.signer, s.config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.literalData.Close(); err != nil {
|
||||
|
||||
+10
-12
@@ -6,18 +6,16 @@ package openpgp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSignDetached(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
|
||||
out := bytes.NewBuffer(nil)
|
||||
message := bytes.NewBufferString(signedInput)
|
||||
err := DetachSign(out, kring[0], message)
|
||||
err := DetachSign(out, kring[0], message, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -29,7 +27,7 @@ func TestSignTextDetached(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
|
||||
out := bytes.NewBuffer(nil)
|
||||
message := bytes.NewBufferString(signedInput)
|
||||
err := DetachSignText(out, kring[0], message)
|
||||
err := DetachSignText(out, kring[0], message, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -41,7 +39,7 @@ func TestSignDetachedDSA(t *testing.T) {
|
||||
kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyPrivateHex))
|
||||
out := bytes.NewBuffer(nil)
|
||||
message := bytes.NewBufferString(signedInput)
|
||||
err := DetachSign(out, kring[0], message)
|
||||
err := DetachSign(out, kring[0], message, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -54,14 +52,14 @@ func TestNewEntity(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
e, err := NewEntity(rand.Reader, time.Now(), "Test User", "test", "test@example.com")
|
||||
e, err := NewEntity("Test User", "test", "test@example.com", nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create entity: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
w := bytes.NewBuffer(nil)
|
||||
if err := e.SerializePrivate(w); err != nil {
|
||||
if err := e.SerializePrivate(w, nil); err != nil {
|
||||
t.Errorf("failed to serialize entity: %s", err)
|
||||
return
|
||||
}
|
||||
@@ -78,7 +76,7 @@ func TestNewEntity(t *testing.T) {
|
||||
}
|
||||
|
||||
w = bytes.NewBuffer(nil)
|
||||
if err := e.SerializePrivate(w); err != nil {
|
||||
if err := e.SerializePrivate(w, nil); err != nil {
|
||||
t.Errorf("failed to serialize entity second time: %s", err)
|
||||
return
|
||||
}
|
||||
@@ -90,7 +88,7 @@ func TestNewEntity(t *testing.T) {
|
||||
|
||||
func TestSymmetricEncryption(t *testing.T) {
|
||||
buf := new(bytes.Buffer)
|
||||
plaintext, err := SymmetricallyEncrypt(buf, []byte("testing"), nil)
|
||||
plaintext, err := SymmetricallyEncrypt(buf, []byte("testing"), nil, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error writing headers: %s", err)
|
||||
return
|
||||
@@ -107,7 +105,7 @@ func TestSymmetricEncryption(t *testing.T) {
|
||||
|
||||
md, err := ReadMessage(buf, nil, func(keys []Key, symmetric bool) ([]byte, error) {
|
||||
return []byte("testing"), nil
|
||||
})
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Errorf("error rereading message: %s", err)
|
||||
}
|
||||
@@ -171,7 +169,7 @@ func TestEncryption(t *testing.T) {
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
w, err := Encrypt(buf, kring[:1], signed, nil /* no hints */ )
|
||||
w, err := Encrypt(buf, kring[:1], signed, nil, /* no hints */ nil)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: error in Encrypt: %s", i, err)
|
||||
continue
|
||||
@@ -189,7 +187,7 @@ func TestEncryption(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
md, err := ReadMessage(buf, kring, nil /* no prompt */ )
|
||||
md, err := ReadMessage(buf, kring, nil, /* no prompt */ nil)
|
||||
if err != nil {
|
||||
t.Errorf("#%d: error reading message: %s", i, err)
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user