Skip to content

Commit 6fab564

Browse files
authored
feat: Adds create and version branch key functionality (#1652)
* feat: Adds VersionKey API to version the branch key (#1642) * feat: Adds VersionKey API to version the branch key * fix: removes console log which caused the lint failures --------- Co-authored-by: Bikram Sharma <shbikram@amazon.com> * feat: Adds CreateKey API to create a branch key * test: update test cases to ensure EC is preserved when creating and versioning a branch key * test: Adds comment about EC prefix behavior difference between dafny and JavaScript implementation * test: Updates the test to ensure EC we get in branch key doesn't contain internal prefix
1 parent 6fd56ea commit 6fab564

3 files changed

Lines changed: 852 additions & 1 deletion

File tree

modules/branch-keystore-node/src/branch_keystore.ts

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import {
1616
decryptBranchKey,
1717
} from './branch_keystore_helpers'
1818
import { KMS_CLIENT_USER_AGENT, TABLE_FIELD } from './constants'
19+
import {
20+
createBranchAndBeaconKeys,
21+
versionActiveBranchKey,
22+
} from './key_helpers'
1923

2024
import {
2125
IBranchKeyStorage,
@@ -45,8 +49,15 @@ interface IBranchKeyStoreNode {
4549
//= type=implication
4650
//# - [GetKeyStoreInfo](#getkeystoreinfo)
4751
getKeyStoreInfo(): KeyStoreInfoOutput
52+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#operations
53+
//= type=implication
54+
//# - [VersionKey](#versionkey)
55+
versionKey(input: VersionKeyInput): Promise<void>
56+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#operations
57+
//= type=implication
58+
//# - [CreateKey](#createkey)
59+
createKey(input?: CreateKeyInput): Promise<CreateKeyOutput>
4860
}
49-
5061
//= aws-encryption-sdk-specification/framework/branch-key-store.md#getkeystoreinfo
5162
//= type=implication
5263
//# This MUST include:
@@ -64,6 +75,19 @@ export interface KeyStoreInfoOutput {
6475
kmsConfiguration: KmsConfig
6576
}
6677

78+
export interface VersionKeyInput {
79+
branchKeyIdentifier: string
80+
}
81+
82+
export interface CreateKeyInput {
83+
branchKeyIdentifier?: string
84+
encryptionContext?: { [key: string]: string }
85+
}
86+
87+
export interface CreateKeyOutput {
88+
branchKeyIdentifier: string
89+
}
90+
6791
export class BranchKeyStoreNode implements IBranchKeyStoreNode {
6892
public declare readonly logicalKeyStoreName: string
6993
public declare readonly kmsConfiguration: Readonly<KmsKeyConfig>
@@ -383,6 +407,83 @@ export class BranchKeyStoreNode implements IBranchKeyStoreNode {
383407
return branchKeyMaterials
384408
}
385409

410+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
411+
//# The CreateKey caller MUST provide:
412+
//# - An optional branch key id
413+
//# - An optional encryption context
414+
async createKey(input?: CreateKeyInput): Promise<CreateKeyOutput> {
415+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
416+
//# If the Keystore's KMS Configuration is `Discovery` or `MRDiscovery`,
417+
//# this operation MUST fail.
418+
needs(
419+
typeof this.kmsConfiguration._config === 'object' &&
420+
('identifier' in this.kmsConfiguration._config ||
421+
'mrkIdentifier' in this.kmsConfiguration._config),
422+
'CreateKey is not supported with Discovery or MRDiscovery KMS Configuration'
423+
)
424+
425+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
426+
//# If an optional branch key id is provided and no encryption context is provided
427+
//# this operation MUST fail.
428+
if (input?.branchKeyIdentifier) {
429+
needs(
430+
input.encryptionContext &&
431+
Object.keys(input.encryptionContext).length > 0,
432+
'If branch key identifier is provided, encryption context must also be provided'
433+
)
434+
}
435+
436+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
437+
//# If no branch key id is provided, then this operation MUST create a
438+
//# version 4 UUID to be used as the branch key id.
439+
const branchKeyIdentifier = input?.branchKeyIdentifier || v4()
440+
const customEncryptionContext = input?.encryptionContext || {}
441+
442+
await createBranchAndBeaconKeys({
443+
branchKeyIdentifier,
444+
customEncryptionContext,
445+
logicalKeyStoreName: this.logicalKeyStoreName,
446+
kmsConfiguration: this.kmsConfiguration,
447+
grantTokens: this.grantTokens,
448+
kmsClient: this.kmsClient,
449+
ddbClient: (this.storage as any).ddbClient,
450+
ddbTableName: (this.storage as any).ddbTableName,
451+
})
452+
453+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#createkey
454+
//# If writing to the keystore succeeds,
455+
//# the operation MUST return the branch-key-id that maps to both the branch key and the beacon key.
456+
return { branchKeyIdentifier }
457+
}
458+
459+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#versionkey
460+
//# On invocation, the caller:
461+
//# - MUST supply a `branch-key-id`
462+
async versionKey(input: VersionKeyInput): Promise<void> {
463+
needs(input.branchKeyIdentifier, 'MUST supply a branch-key-id')
464+
465+
//= aws-encryption-sdk-specification/framework/branch-key-store.md#versionkey
466+
//# If the Keystore's KMS Configuration is `Discovery` or `MRDiscovery`,
467+
//# this operation MUST immediately fail.
468+
needs(
469+
typeof this.kmsConfiguration._config === 'object' &&
470+
('identifier' in this.kmsConfiguration._config ||
471+
'mrkIdentifier' in this.kmsConfiguration._config),
472+
'VersionKey is not supported with Discovery or MRDiscovery KMS Configuration'
473+
)
474+
475+
await versionActiveBranchKey({
476+
branchKeyIdentifier: input.branchKeyIdentifier,
477+
logicalKeyStoreName: this.logicalKeyStoreName,
478+
kmsConfiguration: this.kmsConfiguration,
479+
grantTokens: this.grantTokens,
480+
kmsClient: this.kmsClient,
481+
ddbClient: (this.storage as any).ddbClient,
482+
ddbTableName: (this.storage as any).ddbTableName,
483+
storage: this.storage,
484+
})
485+
}
486+
386487
//= aws-encryption-sdk-specification/framework/branch-key-store.md#getkeystoreinfo
387488
//= type=implication
388489
//# This operation MUST return the keystore information in this keystore configuration.

0 commit comments

Comments
 (0)