2017-09-06 17:10:34 +02:00
|
|
|
'use strict';
|
|
|
|
|
2019-04-09 09:55:53 +02:00
|
|
|
const { Object } = primordials;
|
|
|
|
|
2018-03-04 22:16:24 +01:00
|
|
|
const {
|
|
|
|
ERR_CRYPTO_SIGN_KEY_REQUIRED,
|
2019-03-12 14:17:10 +01:00
|
|
|
ERR_INVALID_ARG_TYPE,
|
2018-03-04 22:16:24 +01:00
|
|
|
ERR_INVALID_OPT_VALUE
|
|
|
|
} = require('internal/errors').codes;
|
2018-08-03 00:51:02 +02:00
|
|
|
const { validateString } = require('internal/validators');
|
2019-03-12 14:17:10 +01:00
|
|
|
const {
|
|
|
|
Sign: _Sign,
|
|
|
|
Verify: _Verify,
|
|
|
|
signOneShot: _signOneShot,
|
|
|
|
verifyOneShot: _verifyOneShot
|
|
|
|
} = internalBinding('crypto');
|
2017-09-06 17:10:34 +02:00
|
|
|
const {
|
|
|
|
getDefaultEncoding,
|
2018-09-05 11:55:00 +02:00
|
|
|
kHandle,
|
2018-05-30 16:14:37 +02:00
|
|
|
toBuf,
|
|
|
|
validateArrayBufferView,
|
2017-09-06 17:10:34 +02:00
|
|
|
} = require('internal/crypto/util');
|
2018-09-20 19:53:44 +02:00
|
|
|
const {
|
|
|
|
preparePrivateKey,
|
2018-12-25 13:13:52 +01:00
|
|
|
preparePublicOrPrivateKey
|
2018-09-20 19:53:44 +02:00
|
|
|
} = require('internal/crypto/keys');
|
2017-09-06 17:10:34 +02:00
|
|
|
const { Writable } = require('stream');
|
2019-03-12 14:17:10 +01:00
|
|
|
const { isArrayBufferView } = require('internal/util/types');
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
function Sign(algorithm, options) {
|
|
|
|
if (!(this instanceof Sign))
|
|
|
|
return new Sign(algorithm, options);
|
2018-08-03 00:51:02 +02:00
|
|
|
validateString(algorithm, 'algorithm');
|
2018-11-09 09:48:48 +01:00
|
|
|
this[kHandle] = new _Sign();
|
2018-09-05 11:55:00 +02:00
|
|
|
this[kHandle].init(algorithm);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
Writable.call(this, options);
|
|
|
|
}
|
|
|
|
|
2018-11-30 17:55:48 +01:00
|
|
|
Object.setPrototypeOf(Sign.prototype, Writable.prototype);
|
2018-12-02 15:03:01 +01:00
|
|
|
Object.setPrototypeOf(Sign, Writable);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
Sign.prototype._write = function _write(chunk, encoding, callback) {
|
2017-10-03 16:28:26 +02:00
|
|
|
this.update(chunk, encoding);
|
2017-09-06 17:10:34 +02:00
|
|
|
callback();
|
|
|
|
};
|
|
|
|
|
|
|
|
Sign.prototype.update = function update(data, encoding) {
|
|
|
|
encoding = encoding || getDefaultEncoding();
|
2018-05-30 16:14:37 +02:00
|
|
|
data = validateArrayBufferView(toBuf(data, encoding),
|
|
|
|
'data');
|
2018-09-05 11:55:00 +02:00
|
|
|
this[kHandle].update(data);
|
2017-09-06 17:10:34 +02:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2018-04-24 10:47:24 +02:00
|
|
|
function getPadding(options) {
|
2019-03-16 23:51:26 +01:00
|
|
|
return getIntOption('padding', options);
|
2018-04-24 10:47:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function getSaltLength(options) {
|
2019-03-16 23:51:26 +01:00
|
|
|
return getIntOption('saltLength', options);
|
2018-04-24 10:47:24 +02:00
|
|
|
}
|
|
|
|
|
2019-03-16 23:51:26 +01:00
|
|
|
function getIntOption(name, options) {
|
2019-03-26 12:16:30 +01:00
|
|
|
const value = options[name];
|
|
|
|
if (value !== undefined) {
|
2018-07-14 18:59:39 +02:00
|
|
|
if (value === value >> 0) {
|
|
|
|
return value;
|
2018-04-24 10:47:24 +02:00
|
|
|
} else {
|
2018-07-14 18:59:39 +02:00
|
|
|
throw new ERR_INVALID_OPT_VALUE(name, value);
|
2018-04-24 10:47:24 +02:00
|
|
|
}
|
|
|
|
}
|
2019-03-16 23:51:26 +01:00
|
|
|
return undefined;
|
2018-04-24 10:47:24 +02:00
|
|
|
}
|
|
|
|
|
2017-09-06 17:10:34 +02:00
|
|
|
Sign.prototype.sign = function sign(options, encoding) {
|
|
|
|
if (!options)
|
2018-03-04 22:16:24 +01:00
|
|
|
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
|
2017-09-06 17:10:34 +02:00
|
|
|
|
2018-09-20 19:53:44 +02:00
|
|
|
const { data, format, type, passphrase } = preparePrivateKey(options, true);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
// Options specific to RSA
|
2018-09-20 19:53:44 +02:00
|
|
|
const rsaPadding = getPadding(options);
|
|
|
|
const pssSaltLength = getSaltLength(options);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
2018-09-20 19:53:44 +02:00
|
|
|
const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding,
|
|
|
|
pssSaltLength);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
encoding = encoding || getDefaultEncoding();
|
|
|
|
if (encoding && encoding !== 'buffer')
|
2018-09-20 19:53:44 +02:00
|
|
|
return ret.toString(encoding);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
2019-03-12 14:17:10 +01:00
|
|
|
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);
|
|
|
|
|
|
|
|
return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data,
|
|
|
|
algorithm, rsaPadding, pssSaltLength);
|
|
|
|
}
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
function Verify(algorithm, options) {
|
|
|
|
if (!(this instanceof Verify))
|
|
|
|
return new Verify(algorithm, options);
|
2018-08-03 00:51:02 +02:00
|
|
|
validateString(algorithm, 'algorithm');
|
2018-11-09 09:48:48 +01:00
|
|
|
this[kHandle] = new _Verify();
|
2018-09-05 11:55:00 +02:00
|
|
|
this[kHandle].init(algorithm);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
Writable.call(this, options);
|
|
|
|
}
|
|
|
|
|
2018-11-30 17:55:48 +01:00
|
|
|
Object.setPrototypeOf(Verify.prototype, Writable.prototype);
|
2018-12-02 15:03:01 +01:00
|
|
|
Object.setPrototypeOf(Verify, Writable);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
|
|
|
Verify.prototype._write = Sign.prototype._write;
|
|
|
|
Verify.prototype.update = Sign.prototype.update;
|
|
|
|
|
|
|
|
Verify.prototype.verify = function verify(options, signature, sigEncoding) {
|
2018-09-20 19:53:44 +02:00
|
|
|
const {
|
|
|
|
data,
|
|
|
|
format,
|
2018-12-25 13:13:52 +01:00
|
|
|
type,
|
|
|
|
passphrase
|
|
|
|
} = preparePublicOrPrivateKey(options, true);
|
2018-09-20 19:53:44 +02:00
|
|
|
|
2017-09-06 17:10:34 +02:00
|
|
|
sigEncoding = sigEncoding || getDefaultEncoding();
|
|
|
|
|
|
|
|
// Options specific to RSA
|
2019-03-26 05:21:27 +01:00
|
|
|
const rsaPadding = getPadding(options);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
2019-03-26 05:21:27 +01:00
|
|
|
const pssSaltLength = getSaltLength(options);
|
2017-09-06 17:10:34 +02:00
|
|
|
|
2018-05-30 16:14:37 +02:00
|
|
|
signature = validateArrayBufferView(toBuf(signature, sigEncoding),
|
|
|
|
'signature');
|
2017-10-03 16:28:26 +02:00
|
|
|
|
2018-12-25 13:13:52 +01:00
|
|
|
return this[kHandle].verify(data, format, type, passphrase, signature,
|
2018-09-20 19:53:44 +02:00
|
|
|
rsaPadding, pssSaltLength);
|
2017-09-06 17:10:34 +02:00
|
|
|
};
|
|
|
|
|
2019-03-12 14:17:10 +01:00
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2017-09-06 17:10:34 +02:00
|
|
|
module.exports = {
|
|
|
|
Sign,
|
2019-03-12 14:17:10 +01:00
|
|
|
signOneShot,
|
|
|
|
Verify,
|
|
|
|
verifyOneShot
|
2017-09-06 17:10:34 +02:00
|
|
|
};
|