Skip to content

Commit 8a4d708

Browse files
authored
fix: 192 bit algorithm suite support in browsers (#131)
Resolves: # 72 Browsers do not support 192 bit keys. The proper place for this is in the WebCryptoAlgorithmSuite class. Move the logic from the CMM to WebCryptoAlgorithmSuite Add tests to cover the precondition.
1 parent 7ce474f commit 8a4d708

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

modules/material-management-browser/src/browser_cryptographic_materials_manager.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ export class WebCryptoDefaultCryptographicMaterialsManager implements WebCryptoM
4949
async getEncryptionMaterials ({ suite, encryptionContext }: WebCryptoEncryptionRequest): Promise<WebCryptoEncryptionResponse> {
5050
suite = suite || new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384)
5151
const material = new WebCryptoEncryptionMaterial(suite)
52-
/* Precondition: Browsers do not support 192 bit keys so I do not support encrypt.
53-
* This is primarily an error in decrypt but this make it clear.
54-
* The error can manifest deep in the decrypt loop making it hard to debug.
55-
*/
56-
needs(suite.keyLength !== 192, '192-bit AES keys are not supported')
5752

5853
const context = await this._generateSigningKeyAndUpdateEncryptionContext(material, encryptionContext)
5954

@@ -69,10 +64,6 @@ export class WebCryptoDefaultCryptographicMaterialsManager implements WebCryptoM
6964
}
7065

7166
async decryptMaterials ({ suite, encryptedDataKeys, encryptionContext }: WebCryptoDecryptionRequest): Promise<WebCryptoDecryptionResponse> {
72-
/* Precondition: Browsers do not support 192 bit keys, do not attempt decrypt.
73-
* The error can manifest deep in the decrypt loop making it hard to debug.
74-
*/
75-
needs(suite.keyLength !== 192, '192-bit AES keys are not supported')
7667
const material = await this._loadVerificationKeyFromEncryptionContext(new WebCryptoDecryptionMaterial(suite), encryptionContext)
7768

7869
await this.keyring.onDecrypt(material, encryptedDataKeys.slice(), encryptionContext)

modules/material-management/src/web_crypto_algorithms.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
IWebCryptoAlgorithmSuite, WebCryptoEncryption, WebCryptoHash, // eslint-disable-line no-unused-vars
2929
WebCryptoECDHCurve, AlgorithmSuiteTypeWebCrypto // eslint-disable-line no-unused-vars
3030
} from './algorithm_suites'
31+
import { needs } from './needs'
3132

3233
/* References to https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/algorithms-reference.html
3334
* These are the composed parameters for each algorithm suite specification for
@@ -41,6 +42,7 @@ const webCryptoAlgAes128GcmIv12Tag16: IWebCryptoAlgorithmSuite = {
4142
tagLength: 128,
4243
cacheSafe: false
4344
}
45+
/* Web browsers do not support 192 bit key lengths at this time. */
4446
const webCryptoAlgAes192GcmIv12Tag16: IWebCryptoAlgorithmSuite = {
4547
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16,
4648
encryption: 'AES-GCM',
@@ -67,6 +69,7 @@ const webCryptoAlgAes128GcmIv12Tag16HkdfSha256: IWebCryptoAlgorithmSuite = {
6769
kdfHash: 'SHA-256',
6870
cacheSafe: true
6971
}
72+
/* Web browsers do not support 192 bit key lengths at this time. */
7073
const webCryptoAlgAes192GcmIv12Tag16HkdfSha256: IWebCryptoAlgorithmSuite = {
7174
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256,
7275
encryption: 'AES-GCM',
@@ -99,6 +102,7 @@ const webCryptoAlgAes128GcmIv12Tag16HkdfSha256EcdsaP256: IWebCryptoAlgorithmSuit
99102
signatureCurve: 'P-256',
100103
signatureHash: 'SHA-256'
101104
}
105+
/* Web browsers do not support 192 bit key lengths at this time. */
102106
const webCryptoAlgAes192GcmIv12Tag16HkdfSha384EcdsaP384: IWebCryptoAlgorithmSuite = {
103107
id: AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384,
104108
encryption: 'AES-GCM',
@@ -137,6 +141,28 @@ const webCryptoAlgorithms: WebCryptoAlgorithms = Object.freeze({
137141
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384)
138142
})
139143

144+
/* Web browsers do not support 192 bit key lengths at this time.
145+
* To maintain type compatibility and TypeScript happiness between Algorithm Suites
146+
* I need to have the same list of AlgorithmSuiteIdentifier.
147+
* This list is maintained here to make sure that the error message is helpful.
148+
*/
149+
type WebCryptoAlgorithmSuiteIdentifier = Exclude<Exclude<Exclude<AlgorithmSuiteIdentifier,
150+
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16>,
151+
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256>,
152+
AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384>
153+
type SupportedWebCryptoAlgorithms = Readonly<{[id in WebCryptoAlgorithmSuiteIdentifier]: IWebCryptoAlgorithmSuite}>
154+
const supportedWebCryptoAlgorithms: SupportedWebCryptoAlgorithms = Object.freeze({
155+
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16),
156+
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16),
157+
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16),
158+
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16HkdfSha256),
159+
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16HkdfSha256),
160+
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA256]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha256),
161+
[AlgorithmSuiteIdentifier.ALG_AES128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256]: Object.freeze(webCryptoAlgAes128GcmIv12Tag16HkdfSha256EcdsaP256),
162+
// [AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes192GcmIv12Tag16HkdfSha384EcdsaP384),
163+
[AlgorithmSuiteIdentifier.ALG_AES256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384]: Object.freeze(webCryptoAlgAes256GcmIv12Tag16HkdfSha384EcdsaP384)
164+
})
165+
140166
export class WebCryptoAlgorithmSuite extends AlgorithmSuite implements IWebCryptoAlgorithmSuite {
141167
encryption!: WebCryptoEncryption
142168
kdfHash?: WebCryptoHash
@@ -145,6 +171,11 @@ export class WebCryptoAlgorithmSuite extends AlgorithmSuite implements IWebCrypt
145171
type: AlgorithmSuiteTypeWebCrypto = 'webCrypto'
146172
constructor (id: AlgorithmSuiteIdentifier) {
147173
super(webCryptoAlgorithms[id])
174+
/* Precondition: Browsers do not support 192 bit keys so the AlgorithmSuiteIdentifier is removed.
175+
* This is primarily an error in decrypt but this make it clear.
176+
* The error can manifest deep in the decrypt loop making it hard to debug.
177+
*/
178+
needs(supportedWebCryptoAlgorithms.hasOwnProperty(id), '192-bit AES keys are not supported')
148179
Object.setPrototypeOf(this, WebCryptoAlgorithmSuite.prototype)
149180
Object.freeze(this)
150181
}

modules/material-management/test/web_crypto_algorithms.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,10 @@ describe('WebCryptoAlgorithmSuite', () => {
4040
expect(Object.isFrozen(WebCryptoAlgorithmSuite)).to.equal(true)
4141
expect(Object.isFrozen(WebCryptoAlgorithmSuite.prototype)).to.equal(true)
4242
})
43+
44+
it('Precondition: Browsers do not support 192 bit keys so the AlgorithmSuiteIdentifier is removed.', () => {
45+
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16)).to.throw()
46+
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA256)).to.throw()
47+
expect(() => new WebCryptoAlgorithmSuite(AlgorithmSuiteIdentifier.ALG_AES192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384)).to.throw()
48+
})
4349
})

0 commit comments

Comments
 (0)