Skip to content
This repository has been archived by the owner on Aug 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #332 from ypukhta/issue-326-kms
Browse files Browse the repository at this point in the history
refactor: remove EDV support
  • Loading branch information
rolsonquadras authored Sep 12, 2022
2 parents b6d0f24 + fca942e commit 215e602
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 465 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ stress-test:
KMS_STRESS_KMS_URL=https://ops-oathkeeper-proxy.dev.trustbloc.dev \
KMS_STRESS_AUTH_KMS_URL=https://authz-oathkeeper-proxy.dev.trustbloc.dev \
KMS_STRESS_HUB_AUTH_URL=https://hub-auth.dev.trustbloc.dev \
KMS_STRESS_EDV_URL=https://edv.dev.trustbloc.dev \
SUBJECT=john.smith23140954@example.com \
ACCESS_TOKEN=m_QNKTLWFgyFEGPf6dHHs3h3f0TOoJ2ZSlD912u_LKw.6xWwAF61vGM5EHxGuQG9nuwAwd_hNKqMMEe4W2V-V1Q \
SECRET_SHARE=dD78WKu9/51CRFVhmzlH7nUYbaZvC5Eb30WNC3rfPjLz \
Expand Down
12 changes: 0 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,6 @@ If Shamir secret lock is used, every request that involves User's Key Store is e
The following databases are supported for the Server DB: MongoDB, CouchDB, and in-memory. You specify a type of the
database in the `KMS_DATABASE_TYPE` environment variable (`--database-type` flag).

User's Key Store can also use EDV for storing working keys. EDV parameters can be set with `create key store` request:

```json
{
"controller": "did:example:controller",
"edv": {
"vault_url": "https://edv-host/encrypted-data-vaults/vault-id",
"capability": "eyJAY29udGV4dCI6Imh0dHBzOi8vdzNpZC5v..."
}
}
```

## Use Cases

Refer [here](docs/use_cases.md) for in-depth description on how lock keys are used in example server's configurations.
Expand Down
1 change: 0 additions & 1 deletion cmd/kms-server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ require (
github.com/google/trillian v1.3.14-0.20210520152752-ceda464a95a3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hyperledger/aries-framework-go-ext/component/vdr/sidetree v1.0.0-rc2.0.20220729203359-da1de2fa21ce // indirect
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85 // indirect
github.com/hyperledger/ursa-wrapper-go v0.3.1 // indirect
github.com/igor-pavlenko/httpsignatures-go v0.0.23 // indirect
github.com/imdario/mergo v0.3.12 // indirect
Expand Down
2 changes: 0 additions & 2 deletions cmd/kms-server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,6 @@ github.com/hyperledger/aries-framework-go-ext/component/vdr/orb v1.0.0-rc2.0.202
github.com/hyperledger/aries-framework-go-ext/component/vdr/orb v1.0.0-rc2.0.20220811162145-47649b185a56/go.mod h1:5ZDdDP1oCcjR8T7+uxOs0JF3PsY8h18pMfylqwjieII=
github.com/hyperledger/aries-framework-go-ext/component/vdr/sidetree v1.0.0-rc2.0.20220729203359-da1de2fa21ce h1:COpeqKShWjBJ/hDnnjgQg0MCC1BuV4tMA2ksSKmchRc=
github.com/hyperledger/aries-framework-go-ext/component/vdr/sidetree v1.0.0-rc2.0.20220729203359-da1de2fa21ce/go.mod h1:mmoE3SQsM0WYLweUmBCQJE2abf73iO4LxpP/e0NONYI=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85 h1:YWww6rlXZprOnBP3LD8RAzbkszmplnLvabtlBZtzLTA=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85 h1:P82lZe6zDjaP2j87nDYQBSBYrB6Nq6nc9MtyNMC3K4A=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85/go.mod h1:ryG46jQRvQUUH/0wjORghfJnxJVH1yIXIsAv1GXIWp8=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220614152730-3d817acfa48b h1:wSUDDrB87VuaxOmyb0CmA3wB8vvgZ3p9Te4Dnsi6NXs=
Expand Down
2 changes: 0 additions & 2 deletions cmd/kms-server/startcmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,6 @@ func startServer(srv server, params *serverParameters) error { //nolint:funlen
BaseKeyStoreURL: baseKeyStoreURL,
ShamirProvider: shamirProvider,
MainKeyType: kms.AES256GCMType,
EDVRecipientKeyType: kms.NISTP256ECDHKW,
EDVMACKeyType: kms.HMACSHA256Tag256,
KeyStoreCacheTTL: params.keyStoreCacheTTL,
MetricsProvider: metrics.Get(),
}
Expand Down
44 changes: 1 addition & 43 deletions docs/use_cases.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Use Cases

**Scenario 1**: server's lock is based on AWS key, user's lock uses local key, no EDV
**Scenario 1**: server's lock is based on AWS key, user's lock uses local key

In this scenario, a key for the user's lock is created when the key store is created. That key is encrypted with an AWS
key and stored in the server's DB. When a working key is created for the user, it is encrypted with that stored lock key.
Expand Down Expand Up @@ -32,45 +32,3 @@ Before using, user's lock key should be decrypted with an AWS key.
Storage-->>KMS: {key ID}
KMS-->>User: {key URL, public key bytes}
```

**Scenario 2**: server's lock is based on local key, user's lock uses Shamir-based key, working keys are stored in EDV

Key for the server's lock is stored in a local file and the path to it is specified in a startup flag or environment
variable. When a key store is created, helper recipient and MAC keys for the EDV provider are created as well. They are
encrypted with a key from the local file (server's lock) and saved to the server's DB. These keys are associated with
a created key store to support EDV operations.

User's lock key is created on a fly using HKDF algorithm that expands the combined secret (from shares using Shamir
Secret Sharing) into a symmetric key. That key is used to encrypt/decrypt the user's working keys stored in EDV.

```mermaid
sequenceDiagram
participant User
participant KMS
participant DB
participant EDV
participant Auth as Auth Server
User->>KMS: create keystore {controller, EDV vault URL and ZCAPs}
loop for EDV recipient key, EDV MAC key
KMS->>KMS: create key
KMS->>KMS: encrypt key with server's local (master) key
KMS->>DB: save encrypted key
DB-->>KMS: {key ID}
end
KMS-->>User: {keystore URL, root ZCAPs}
User->>KMS: create key {key type, secret share}
KMS->>KMS: create key
KMS->>Auth: get secret share
Auth-->>KMS: secret share
KMS->>KMS: create lock key on a fly from secret shares
KMS->>KMS: encrypt key with lock key
loop for EDV recipient key, EDV MAC key
KMS->>DB: get key
KMS->>KMS: decrypt key with server's local (master) key
end
KMS->>EDV: save encrypted key
EDV-->>KMS: {key ID}
KMS-->>User: {key URL, public key bytes}
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
github.com/google/tink/go v1.6.1
github.com/gorilla/mux v1.8.0
github.com/hyperledger/aries-framework-go v0.1.9-0.20220822173318-77fbef728d02
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220610133818-119077b0ec85
github.com/igor-pavlenko/httpsignatures-go v0.0.23
Expand All @@ -39,6 +38,7 @@ require (
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 // indirect
github.com/hyperledger/ursa-wrapper-go v0.3.1 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down
3 changes: 1 addition & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,12 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/aries-framework-go v0.1.9-0.20220822173318-77fbef728d02 h1:phipjA38PzjN7/h6t+8Vv8XPlW5t+327GD0p9v8wx4Y=
github.com/hyperledger/aries-framework-go v0.1.9-0.20220822173318-77fbef728d02/go.mod h1:28aD9QTgVjeAl86vHNFwkOYwQwZiTrrODMpjE2PYz3M=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85 h1:YWww6rlXZprOnBP3LD8RAzbkszmplnLvabtlBZtzLTA=
github.com/hyperledger/aries-framework-go/component/storage/edv v0.0.0-20220610133818-119077b0ec85/go.mod h1:JrwivOOQmuXbV1mFWgBGWnfCorOFdfGkpBsYK8dYrfM=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85 h1:P82lZe6zDjaP2j87nDYQBSBYrB6Nq6nc9MtyNMC3K4A=
github.com/hyperledger/aries-framework-go/component/storageutil v0.0.0-20220610133818-119077b0ec85/go.mod h1:ryG46jQRvQUUH/0wjORghfJnxJVH1yIXIsAv1GXIWp8=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220610133818-119077b0ec85 h1:y+9tj2KusE4tT2iDKdB20GfRY4W7Ftvpp2kB/TEVrGs=
github.com/hyperledger/aries-framework-go/spi v0.0.0-20220610133818-119077b0ec85/go.mod h1:4bD5c5fj5K7rkQurVa/8I8+TfNcI4bxIBzaUNcxTOTg=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1 h1:vxZ0DlFNLjgxMdBESLZu895AsI1JWL2SJerphwIn8Po=
github.com/hyperledger/aries-framework-go/test/component v0.0.0-20220428211718-66cc046674a1/go.mod h1:lykx3N+GX+sAWSxO2Ycc4Dz+ynV9b0Fv4NdP+ms4Alc=
github.com/hyperledger/ursa-wrapper-go v0.3.1 h1:Do+QrVNniY77YK2jTIcyWqj9rm/Yb5SScN0bqCjiibA=
github.com/hyperledger/ursa-wrapper-go v0.3.1/go.mod h1:nPSAuMasIzSVciQo22PedBk4Opph6bJ6ia3ms7BH/mk=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand Down
2 changes: 0 additions & 2 deletions pkg/controller/command/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const (
ActionBlind = "blind"
ActionCorrectnessProof = "correctnessProof"
ActionSignWithSecrets = "signWithSecrets"
ActionStoreCapability = "updateEDVCapability"
)

func allActions() []string {
Expand All @@ -59,6 +58,5 @@ func allActions() []string {
ActionBlind,
ActionCorrectnessProof,
ActionSignWithSecrets,
ActionStoreCapability,
}
}
168 changes: 42 additions & 126 deletions pkg/controller/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import (
"time"

"github.com/google/tink/go/keyset"
"github.com/hyperledger/aries-framework-go/component/storage/edv"
"github.com/hyperledger/aries-framework-go/pkg/crypto"
"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/secretlock"
"github.com/hyperledger/aries-framework-go/spi/storage"
Expand All @@ -32,7 +30,6 @@ import (

"github.com/trustbloc/kms/pkg/controller/errors"
"github.com/trustbloc/kms/pkg/secretlock/key"
"github.com/trustbloc/kms/pkg/storage/metrics"
)

type zcapService interface {
Expand Down Expand Up @@ -99,36 +96,32 @@ type Config struct {
BaseKeyStoreURL string
ShamirProvider shamirProvider
MainKeyType kms.KeyType
EDVRecipientKeyType kms.KeyType
EDVMACKeyType kms.KeyType
MetricsProvider metricsProvider
CacheProvider cacheProvider
KeyStoreCacheTTL time.Duration
}

// Command is a controller for commands.
type Command struct {
store storage.Store
keyStorageProvider storage.Provider
kms kms.KeyManager // server's key manager
crypto crypto.Crypto
zcap zcapService
enableZCAPs bool
vdr zcapld.VDRResolver
documentLoader ld.DocumentLoader
keyStoreCreator keyStoreCreator // user's key manager creator
cryptoBox cryptoBoxCreator
shamirLock shamirSecretLockCreator
headerSigner headerSigner
tlsConfig *tls.Config
baseKeyStoreURL string
shamirProvider shamirProvider
mainKeyType kms.KeyType
edvRecipientKeyType kms.KeyType
edvMACKeyType kms.KeyType
cacheProvider cacheProvider
keyStoreCacheTTL time.Duration
metrics metricsProvider
store storage.Store
keyStorageProvider storage.Provider
kms kms.KeyManager // server's key manager
crypto crypto.Crypto
zcap zcapService
enableZCAPs bool
vdr zcapld.VDRResolver
documentLoader ld.DocumentLoader
keyStoreCreator keyStoreCreator // user's key manager creator
cryptoBox cryptoBoxCreator
shamirLock shamirSecretLockCreator
headerSigner headerSigner
tlsConfig *tls.Config
baseKeyStoreURL string
shamirProvider shamirProvider
mainKeyType kms.KeyType
cacheProvider cacheProvider
keyStoreCacheTTL time.Duration
metrics metricsProvider
}

// New returns a new instance of Command.
Expand All @@ -139,27 +132,25 @@ func New(c *Config) (*Command, error) {
}

return &Command{
store: store,
keyStorageProvider: c.KeyStorageProvider,
kms: c.KMS,
crypto: c.Crypto,
zcap: c.ZCAPService,
enableZCAPs: c.EnableZCAPs,
vdr: c.VDRResolver,
documentLoader: c.DocumentLoader,
keyStoreCreator: c.KeyStoreCreator,
shamirLock: c.ShamirSecretLockCreator,
cryptoBox: c.CryptBoxCreator,
headerSigner: c.HeaderSigner,
tlsConfig: c.TLSConfig,
baseKeyStoreURL: c.BaseKeyStoreURL,
shamirProvider: c.ShamirProvider,
mainKeyType: c.MainKeyType,
edvRecipientKeyType: c.EDVRecipientKeyType,
edvMACKeyType: c.EDVMACKeyType,
cacheProvider: c.CacheProvider,
keyStoreCacheTTL: c.KeyStoreCacheTTL,
metrics: c.MetricsProvider,
store: store,
keyStorageProvider: c.KeyStorageProvider,
kms: c.KMS,
crypto: c.Crypto,
zcap: c.ZCAPService,
enableZCAPs: c.EnableZCAPs,
vdr: c.VDRResolver,
documentLoader: c.DocumentLoader,
keyStoreCreator: c.KeyStoreCreator,
shamirLock: c.ShamirSecretLockCreator,
cryptoBox: c.CryptBoxCreator,
headerSigner: c.HeaderSigner,
tlsConfig: c.TLSConfig,
baseKeyStoreURL: c.BaseKeyStoreURL,
shamirProvider: c.ShamirProvider,
mainKeyType: c.MainKeyType,
cacheProvider: c.CacheProvider,
keyStoreCacheTTL: c.KeyStoreCacheTTL,
metrics: c.MetricsProvider,
}, nil
}

Expand Down Expand Up @@ -774,10 +765,7 @@ func (c *Command) resolveKeyStore(keyStoreID, user string, secretShare []byte) (
return nil, fmt.Errorf("unmarshal key store meta: %w", err)
}

storageProvider, err := c.getStorageProvider(&meta)
if err != nil {
return nil, err
}
storageProvider := c.getStorageProvider()

var secretLock secretlock.Service

Expand Down Expand Up @@ -812,84 +800,12 @@ func (c *Command) resolveKeyStore(keyStoreID, user string, secretShare []byte) (
})
}

func (c *Command) getStorageProvider(meta *keyStoreMeta) (storage.Provider, error) {
var storageProvider storage.Provider

if meta.EDV.VaultURL != "" {
var err error

storageProvider, err = c.resolveEDVProvider(meta.EDV.VaultURL, meta.EDV.RecipientKeyID, meta.EDV.MACKeyID,
meta.EDV.Capability)
if err != nil {
return nil, fmt.Errorf("resolve edv provider: %w", err)
}

storageProvider = metrics.Wrap(storageProvider, "EDV")
} else {
storageProvider = c.keyStorageProvider
}
func (c *Command) getStorageProvider() storage.Provider {
storageProvider := c.keyStorageProvider

if c.cacheProvider != nil && c.keyStoreCacheTTL > 0 {
storageProvider = c.cacheProvider.Wrap(storageProvider, c.keyStoreCacheTTL)
}

return storageProvider, nil
}

func (c *Command) resolveEDVProvider(vaultURL, recKeyID, macKeyID string, capability []byte) (storage.Provider, error) {
recPubBytes, _, err := c.kms.ExportPubKeyBytes(recKeyID)
if err != nil {
return nil, fmt.Errorf("get edv recipient key: %w", err)
}

recPub := new(crypto.PublicKey)
recPub.KID = recKeyID

if err = json.Unmarshal(recPubBytes, recPub); err != nil {
return nil, fmt.Errorf("unmarshal recipient key bytes to public key: %w", err)
}

macKH, err := c.kms.Get(macKeyID)
if err != nil {
return nil, fmt.Errorf("get edv mac key handle: %w", err)
}

edvProvider, err := c.createEDVStorageProvider(vaultURL, recPub, macKH, capability)
if err != nil {
return nil, fmt.Errorf("create edv provider: %w", err)
}

return edvProvider, nil
}

func (c *Command) createEDVStorageProvider(vaultURL string, recipientPubKey *crypto.PublicKey,
macKeyHandle interface{}, capability []byte) (storage.Provider, error) {
jweEncrypt, err := jose.NewJWEEncrypt(encAlg, encType, "", "", nil, []*crypto.PublicKey{recipientPubKey}, c.crypto)
if err != nil {
return nil, fmt.Errorf("create jwe encrypt: %w", err)
}

jweDecrypt := jose.NewJWEDecrypt(nil, c.crypto, c.kms)

encryptedFormatter := edv.NewEncryptedFormatter(
jweEncrypt,
jweDecrypt,
edv.NewMACCrypto(macKeyHandle, c.crypto),
edv.WithDeterministicDocumentIDs(),
)

s := strings.Split(vaultURL, "/")

edvServerURL := strings.Join(s[:len(s)-1], "/")
vaultID := s[len(s)-1]

return edv.NewRESTProvider(
edvServerURL,
vaultID,
encryptedFormatter,
edv.WithTLSConfig(c.tlsConfig),
edv.WithHeaders(func(req *http.Request) (*http.Header, error) {
return c.headerSigner.SignHeader(req, capability)
}),
), nil
return storageProvider
}
Loading

0 comments on commit 215e602

Please sign in to comment.