|
1 | 1 | package vcs
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "crypto/aes" |
| 5 | + "crypto/cipher" |
| 6 | + "crypto/rand" |
4 | 7 | "encoding/base64"
|
5 | 8 | "encoding/json"
|
6 | 9 | "errors"
|
| 10 | + "io" |
7 | 11 |
|
8 |
| - "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption" |
9 | 12 | "golang.org/x/oauth2"
|
10 | 13 | )
|
11 | 14 |
|
12 |
| -const gcmNonceSize = 12 |
13 |
| - |
14 | 15 | func encryptToken(token *oauth2.Token, key []byte) (string, error) {
|
15 |
| - cipher, err := encryption.NewGCMCipher(key) |
| 16 | + plaintext, err := json.Marshal(token) |
16 | 17 | if err != nil {
|
17 | 18 | return "", err
|
18 | 19 | }
|
19 |
| - textBytes, err := json.Marshal(token) |
| 20 | + |
| 21 | + block, err := aes.NewCipher(key) |
20 | 22 | if err != nil {
|
21 | 23 | return "", err
|
22 | 24 | }
|
23 |
| - enc, err := cipher.Encrypt(textBytes) |
| 25 | + |
| 26 | + gcm, err := cipher.NewGCM(block) |
24 | 27 | if err != nil {
|
25 | 28 | return "", err
|
26 | 29 | }
|
27 |
| - return base64.StdEncoding.EncodeToString(enc), nil |
| 30 | + |
| 31 | + nonce := make([]byte, gcm.NonceSize()) |
| 32 | + if _, err = io.ReadFull(rand.Reader, nonce); err != nil { |
| 33 | + return "", err |
| 34 | + } |
| 35 | + |
| 36 | + // Using nonce as Seal's dst argument results in it being the first |
| 37 | + // chunk of bytes in the ciphertext. Decrypt retrieves the nonce/IV from this. |
| 38 | + ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) |
| 39 | + |
| 40 | + return base64.StdEncoding.EncodeToString(ciphertext), nil |
28 | 41 | }
|
29 | 42 |
|
30 |
| -func decryptToken(encodedText string, key []byte) (*oauth2.Token, error) { |
31 |
| - encryptedData, err := base64.StdEncoding.DecodeString(encodedText) |
| 43 | +func decryptToken(ciphertextBase64 string, key []byte) (*oauth2.Token, error) { |
| 44 | + ciphertext, err := base64.StdEncoding.DecodeString(ciphertextBase64) |
32 | 45 | if err != nil {
|
33 | 46 | return nil, err
|
34 | 47 | }
|
35 | 48 |
|
36 |
| - if len(encryptedData) < gcmNonceSize { |
37 |
| - return nil, errors.New("malformed token") |
| 49 | + block, err := aes.NewCipher(key) |
| 50 | + if err != nil { |
| 51 | + return nil, err |
38 | 52 | }
|
39 | 53 |
|
40 |
| - cipher, err := encryption.NewGCMCipher(key) |
| 54 | + gcm, err := cipher.NewGCM(block) |
41 | 55 | if err != nil {
|
42 | 56 | return nil, err
|
43 | 57 | }
|
44 | 58 |
|
45 |
| - plaintext, err := cipher.Decrypt(encryptedData) |
| 59 | + nonceSize := gcm.NonceSize() |
| 60 | + if len(ciphertext) < nonceSize { |
| 61 | + return nil, errors.New("malformed token") |
| 62 | + } |
| 63 | + nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] |
| 64 | + |
| 65 | + plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) |
46 | 66 | if err != nil {
|
47 | 67 | return nil, err
|
48 | 68 | }
|
49 | 69 |
|
50 | 70 | var token oauth2.Token
|
51 |
| - err = json.Unmarshal(plaintext, &token) |
52 |
| - return &token, err |
| 71 | + if err = json.Unmarshal(plaintext, &token); err != nil { |
| 72 | + return nil, err |
| 73 | + } |
| 74 | + |
| 75 | + return &token, nil |
53 | 76 | }
|
0 commit comments