|
1 | 1 | // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
2 | 2 | // SPDX-License-Identifier: Apache-2.0
|
3 | 3 |
|
4 |
| -import { IBranchKeyStorage, EncryptedHierarchicalKey } from './types' |
| 4 | +import { |
| 5 | + IBranchKeyStorage, |
| 6 | + EncryptedHierarchicalKey, |
| 7 | + ActiveHierarchicalSymmetricVersion, |
| 8 | + HierarchicalSymmetricVersion, |
| 9 | +} from './types' |
5 | 10 | import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
|
6 | 11 | import {
|
7 | 12 | getBranchKeyItem,
|
@@ -32,6 +37,9 @@ export interface DynamoDBKeyStorageInput {
|
32 | 37 | ddbClient: DynamoDBClient
|
33 | 38 | }
|
34 | 39 |
|
| 40 | +//= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#operations |
| 41 | +//= type=implication |
| 42 | +//# The Dynamodb Key Storage Interface MUST implement the [key storage interface](./key-storage.md#interface). |
35 | 43 | export class DynamoDBKeyStorage implements IBranchKeyStorage {
|
36 | 44 | public declare readonly ddbTableName: string
|
37 | 45 | public declare readonly logicalKeyStoreName: string
|
@@ -70,52 +78,140 @@ export class DynamoDBKeyStorage implements IBranchKeyStorage {
|
70 | 78 | public async getEncryptedActiveBranchKey(
|
71 | 79 | branchKeyId: string
|
72 | 80 | ): Promise<EncryptedHierarchicalKey> {
|
| 81 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedactivebranchkey |
| 82 | + //# To get the active version for the branch key id from the keystore |
| 83 | + //# this operation MUST call AWS DDB `GetItem` |
| 84 | + //# using the `branch-key-id` as the Partition Key and `"branch:ACTIVE"` value as the Sort Key. |
| 85 | + |
73 | 86 | // get the ddb response item using the partition & sort keys
|
74 | 87 | const ddbBranchKeyItem = await getBranchKeyItem(
|
75 | 88 | this,
|
76 | 89 | branchKeyId,
|
77 | 90 | BRANCH_KEY_ACTIVE_TYPE
|
78 | 91 | )
|
79 | 92 | // validate and form the branch key record
|
| 93 | + |
| 94 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedactivebranchkey |
| 95 | + //# If the record does not contain the defined fields, this operation MUST fail. |
| 96 | + |
| 97 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedactivebranchkey |
| 98 | + //# The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format). |
80 | 99 | const ddbBranchKeyRecord = validateBranchKeyRecord(ddbBranchKeyItem)
|
81 | 100 | // construct an encryption context from the record
|
82 | 101 | const authenticatedEncryptionContext =
|
83 | 102 | constructAuthenticatedEncryptionContext(this, ddbBranchKeyRecord)
|
84 | 103 |
|
85 |
| - return new EncryptedHierarchicalKey( |
| 104 | + const encrypted = new EncryptedHierarchicalKey( |
86 | 105 | authenticatedEncryptionContext,
|
87 | 106 | ddbBranchKeyRecord[BRANCH_KEY_FIELD]
|
88 | 107 | )
|
| 108 | + |
| 109 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedactivebranchkey |
| 110 | + //# The returned EncryptedHierarchicalKey MUST have the same identifier as the input. |
| 111 | + needs(encrypted.branchKeyId == branchKeyId, 'Unexpected branch key id.') |
| 112 | + |
| 113 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedactivebranchkey |
| 114 | + //# The returned EncryptedHierarchicalKey MUST have a type of ActiveHierarchicalSymmetricVersion. |
| 115 | + needs( |
| 116 | + encrypted.type instanceof ActiveHierarchicalSymmetricVersion, |
| 117 | + 'Unexpected type. Not an active record.' |
| 118 | + ) |
| 119 | + |
| 120 | + return encrypted |
89 | 121 | }
|
90 | 122 |
|
91 | 123 | public async getEncryptedBranchKeyVersion(
|
92 | 124 | branchKeyId: string,
|
93 | 125 | branchKeyVersion: string
|
94 | 126 | ): Promise<EncryptedHierarchicalKey> {
|
| 127 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 128 | + //# To get a branch key from the keystore this operation MUST call AWS DDB `GetItem` |
| 129 | + //# using the `branch-key-id` as the Partition Key and "branch:version:" + `branchKeyVersion` value as the Sort Key. |
| 130 | + |
95 | 131 | // get the ddb response item using the partition & sort keys
|
96 | 132 | const ddbBranchKeyItem = await getBranchKeyItem(
|
97 | 133 | this,
|
98 | 134 | branchKeyId,
|
99 | 135 | BRANCH_KEY_TYPE_PREFIX + branchKeyVersion
|
100 | 136 | )
|
| 137 | + |
| 138 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 139 | + //# If the record does not contain the defined fields, this operation MUST fail. |
| 140 | + |
| 141 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 142 | + //# The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format). |
| 143 | + |
101 | 144 | // validate and form the branch key record
|
102 | 145 | const ddbBranchKeyRecord = validateBranchKeyRecord(ddbBranchKeyItem)
|
103 | 146 | // construct an encryption context from the record
|
104 | 147 | const authenticatedEncryptionContext =
|
105 | 148 | constructAuthenticatedEncryptionContext(this, ddbBranchKeyRecord)
|
106 | 149 |
|
107 |
| - return new EncryptedHierarchicalKey( |
| 150 | + const encrypted = new EncryptedHierarchicalKey( |
108 | 151 | authenticatedEncryptionContext,
|
109 | 152 | ddbBranchKeyRecord[BRANCH_KEY_FIELD]
|
110 | 153 | )
|
| 154 | + |
| 155 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 156 | + //# The returned EncryptedHierarchicalKey MUST have the same identifier as the input. |
| 157 | + needs(encrypted.branchKeyId == branchKeyId, 'Unexpected branch key id.') |
| 158 | + |
| 159 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 160 | + //# The returned EncryptedHierarchicalKey MUST have the same version as the input. |
| 161 | + needs( |
| 162 | + encrypted.type.version == branchKeyVersion, |
| 163 | + 'Unexpected branch key version.' |
| 164 | + ) |
| 165 | + |
| 166 | + //= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbranchkeyversion |
| 167 | + //# The returned EncryptedHierarchicalKey MUST have a type of HierarchicalSymmetricVersion. |
| 168 | + needs( |
| 169 | + encrypted.type instanceof HierarchicalSymmetricVersion, |
| 170 | + 'Unexpected type. Not an version record.' |
| 171 | + ) |
| 172 | + |
| 173 | + return encrypted |
111 | 174 | }
|
112 | 175 |
|
113 | 176 | getKeyStorageInfo() {
|
114 | 177 | return {
|
115 | 178 | name: this.ddbTableName,
|
116 |
| - logicalName: this.logicalKeyStoreName |
| 179 | + logicalName: this.logicalKeyStoreName, |
117 | 180 | }
|
118 | 181 | }
|
119 | 182 | }
|
120 | 183 |
|
121 | 184 | immutableClass(DynamoDBKeyStorage)
|
| 185 | + |
| 186 | +// This is a limited release for JS only. |
| 187 | +// The full Key Store operations are available |
| 188 | +// in the AWS Cryptographic Material Providers library |
| 189 | +// in various languages (Java, .Net, Python, Rust...) |
| 190 | + |
| 191 | +//= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#writenewencryptedbranchkey |
| 192 | +//= type=exception |
| 193 | +//# To add the branch keys and a beacon key to the keystore the |
| 194 | +//# operation MUST call [Amazon DynamoDB API TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html). |
| 195 | +//# The call to Amazon DynamoDB TransactWriteItems MUST use the configured Amazon DynamoDB Client to make the call. |
| 196 | +//# The operation MUST call Amazon DynamoDB TransactWriteItems with a request constructed as follows: |
| 197 | + |
| 198 | +//= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#writenewencryptedbranchkey |
| 199 | +//= type=exception |
| 200 | +//# If DDB TransactWriteItems is successful, this operation MUST return a successful response containing no additional data. |
| 201 | +//# Otherwise, this operation MUST yield an error. |
| 202 | + |
| 203 | +//= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#writenewencryptedbranchkeyversion |
| 204 | +//= type=exception |
| 205 | +//# To add the new branch key to the keystore, |
| 206 | +//# the operation MUST call [Amazon DynamoDB API TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html). |
| 207 | +//# The call to Amazon DynamoDB TransactWriteItems MUST use the configured Amazon DynamoDB Client to make the call. |
| 208 | +//# The operation MUST call Amazon DynamoDB TransactWriteItems with a request constructed as follows: |
| 209 | + |
| 210 | +//= aws-encryption-sdk-specification/framework/key-store/dynamodb-key-storage.md#getencryptedbeaconkey |
| 211 | +//= type=exception |
| 212 | +//# To get a branch key from the keystore this operation MUST call AWS DDB `GetItem` |
| 213 | +//# using the `branch-key-id` as the Partition Key and "beacon:ACTIVE" value as the Sort Key. |
| 214 | +//# The AWS DDB response MUST contain the fields defined in the [branch keystore record format](#record-format). |
| 215 | +//# The returned EncryptedHierarchicalKey MUST have the same identifier as the input. |
| 216 | +//# The returned EncryptedHierarchicalKey MUST have a type of ActiveHierarchicalSymmetricBeacon. |
| 217 | +//# If the record does not contain the defined fields, this operation MUST fail. |
0 commit comments