...
1 package handlers
2
3 import (
4 "crypto/hmac"
5 "crypto/sha256"
6 "encoding/base64"
7 "encoding/json"
8 "fmt"
9 "time"
10 )
11
12
13 type blobUploadState struct {
14
15 Name string
16
17
18 UUID string
19
20
21 Offset int64
22
23
24 StartedAt time.Time
25 }
26
27 type hmacKey string
28
29 var errInvalidSecret = fmt.Errorf("invalid secret")
30
31
32
33 func (secret hmacKey) unpackUploadState(token string) (blobUploadState, error) {
34 var state blobUploadState
35
36 tokenBytes, err := base64.URLEncoding.DecodeString(token)
37 if err != nil {
38 return state, err
39 }
40 mac := hmac.New(sha256.New, []byte(secret))
41
42 if len(tokenBytes) < mac.Size() {
43 return state, errInvalidSecret
44 }
45
46 macBytes := tokenBytes[:mac.Size()]
47 messageBytes := tokenBytes[mac.Size():]
48
49 mac.Write(messageBytes)
50 if !hmac.Equal(mac.Sum(nil), macBytes) {
51 return state, errInvalidSecret
52 }
53
54 if err := json.Unmarshal(messageBytes, &state); err != nil {
55 return state, err
56 }
57
58 return state, nil
59 }
60
61
62
63
64 func (secret hmacKey) packUploadState(lus blobUploadState) (string, error) {
65 mac := hmac.New(sha256.New, []byte(secret))
66 p, err := json.Marshal(lus)
67 if err != nil {
68 return "", err
69 }
70
71 mac.Write(p)
72
73 return base64.URLEncoding.EncodeToString(append(mac.Sum(nil), p...)), nil
74 }
75
View as plain text