UNPKG

crypto-conditions

Version:

Implementation of crypto-conditions in JavaScript

229 lines (187 loc) 7.54 kB
"use strict"; var _Reflect$construct = require("@babel/runtime-corejs3/core-js-stable/reflect/construct"); var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property"); var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); _Object$defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass")); var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/getPrototypeOf")); var _rsa = _interopRequireDefault(require("../crypto/rsa")); var _pem = _interopRequireDefault(require("../util/pem")); var _baseSha = _interopRequireDefault(require("./base-sha256")); var _missingDataError = _interopRequireDefault(require("../errors/missing-data-error")); var _validationError = _interopRequireDefault(require("../errors/validation-error")); var _fingerprint = require("../schemas/fingerprint"); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } // Instantiate RSA signer with standard settings var rsa = new _rsa.default(); /** * RSA-SHA-256: RSA signature condition using SHA-256. * * This RSA condition uses RSA-PSS padding with SHA-256. The salt length is set * equal the digest length of 32 bytes. * * The public exponent is fixed at 65537 and the public modulus must be between * 128 (1017 bits) and 512 bytes (4096 bits) long. * * RSA-SHA-256 is assigned the type ID 3. It relies on the SHA-256 and RSA-PSS * feature suites which corresponds to a feature bitmask of 0x11. */ var RsaSha256 = /*#__PURE__*/function (_BaseSha) { (0, _inherits2.default)(RsaSha256, _BaseSha); var _super = _createSuper(RsaSha256); function RsaSha256() { var _this; (0, _classCallCheck2.default)(this, RsaSha256); _this = _super.call(this); _this.modulus = null; _this.signature = null; return _this; } (0, _createClass2.default)(RsaSha256, [{ key: "parseJson", value: function parseJson(json) { this.modulus = Buffer.from(json.modulus, 'base64'); this.signature = Buffer.from(json.signature, 'base64'); } /** * Produce the contents of the condition hash. * * This function is called internally by the `getCondition` method. * * @return {Buffer} Encoded contents of fingerprint hash. * * @private */ }, { key: "getFingerprintContents", value: function getFingerprintContents() { if (!this.modulus) { throw new _missingDataError.default('Requires modulus'); } return _fingerprint.RsaFingerprintContents.encode({ modulus: this.modulus }); } }, { key: "getAsn1JsonPayload", value: function getAsn1JsonPayload() { return { modulus: this.modulus, signature: this.signature }; } /** * Set the public modulus. * * This is the modulus of the RSA public key. It has to be provided as a raw * buffer with no leading zeros. * * @param {Buffer} modulus Public RSA modulus */ }, { key: "setPublicModulus", value: function setPublicModulus(modulus) { if (!Buffer.isBuffer(modulus)) { throw new TypeError('Modulus must be a buffer, was: ' + modulus); } if (modulus[0] === 0) { throw new Error('Modulus may not contain leading zeros'); } if (modulus.length > 512 || modulus.length < 128) { throw new Error('Modulus must be between 128 bytes (1017 bits) and ' + '512 bytes (4096 bits), was: ' + modulus.length + ' bytes'); } this.modulus = modulus; } /** * Set the signature manually. * * The signature must be a valid RSA-PSS siganture. * * @param {Buffer} signature RSA signature. */ }, { key: "setSignature", value: function setSignature(signature) { if (!Buffer.isBuffer(signature)) { throw new TypeError('Signature must be a buffer, was: ' + signature); } this.signature = signature; } /** * Sign the message. * * This method will take the provided message and create a signature using the * provided RSA private key. The resulting signature is stored in the * fulfillment. * * The key should be provided as a PEM encoded private key string. * * The message is padded using RSA-PSS with SHA256. * * @param {Buffer} message Message to sign. * @param {String} privateKey RSA private key */ }, { key: "sign", value: function sign(message, privateKey) { if (!this.modulus) { this.setPublicModulus(_pem.default.modulusFromPrivateKey(privateKey)); } this.signature = rsa.sign(privateKey, message); } /** * Calculate the cost of fulfilling this condition. * * The cost of the RSA condition is the size of the modulus squared, divided * by 64. * * @return {Number} Expected maximum cost to fulfill this condition * @private */ }, { key: "calculateCost", value: function calculateCost() { if (!this.modulus) { throw new _missingDataError.default('Requires a public modulus'); } return Math.pow(rsa.getModulusBitLength(this.modulus), 2) >>> RsaSha256.COST_RIGHT_SHIFT; } /** * Verify the signature of this RSA fulfillment. * * The signature of this RSA fulfillment is verified against the provided * message and the condition's public modulus. * * @param {Buffer} message Message to verify. * @return {Boolean} Whether this fulfillment is valid. */ }, { key: "validate", value: function validate(message) { if (!Buffer.isBuffer(message)) { throw new Error('Message must be provided as a Buffer, was: ' + message); } var pssResult = rsa.verify(this.modulus, message, this.signature); if (!pssResult) { throw new _validationError.default('Invalid RSA signature'); } return true; } }]); return RsaSha256; }(_baseSha.default); RsaSha256.TYPE_ID = 3; RsaSha256.TYPE_NAME = 'rsa-sha-256'; RsaSha256.TYPE_ASN1_CONDITION = 'rsaSha256Condition'; RsaSha256.TYPE_ASN1_FULFILLMENT = 'rsaSha256Fulfillment'; RsaSha256.TYPE_CATEGORY = 'simple'; RsaSha256.COST_RIGHT_SHIFT = 6; // 2^6 = 64 var _default = RsaSha256; exports.default = _default;