diff --git a/modules/cache-material/src/caching_cryptographic_materials_decorators.ts b/modules/cache-material/src/caching_cryptographic_materials_decorators.ts index c17c87cb2..87361bcb2 100644 --- a/modules/cache-material/src/caching_cryptographic_materials_decorators.ts +++ b/modules/cache-material/src/caching_cryptographic_materials_decorators.ts @@ -49,17 +49,17 @@ export function decorateProperties ( /* Precondition: You *can not* cache something forever. */ needs(maxAge > 0, 'You must configure a maxAge') /* Precondition: maxBytesEncrypted must be inside bounds. i.e. positive and not more than the maximum. */ - needs(!maxBytesEncrypted || (maxBytesEncrypted > 0 && Maximum.BYTES_PER_KEY >= maxBytesEncrypted), 'maxBytesEncrypted is outside of bounds.') + needs(!maxBytesEncrypted || (maxBytesEncrypted > 0 && Maximum.BYTES_PER_CACHED_KEY_LIMIT >= maxBytesEncrypted), 'maxBytesEncrypted is outside of bounds.') /* Precondition: maxMessagesEncrypted must be inside bounds. i.e. positive and not more than the maximum. */ - needs(!maxMessagesEncrypted || (maxMessagesEncrypted > 0 && Maximum.MESSAGES_PER_KEY >= maxMessagesEncrypted), 'maxMessagesEncrypted is outside of bounds.') + needs(!maxMessagesEncrypted || (maxMessagesEncrypted > 0 && Maximum.MESSAGES_PER_CACHED_KEY_LIMIT >= maxMessagesEncrypted), 'maxMessagesEncrypted is outside of bounds.') /* Precondition: partition must be a string. */ needs(partition && typeof partition === 'string', 'partition must be a string.') readOnlyProperty(obj, '_cache', cache) readOnlyProperty(obj, '_backingMaterialsManager', backingMaterialsManager) readOnlyProperty(obj, '_maxAge', maxAge) - readOnlyProperty(obj, '_maxBytesEncrypted', maxBytesEncrypted || Maximum.BYTES_PER_KEY) - readOnlyProperty(obj, '_maxMessagesEncrypted', maxMessagesEncrypted || Maximum.MESSAGES_PER_KEY) + readOnlyProperty(obj, '_maxBytesEncrypted', maxBytesEncrypted || Maximum.BYTES_PER_CACHED_KEY_LIMIT) + readOnlyProperty(obj, '_maxMessagesEncrypted', maxMessagesEncrypted || Maximum.MESSAGES_PER_CACHED_KEY_LIMIT) readOnlyProperty(obj, '_partition', partition) } diff --git a/modules/serialize/src/identifiers.ts b/modules/serialize/src/identifiers.ts index a92e28318..6da3c56a5 100644 --- a/modules/serialize/src/identifiers.ts +++ b/modules/serialize/src/identifiers.ts @@ -61,9 +61,25 @@ Object.freeze(SequenceIdentifier) export enum Maximum { // Maximum number of messages which are allowed to be encrypted under a single cached data key - MESSAGES_PER_KEY = 2 ** 32, // eslint-disable-line no-unused-vars - // Maximum number of bytes which are allowed to be encrypted under a single cached data key - BYTES_PER_KEY = 2 ** 63 - 1, // eslint-disable-line no-unused-vars + MESSAGES_PER_CACHED_KEY_LIMIT = 2 ** 32, // eslint-disable-line no-unused-vars + /* Maximum number of bytes that are allowed to be encrypted + * under a single cached data key across messages. + * The maximum value defined in the AWS Encryption SDK specification is 2 ** 63 - 1. + * However Javascript can only perform safe operations on values + * up to Number.MAX_SAFE_INTEGER === 9007199254740991 === 2 ** 53 - 1. + * e.g + * Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 => true + * Number.MAX_SAFE_INTEGER + 1 > Number.MAX_SAFE_INTEGER + 2 => false + * Number.MAX_SAFE_INTEGER + 1 < Number.MAX_SAFE_INTEGER + 2 => false + * + * This means that after 2 ** 53 - 1 the process of accumulating a byte count + * will never yield an accurate comparison and so, never halt. + * + * The choice here to use 2 ** 53 - 1 instead of Number.MAX_SAFE_INTEGER is deliberate. + * This is because in the future Number.MAX_SAFE_INTEGER could be raised to 2 ** 66 + * or some value larger 2 ** 63. + */ + BYTES_PER_CACHED_KEY_LIMIT = 2 ** 53 - 1, // eslint-disable-line no-unused-vars // Maximum number of frames allowed in one message as defined in specification FRAME_COUNT = 2 ** 32 - 1, // eslint-disable-line no-unused-vars // Maximum bytes allowed in a single frame as defined in specification