~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/gopkg.in/macaroon.v1/crypto.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package macaroon
 
2
 
 
3
import (
 
4
        "crypto/hmac"
 
5
        "crypto/sha256"
 
6
        "fmt"
 
7
        "hash"
 
8
        "io"
 
9
 
 
10
        "golang.org/x/crypto/nacl/secretbox"
 
11
)
 
12
 
 
13
func keyedHash(key *[hashLen]byte, text []byte) *[hashLen]byte {
 
14
        h := keyedHasher(key)
 
15
        h.Write([]byte(text))
 
16
        var sum [hashLen]byte
 
17
        hashSum(h, &sum)
 
18
        return &sum
 
19
}
 
20
 
 
21
func keyedHasher(key *[hashLen]byte) hash.Hash {
 
22
        return hmac.New(sha256.New, key[:])
 
23
}
 
24
 
 
25
var keyGen = []byte("macaroons-key-generator")
 
26
 
 
27
// makeKey derives a fixed length key from a variable
 
28
// length key. The keyGen constant is the same
 
29
// as that used in libmacaroons.
 
30
func makeKey(variableKey []byte) *[keyLen]byte {
 
31
        h := hmac.New(sha256.New, keyGen)
 
32
        h.Write(variableKey)
 
33
        var key [keyLen]byte
 
34
        hashSum(h, &key)
 
35
        return &key
 
36
}
 
37
 
 
38
// hashSum calls h.Sum to put the sum into
 
39
// the given destination. It also sanity
 
40
// checks that the result really is the expected
 
41
// size.
 
42
func hashSum(h hash.Hash, dest *[hashLen]byte) {
 
43
        r := h.Sum(dest[:0])
 
44
        if len(r) != len(dest) {
 
45
                panic("hash size inconsistency")
 
46
        }
 
47
}
 
48
 
 
49
const (
 
50
        keyLen   = 32
 
51
        nonceLen = 24
 
52
        hashLen  = sha256.Size
 
53
)
 
54
 
 
55
func newNonce(r io.Reader) (*[nonceLen]byte, error) {
 
56
        var nonce [nonceLen]byte
 
57
        _, err := r.Read(nonce[:])
 
58
        if err != nil {
 
59
                return nil, fmt.Errorf("cannot generate random bytes: %v", err)
 
60
        }
 
61
        return &nonce, nil
 
62
}
 
63
 
 
64
func encrypt(key *[keyLen]byte, text *[hashLen]byte, r io.Reader) ([]byte, error) {
 
65
        nonce, err := newNonce(r)
 
66
        if err != nil {
 
67
                return nil, err
 
68
        }
 
69
        out := make([]byte, 0, len(nonce)+secretbox.Overhead+len(text))
 
70
        out = append(out, nonce[:]...)
 
71
        return secretbox.Seal(out, text[:], nonce, key), nil
 
72
}
 
73
 
 
74
func decrypt(key *[keyLen]byte, ciphertext []byte) (*[hashLen]byte, error) {
 
75
        if len(ciphertext) < nonceLen+secretbox.Overhead {
 
76
                return nil, fmt.Errorf("message too short")
 
77
        }
 
78
        var nonce [nonceLen]byte
 
79
        copy(nonce[:], ciphertext)
 
80
        ciphertext = ciphertext[nonceLen:]
 
81
        text, ok := secretbox.Open(nil, ciphertext, &nonce, key)
 
82
        if !ok {
 
83
                return nil, fmt.Errorf("decryption failure")
 
84
        }
 
85
        if len(text) != hashLen {
 
86
                return nil, fmt.Errorf("decrypted text is wrong length")
 
87
        }
 
88
        var rtext [hashLen]byte
 
89
        copy(rtext[:], text)
 
90
        return &rtext, nil
 
91
}