@@ -12,53 +12,46 @@ import {
1212 NodeDecryptionMaterial ,
1313 NodeEncryptionMaterial ,
1414} from '@aws-crypto/material-management-node'
15- import { buildDecrypt } from '../src/index'
15+ import { buildDecrypt , DecryptOutput } from '../src/index'
16+ import { buildEncrypt } from '@aws-crypto/encrypt-node'
1617import * as fixtures from './fixtures'
1718chai . use ( chaiAsPromised )
1819const { expect } = chai
1920import {
21+ AlgorithmSuiteIdentifier ,
2022 CommitmentPolicy ,
2123 MessageFormat ,
2224 needs ,
25+ NodeBranchKeyMaterial ,
2326} from '@aws-crypto/material-management'
2427
25- import { KmsKeyringNode } from '@aws-crypto/kms-keyring-node'
28+ import {
29+ KmsHierarchicalKeyRingNode ,
30+ KmsKeyringNode ,
31+ } from '@aws-crypto/kms-keyring-node'
32+ import { BranchKeyStoreNode } from '@aws-crypto/branch-keystore-node'
33+
34+ import { deserializeFactory } from '@aws-crypto/serialize'
35+ import { NodeAlgorithmSuite } from '@aws-crypto/material-management-node'
36+ import { readFileSync , writeFileSync } from 'fs'
37+ const toUtf8 = ( input : Uint8Array ) =>
38+ Buffer . from ( input . buffer , input . byteOffset , input . byteLength ) . toString ( 'utf8' )
39+ const deserialize = deserializeFactory ( toUtf8 , NodeAlgorithmSuite )
2640
2741const { decrypt } = buildDecrypt ( CommitmentPolicy . FORBID_ENCRYPT_ALLOW_DECRYPT )
42+ const { encrypt } = buildEncrypt ( CommitmentPolicy . REQUIRE_ENCRYPT_ALLOW_DECRYPT )
2843
2944describe ( 'committing algorithm test' , ( ) => {
3045 fixtures . compatibilityVectors ( ) . tests . forEach ( ( test ) => {
3146 it ( test . comment , async ( ) => {
32- const {
33- ciphertext,
34- status,
35- 'plaintext-frames' : plaintextFrames ,
36- commitment,
37- 'message-id' : messageId ,
38- 'encryption-context' : encryptionContext ,
39- } = test
47+ const { ciphertext, status } = test
4048 const keyring = buildKeyring ( test )
4149 if ( status ) {
42- const { plaintext, messageHeader } = await decrypt (
43- keyring ,
44- ciphertext ,
45- {
46- encoding : 'base64' ,
47- }
48- )
49- needs (
50- plaintextFrames && messageHeader . version === MessageFormat . V2 ,
51- 'Message Failure'
52- )
53-
54- expect ( plaintext . toString ( ) ) . to . equal ( plaintextFrames . join ( '' ) )
55- expect (
56- Buffer . from ( messageHeader . suiteData ) . toString ( 'base64' )
57- ) . to . deep . equal ( commitment )
58- expect (
59- Buffer . from ( messageHeader . messageId ) . toString ( 'base64' )
60- ) . to . deep . equal ( messageId )
61- expect ( messageHeader . encryptionContext ) . to . deep . equal ( encryptionContext )
50+ const output = await decrypt ( keyring , ciphertext , {
51+ encoding : 'base64' ,
52+ } )
53+
54+ ExpectCompatibilityVector ( test , output )
6255 } else {
6356 await expect (
6457 decrypt ( keyring , ciphertext , { encoding : 'base64' } )
@@ -67,26 +60,172 @@ describe('committing algorithm test', () => {
6760 } )
6861 } )
6962
63+ fixtures . hierarchicalKeyringCompatibilityVectors ( ) . tests . forEach ( ( test ) => {
64+ it ( `Decrypt test: ${ test . comment } ` , async ( ) => {
65+ const { ciphertext, status } = test
66+ const keyring = buildKeyring ( test )
67+ needs ( status , 'Unexpected Status' )
68+ const output = await decrypt ( keyring , ciphertext , {
69+ encoding : 'base64' ,
70+ } )
71+
72+ ExpectCompatibilityVector ( test , output )
73+ } )
74+ } )
75+
76+ fixtures . hierarchicalKeyringCompatibilityVectors ( ) . tests . forEach ( ( test ) => {
77+ let once = false
78+ it ( `Encrypt test: ${ test . comment } ` , async ( ) => {
79+ const { plaintextBase64, status } = test
80+ const keyring = buildKeyring ( test )
81+ needs ( status , 'Unexpected Status' )
82+ needs ( plaintextBase64 , 'Nothing to encrypt' )
83+
84+ const suiteId = AlgorithmSuiteIdentifier . ALG_AES256_GCM_IV12_TAG16_HKDF_SHA512_COMMIT_KEY
85+ once = true
86+
87+ const encryptOutput = await encrypt ( keyring , plaintextBase64 , {
88+ encoding : 'base64' ,
89+ suiteId,
90+ } )
91+
92+ const decryptOutput = await decrypt ( keyring , encryptOutput . result )
93+ expect ( decryptOutput . plaintext . toString ( 'base64' ) ) . to . equal (
94+ plaintextBase64
95+ )
96+ } )
97+ } )
98+
99+ function ExpectCompatibilityVector (
100+ {
101+ 'plaintext-frames' : plaintextFrames ,
102+ plaintextBase64,
103+ commitment,
104+ 'message-id' : messageId ,
105+ 'encryption-context' : encryptionContext ,
106+ } : fixtures . VectorTest ,
107+ { plaintext, messageHeader } : DecryptOutput
108+ ) {
109+ needs ( messageHeader . version === MessageFormat . V2 , 'Message Failure' )
110+
111+ if ( plaintextBase64 ) {
112+ expect ( plaintext . toString ( 'base64' ) ) . to . equal ( plaintextBase64 )
113+ }
114+ if ( plaintextFrames ) {
115+ expect ( plaintext . toString ( ) ) . to . equal ( plaintextFrames . join ( '' ) )
116+ }
117+ expect (
118+ Buffer . from ( messageHeader . suiteData ) . toString ( 'base64' )
119+ ) . to . deep . equal ( commitment )
120+ expect (
121+ Buffer . from ( messageHeader . messageId ) . toString ( 'base64' )
122+ ) . to . deep . equal ( messageId )
123+ expect ( messageHeader . encryptionContext ) . to . deep . equal ( encryptionContext )
124+ }
125+
70126 function buildKeyring ( test : fixtures . VectorTest ) {
71- if ( test [ 'keyring-type' ] === 'aws-kms' ) {
72- return new KmsKeyringNode ( { discovery : true } )
127+ switch ( test [ 'keyring-type' ] ) {
128+ case 'aws-kms' :
129+ return new KmsKeyringNode ( { discovery : true } )
130+ case 'static' :
131+ const dataKey = Buffer . alloc ( 32 , test [ 'decrypted-dek' ] , 'base64' )
132+
133+ return new ( class TestKeyring extends KeyringNode {
134+ async _onEncrypt ( ) : Promise < NodeEncryptionMaterial > {
135+ throw new Error ( 'I should never see this error' )
136+ }
137+ async _onDecrypt ( material : NodeDecryptionMaterial ) {
138+ const unencryptedDataKey = dataKey
139+ const trace = {
140+ keyNamespace : 'k' ,
141+ keyName : 'k' ,
142+ flags : KeyringTraceFlag . WRAPPING_KEY_DECRYPTED_DATA_KEY ,
143+ }
144+ return material . setUnencryptedDataKey ( unencryptedDataKey , trace )
145+ }
146+ } ) ( )
147+
148+ case 'static-branch-key' :
149+ // This is serious hackery.
150+ // This is *NOT* recommended.
151+ // The proper extension point for the KeyStore is _only_ the Storage interface!
152+ // However, this does let us do some quick test vector testing.
153+ // At this time this is overly perscriptive,
154+ // but the expectation is to be able to depracate this
155+ // in favor of the test vectors project (integration-node)
156+ const keyStore = {
157+ __proto__ : BranchKeyStoreNode . prototype ,
158+ kmsConfiguration : {
159+ getRegion ( ) {
160+ return null
161+ } ,
162+ } ,
163+
164+ getKeyStoreInfo ( ) {
165+ return {
166+ logicalKeyStoreName : 'logicalKeyStoreName' ,
167+ }
168+ } ,
169+
170+ async getBranchKeyVersion (
171+ branchKeyId : string ,
172+ branchKeyVersion : string
173+ ) : Promise < NodeBranchKeyMaterial > {
174+ needs (
175+ branchKeyId == 'bd3842ff-3076-4092-9918-4395730050b8' ,
176+ branchKeyId
177+ )
178+ needs (
179+ branchKeyVersion == 'e9ce18a3-edb5-4272-9f86-1cacb7997ff6' ,
180+ branchKeyVersion
181+ )
182+
183+ return new NodeBranchKeyMaterial (
184+ Buffer . from (
185+ 'tJwf65epYvUt5HMiQsl/6jlvLxS0tgdjIuvFy2BLIwg=' ,
186+ 'base64'
187+ ) ,
188+ branchKeyId ,
189+ branchKeyVersion ,
190+ { }
191+ )
192+ } ,
193+ async getActiveBranchKey (
194+ branchKeyId : string
195+ ) : Promise < NodeBranchKeyMaterial > {
196+ needs (
197+ branchKeyId == 'bd3842ff-3076-4092-9918-4395730050b8' ,
198+ branchKeyId
199+ )
200+
201+ return new NodeBranchKeyMaterial (
202+ Buffer . from (
203+ 'tJwf65epYvUt5HMiQsl/6jlvLxS0tgdjIuvFy2BLIwg=' ,
204+ 'base64'
205+ ) ,
206+ branchKeyId ,
207+ 'e9ce18a3-edb5-4272-9f86-1cacb7997ff6' ,
208+ { }
209+ )
210+ } ,
211+
212+ storage : {
213+ _config : { } ,
214+ getKeyStorageInfo ( ) {
215+ return {
216+ logicalName : 'logicalKeyStoreName' ,
217+ }
218+ } ,
219+ } ,
220+ } as any
221+
222+ return new KmsHierarchicalKeyRingNode ( {
223+ branchKeyId : 'bd3842ff-3076-4092-9918-4395730050b8' ,
224+ keyStore,
225+ cacheLimitTtl : 1 ,
226+ } )
73227 }
74- needs ( test [ 'keyring-type' ] === 'static' , 'wtf yo' )
75- const dataKey = Buffer . alloc ( 32 , test [ 'decrypted-dek' ] , 'base64' )
76228
77- return new ( class TestKeyring extends KeyringNode {
78- async _onEncrypt ( ) : Promise < NodeEncryptionMaterial > {
79- throw new Error ( 'I should never see this error' )
80- }
81- async _onDecrypt ( material : NodeDecryptionMaterial ) {
82- const unencryptedDataKey = dataKey
83- const trace = {
84- keyNamespace : 'k' ,
85- keyName : 'k' ,
86- flags : KeyringTraceFlag . WRAPPING_KEY_DECRYPTED_DATA_KEY ,
87- }
88- return material . setUnencryptedDataKey ( unencryptedDataKey , trace )
89- }
90- } ) ( )
229+ needs ( false , 'Unexpected keyring-type:' + test [ 'keyring-type' ] )
91230 }
92231} )
0 commit comments