@bedrock/kms-http 14.3.0 → 14.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/lib/http.js +2 -0
- package/lib/middleware.js +7 -7
- package/package.json +2 -2
- package/test/mocha/11-keystore-kms-client.js +71 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# bedrock-kms-http ChangeLog
|
|
2
2
|
|
|
3
|
+
## 14.3.1 - 2022-05-16
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Use `@digitalbazaar/webkms-switch@10.2` to ensure that pre-cached `webkms`
|
|
7
|
+
request meta data is not overwritten and that a custom `getRootController`
|
|
8
|
+
function is used (to enable cache busting on KMS operations).
|
|
9
|
+
|
|
3
10
|
## 14.3.0 - 2022-05-16
|
|
4
11
|
|
|
5
12
|
### Added
|
package/lib/http.js
CHANGED
|
@@ -191,6 +191,7 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
|
|
|
191
191
|
app.post(
|
|
192
192
|
routes.keys,
|
|
193
193
|
cors(),
|
|
194
|
+
getKeystoreConfig,
|
|
194
195
|
handleOperation);
|
|
195
196
|
|
|
196
197
|
// invoke KMS operation on an existing key
|
|
@@ -198,6 +199,7 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
|
|
|
198
199
|
app.post(
|
|
199
200
|
routes.key,
|
|
200
201
|
cors(),
|
|
202
|
+
getKeystoreConfig,
|
|
201
203
|
handleOperation);
|
|
202
204
|
|
|
203
205
|
// TODO: consider whether this should be exposed w/o authorization
|
package/lib/middleware.js
CHANGED
|
@@ -46,7 +46,7 @@ export function createGetKeystoreConfig({routes}) {
|
|
|
46
46
|
id: keystoreId, req, returnRecord: true
|
|
47
47
|
});
|
|
48
48
|
const {config: keystore} = configRecord;
|
|
49
|
-
req.webkms = {keystore, configRecord};
|
|
49
|
+
req.webkms = {...req.webkms, keystore, configRecord};
|
|
50
50
|
}
|
|
51
51
|
next();
|
|
52
52
|
});
|
|
@@ -58,7 +58,10 @@ export function createKmsOperationMiddleware() {
|
|
|
58
58
|
return createOperationMiddleware({
|
|
59
59
|
...kmsOperationOptions,
|
|
60
60
|
storage, moduleManager, documentLoader,
|
|
61
|
-
expectedHost: config.server.host,
|
|
61
|
+
expectedHost: config.server.host,
|
|
62
|
+
// override `getRootController` to provide cache busting capability
|
|
63
|
+
getRootController: getKeystoreController,
|
|
64
|
+
getVerifier,
|
|
62
65
|
inspectCapabilityChain,
|
|
63
66
|
onError, onSuccess: reportOperationUsage, suiteFactory
|
|
64
67
|
});
|
|
@@ -185,7 +188,7 @@ async function getKeystoreController({req}) {
|
|
|
185
188
|
id: req.webkms.keystore.id, req, returnRecord: true, fresh: true
|
|
186
189
|
});
|
|
187
190
|
const {config: keystore} = configRecord;
|
|
188
|
-
req.webkms = {keystore, configRecord};
|
|
191
|
+
req.webkms = {...req.webkms, keystore, configRecord};
|
|
189
192
|
logger.debug('Forced fresh keystore config retrieval during zcap check.');
|
|
190
193
|
}
|
|
191
194
|
|
|
@@ -243,10 +246,7 @@ function onError({error}) {
|
|
|
243
246
|
if(!(error instanceof BedrockError)) {
|
|
244
247
|
// always expose cause message and name; expose cause details as
|
|
245
248
|
// BedrockError if error is marked public
|
|
246
|
-
|
|
247
|
-
if(error.details && error.details.public) {
|
|
248
|
-
details = error.details;
|
|
249
|
-
}
|
|
249
|
+
const details = error.details?.public ? error.details : {};
|
|
250
250
|
error = new BedrockError(
|
|
251
251
|
error.message,
|
|
252
252
|
error.name || 'NotAllowedError', {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bedrock/kms-http",
|
|
3
|
-
"version": "14.3.
|
|
3
|
+
"version": "14.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bedrock KMS HTTP API",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@digitalbazaar/ed25519-signature-2020": "^3.0.0",
|
|
28
28
|
"@digitalbazaar/ed25519-verification-key-2020": "^3.2.0",
|
|
29
29
|
"@digitalbazaar/ezcap-express": "^6.2.0",
|
|
30
|
-
"@digitalbazaar/webkms-switch": "^10.
|
|
30
|
+
"@digitalbazaar/webkms-switch": "^10.2.0",
|
|
31
31
|
"cidr-regex": "^3.1.1",
|
|
32
32
|
"cors": "^2.8.5",
|
|
33
33
|
"crypto-ld": "^6.0.0",
|
|
@@ -67,7 +67,7 @@ describe('keystore API interactions using webkms-client', () => {
|
|
|
67
67
|
bobKeystoreAgent.keystoreId);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
it('updates config
|
|
70
|
+
it('updates config and uses key proving cache busting', async () => {
|
|
71
71
|
const keystoreId = aliceKeystoreConfig.id;
|
|
72
72
|
const kmsClient = new KmsClient({httpsAgent});
|
|
73
73
|
|
|
@@ -88,6 +88,9 @@ describe('keystore API interactions using webkms-client', () => {
|
|
|
88
88
|
const agent3KeystoreAgent = new KeystoreAgent(
|
|
89
89
|
{capabilityAgent: agent3, keystoreId, kmsClient});
|
|
90
90
|
|
|
91
|
+
// generate a key for use
|
|
92
|
+
const hmacKey = await aliceKeystoreAgent.generateKey({type: 'hmac'});
|
|
93
|
+
|
|
91
94
|
// delegate zcap for updating config from agent2 to agent3 to test
|
|
92
95
|
// cache busting with delegated zcap
|
|
93
96
|
const rootCapability = ZCAP_ROOT_PREFIX + encodeURIComponent(keystoreId);
|
|
@@ -120,7 +123,7 @@ describe('keystore API interactions using webkms-client', () => {
|
|
|
120
123
|
// disable cache delete functionality on update
|
|
121
124
|
keystores._disableClearCacheOnUpdate(true);
|
|
122
125
|
|
|
123
|
-
// update controller alice => agent1 (no cache busting required
|
|
126
|
+
// update controller alice => agent1 (no cache busting required)
|
|
124
127
|
{
|
|
125
128
|
config.sequence++;
|
|
126
129
|
config.controller = agent1.id;
|
|
@@ -164,6 +167,72 @@ describe('keystore API interactions using webkms-client', () => {
|
|
|
164
167
|
result.config.controller.should.eql(agent1.id);
|
|
165
168
|
({config} = result);
|
|
166
169
|
}
|
|
170
|
+
|
|
171
|
+
// update controller back to alice to test key op cache busting
|
|
172
|
+
{
|
|
173
|
+
config.sequence++;
|
|
174
|
+
config.controller = aliceCapabilityAgent.id;
|
|
175
|
+
const result = await agent1KeystoreAgent.updateConfig({config});
|
|
176
|
+
result.config.id.should.eql(config.id);
|
|
177
|
+
result.config.controller.should.eql(aliceCapabilityAgent.id);
|
|
178
|
+
({config} = result);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// use hmac key as alice (requires cache busting by inspecting root
|
|
182
|
+
// zcap)
|
|
183
|
+
await hmacKey.sign({data: new Uint8Array([0])});
|
|
184
|
+
|
|
185
|
+
// update controller alice => agent1 (no cache busting required)
|
|
186
|
+
{
|
|
187
|
+
config.sequence++;
|
|
188
|
+
config.controller = agent1.id;
|
|
189
|
+
const result = await aliceKeystoreAgent.updateConfig({config});
|
|
190
|
+
result.config.id.should.eql(config.id);
|
|
191
|
+
result.config.controller.should.eql(agent1.id);
|
|
192
|
+
({config} = result);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// use hmac key as agent1 (requires cache busting by
|
|
196
|
+
// inspecting the root zcap)
|
|
197
|
+
hmacKey.invocationSigner = agent1.getSigner();
|
|
198
|
+
// use different data each time to avoid hmac caching
|
|
199
|
+
await hmacKey.sign({data: new Uint8Array([1])});
|
|
200
|
+
|
|
201
|
+
// update controller agent1 => agent2 (requires cache busting by
|
|
202
|
+
// inspecting the root zcap)
|
|
203
|
+
{
|
|
204
|
+
config.sequence++;
|
|
205
|
+
config.controller = agent2.id;
|
|
206
|
+
const result = await agent1KeystoreAgent.updateConfig({config});
|
|
207
|
+
result.config.id.should.eql(config.id);
|
|
208
|
+
result.config.controller.should.eql(agent2.id);
|
|
209
|
+
({config} = result);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// use hmac key as agent3 (requires cache busting by
|
|
213
|
+
// inspecting a delegated zcap)
|
|
214
|
+
hmacKey.capability = agent3Zcap;
|
|
215
|
+
hmacKey.invocationSigner = agent3.getSigner();
|
|
216
|
+
// use different data each time to avoid hmac caching
|
|
217
|
+
await hmacKey.sign({data: new Uint8Array([1])});
|
|
218
|
+
|
|
219
|
+
// update controller agent2 => agent3 (cache should already be fresh)
|
|
220
|
+
{
|
|
221
|
+
config.sequence++;
|
|
222
|
+
config.controller = agent3.id;
|
|
223
|
+
const result = await agent3KeystoreAgent.updateConfig(
|
|
224
|
+
{capability: agent3Zcap, config});
|
|
225
|
+
result.config.id.should.eql(config.id);
|
|
226
|
+
result.config.controller.should.eql(agent3.id);
|
|
227
|
+
({config} = result);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// use hmac key as agent1 (requires cache busting by
|
|
231
|
+
// inspecting a deep delegated zcap)
|
|
232
|
+
hmacKey.capability = agent1Zcap;
|
|
233
|
+
hmacKey.invocationSigner = agent1.getSigner();
|
|
234
|
+
// use different data each time to avoid hmac caching
|
|
235
|
+
await hmacKey.sign({data: new Uint8Array([1])});
|
|
167
236
|
} catch(e) {
|
|
168
237
|
assertNoError(e);
|
|
169
238
|
} finally {
|