-
Notifications
You must be signed in to change notification settings - Fork 10
/
path_encrypt.go
129 lines (109 loc) · 3.7 KB
/
path_encrypt.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
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package gcpkms
import (
"context"
"encoding/base64"
"fmt"
"path"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)
func (b *backend) pathEncrypt() *framework.Path {
return &framework.Path{
Pattern: "encrypt/" + framework.GenericNameRegex("key"),
DisplayAttrs: &framework.DisplayAttributes{
OperationPrefix: operationPrefixGoogleCloudKMS,
OperationVerb: "encrypt",
},
HelpSynopsis: "Encrypt a plaintext value using a named key",
HelpDescription: `
Use the named encryption key to encrypt an arbitrary plaintext string. The
response will be the base64-encoded encrypted value (ciphertext).
`,
Fields: map[string]*framework.FieldSchema{
"key": &framework.FieldSchema{
Type: framework.TypeString,
Description: `
Name of the key in Vault to use for encryption. This key must already exist in
Vault and must map back to a Google Cloud KMS key.
`,
},
"additional_authenticated_data": &framework.FieldSchema{
Type: framework.TypeString,
Description: `
Optional base64-encoded data that, if specified, must also be provided to
decrypt this payload.
`,
},
"key_version": &framework.FieldSchema{
Type: framework.TypeInt,
Description: `
Integer version of the crypto key version to use for encryption. If unspecified,
this defaults to the latest active crypto key version.
`,
},
"plaintext": &framework.FieldSchema{
Type: framework.TypeString,
Description: `
Plaintext value to be encrypted. This can be a string or binary, but the size
is limited. See the Google Cloud KMS documentation for information on size
limitations by key types.
`,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.UpdateOperation: withFieldValidator(b.pathEncryptWrite),
},
}
}
// pathEncryptWrite corresponds to PUT/POST gcpkms/encrypt/:key and is
// used to encrypt the plaintext string using the named key.
func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
key := d.Get("key").(string)
aad := d.Get("additional_authenticated_data").(string)
plaintext := d.Get("plaintext").(string)
keyVersion := d.Get("key_version").(int)
k, err := b.Key(ctx, req.Storage, key)
if err != nil {
if err == ErrKeyNotFound {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
return nil, err
}
cryptoKey := k.CryptoKeyID
if keyVersion > 0 {
if k.MinVersion > 0 && keyVersion < k.MinVersion {
resp := fmt.Sprintf("requested version %d is less than minimum allowed version of %d",
keyVersion, k.MinVersion)
return logical.ErrorResponse(resp), logical.ErrPermissionDenied
}
if k.MaxVersion > 0 && keyVersion > k.MaxVersion {
resp := fmt.Sprintf("requested version %d is greater than maximum allowed version of %d",
keyVersion, k.MaxVersion)
return logical.ErrorResponse(resp), logical.ErrPermissionDenied
}
cryptoKey = fmt.Sprintf("%s/cryptoKeyVersions/%d", cryptoKey, keyVersion)
}
kmsClient, closer, err := b.KMSClient(req.Storage)
if err != nil {
return nil, err
}
defer closer()
resp, err := kmsClient.Encrypt(ctx, &kmspb.EncryptRequest{
Name: cryptoKey,
Plaintext: []byte(plaintext),
AdditionalAuthenticatedData: []byte(aad),
})
if err != nil {
return nil, errwrap.Wrapf("failed to encrypt plaintext: {{err}}", err)
}
return &logical.Response{
Data: map[string]interface{}{
"key_version": path.Base(resp.Name),
"ciphertext": base64.StdEncoding.EncodeToString(resp.Ciphertext),
},
}, nil
}