-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtransit.go
130 lines (107 loc) · 3.9 KB
/
transit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2021 Outreach Corporation. All Rights Reserved.
// Description: Stores functions to interact with basic /transit endpoints
package vault_client //nolint:revive // Why: We're using - in the name
import (
"context"
"encoding/base64"
"fmt"
"net/http"
"github.com/pkg/errors"
)
// transitEncryptPath returns the path for vault transit encryption using the passed in key
// name.
func (*Client) transitEncryptPath(key string) string {
return fmt.Sprintf("transit/encrypt/%s", key)
}
// transitEncryptPayload is the request body for the path that TransitEncrypt invokes.
type transitEncryptPayload struct {
Plaintext string `json:"plaintext"`
}
// transitEncryptResponse is the response body for the path that TransitEncrypt invokes.
type transitEncryptResponse struct {
Data struct {
Ciphertext string `json:"ciphertext"`
} `json:"data"`
}
// TransitEncrypt takes plaintext data to be encrypted and returns the corresponding
// ciphertext.
func (c *Client) TransitEncrypt(ctx context.Context, key string, in []byte) ([]byte, error) {
payload := transitEncryptPayload{
Plaintext: base64.StdEncoding.EncodeToString(in),
}
var resp transitEncryptResponse
if err := c.doRequest(ctx, http.MethodPost, c.transitEncryptPath(key), payload, &resp); err != nil {
return nil, errors.Wrap(err, "do vault encryption")
}
return []byte(resp.Data.Ciphertext), nil
}
// transitDecryptPath returns the path for vault transit decryption using the passed in key
// name.
func (*Client) transitDecryptPath(key string) string {
return fmt.Sprintf("transit/decrypt/%s", key)
}
// transitDecryptPayload is the request body for the path that TransitDecrypt invokes.
type transitDecryptPayload struct {
Ciphertext string `json:"ciphertext"`
}
// transitDecryptResponse is the response body for the path that TransitDecrypt invokes.
type transitDecryptResponse struct {
Data struct {
Plaintext string `json:"plaintext"`
} `json:"data"`
}
// TransitDecrypt takes ciphertext data to be decrypted and returns the corresponding
// plaintext.
func (c *Client) TransitDecrypt(ctx context.Context, key string, in []byte) ([]byte, error) {
payload := transitDecryptPayload{
Ciphertext: string(in),
}
var resp transitDecryptResponse
if err := c.doRequest(ctx, http.MethodPost, c.transitDecryptPath(key), payload, &resp); err != nil {
return nil, errors.Wrap(err, "do vault encryption")
}
out, err := base64.StdEncoding.DecodeString(resp.Data.Plaintext)
if err != nil {
return nil, errors.Wrap(err, "base64 decode plaintext")
}
return out, nil
}
// transitBatchDecryptPayload is the request body for the path that TransitBatchDecrypt invokes.
type transitBatchDecryptPayload struct {
BatchInput []struct {
Ciphertext string `json:"ciphertext"`
} `json:"batch_input"`
}
// transitBatchDecryptResponse is the response body for the path that TransitDecrypt invokes.
type transitBatchDecryptResponse struct {
Data struct {
BatchResults []struct {
Plaintext string `json:"plaintext"`
} `json:"batch_results"`
} `json:"data"`
}
// TransitBatchDecrypt takes in an array of cyphertext data to be decrypted and returns the corresponding
// array of plaintext
func (c *Client) TransitBatchDecrypt(ctx context.Context, key string, in []string) ([][]byte, error) {
var payload transitBatchDecryptPayload
for _, v := range in {
payload.BatchInput = append(payload.BatchInput, struct {
Ciphertext string `json:"ciphertext"`
}{
Ciphertext: v,
})
}
var resp transitBatchDecryptResponse
if err := c.doRequest(ctx, http.MethodPost, c.transitDecryptPath(key), payload, &resp); err != nil {
return nil, errors.Wrap(err, "do vault decryption")
}
out := make([][]byte, 0, len(resp.Data.BatchResults))
for _, result := range resp.Data.BatchResults {
decoded, err := base64.StdEncoding.DecodeString(result.Plaintext)
if err != nil {
return nil, errors.Wrap(err, "base64 decode plaintext")
}
out = append(out, decoded)
}
return out, nil
}