/
path_pubkey.go
97 lines (81 loc) · 2.69 KB
/
path_pubkey.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
package awskms
import (
"context"
"fmt"
"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) pathPubkey() *framework.Path {
return &framework.Path{
Pattern: "pubkey/" + framework.GenericNameRegex("key"),
HelpSynopsis: "Retrieve the public key associated with the named key",
HelpDescription: `
Retrieve the PEM-encoded Google Cloud KMS public key associated with the Vault
named key. The key will only be available if the key is asymmetric.
`,
Fields: map[string]*framework.FieldSchema{
"key": &framework.FieldSchema{
Type: framework.TypeString,
Description: `
Name of the key for which to get the public key. This key must already exist in
Vault and Google Cloud KMS.
`,
},
"key_version": &framework.FieldSchema{
Type: framework.TypeInt,
Description: `
Integer version of the crypto key version from which to exact the public key.
This field is required.
`,
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: withFieldValidator(b.pathPubkeyRead),
},
}
}
// pathPubkeyRead corresponds to GET awskms/pubkey/:key and is used to read the
// public key contents of the crypto key version.
func (b *backend) pathPubkeyRead(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
key := d.Get("key").(string)
keyVersion := d.Get("key_version").(int)
if keyVersion == 0 {
return nil, errMissingFields("key_version")
}
k, err := b.Key(ctx, req.Storage, key)
if err != nil {
if err == ErrKeyNotFound {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
return nil, err
}
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
}
kmsClient, closer, err := b.KMSClient(req.Storage)
if err != nil {
return nil, err
}
defer closer()
pk, err := kmsClient.GetPublicKey(ctx, &kmspb.GetPublicKeyRequest{
Name: fmt.Sprintf("%s/cryptoKeyVersions/%d", k.CryptoKeyID, keyVersion),
})
if err != nil {
return nil, errwrap.Wrapf("failed to get public key: {{err}}", err)
}
return &logical.Response{
Data: map[string]interface{}{
"pem": pk.Pem,
"algorithm": algorithmToString(pk.Algorithm),
},
}, nil
}