11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci FunctionPrototypeCall, 51cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 61cb0ef41Sopenharmony_ci ReflectApply, 71cb0ef41Sopenharmony_ci} = primordials; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst { 101cb0ef41Sopenharmony_ci codes: { 111cb0ef41Sopenharmony_ci ERR_CRYPTO_SIGN_KEY_REQUIRED, 121cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 131cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 141cb0ef41Sopenharmony_ci }, 151cb0ef41Sopenharmony_ci} = require('internal/errors'); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciconst { 181cb0ef41Sopenharmony_ci validateFunction, 191cb0ef41Sopenharmony_ci validateEncoding, 201cb0ef41Sopenharmony_ci validateString, 211cb0ef41Sopenharmony_ci} = require('internal/validators'); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciconst { 241cb0ef41Sopenharmony_ci Sign: _Sign, 251cb0ef41Sopenharmony_ci SignJob, 261cb0ef41Sopenharmony_ci Verify: _Verify, 271cb0ef41Sopenharmony_ci kCryptoJobAsync, 281cb0ef41Sopenharmony_ci kCryptoJobSync, 291cb0ef41Sopenharmony_ci kSigEncDER, 301cb0ef41Sopenharmony_ci kSigEncP1363, 311cb0ef41Sopenharmony_ci kSignJobModeSign, 321cb0ef41Sopenharmony_ci kSignJobModeVerify, 331cb0ef41Sopenharmony_ci} = internalBinding('crypto'); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciconst { 361cb0ef41Sopenharmony_ci getArrayBufferOrView, 371cb0ef41Sopenharmony_ci getDefaultEncoding, 381cb0ef41Sopenharmony_ci kHandle, 391cb0ef41Sopenharmony_ci} = require('internal/crypto/util'); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ciconst { 421cb0ef41Sopenharmony_ci preparePrivateKey, 431cb0ef41Sopenharmony_ci preparePublicOrPrivateKey, 441cb0ef41Sopenharmony_ci} = require('internal/crypto/keys'); 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciconst { Writable } = require('stream'); 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciconst { 511cb0ef41Sopenharmony_ci isArrayBufferView, 521cb0ef41Sopenharmony_ci} = require('internal/util/types'); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_cifunction Sign(algorithm, options) { 551cb0ef41Sopenharmony_ci if (!(this instanceof Sign)) 561cb0ef41Sopenharmony_ci return new Sign(algorithm, options); 571cb0ef41Sopenharmony_ci validateString(algorithm, 'algorithm'); 581cb0ef41Sopenharmony_ci this[kHandle] = new _Sign(); 591cb0ef41Sopenharmony_ci this[kHandle].init(algorithm); 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci ReflectApply(Writable, this, [options]); 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Sign.prototype, Writable.prototype); 651cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Sign, Writable); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ciSign.prototype._write = function _write(chunk, encoding, callback) { 681cb0ef41Sopenharmony_ci this.update(chunk, encoding); 691cb0ef41Sopenharmony_ci callback(); 701cb0ef41Sopenharmony_ci}; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ciSign.prototype.update = function update(data, encoding) { 731cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci if (typeof data === 'string') { 761cb0ef41Sopenharmony_ci validateEncoding(data, encoding); 771cb0ef41Sopenharmony_ci } else if (!isArrayBufferView(data)) { 781cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 791cb0ef41Sopenharmony_ci 'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data); 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci this[kHandle].update(data, encoding); 831cb0ef41Sopenharmony_ci return this; 841cb0ef41Sopenharmony_ci}; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_cifunction getPadding(options) { 871cb0ef41Sopenharmony_ci return getIntOption('padding', options); 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_cifunction getSaltLength(options) { 911cb0ef41Sopenharmony_ci return getIntOption('saltLength', options); 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_cifunction getDSASignatureEncoding(options) { 951cb0ef41Sopenharmony_ci if (typeof options === 'object') { 961cb0ef41Sopenharmony_ci const { dsaEncoding = 'der' } = options; 971cb0ef41Sopenharmony_ci if (dsaEncoding === 'der') 981cb0ef41Sopenharmony_ci return kSigEncDER; 991cb0ef41Sopenharmony_ci else if (dsaEncoding === 'ieee-p1363') 1001cb0ef41Sopenharmony_ci return kSigEncP1363; 1011cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('options.dsaEncoding', dsaEncoding); 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci return kSigEncDER; 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cifunction getIntOption(name, options) { 1081cb0ef41Sopenharmony_ci const value = options[name]; 1091cb0ef41Sopenharmony_ci if (value !== undefined) { 1101cb0ef41Sopenharmony_ci if (value === value >> 0) { 1111cb0ef41Sopenharmony_ci return value; 1121cb0ef41Sopenharmony_ci } 1131cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(`options.${name}`, value); 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci return undefined; 1161cb0ef41Sopenharmony_ci} 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ciSign.prototype.sign = function sign(options, encoding) { 1191cb0ef41Sopenharmony_ci if (!options) 1201cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_SIGN_KEY_REQUIRED(); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci const { data, format, type, passphrase } = preparePrivateKey(options, true); 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci // Options specific to RSA 1251cb0ef41Sopenharmony_ci const rsaPadding = getPadding(options); 1261cb0ef41Sopenharmony_ci const pssSaltLength = getSaltLength(options); 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci // Options specific to (EC)DSA 1291cb0ef41Sopenharmony_ci const dsaSigEnc = getDSASignatureEncoding(options); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding, 1321cb0ef41Sopenharmony_ci pssSaltLength, dsaSigEnc); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci encoding = encoding || getDefaultEncoding(); 1351cb0ef41Sopenharmony_ci if (encoding && encoding !== 'buffer') 1361cb0ef41Sopenharmony_ci return ret.toString(encoding); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci return ret; 1391cb0ef41Sopenharmony_ci}; 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_cifunction signOneShot(algorithm, data, key, callback) { 1421cb0ef41Sopenharmony_ci if (algorithm != null) 1431cb0ef41Sopenharmony_ci validateString(algorithm, 'algorithm'); 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci if (callback !== undefined) 1461cb0ef41Sopenharmony_ci validateFunction(callback, 'callback'); 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci data = getArrayBufferOrView(data, 'data'); 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci if (!key) 1511cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_SIGN_KEY_REQUIRED(); 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci // Options specific to RSA 1541cb0ef41Sopenharmony_ci const rsaPadding = getPadding(key); 1551cb0ef41Sopenharmony_ci const pssSaltLength = getSaltLength(key); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci // Options specific to (EC)DSA 1581cb0ef41Sopenharmony_ci const dsaSigEnc = getDSASignatureEncoding(key); 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci const { 1611cb0ef41Sopenharmony_ci data: keyData, 1621cb0ef41Sopenharmony_ci format: keyFormat, 1631cb0ef41Sopenharmony_ci type: keyType, 1641cb0ef41Sopenharmony_ci passphrase: keyPassphrase, 1651cb0ef41Sopenharmony_ci } = preparePrivateKey(key); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci const job = new SignJob( 1681cb0ef41Sopenharmony_ci callback ? kCryptoJobAsync : kCryptoJobSync, 1691cb0ef41Sopenharmony_ci kSignJobModeSign, 1701cb0ef41Sopenharmony_ci keyData, 1711cb0ef41Sopenharmony_ci keyFormat, 1721cb0ef41Sopenharmony_ci keyType, 1731cb0ef41Sopenharmony_ci keyPassphrase, 1741cb0ef41Sopenharmony_ci data, 1751cb0ef41Sopenharmony_ci algorithm, 1761cb0ef41Sopenharmony_ci pssSaltLength, 1771cb0ef41Sopenharmony_ci rsaPadding, 1781cb0ef41Sopenharmony_ci dsaSigEnc); 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci if (!callback) { 1811cb0ef41Sopenharmony_ci const { 0: err, 1: signature } = job.run(); 1821cb0ef41Sopenharmony_ci if (err !== undefined) 1831cb0ef41Sopenharmony_ci throw err; 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci return Buffer.from(signature); 1861cb0ef41Sopenharmony_ci } 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci job.ondone = (error, signature) => { 1891cb0ef41Sopenharmony_ci if (error) return FunctionPrototypeCall(callback, job, error); 1901cb0ef41Sopenharmony_ci FunctionPrototypeCall(callback, job, null, Buffer.from(signature)); 1911cb0ef41Sopenharmony_ci }; 1921cb0ef41Sopenharmony_ci job.run(); 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_cifunction Verify(algorithm, options) { 1961cb0ef41Sopenharmony_ci if (!(this instanceof Verify)) 1971cb0ef41Sopenharmony_ci return new Verify(algorithm, options); 1981cb0ef41Sopenharmony_ci validateString(algorithm, 'algorithm'); 1991cb0ef41Sopenharmony_ci this[kHandle] = new _Verify(); 2001cb0ef41Sopenharmony_ci this[kHandle].init(algorithm); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci ReflectApply(Writable, this, [options]); 2031cb0ef41Sopenharmony_ci} 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Verify.prototype, Writable.prototype); 2061cb0ef41Sopenharmony_ciObjectSetPrototypeOf(Verify, Writable); 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ciVerify.prototype._write = Sign.prototype._write; 2091cb0ef41Sopenharmony_ciVerify.prototype.update = Sign.prototype.update; 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ciVerify.prototype.verify = function verify(options, signature, sigEncoding) { 2121cb0ef41Sopenharmony_ci const { 2131cb0ef41Sopenharmony_ci data, 2141cb0ef41Sopenharmony_ci format, 2151cb0ef41Sopenharmony_ci type, 2161cb0ef41Sopenharmony_ci passphrase, 2171cb0ef41Sopenharmony_ci } = preparePublicOrPrivateKey(options, true); 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci sigEncoding = sigEncoding || getDefaultEncoding(); 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci // Options specific to RSA 2221cb0ef41Sopenharmony_ci const rsaPadding = getPadding(options); 2231cb0ef41Sopenharmony_ci const pssSaltLength = getSaltLength(options); 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci // Options specific to (EC)DSA 2261cb0ef41Sopenharmony_ci const dsaSigEnc = getDSASignatureEncoding(options); 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci signature = getArrayBufferOrView(signature, 'signature', sigEncoding); 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci return this[kHandle].verify(data, format, type, passphrase, signature, 2311cb0ef41Sopenharmony_ci rsaPadding, pssSaltLength, dsaSigEnc); 2321cb0ef41Sopenharmony_ci}; 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_cifunction verifyOneShot(algorithm, data, key, signature, callback) { 2351cb0ef41Sopenharmony_ci if (algorithm != null) 2361cb0ef41Sopenharmony_ci validateString(algorithm, 'algorithm'); 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci if (callback !== undefined) 2391cb0ef41Sopenharmony_ci validateFunction(callback, 'callback'); 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci data = getArrayBufferOrView(data, 'data'); 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci if (!isArrayBufferView(data)) { 2441cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 2451cb0ef41Sopenharmony_ci 'data', 2461cb0ef41Sopenharmony_ci ['Buffer', 'TypedArray', 'DataView'], 2471cb0ef41Sopenharmony_ci data, 2481cb0ef41Sopenharmony_ci ); 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci // Options specific to RSA 2521cb0ef41Sopenharmony_ci const rsaPadding = getPadding(key); 2531cb0ef41Sopenharmony_ci const pssSaltLength = getSaltLength(key); 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci // Options specific to (EC)DSA 2561cb0ef41Sopenharmony_ci const dsaSigEnc = getDSASignatureEncoding(key); 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ci if (!isArrayBufferView(signature)) { 2591cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 2601cb0ef41Sopenharmony_ci 'signature', 2611cb0ef41Sopenharmony_ci ['Buffer', 'TypedArray', 'DataView'], 2621cb0ef41Sopenharmony_ci signature, 2631cb0ef41Sopenharmony_ci ); 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci const { 2671cb0ef41Sopenharmony_ci data: keyData, 2681cb0ef41Sopenharmony_ci format: keyFormat, 2691cb0ef41Sopenharmony_ci type: keyType, 2701cb0ef41Sopenharmony_ci passphrase: keyPassphrase, 2711cb0ef41Sopenharmony_ci } = preparePublicOrPrivateKey(key); 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_ci const job = new SignJob( 2741cb0ef41Sopenharmony_ci callback ? kCryptoJobAsync : kCryptoJobSync, 2751cb0ef41Sopenharmony_ci kSignJobModeVerify, 2761cb0ef41Sopenharmony_ci keyData, 2771cb0ef41Sopenharmony_ci keyFormat, 2781cb0ef41Sopenharmony_ci keyType, 2791cb0ef41Sopenharmony_ci keyPassphrase, 2801cb0ef41Sopenharmony_ci data, 2811cb0ef41Sopenharmony_ci algorithm, 2821cb0ef41Sopenharmony_ci pssSaltLength, 2831cb0ef41Sopenharmony_ci rsaPadding, 2841cb0ef41Sopenharmony_ci dsaSigEnc, 2851cb0ef41Sopenharmony_ci signature); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci if (!callback) { 2881cb0ef41Sopenharmony_ci const { 0: err, 1: result } = job.run(); 2891cb0ef41Sopenharmony_ci if (err !== undefined) 2901cb0ef41Sopenharmony_ci throw err; 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci return result; 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci job.ondone = (error, result) => { 2961cb0ef41Sopenharmony_ci if (error) return FunctionPrototypeCall(callback, job, error); 2971cb0ef41Sopenharmony_ci FunctionPrototypeCall(callback, job, null, result); 2981cb0ef41Sopenharmony_ci }; 2991cb0ef41Sopenharmony_ci job.run(); 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_cimodule.exports = { 3031cb0ef41Sopenharmony_ci Sign, 3041cb0ef41Sopenharmony_ci signOneShot, 3051cb0ef41Sopenharmony_ci Verify, 3061cb0ef41Sopenharmony_ci verifyOneShot, 3071cb0ef41Sopenharmony_ci}; 308