aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/key.go10
-rw-r--r--crypto/rand.go32
2 files changed, 42 insertions, 0 deletions
diff --git a/crypto/key.go b/crypto/key.go
index 2220652..77adc95 100644
--- a/crypto/key.go
+++ b/crypto/key.go
@@ -195,6 +195,16 @@ func (key *Key) UnsafeToCString() unsafe.Pointer {
return data
}
+// Clone creates a key as a copy of another one.
+func (key *Key) Clone() (*Key, error) {
+ newKey, err := NewBlankKey(key.Len())
+ if err != nil {
+ return nil, err
+ }
+ copy(newKey.data, key.data)
+ return newKey, nil
+}
+
// NewKeyFromCString creates of a copy of some C string's data in a key. Note
// that the original C string is not modified at all, so steps must be taken to
// ensure that this original copy is secured.
diff --git a/crypto/rand.go b/crypto/rand.go
index 736d969..4d8c044 100644
--- a/crypto/rand.go
+++ b/crypto/rand.go
@@ -49,6 +49,38 @@ func NewRandomKey(length int) (*Key, error) {
return NewFixedLengthKeyFromReader(randReader{}, length)
}
+// NewRandomPassphrase creates a random passphrase of the specified length
+// containing random alphabetic characters.
+func NewRandomPassphrase(length int) (*Key, error) {
+ chars := []byte("abcdefghijklmnopqrstuvwxyz")
+ passphrase, err := NewBlankKey(length)
+ if err != nil {
+ return nil, err
+ }
+ for i := 0; i < length; {
+ // Get some random bytes.
+ raw, err := NewRandomKey((length - i) * 2)
+ if err != nil {
+ return nil, err
+ }
+ // Translate the random bytes into random characters.
+ for _, b := range raw.data {
+ if int(b) >= 256-(256%len(chars)) {
+ // Avoid bias towards the first characters in the list.
+ continue
+ }
+ c := chars[int(b)%len(chars)]
+ passphrase.data[i] = c
+ i++
+ if i == length {
+ break
+ }
+ }
+ raw.Wipe()
+ }
+ return passphrase, nil
+}
+
// randReader just calls into Getrandom, so no internal data is needed.
type randReader struct{}