15
type SecureCookie struct {
20
// For testing purposes
27
func NewSecureCookie(hashKey, cipherKey string) *SecureCookie {
30
panic(errors.New("session: invalid hash size"))
33
h.Write([]byte(cipherKey))
34
cipherKeyHash := h.Sum(nil)
35
block, _ := des.NewTripleDESCipher(cipherKeyHash[:24])
40
hashKey: []byte(hashKey),
45
func (sc *SecureCookie) encode(data internalData) error {
49
if b, err = sc.sz.serialize(data); err != nil {
54
if b, err = encrypt(sc.block, b); err != nil {
59
mac := createMac(b, sc.hashKey)
63
if sc.maxLength != 0 && len(b) > sc.maxLength {
64
return EncodedValueTooLong
67
sc.encoded = string(b)
72
func (sc *SecureCookie) decode(value string) (internalData, error) {
77
b, err = decode(value)
82
if err = verifyMac(b, sc.hashKey); err != nil {
87
if b, err = decrypt(sc.block, b); err != nil {
92
data, err = sc.sz.deserialize(b)
97
if !sc.skipExpiration && data.deadline.IsExpired() {
104
func (*SecureCookie) Name() string {
108
func (*SecureCookie) Path() string {
112
func (*SecureCookie) Persist() bool {
116
func (sc *SecureCookie) Value() string {
120
func encode(value []byte) []byte {
121
encoded := make([]byte, base64.URLEncoding.EncodedLen(len(value)))
122
base64.URLEncoding.Encode(encoded, value)
127
func decode(value string) ([]byte, error) {
128
return base64.URLEncoding.DecodeString(value)
131
// createMac creates a message authentication code.
132
func createMac(value, key []byte) []byte {
133
h := hmac.New(hashFunc(), key)
139
func verifyMac(value, key []byte) error {
141
mac := createMac(value[:len(value)-h.Size()], key)
142
if subtle.ConstantTimeCompare(value[len(value)-h.Size():], mac) == 1 {
149
// For testing purposes
150
func (sc *SecureCookie) ignoreExpiration() {
151
sc.skipExpiration = true
154
func encrypt(block cipher.Block, value []byte) ([]byte, error) {
155
iv := make([]byte, block.BlockSize())
156
_, err := rand.Read(iv)
158
return nil, EncryptionError
161
stream := cipher.NewCTR(block, iv)
162
stream.XORKeyStream(value, value)
164
return append(iv, value...), nil
167
func decrypt(block cipher.Block, value []byte) ([]byte, error) {
168
size := block.BlockSize()
169
if len(value) > size {
172
stream := cipher.NewCTR(block, iv)
173
stream.XORKeyStream(value, value)
177
return nil, DecryptionError
180
func hashFunc() func() hash.Hash {