summaryrefslogtreecommitdiff
path: root/src/pkg/crypto/openpgp/s2k
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/crypto/openpgp/s2k')
-rw-r--r--src/pkg/crypto/openpgp/s2k/s2k.go22
-rw-r--r--src/pkg/crypto/openpgp/s2k/s2k_test.go24
2 files changed, 45 insertions, 1 deletions
diff --git a/src/pkg/crypto/openpgp/s2k/s2k.go b/src/pkg/crypto/openpgp/s2k/s2k.go
index 93b7582fa..da926a76e 100644
--- a/src/pkg/crypto/openpgp/s2k/s2k.go
+++ b/src/pkg/crypto/openpgp/s2k/s2k.go
@@ -90,7 +90,7 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) {
}
h := hash.New()
if h == nil {
- return nil, error.UnsupportedError("hash not availible: " + strconv.Itoa(int(hash)))
+ return nil, error.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
}
switch buf[0] {
@@ -123,6 +123,26 @@ func Parse(r io.Reader) (f func(out, in []byte), err os.Error) {
return nil, error.UnsupportedError("S2K function")
}
+// Serialize salts and stretches the given passphrase and writes the resulting
+// key into key. It also serializes an S2K descriptor to w.
+func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte) os.Error {
+ var buf [11]byte
+ buf[0] = 3 /* iterated and salted */
+ buf[1], _ = HashToHashId(crypto.SHA1)
+ salt := buf[2:10]
+ if _, err := io.ReadFull(rand, salt); err != nil {
+ return err
+ }
+ const count = 65536 // this is the default in gpg
+ buf[10] = 96 // 65536 iterations
+ if _, err := w.Write(buf[:]); err != nil {
+ return err
+ }
+
+ Iterated(key, crypto.SHA1.New(), passphrase, salt, count)
+ return nil
+}
+
// hashToHashIdMapping contains pairs relating OpenPGP's hash identifier with
// Go's crypto.Hash type. See RFC 4880, section 9.4.
var hashToHashIdMapping = []struct {
diff --git a/src/pkg/crypto/openpgp/s2k/s2k_test.go b/src/pkg/crypto/openpgp/s2k/s2k_test.go
index 75bc47ec1..27d2e9ae0 100644
--- a/src/pkg/crypto/openpgp/s2k/s2k_test.go
+++ b/src/pkg/crypto/openpgp/s2k/s2k_test.go
@@ -7,6 +7,7 @@ package s2k
import (
"bytes"
"crypto/sha1"
+ "crypto/rand"
"encoding/hex"
"testing"
)
@@ -95,3 +96,26 @@ func TestParse(t *testing.T) {
}
}
}
+
+
+func TestSerialize(t *testing.T) {
+ buf := bytes.NewBuffer(nil)
+ key := make([]byte, 16)
+ passphrase := []byte("testing")
+ err := Serialize(buf, key, rand.Reader, passphrase)
+ if err != nil {
+ t.Errorf("failed to serialize: %s", err)
+ return
+ }
+
+ f, err := Parse(buf)
+ if err != nil {
+ t.Errorf("failed to reparse: %s", err)
+ return
+ }
+ key2 := make([]byte, len(key))
+ f(key2, passphrase)
+ if !bytes.Equal(key2, key) {
+ t.Errorf("keys don't match: %x (serialied) vs %x (parsed)", key, key2)
+ }
+}