|
@@ -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 (
|
|
|
|
|
|
|
|
|
|
|
|
-func DetachSign(w io.Writer, signer *Entity, message io.Reader) error {
|
|
|
- return detachSign(w, signer, message, packet.SigTypeBinary)
|
|
|
+
|
|
|
+func DetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
|
|
|
+ return detachSign(w, signer, message, packet.SigTypeBinary, config)
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader) (err error) {
|
|
|
- return armoredDetachSign(w, signer, message, packet.SigTypeBinary)
|
|
|
+
|
|
|
+func ArmoredDetachSign(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) (err error) {
|
|
|
+ return armoredDetachSign(w, signer, message, packet.SigTypeBinary, config)
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-func DetachSignText(w io.Writer, signer *Entity, message io.Reader) error {
|
|
|
- return detachSign(w, signer, message, packet.SigTypeText)
|
|
|
+
|
|
|
+func DetachSignText(w io.Writer, signer *Entity, message io.Reader, config *packet.Config) error {
|
|
|
+ return detachSign(w, signer, message, packet.SigTypeText, config)
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-func ArmoredDetachSignText(w io.Writer, signer *Entity, message io.Reader) error {
|
|
|
- return armoredDetachSign(w, signer, message, packet.SigTypeText)
|
|
|
+
|
|
|
+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 {
|
|
|
|
|
|
|
|
|
|
|
|
-func SymmetricallyEncrypt(ciphertext io.Writer, passphrase []byte, hints *FileHints) (plaintext io.WriteCloser, err error) {
|
|
|
+
|
|
|
+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 {
|
|
|
|
|
|
|
|
|
|
|
|
-func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints) (plaintext io.WriteCloser, err error) {
|
|
|
+
|
|
|
+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])
|
|
|
+
|
|
|
+ configuredCipher := config.Cipher()
|
|
|
+ for _, c := range candidateCiphers {
|
|
|
+ cipherFunc := packet.CipherFunction(c)
|
|
|
+ if cipherFunc == configuredCipher {
|
|
|
+ cipher = cipherFunc
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ hashFunc := candidateHashes[0]
|
|
|
+
|
|
|
+ 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 {
|