const crypto = require('crypto');
const zlib = require('zlib');
const { promisify } = require('util');
+const { base64ToBase64URL, base64URLToBase64 } = require('@squeep/base64url');
const common = require('./common');
const allVersions = require('./version-parameters');
const { performance } = require('perf_hooks');
const tag = cipher.getAuthTag();
const merged = Buffer.concat([versionBuffer, flagsBuffer, iv, salt, tag, encrypted, final]).toString('base64');
- const result = common.base64ToBase64URL(merged);
+ const result = base64ToBase64URL(merged);
timingsMs.end = timingsMs.postCrypt = performance.now();
this.logger.debug(_scope, 'statistics', { version, flags: this._prettyFlags(flags), serialized: contents.length, compressed: payload.length, encoded: result.length, ...MysteryBox._timingsLog(timingsMs) });
end: 0,
};
- const raw = Buffer.from(common.base64URLToBase64(box), 'base64');
+ if (!box) {
+ throw new RangeError('nothing to unpack');
+ }
+
+ const raw = Buffer.from(base64URLToBase64(box), 'base64');
let offset = 0;
const version = raw.slice(offset, 1).readUInt8(0);
const v = this.versionParameters[version];
offset += v.versionBytes;
+ const minBytes = v.versionBytes + v.flagsBytes + v.ivBytes + v.saltBytes + v.tagBytes;
+ if (raw.length < minBytes) {
+ throw new RangeError('not enough to unpack');
+ }
+
const flags = raw.slice(offset, offset + v.flagsBytes).readUInt8(0);
offset += v.flagsBytes;