mirror of
https://github.com/nodejs/node.git
synced 2025-05-13 02:59:02 +00:00

Store all primordials as properties of the primordials object. Static functions are prefixed by the constructor's name and prototype methods are prefixed by the constructor's name followed by "Prototype". For example: primordials.Object.keys becomes primordials.ObjectKeys. PR-URL: https://github.com/nodejs/node/pull/30610 Refs: https://github.com/nodejs/node/issues/29766 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
231 lines
5.6 KiB
JavaScript
231 lines
5.6 KiB
JavaScript
'use strict';
|
|
|
|
const {
|
|
ObjectSetPrototypeOf,
|
|
} = primordials;
|
|
|
|
const {
|
|
ERR_CRYPTO_SIGN_KEY_REQUIRED,
|
|
ERR_INVALID_ARG_TYPE,
|
|
ERR_INVALID_OPT_VALUE
|
|
} = require('internal/errors').codes;
|
|
const { validateString } = require('internal/validators');
|
|
const {
|
|
Sign: _Sign,
|
|
Verify: _Verify,
|
|
kSigEncDER,
|
|
kSigEncP1363,
|
|
signOneShot: _signOneShot,
|
|
verifyOneShot: _verifyOneShot
|
|
} = internalBinding('crypto');
|
|
const {
|
|
getDefaultEncoding,
|
|
kHandle,
|
|
getArrayBufferView,
|
|
} = require('internal/crypto/util');
|
|
const {
|
|
preparePrivateKey,
|
|
preparePublicOrPrivateKey
|
|
} = require('internal/crypto/keys');
|
|
const { Writable } = require('stream');
|
|
const { isArrayBufferView } = require('internal/util/types');
|
|
|
|
function Sign(algorithm, options) {
|
|
if (!(this instanceof Sign))
|
|
return new Sign(algorithm, options);
|
|
validateString(algorithm, 'algorithm');
|
|
this[kHandle] = new _Sign();
|
|
this[kHandle].init(algorithm);
|
|
|
|
Writable.call(this, options);
|
|
}
|
|
|
|
ObjectSetPrototypeOf(Sign.prototype, Writable.prototype);
|
|
ObjectSetPrototypeOf(Sign, Writable);
|
|
|
|
Sign.prototype._write = function _write(chunk, encoding, callback) {
|
|
this.update(chunk, encoding);
|
|
callback();
|
|
};
|
|
|
|
Sign.prototype.update = function update(data, encoding) {
|
|
encoding = encoding || getDefaultEncoding();
|
|
data = getArrayBufferView(data, 'data', encoding);
|
|
this[kHandle].update(data);
|
|
return this;
|
|
};
|
|
|
|
function getPadding(options) {
|
|
return getIntOption('padding', options);
|
|
}
|
|
|
|
function getSaltLength(options) {
|
|
return getIntOption('saltLength', options);
|
|
}
|
|
|
|
function getDSASignatureEncoding(options) {
|
|
if (typeof options === 'object') {
|
|
const { dsaEncoding = 'der' } = options;
|
|
if (dsaEncoding === 'der')
|
|
return kSigEncDER;
|
|
else if (dsaEncoding === 'ieee-p1363')
|
|
return kSigEncP1363;
|
|
else
|
|
throw new ERR_INVALID_OPT_VALUE('dsaEncoding', dsaEncoding);
|
|
}
|
|
|
|
return kSigEncDER;
|
|
}
|
|
|
|
function getIntOption(name, options) {
|
|
const value = options[name];
|
|
if (value !== undefined) {
|
|
if (value === value >> 0) {
|
|
return value;
|
|
} else {
|
|
throw new ERR_INVALID_OPT_VALUE(name, value);
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
Sign.prototype.sign = function sign(options, encoding) {
|
|
if (!options)
|
|
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
|
|
|
|
const { data, format, type, passphrase } = preparePrivateKey(options, true);
|
|
|
|
// Options specific to RSA
|
|
const rsaPadding = getPadding(options);
|
|
const pssSaltLength = getSaltLength(options);
|
|
|
|
// Options specific to (EC)DSA
|
|
const dsaSigEnc = getDSASignatureEncoding(options);
|
|
|
|
const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding,
|
|
pssSaltLength, dsaSigEnc);
|
|
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
return ret.toString(encoding);
|
|
|
|
return ret;
|
|
};
|
|
|
|
function signOneShot(algorithm, data, key) {
|
|
if (algorithm != null)
|
|
validateString(algorithm, 'algorithm');
|
|
|
|
if (!isArrayBufferView(data)) {
|
|
throw new ERR_INVALID_ARG_TYPE(
|
|
'data',
|
|
['Buffer', 'TypedArray', 'DataView'],
|
|
data
|
|
);
|
|
}
|
|
|
|
if (!key)
|
|
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
|
|
|
|
const {
|
|
data: keyData,
|
|
format: keyFormat,
|
|
type: keyType,
|
|
passphrase: keyPassphrase
|
|
} = preparePrivateKey(key);
|
|
|
|
// Options specific to RSA
|
|
const rsaPadding = getPadding(key);
|
|
const pssSaltLength = getSaltLength(key);
|
|
|
|
// Options specific to (EC)DSA
|
|
const dsaSigEnc = getDSASignatureEncoding(key);
|
|
|
|
return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data,
|
|
algorithm, rsaPadding, pssSaltLength, dsaSigEnc);
|
|
}
|
|
|
|
function Verify(algorithm, options) {
|
|
if (!(this instanceof Verify))
|
|
return new Verify(algorithm, options);
|
|
validateString(algorithm, 'algorithm');
|
|
this[kHandle] = new _Verify();
|
|
this[kHandle].init(algorithm);
|
|
|
|
Writable.call(this, options);
|
|
}
|
|
|
|
ObjectSetPrototypeOf(Verify.prototype, Writable.prototype);
|
|
ObjectSetPrototypeOf(Verify, Writable);
|
|
|
|
Verify.prototype._write = Sign.prototype._write;
|
|
Verify.prototype.update = Sign.prototype.update;
|
|
|
|
Verify.prototype.verify = function verify(options, signature, sigEncoding) {
|
|
const {
|
|
data,
|
|
format,
|
|
type,
|
|
passphrase
|
|
} = preparePublicOrPrivateKey(options, true);
|
|
|
|
sigEncoding = sigEncoding || getDefaultEncoding();
|
|
|
|
// Options specific to RSA
|
|
const rsaPadding = getPadding(options);
|
|
const pssSaltLength = getSaltLength(options);
|
|
|
|
// Options specific to (EC)DSA
|
|
const dsaSigEnc = getDSASignatureEncoding(options);
|
|
|
|
signature = getArrayBufferView(signature, 'signature', sigEncoding);
|
|
|
|
return this[kHandle].verify(data, format, type, passphrase, signature,
|
|
rsaPadding, pssSaltLength, dsaSigEnc);
|
|
};
|
|
|
|
function verifyOneShot(algorithm, data, key, signature) {
|
|
if (algorithm != null)
|
|
validateString(algorithm, 'algorithm');
|
|
|
|
if (!isArrayBufferView(data)) {
|
|
throw new ERR_INVALID_ARG_TYPE(
|
|
'data',
|
|
['Buffer', 'TypedArray', 'DataView'],
|
|
data
|
|
);
|
|
}
|
|
|
|
const {
|
|
data: keyData,
|
|
format: keyFormat,
|
|
type: keyType,
|
|
passphrase: keyPassphrase
|
|
} = preparePublicOrPrivateKey(key);
|
|
|
|
// Options specific to RSA
|
|
const rsaPadding = getPadding(key);
|
|
const pssSaltLength = getSaltLength(key);
|
|
|
|
// Options specific to (EC)DSA
|
|
const dsaSigEnc = getDSASignatureEncoding(key);
|
|
|
|
if (!isArrayBufferView(signature)) {
|
|
throw new ERR_INVALID_ARG_TYPE(
|
|
'signature',
|
|
['Buffer', 'TypedArray', 'DataView'],
|
|
signature
|
|
);
|
|
}
|
|
|
|
return _verifyOneShot(keyData, keyFormat, keyType, keyPassphrase, signature,
|
|
data, algorithm, rsaPadding, pssSaltLength, dsaSigEnc);
|
|
}
|
|
|
|
module.exports = {
|
|
Sign,
|
|
signOneShot,
|
|
Verify,
|
|
verifyOneShot
|
|
};
|