UNPKG

react-native-quick-crypto

Version:

A fast implementation of Node's `crypto` module written in C/C++ JSI

275 lines (261 loc) 9.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ecExportKey = ecExportKey; exports.ecGenerateKey = void 0; exports.ecImportKey = ecImportKey; exports.ecdsaSignVerify = void 0; var _Cipher = require("./Cipher"); var _NativeQuickCrypto = require("./NativeQuickCrypto/NativeQuickCrypto"); var _sig = require("./NativeQuickCrypto/sig"); var _Utils = require("./Utils"); var _keys = require("./keys"); // const { // ArrayPrototypeIncludes, // ObjectKeys, // SafeSet, // } = primordials; // const { // ECKeyExportJob, // KeyObjectHandle, // SignJob, // kCryptoJobAsync, // kKeyTypePrivate, // kSignJobModeSign, // kSignJobModeVerify, // kSigEncP1363, // } = internalBinding('crypto'); // const { // getUsagesUnion, // hasAnyNotIn, // jobPromise, // normalizeHashName, // validateKeyOps, // kHandle, // kKeyObject, // kNamedCurveAliases, // } = require('internal/crypto/util'); // const { // lazyDOMException, // promisify, // } = require('internal/util'); // const { // generateKeyPair: _generateKeyPair, // } = require('internal/crypto/keygen'); // const { // InternalCryptoKey, // PrivateKeyObject, // PublicKeyObject, // createPrivateKey, // createPublicKey, // } = require('internal/crypto/keys'); // const generateKeyPair = promisify(_generateKeyPair); function verifyAcceptableEcKeyUse(name, isPublic, usages) { let checkSet; switch (name) { case 'ECDH': checkSet = isPublic ? [] : ['deriveKey', 'deriveBits']; break; case 'ECDSA': checkSet = isPublic ? ['verify'] : ['sign']; break; default: throw (0, _Utils.lazyDOMException)('The algorithm is not supported', 'NotSupportedError'); } if ((0, _Utils.hasAnyNotIn)(usages, checkSet)) { throw (0, _Utils.lazyDOMException)(`Unsupported key usage for a ${name} key`, 'SyntaxError'); } } function createECPublicKeyRaw(namedCurve, keyData) { if (!namedCurve) { throw new Error('Invalid namedCurve'); } const handle = _NativeQuickCrypto.NativeQuickCrypto.webcrypto.createKeyObjectHandle(); if (!handle.initECRaw(_keys.kNamedCurveAliases[namedCurve], keyData)) { console.log('keyData', (0, _Utils.ab2str)(keyData)); throw new Error('Invalid keyData 1'); } return new _keys.PublicKeyObject(handle); } function ecExportKey(key, format) { return _NativeQuickCrypto.NativeQuickCrypto.webcrypto.ecExportKey(format, key.keyObject.handle); } function ecImportKey(format, keyData, algorithm, extractable, keyUsages) { const { name, namedCurve } = algorithm; // if (!ArrayPrototypeIncludes(ObjectKeys(kNamedCurveAliases), namedCurve)) { // throw lazyDOMException('Unrecognized namedCurve', 'NotSupportedError'); // } let keyObject; // const usagesSet = new SafeSet(keyUsages); switch (format) { // case 'spki': { // // verifyAcceptableEcKeyUse(name, true, usagesSet); // try { // keyObject = createPublicKey({ // key: keyData, // format: 'der', // type: 'spki', // }); // } catch (err) { // throw new Error(`Invalid keyData 2: ${err}`); // } // break; // } // case 'pkcs8': { // // verifyAcceptableEcKeyUse(name, false, usagesSet); // try { // keyObject = createPrivateKey({ // key: keyData, // format: 'der', // type: 'pkcs8', // }); // } catch (err) { // throw new Error(`Invalid keyData 3 ${err}`); // } // break; // } case 'jwk': { const data = keyData; if (!data.kty) throw (0, _Utils.lazyDOMException)('Invalid keyData 4', 'DataError'); if (data.kty !== 'EC') throw (0, _Utils.lazyDOMException)('Invalid JWK "kty" Parameter', 'DataError'); if (data.crv !== namedCurve) throw (0, _Utils.lazyDOMException)('JWK "crv" does not match the requested algorithm', 'DataError'); verifyAcceptableEcKeyUse(name, data.d === undefined, keyUsages); if (keyUsages.length > 0 && data.use !== undefined) { const checkUse = name === 'ECDH' ? 'enc' : 'sig'; if (data.use !== checkUse) throw (0, _Utils.lazyDOMException)('Invalid JWK "use" Parameter', 'DataError'); } (0, _Utils.validateKeyOps)(data.key_ops, keyUsages); if (data.ext !== undefined && data.ext === false && extractable === true) { throw (0, _Utils.lazyDOMException)('JWK "ext" Parameter and extractable mismatch', 'DataError'); } if (algorithm.name === 'ECDSA' && data.alg !== undefined) { let algNamedCurve; switch (data.alg) { case 'ES256': algNamedCurve = 'P-256'; break; case 'ES384': algNamedCurve = 'P-384'; break; case 'ES512': algNamedCurve = 'P-521'; break; } if (algNamedCurve !== namedCurve) throw (0, _Utils.lazyDOMException)('JWK "alg" does not match the requested algorithm', 'DataError'); } const handle = _NativeQuickCrypto.NativeQuickCrypto.webcrypto.createKeyObjectHandle(); const type = handle.initJwk(data, namedCurve); if (type === undefined) throw (0, _Utils.lazyDOMException)('Invalid JWK', 'DataError'); keyObject = type === _keys.KeyType.Private ? new _keys.PrivateKeyObject(handle) : new _keys.PublicKeyObject(handle); break; } case 'raw': { const data = keyData; verifyAcceptableEcKeyUse(name, true, keyUsages); const buffer = typeof data === 'string' ? (0, _Utils.binaryLikeToArrayBuffer)(data) : (0, _Utils.bufferLikeToArrayBuffer)(data); keyObject = createECPublicKeyRaw(namedCurve, buffer); break; } default: { throw new Error(`Unknown EC import format: ${format}`); } } switch (algorithm.name) { case 'ECDSA': // Fall through case 'ECDH': if (keyObject.asymmetricKeyType !== 'ec') throw new Error('Invalid key type'); break; } // if (!keyObject[kHandle].checkEcKeyData()) { // throw new Error('Invalid keyData 5'); // } // const { namedCurve: checkNamedCurve } = keyObject[kHandle].keyDetail({}); // if (kNamedCurveAliases[namedCurve] !== checkNamedCurve) // throw new Error('Named curve mismatch'); return new _keys.CryptoKey(keyObject, { name, namedCurve }, keyUsages, extractable); } const ecdsaSignVerify = (key, data, { hash }, signature) => { const mode = signature === undefined ? _sig.SignMode.kSignJobModeSign : _sig.SignMode.kSignJobModeVerify; const type = mode === _sig.SignMode.kSignJobModeSign ? 'private' : 'public'; if (key.type !== type) throw (0, _Utils.lazyDOMException)(`Key must be a ${type} key`, 'InvalidAccessError'); const hashname = (0, _Utils.normalizeHashName)(hash); return _NativeQuickCrypto.NativeQuickCrypto.webcrypto.signVerify(mode, key.keyObject.handle, // three undefined args because C++ uses `GetPublicOrPrivateKeyFromJs` & friends undefined, undefined, undefined, (0, _Utils.bufferLikeToArrayBuffer)(data), hashname, undefined, // salt length, not used with ECDSA undefined, // pss padding, not used with ECDSA _sig.DSASigEnc.kSigEncP1363, (0, _Utils.bufferLikeToArrayBuffer)(signature || new ArrayBuffer(0))); }; exports.ecdsaSignVerify = ecdsaSignVerify; const ecGenerateKey = async (algorithm, extractable, keyUsages) => { const { name, namedCurve } = algorithm; if (!Object.keys(_keys.kNamedCurveAliases).includes(namedCurve || '')) { throw (0, _Utils.lazyDOMException)(`Unrecognized namedCurve '${namedCurve}'`, 'NotSupportedError'); } // const usageSet = new SafeSet(keyUsages); switch (name) { case 'ECDSA': if ((0, _Utils.hasAnyNotIn)(keyUsages, ['sign', 'verify'])) { throw (0, _Utils.lazyDOMException)('Unsupported key usage for an ECDSA key', 'SyntaxError'); } break; case 'ECDH': if ((0, _Utils.hasAnyNotIn)(keyUsages, ['deriveKey', 'deriveBits'])) { throw (0, _Utils.lazyDOMException)('Unsupported key usage for an ECDH key', 'SyntaxError'); } // Fall through } const options = { namedCurve }; const [err, keypair] = await (0, _Cipher.generateKeyPairPromise)('ec', options); if (err) { throw (0, _Utils.lazyDOMException)('ecGenerateKey (generateKeyPairPromise) failed', { name: 'OperationError', cause: err }); } let publicUsages = []; let privateUsages = []; switch (name) { case 'ECDSA': publicUsages = (0, _Utils.getUsagesUnion)(keyUsages, 'verify'); privateUsages = (0, _Utils.getUsagesUnion)(keyUsages, 'sign'); break; case 'ECDH': publicUsages = []; privateUsages = (0, _Utils.getUsagesUnion)(keyUsages, 'deriveKey', 'deriveBits'); break; } const keyAlgorithm = { name, namedCurve }; const pub = new _keys.PublicKeyObject(keypair?.publicKey); const publicKey = new _keys.CryptoKey(pub, keyAlgorithm, publicUsages, true); const priv = new _keys.PrivateKeyObject(keypair?.privateKey); const privateKey = new _keys.CryptoKey(priv, keyAlgorithm, privateUsages, extractable); return { publicKey, privateKey }; }; exports.ecGenerateKey = ecGenerateKey; //# sourceMappingURL=ec.js.map