react-native-quick-crypto
Version:
A fast implementation of Node's `crypto` module written in C/C++ JSI
98 lines (96 loc) • 3.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getUsagesUnion = void 0;
exports.hasAnyNotIn = hasAnyNotIn;
exports.isStringOrBuffer = isStringOrBuffer;
exports.validateFunction = validateFunction;
exports.validateMaxBufferLength = exports.validateKeyOps = void 0;
exports.validateObject = validateObject;
var _safeBuffer = require("safe-buffer");
var _errors = require("./errors");
// The maximum buffer size that we'll support in the WebCrypto impl
const kMaxBufferLength = 2 ** 31 - 1;
function validateFunction(f) {
return f !== null && typeof f === 'function';
}
function isStringOrBuffer(val) {
return typeof val === 'string' || ArrayBuffer.isView(val) || val instanceof ArrayBuffer;
}
function validateObject(value, name, options) {
const useDefaultOptions = options == null;
const allowArray = useDefaultOptions ? false : options.allowArray;
const allowFunction = useDefaultOptions ? false : options.allowFunction;
const nullable = useDefaultOptions ? false : options.nullable;
if (!nullable && value === null || !allowArray && Array.isArray(value) || typeof value !== 'object' && (!allowFunction || typeof value !== 'function')) {
throw new Error(`${name} is not a valid object ${value}`);
}
return true;
}
const validateMaxBufferLength = (data, name) => {
const length = typeof data === 'string' || data instanceof _safeBuffer.Buffer ? data.length : data.byteLength;
if (length > kMaxBufferLength) {
throw (0, _errors.lazyDOMException)(`${name} must be less than ${kMaxBufferLength + 1} bits`, 'OperationError');
}
};
exports.validateMaxBufferLength = validateMaxBufferLength;
const getUsagesUnion = (usageSet, ...usages) => {
const newset = [];
for (let n = 0; n < usages.length; n++) {
if (!usages[n] || usages[n] === undefined) continue;
if (usageSet.includes(usages[n])) newset.push(usages[n]);
}
return newset;
};
exports.getUsagesUnion = getUsagesUnion;
const kKeyOps = {
sign: 1,
verify: 2,
encrypt: 3,
decrypt: 4,
wrapKey: 5,
unwrapKey: 6,
deriveKey: 7,
deriveBits: 8,
encapsulateBits: 9,
decapsulateBits: 10,
encapsulateKey: 11,
decapsulateKey: 12
};
const validateKeyOps = (keyOps, usagesSet) => {
if (keyOps === undefined) return;
if (!Array.isArray(keyOps)) {
throw (0, _errors.lazyDOMException)('keyData.key_ops', 'InvalidArgument');
}
let flags = 0;
for (let n = 0; n < keyOps.length; n++) {
const op = keyOps[n];
const op_flag = kKeyOps[op];
// Skipping unknown key ops
if (op_flag === undefined) continue;
// Have we seen it already? if so, error
if (flags & 1 << op_flag) throw (0, _errors.lazyDOMException)('Duplicate key operation', 'DataError');
flags |= 1 << op_flag;
// TODO(@jasnell): RFC7517 section 4.3 strong recommends validating
// key usage combinations. Specifically, it says that unrelated key
// ops SHOULD NOT be used together. We're not yet validating that here.
}
if (usagesSet !== undefined) {
for (const use of usagesSet) {
if (!keyOps.includes(use)) {
throw (0, _errors.lazyDOMException)('Key operations and usage mismatch', 'DataError');
}
}
}
};
exports.validateKeyOps = validateKeyOps;
function hasAnyNotIn(set, checks) {
for (const s of set) {
if (!checks.includes(s)) {
return true;
}
}
return false;
}
//# sourceMappingURL=validation.js.map