Vault-11713: Add the ability for transit to use managed keys (#18844)
* add the ability for transit to use managed keys * add fields for rotate * reorganize managed keys for better error messaging * add aad for managed keys * change encrypting key interface * fix import error * fix fmt errors * move managed key rotation to a separate function * fix fmt issue * fix import error * fix go.mod issue * fix go.mod * remove extra rotate param * fix locking issue in rotation * fix errors in policy tests * move managed key params to fit existing policy functions * fix sign and verify * fix policy tests * fix test error
This commit is contained in:
parent
7a0c055c2a
commit
d228e62b51
@ -30,6 +30,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.5 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||
@ -46,6 +47,7 @@ require (
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
github.com/oklog/run v1.0.0 // indirect
|
||||
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
@ -53,5 +55,5 @@ require (
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||
google.golang.org/grpc v1.41.0 // indirect
|
||||
google.golang.org/protobuf v1.26.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
)
|
||||
|
11
api/go.sum
11
api/go.sum
@ -73,8 +73,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
@ -91,6 +91,8 @@ github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6 h1:szfBtjzqyJ/sjOAOGM1XIGnzkLFSAbCqgrNZXBqojMY=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6/go.mod h1:sDQAfwJGv25uGPZA04x87ERglCG6avnRcBT9wYoMII8=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
@ -129,8 +131,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@ -186,6 +188,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
@ -284,8 +288,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -73,6 +73,8 @@ func Backend(ctx context.Context, conf *logical.BackendConfig) (*backend, error)
|
||||
PeriodicFunc: b.periodicFunc,
|
||||
}
|
||||
|
||||
b.backendUUID = conf.BackendUUID
|
||||
|
||||
// determine cacheSize to use. Defaults to 0 which means unlimited
|
||||
cacheSize := 0
|
||||
useCache := !conf.System.CachingDisabled()
|
||||
@ -106,6 +108,7 @@ type backend struct {
|
||||
cacheSizeChanged bool
|
||||
checkAutoRotateAfter time.Time
|
||||
autoRotateOnce sync.Once
|
||||
backendUUID string
|
||||
}
|
||||
|
||||
func GetCacheSizeFromStorage(ctx context.Context, s logical.Storage) (int, error) {
|
||||
|
12
builtin/logical/transit/managed_key_util.go
Normal file
12
builtin/logical/transit/managed_key_util.go
Normal file
@ -0,0 +1,12 @@
|
||||
package transit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var errEntOnly = errors.New("managed keys are supported within enterprise edition only")
|
||||
|
||||
func GetManagedKeyUUID(ctx context.Context, b *backend, keyName string, keyId string) (uuid string, err error) {
|
||||
return "", errEntOnly
|
||||
}
|
@ -3,6 +3,7 @@ package transit
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/framework"
|
||||
@ -191,7 +192,23 @@ func (b *backend) pathDecryptWrite(ctx context.Context, req *logical.Request, d
|
||||
factory = AssocDataFactory{item.AssociatedData}
|
||||
}
|
||||
|
||||
plaintext, err := p.DecryptWithFactory(item.DecodedContext, item.DecodedNonce, item.Ciphertext, factory)
|
||||
var managedKeyFactory ManagedKeyFactory
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
managedKeySystemView, ok := b.System().(logical.ManagedKeySystemView)
|
||||
if !ok {
|
||||
batchResponseItems[i].Error = errors.New("unsupported system view").Error()
|
||||
}
|
||||
|
||||
managedKeyFactory = ManagedKeyFactory{
|
||||
managedKeyParams: keysutil.ManagedKeyParameters{
|
||||
ManagedKeySystemView: managedKeySystemView,
|
||||
BackendUUID: b.backendUUID,
|
||||
Context: ctx,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
plaintext, err := p.DecryptWithFactory(item.DecodedContext, item.DecodedNonce, item.Ciphertext, factory, managedKeyFactory)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errutil.InternalError:
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
@ -74,6 +75,14 @@ func (a AssocDataFactory) GetAssociatedData() ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(a.Encoded)
|
||||
}
|
||||
|
||||
type ManagedKeyFactory struct {
|
||||
managedKeyParams keysutil.ManagedKeyParameters
|
||||
}
|
||||
|
||||
func (m ManagedKeyFactory) GetManagedKeyParameters() keysutil.ManagedKeyParameters {
|
||||
return m.managedKeyParams
|
||||
}
|
||||
|
||||
func (b *backend) pathEncrypt() *framework.Path {
|
||||
return &framework.Path{
|
||||
Pattern: "encrypt/" + framework.GenericNameRegex("name"),
|
||||
@ -420,6 +429,8 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d
|
||||
polReq.KeyType = keysutil.KeyType_ChaCha20_Poly1305
|
||||
case "ecdsa-p256", "ecdsa-p384", "ecdsa-p521":
|
||||
return logical.ErrorResponse(fmt.Sprintf("key type %v not supported for this operation", keyType)), logical.ErrInvalidRequest
|
||||
case "managed_key":
|
||||
polReq.KeyType = keysutil.KeyType_MANAGED_KEY
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest
|
||||
}
|
||||
@ -465,7 +476,23 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d
|
||||
factory = AssocDataFactory{item.AssociatedData}
|
||||
}
|
||||
|
||||
ciphertext, err := p.EncryptWithFactory(item.KeyVersion, item.DecodedContext, item.DecodedNonce, item.Plaintext, factory)
|
||||
var managedKeyFactory ManagedKeyFactory
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
managedKeySystemView, ok := b.System().(logical.ManagedKeySystemView)
|
||||
if !ok {
|
||||
batchResponseItems[i].Error = errors.New("unsupported system view").Error()
|
||||
}
|
||||
|
||||
managedKeyFactory = ManagedKeyFactory{
|
||||
managedKeyParams: keysutil.ManagedKeyParameters{
|
||||
ManagedKeySystemView: managedKeySystemView,
|
||||
BackendUUID: b.backendUUID,
|
||||
Context: ctx,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ciphertext, err := p.EncryptWithFactory(item.KeyVersion, item.DecodedContext, item.DecodedNonce, item.Plaintext, factory, managedKeyFactory)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errutil.InternalError:
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -143,7 +144,7 @@ func (b *backend) pathHMACWrite(ctx context.Context, req *logical.Request, d *fr
|
||||
p.Unlock()
|
||||
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
if key == nil {
|
||||
if key == nil && p.Type != keysutil.KeyType_MANAGED_KEY {
|
||||
p.Unlock()
|
||||
return nil, fmt.Errorf("HMAC key value could not be computed")
|
||||
}
|
||||
@ -199,9 +200,23 @@ func (b *backend) pathHMACWrite(ctx context.Context, req *logical.Request, d *fr
|
||||
continue
|
||||
}
|
||||
|
||||
hf := hmac.New(hashAlg, key)
|
||||
hf.Write(input)
|
||||
retBytes := hf.Sum(nil)
|
||||
var retBytes []byte
|
||||
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
managedKeySystemView, ok := b.System().(logical.ManagedKeySystemView)
|
||||
if !ok {
|
||||
response[i].err = errors.New("unsupported system view")
|
||||
}
|
||||
|
||||
retBytes, err = p.HMACWithManagedKey(ctx, ver, managedKeySystemView, b.backendUUID, algorithm, input)
|
||||
if err != nil {
|
||||
response[i].err = err
|
||||
}
|
||||
} else {
|
||||
hf := hmac.New(hashAlg, key)
|
||||
hf.Write(input)
|
||||
retBytes = hf.Sum(nil)
|
||||
}
|
||||
|
||||
retStr := base64.StdEncoding.EncodeToString(retBytes)
|
||||
retStr = fmt.Sprintf("vault:v%s:%s", strconv.Itoa(ver), retStr)
|
||||
|
@ -108,6 +108,14 @@ key.`,
|
||||
Default: 0,
|
||||
Description: fmt.Sprintf("The key size in bytes for the algorithm. Only applies to HMAC and must be no fewer than %d bytes and no more than %d", keysutil.HmacMinKeySize, keysutil.HmacMaxKeySize),
|
||||
},
|
||||
"managed_key_name": {
|
||||
Type: framework.TypeString,
|
||||
Description: "The name of the managed key to use for this transit key",
|
||||
},
|
||||
"managed_key_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "The UUID of the managed key to use for this transit key",
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
@ -139,6 +147,8 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
exportable := d.Get("exportable").(bool)
|
||||
allowPlaintextBackup := d.Get("allow_plaintext_backup").(bool)
|
||||
autoRotatePeriod := time.Second * time.Duration(d.Get("auto_rotate_period").(int))
|
||||
managedKeyName := d.Get("managed_key_name").(string)
|
||||
managedKeyId := d.Get("managed_key_id").(string)
|
||||
|
||||
if autoRotatePeriod != 0 && autoRotatePeriod < time.Hour {
|
||||
return logical.ErrorResponse("auto rotate period must be 0 to disable or at least an hour"), nil
|
||||
@ -182,6 +192,8 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
polReq.KeyType = keysutil.KeyType_RSA4096
|
||||
case "hmac":
|
||||
polReq.KeyType = keysutil.KeyType_HMAC
|
||||
case "managed_key":
|
||||
polReq.KeyType = keysutil.KeyType_MANAGED_KEY
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest
|
||||
}
|
||||
@ -195,6 +207,15 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
polReq.KeySize = keySize
|
||||
}
|
||||
|
||||
if polReq.KeyType == keysutil.KeyType_MANAGED_KEY {
|
||||
keyId, err := GetManagedKeyUUID(ctx, b, managedKeyName, managedKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
polReq.ManagedKeyUUID = keyId
|
||||
}
|
||||
|
||||
p, upserted, err := b.GetPolicy(ctx, polReq, b.GetRandomReader())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -16,6 +16,14 @@ func (b *backend) pathRotate() *framework.Path {
|
||||
Type: framework.TypeString,
|
||||
Description: "Name of the key",
|
||||
},
|
||||
"managed_key_name": {
|
||||
Type: framework.TypeString,
|
||||
Description: "The name of the managed key to use for the new version of this transit key",
|
||||
},
|
||||
"managed_key_id": {
|
||||
Type: framework.TypeString,
|
||||
Description: "The UUID of the managed key to use for the new version of this transit key",
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
@ -29,6 +37,8 @@ func (b *backend) pathRotate() *framework.Path {
|
||||
|
||||
func (b *backend) pathRotateWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
name := d.Get("name").(string)
|
||||
managedKeyName := d.Get("managed_key_name").(string)
|
||||
managedKeyId := d.Get("managed_key_id").(string)
|
||||
|
||||
// Get the policy
|
||||
p, _, err := b.GetPolicy(ctx, keysutil.PolicyRequest{
|
||||
@ -45,8 +55,18 @@ func (b *backend) pathRotateWrite(ctx context.Context, req *logical.Request, d *
|
||||
p.Lock(true)
|
||||
}
|
||||
|
||||
// Rotate the policy
|
||||
err = p.Rotate(ctx, req.Storage, b.GetRandomReader())
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
var keyId string
|
||||
keyId, err = GetManagedKeyUUID(ctx, b, managedKeyName, managedKeyId)
|
||||
if err != nil {
|
||||
p.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
err = p.RotateManagedKey(ctx, req.Storage, keyId)
|
||||
} else {
|
||||
// Rotate the policy
|
||||
err = p.Rotate(ctx, req.Storage, b.GetRandomReader())
|
||||
}
|
||||
|
||||
p.Unlock()
|
||||
return nil, err
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -416,11 +417,26 @@ func (b *backend) pathSignWrite(ctx context.Context, req *logical.Request, d *fr
|
||||
}
|
||||
}
|
||||
|
||||
var managedKeyParameters keysutil.ManagedKeyParameters
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
managedKeySystemView, ok := b.System().(logical.ManagedKeySystemView)
|
||||
if !ok {
|
||||
return nil, errors.New("unsupported system view")
|
||||
}
|
||||
|
||||
managedKeyParameters = keysutil.ManagedKeyParameters{
|
||||
ManagedKeySystemView: managedKeySystemView,
|
||||
BackendUUID: b.backendUUID,
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
sig, err := p.SignWithOptions(ver, context, input, &keysutil.SigningOptions{
|
||||
HashAlgorithm: hashAlgorithm,
|
||||
Marshaling: marshaling,
|
||||
SaltLength: saltLength,
|
||||
SigAlgorithm: sigAlgorithm,
|
||||
HashAlgorithm: hashAlgorithm,
|
||||
Marshaling: marshaling,
|
||||
SaltLength: saltLength,
|
||||
SigAlgorithm: sigAlgorithm,
|
||||
ManagedKeyParams: managedKeyParameters,
|
||||
})
|
||||
if err != nil {
|
||||
if batchInputRaw != nil {
|
||||
@ -638,13 +654,29 @@ func (b *backend) pathVerifyWrite(ctx context.Context, req *logical.Request, d *
|
||||
continue
|
||||
}
|
||||
}
|
||||
var managedKeyParameters keysutil.ManagedKeyParameters
|
||||
if p.Type == keysutil.KeyType_MANAGED_KEY {
|
||||
managedKeySystemView, ok := b.System().(logical.ManagedKeySystemView)
|
||||
if !ok {
|
||||
return nil, errors.New("unsupported system view")
|
||||
}
|
||||
|
||||
valid, err := p.VerifySignatureWithOptions(context, input, sig, &keysutil.SigningOptions{
|
||||
HashAlgorithm: hashAlgorithm,
|
||||
Marshaling: marshaling,
|
||||
SaltLength: saltLength,
|
||||
SigAlgorithm: sigAlgorithm,
|
||||
})
|
||||
managedKeyParameters = keysutil.ManagedKeyParameters{
|
||||
ManagedKeySystemView: managedKeySystemView,
|
||||
BackendUUID: b.backendUUID,
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
signingOptions := &keysutil.SigningOptions{
|
||||
HashAlgorithm: hashAlgorithm,
|
||||
Marshaling: marshaling,
|
||||
SaltLength: saltLength,
|
||||
SigAlgorithm: sigAlgorithm,
|
||||
ManagedKeyParams: managedKeyParameters,
|
||||
}
|
||||
|
||||
valid, err := p.VerifySignatureWithOptions(context, input, sig, signingOptions)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case errutil.UserError:
|
||||
|
4
go.mod
4
go.mod
@ -69,7 +69,7 @@ require (
|
||||
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192
|
||||
github.com/hashicorp/go-gcp-common v0.8.0
|
||||
github.com/hashicorp/go-hclog v1.4.0
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.5
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.4
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.1
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.1
|
||||
@ -398,7 +398,7 @@ require (
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
github.com/snowflakedb/gosnowflake v1.6.3 // indirect
|
||||
|
11
go.sum
11
go.sum
@ -995,8 +995,8 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0 h1:pSjQfW3vPtrOTcasTUKgCTQT7OGPPTTMVRrOfU6FJD8=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.5 h1:rOFDv+3k05mnW0oaDLffhVUwg03Csn0mvfO98Wdd2bE=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.5/go.mod h1:sDQAfwJGv25uGPZA04x87ERglCG6avnRcBT9wYoMII8=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6 h1:szfBtjzqyJ/sjOAOGM1XIGnzkLFSAbCqgrNZXBqojMY=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6/go.mod h1:sDQAfwJGv25uGPZA04x87ERglCG6avnRcBT9wYoMII8=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.4 h1:ws2CPDuXMKwaBb2z/duBCdnB9pSxlN2nuDZWXcVj6RU=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.4/go.mod h1:dDxt3GXi5QONVHYrJi2+EjsJLCUs59FktZQA8ZMnm+U=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2 v2.0.1 h1:ydUCtmr8f9F+mHZ1iCsvzqFTXqNVpewX3s9zcYipMKI=
|
||||
@ -1477,6 +1477,7 @@ github.com/mongodb-forks/digest v1.0.3/go.mod h1:eHRfgovT+dvSFfltrOa27hy1oR/rcwy
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
@ -1672,8 +1673,8 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
@ -1955,6 +1956,7 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
@ -2599,7 +2601,6 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
|
@ -39,7 +39,7 @@ require (
|
||||
golang.org/x/crypto v0.5.0
|
||||
golang.org/x/text v0.6.0
|
||||
google.golang.org/grpc v1.41.0
|
||||
google.golang.org/protobuf v1.26.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
||||
require (
|
||||
@ -48,6 +48,7 @@ require (
|
||||
github.com/frankban/quicktest v1.10.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.3.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 // indirect
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
|
@ -96,6 +96,8 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0 h1:pSjQfW3vPtrOTcasTUKgCTQT7OGPPTTMVRrOfU6FJD8=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6 h1:szfBtjzqyJ/sjOAOGM1XIGnzkLFSAbCqgrNZXBqojMY=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6/go.mod h1:sDQAfwJGv25uGPZA04x87ERglCG6avnRcBT9wYoMII8=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
@ -304,6 +306,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
@ -59,6 +59,9 @@ type PolicyRequest struct {
|
||||
|
||||
// AllowImportedKeyRotation indicates whether an imported key may be rotated by Vault
|
||||
AllowImportedKeyRotation bool
|
||||
|
||||
// The UUID of the managed key, if using one
|
||||
ManagedKeyUUID string
|
||||
}
|
||||
|
||||
type LockManager struct {
|
||||
@ -382,6 +385,12 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
case KeyType_MANAGED_KEY:
|
||||
if req.Derived || req.Convergent {
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
default:
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("unsupported key type %v", req.KeyType)
|
||||
@ -412,7 +421,11 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
|
||||
}
|
||||
|
||||
// Performs the actual persist and does setup
|
||||
err = p.Rotate(ctx, req.Storage, rand)
|
||||
if p.Type == KeyType_MANAGED_KEY {
|
||||
err = p.RotateManagedKey(ctx, req.Storage, req.ManagedKeyUUID)
|
||||
} else {
|
||||
err = p.Rotate(ctx, req.Storage, rand)
|
||||
}
|
||||
if err != nil {
|
||||
cleanup()
|
||||
return nil, false, err
|
||||
|
40
sdk/helper/keysutil/managed_key_util.go
Normal file
40
sdk/helper/keysutil/managed_key_util.go
Normal file
@ -0,0 +1,40 @@
|
||||
package keysutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
)
|
||||
|
||||
type ManagedKeyParameters struct {
|
||||
ManagedKeySystemView logical.ManagedKeySystemView
|
||||
BackendUUID string
|
||||
Context context.Context
|
||||
}
|
||||
|
||||
var errEntOnly = errors.New("managed keys are supported within enterprise edition only")
|
||||
|
||||
func (p *Policy) decryptWithManagedKey(params ManagedKeyParameters, keyEntry KeyEntry, ciphertext []byte, nonce []byte, aad []byte) (plaintext []byte, err error) {
|
||||
return nil, errEntOnly
|
||||
}
|
||||
|
||||
func (p *Policy) encryptWithManagedKey(params ManagedKeyParameters, keyEntry KeyEntry, plaintext []byte, nonce []byte, aad []byte) (ciphertext []byte, err error) {
|
||||
return nil, errEntOnly
|
||||
}
|
||||
|
||||
func (p *Policy) signWithManagedKey(options *SigningOptions, keyEntry KeyEntry, input []byte) (sig []byte, err error) {
|
||||
return nil, errEntOnly
|
||||
}
|
||||
|
||||
func (p *Policy) verifyWithManagedKey(options *SigningOptions, keyEntry KeyEntry, input, sig []byte) (verified bool, err error) {
|
||||
return false, errEntOnly
|
||||
}
|
||||
|
||||
func (p *Policy) HMACWithManagedKey(ctx context.Context, ver int, managedKeySystemView logical.ManagedKeySystemView, backendUUID string, algorithm string, data []byte) (hmacBytes []byte, err error) {
|
||||
return nil, errEntOnly
|
||||
}
|
||||
|
||||
func (p *Policy) RotateManagedKey(ctx context.Context, storage logical.Storage, managedKeyUUID string) error {
|
||||
return errEntOnly
|
||||
}
|
@ -83,6 +83,10 @@ type AssociatedDataFactory interface {
|
||||
GetAssociatedData() ([]byte, error)
|
||||
}
|
||||
|
||||
type ManagedKeyFactory interface {
|
||||
GetManagedKeyParameters() ManagedKeyParameters
|
||||
}
|
||||
|
||||
type RestoreInfo struct {
|
||||
Time time.Time `json:"time"`
|
||||
Version int `json:"version"`
|
||||
@ -94,10 +98,11 @@ type BackupInfo struct {
|
||||
}
|
||||
|
||||
type SigningOptions struct {
|
||||
HashAlgorithm HashType
|
||||
Marshaling MarshalingType
|
||||
SaltLength int
|
||||
SigAlgorithm string
|
||||
HashAlgorithm HashType
|
||||
Marshaling MarshalingType
|
||||
SaltLength int
|
||||
SigAlgorithm string
|
||||
ManagedKeyParams ManagedKeyParameters
|
||||
}
|
||||
|
||||
type SigningResult struct {
|
||||
@ -113,7 +118,7 @@ type KeyType int
|
||||
|
||||
func (kt KeyType) EncryptionSupported() bool {
|
||||
switch kt {
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -121,7 +126,7 @@ func (kt KeyType) EncryptionSupported() bool {
|
||||
|
||||
func (kt KeyType) DecryptionSupported() bool {
|
||||
switch kt {
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -129,7 +134,7 @@ func (kt KeyType) DecryptionSupported() bool {
|
||||
|
||||
func (kt KeyType) SigningSupported() bool {
|
||||
switch kt {
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096:
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -153,7 +158,7 @@ func (kt KeyType) DerivationSupported() bool {
|
||||
|
||||
func (kt KeyType) AssociatedDataSupported() bool {
|
||||
switch kt {
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305:
|
||||
case KeyType_AES128_GCM96, KeyType_AES256_GCM96, KeyType_ChaCha20_Poly1305, KeyType_MANAGED_KEY:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -183,6 +188,8 @@ func (kt KeyType) String() string {
|
||||
return "rsa-4096"
|
||||
case KeyType_HMAC:
|
||||
return "hmac"
|
||||
case KeyType_MANAGED_KEY:
|
||||
return "managed_key"
|
||||
}
|
||||
|
||||
return "[unknown]"
|
||||
@ -220,6 +227,8 @@ type KeyEntry struct {
|
||||
// This is deprecated (but still filled) in favor of the value above which
|
||||
// is more precise
|
||||
DeprecatedCreationTime int64 `json:"creation_time"`
|
||||
|
||||
ManagedKeyUUID string `json:"managed_key_id,omitempty"`
|
||||
}
|
||||
|
||||
// deprecatedKeyEntryMap is used to allow JSON marshal/unmarshal
|
||||
@ -419,8 +428,6 @@ type Policy struct {
|
||||
|
||||
// AllowImportedKeyRotation indicates whether an imported key may be rotated by Vault
|
||||
AllowImportedKeyRotation bool
|
||||
|
||||
ManagedKeyName string `json:"managed_key_name,omitempty"`
|
||||
}
|
||||
|
||||
func (p *Policy) Lock(exclusive bool) {
|
||||
@ -943,6 +950,7 @@ func (p *Policy) DecryptWithFactory(context, nonce []byte, value string, factori
|
||||
if err != nil {
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unable to get associated_data/additional_data from factory[%d]: %v", index, err)}
|
||||
}
|
||||
case ManagedKeyFactory:
|
||||
default:
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unknown type of factory[%d]: %T", index, rawFactory)}
|
||||
}
|
||||
@ -962,6 +970,33 @@ func (p *Policy) DecryptWithFactory(context, nonce []byte, value string, factori
|
||||
if err != nil {
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA decrypt the ciphertext: %v", err)}
|
||||
}
|
||||
case KeyType_MANAGED_KEY:
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var aad []byte
|
||||
var managedKeyFactory ManagedKeyFactory
|
||||
for _, f := range factories {
|
||||
switch factory := f.(type) {
|
||||
case AssociatedDataFactory:
|
||||
aad, err = factory.GetAssociatedData()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
case ManagedKeyFactory:
|
||||
managedKeyFactory = factory
|
||||
}
|
||||
}
|
||||
|
||||
if managedKeyFactory == nil {
|
||||
return "", errors.New("key type is managed_key, but managed key parameters were not provided")
|
||||
}
|
||||
|
||||
plain, err = p.decryptWithManagedKey(managedKeyFactory.GetManagedKeyParameters(), keyEntry, decoded, nonce, aad)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
default:
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)}
|
||||
@ -1160,6 +1195,17 @@ func (p *Policy) SignWithOptions(ver int, context, input []byte, options *Signin
|
||||
return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported rsa signature algorithm %s", sigAlgorithm)}
|
||||
}
|
||||
|
||||
case KeyType_MANAGED_KEY:
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, err = p.signWithManagedKey(options, keyEntry, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported key type %v", p.Type)
|
||||
}
|
||||
@ -1333,6 +1379,14 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
|
||||
|
||||
return err == nil, nil
|
||||
|
||||
case KeyType_MANAGED_KEY:
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return p.verifyWithManagedKey(options, keyEntry, input, sigBytes)
|
||||
|
||||
default:
|
||||
return false, errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)}
|
||||
}
|
||||
@ -1941,6 +1995,7 @@ func (p *Policy) EncryptWithFactory(ver int, context []byte, nonce []byte, value
|
||||
if err != nil {
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unable to get associated_data/additional_data from factory[%d]: %v", index, err)}
|
||||
}
|
||||
case ManagedKeyFactory:
|
||||
default:
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unknown type of factory[%d]: %T", index, rawFactory)}
|
||||
}
|
||||
@ -1960,6 +2015,34 @@ func (p *Policy) EncryptWithFactory(ver int, context []byte, nonce []byte, value
|
||||
if err != nil {
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("failed to RSA encrypt the plaintext: %v", err)}
|
||||
}
|
||||
case KeyType_MANAGED_KEY:
|
||||
keyEntry, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var aad []byte
|
||||
var managedKeyFactory ManagedKeyFactory
|
||||
for _, f := range factories {
|
||||
switch factory := f.(type) {
|
||||
case AssociatedDataFactory:
|
||||
aad, err = factory.GetAssociatedData()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
case ManagedKeyFactory:
|
||||
managedKeyFactory = factory
|
||||
}
|
||||
}
|
||||
|
||||
if managedKeyFactory == nil {
|
||||
return "", errors.New("key type is managed_key, but managed key parameters were not provided")
|
||||
}
|
||||
|
||||
ciphertext, err = p.encryptWithManagedKey(managedKeyFactory.GetManagedKeyParameters(), keyEntry, plaintext, nonce, aad)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
default:
|
||||
return "", errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)}
|
||||
|
@ -3,8 +3,9 @@ package logical
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/cipher"
|
||||
"io"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
)
|
||||
|
||||
type KeyUsage int
|
||||
@ -102,7 +103,8 @@ type ManagedSigningKey interface {
|
||||
|
||||
type ManagedEncryptingKey interface {
|
||||
ManagedKey
|
||||
GetAEAD(iv []byte) (cipher.AEAD, error)
|
||||
Encrypt(ctx context.Context, plaintext []byte, options ...wrapping.Option) ([]byte, error)
|
||||
Decrypt(ctx context.Context, ciphertext []byte, options ...wrapping.Option) ([]byte, error)
|
||||
}
|
||||
|
||||
type ManagedMACKey interface {
|
||||
|
Loading…
Reference in New Issue
Block a user