Buckets:
| var Buffer = require('safe-buffer').Buffer; | |
| var crypto = require('crypto'); | |
| var formatEcdsa = require('ecdsa-sig-formatter'); | |
| var util = require('util'); | |
| var MSG_INVALID_ALGORITHM = '"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".' | |
| var MSG_INVALID_SECRET = 'secret must be a string or buffer'; | |
| var MSG_INVALID_VERIFIER_KEY = 'key must be a string or a buffer'; | |
| var MSG_INVALID_SIGNER_KEY = 'key must be a string, a buffer or an object'; | |
| var supportsKeyObjects = typeof crypto.createPublicKey === 'function'; | |
| if (supportsKeyObjects) { | |
| MSG_INVALID_VERIFIER_KEY += ' or a KeyObject'; | |
| MSG_INVALID_SECRET += 'or a KeyObject'; | |
| } | |
| function checkIsPublicKey(key) { | |
| if (Buffer.isBuffer(key)) { | |
| return; | |
| } | |
| if (typeof key === 'string') { | |
| return; | |
| } | |
| if (!supportsKeyObjects) { | |
| throw typeError(MSG_INVALID_VERIFIER_KEY); | |
| } | |
| if (typeof key !== 'object') { | |
| throw typeError(MSG_INVALID_VERIFIER_KEY); | |
| } | |
| if (typeof key.type !== 'string') { | |
| throw typeError(MSG_INVALID_VERIFIER_KEY); | |
| } | |
| if (typeof key.asymmetricKeyType !== 'string') { | |
| throw typeError(MSG_INVALID_VERIFIER_KEY); | |
| } | |
| if (typeof key.export !== 'function') { | |
| throw typeError(MSG_INVALID_VERIFIER_KEY); | |
| } | |
| }; | |
| function checkIsPrivateKey(key) { | |
| if (Buffer.isBuffer(key)) { | |
| return; | |
| } | |
| if (typeof key === 'string') { | |
| return; | |
| } | |
| if (typeof key === 'object') { | |
| return; | |
| } | |
| throw typeError(MSG_INVALID_SIGNER_KEY); | |
| }; | |
| function checkIsSecretKey(key) { | |
| if (Buffer.isBuffer(key)) { | |
| return; | |
| } | |
| if (typeof key === 'string') { | |
| return key; | |
| } | |
| if (!supportsKeyObjects) { | |
| throw typeError(MSG_INVALID_SECRET); | |
| } | |
| if (typeof key !== 'object') { | |
| throw typeError(MSG_INVALID_SECRET); | |
| } | |
| if (key.type !== 'secret') { | |
| throw typeError(MSG_INVALID_SECRET); | |
| } | |
| if (typeof key.export !== 'function') { | |
| throw typeError(MSG_INVALID_SECRET); | |
| } | |
| } | |
| function fromBase64(base64) { | |
| return base64 | |
| .replace(/=/g, '') | |
| .replace(/\+/g, '-') | |
| .replace(/\//g, '_'); | |
| } | |
| function toBase64(base64url) { | |
| base64url = base64url.toString(); | |
| var padding = 4 - base64url.length % 4; | |
| if (padding !== 4) { | |
| for (var i = 0; i < padding; ++i) { | |
| base64url += '='; | |
| } | |
| } | |
| return base64url | |
| .replace(/\-/g, '+') | |
| .replace(/_/g, '/'); | |
| } | |
| function typeError(template) { | |
| var args = [].slice.call(arguments, 1); | |
| var errMsg = util.format.bind(util, template).apply(null, args); | |
| return new TypeError(errMsg); | |
| } | |
| function bufferOrString(obj) { | |
| return Buffer.isBuffer(obj) || typeof obj === 'string'; | |
| } | |
| function normalizeInput(thing) { | |
| if (!bufferOrString(thing)) | |
| thing = JSON.stringify(thing); | |
| return thing; | |
| } | |
| function createHmacSigner(bits) { | |
| return function sign(thing, secret) { | |
| checkIsSecretKey(secret); | |
| thing = normalizeInput(thing); | |
| var hmac = crypto.createHmac('sha' + bits, secret); | |
| var sig = (hmac.update(thing), hmac.digest('base64')) | |
| return fromBase64(sig); | |
| } | |
| } | |
| var bufferEqual; | |
| var timingSafeEqual = 'timingSafeEqual' in crypto ? function timingSafeEqual(a, b) { | |
| if (a.byteLength !== b.byteLength) { | |
| return false; | |
| } | |
| return crypto.timingSafeEqual(a, b) | |
| } : function timingSafeEqual(a, b) { | |
| if (!bufferEqual) { | |
| bufferEqual = require('buffer-equal-constant-time'); | |
| } | |
| return bufferEqual(a, b) | |
| } | |
| function createHmacVerifier(bits) { | |
| return function verify(thing, signature, secret) { | |
| var computedSig = createHmacSigner(bits)(thing, secret); | |
| return timingSafeEqual(Buffer.from(signature), Buffer.from(computedSig)); | |
| } | |
| } | |
| function createKeySigner(bits) { | |
| return function sign(thing, privateKey) { | |
| checkIsPrivateKey(privateKey); | |
| thing = normalizeInput(thing); | |
| // Even though we are specifying "RSA" here, this works with ECDSA | |
| // keys as well. | |
| var signer = crypto.createSign('RSA-SHA' + bits); | |
| var sig = (signer.update(thing), signer.sign(privateKey, 'base64')); | |
| return fromBase64(sig); | |
| } | |
| } | |
| function createKeyVerifier(bits) { | |
| return function verify(thing, signature, publicKey) { | |
| checkIsPublicKey(publicKey); | |
| thing = normalizeInput(thing); | |
| signature = toBase64(signature); | |
| var verifier = crypto.createVerify('RSA-SHA' + bits); | |
| verifier.update(thing); | |
| return verifier.verify(publicKey, signature, 'base64'); | |
| } | |
| } | |
| function createPSSKeySigner(bits) { | |
| return function sign(thing, privateKey) { | |
| checkIsPrivateKey(privateKey); | |
| thing = normalizeInput(thing); | |
| var signer = crypto.createSign('RSA-SHA' + bits); | |
| var sig = (signer.update(thing), signer.sign({ | |
| key: privateKey, | |
| padding: crypto.constants.RSA_PKCS1_PSS_PADDING, | |
| saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST | |
| }, 'base64')); | |
| return fromBase64(sig); | |
| } | |
| } | |
| function createPSSKeyVerifier(bits) { | |
| return function verify(thing, signature, publicKey) { | |
| checkIsPublicKey(publicKey); | |
| thing = normalizeInput(thing); | |
| signature = toBase64(signature); | |
| var verifier = crypto.createVerify('RSA-SHA' + bits); | |
| verifier.update(thing); | |
| return verifier.verify({ | |
| key: publicKey, | |
| padding: crypto.constants.RSA_PKCS1_PSS_PADDING, | |
| saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST | |
| }, signature, 'base64'); | |
| } | |
| } | |
| function createECDSASigner(bits) { | |
| var inner = createKeySigner(bits); | |
| return function sign() { | |
| var signature = inner.apply(null, arguments); | |
| signature = formatEcdsa.derToJose(signature, 'ES' + bits); | |
| return signature; | |
| }; | |
| } | |
| function createECDSAVerifer(bits) { | |
| var inner = createKeyVerifier(bits); | |
| return function verify(thing, signature, publicKey) { | |
| signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64'); | |
| var result = inner(thing, signature, publicKey); | |
| return result; | |
| }; | |
| } | |
| function createNoneSigner() { | |
| return function sign() { | |
| return ''; | |
| } | |
| } | |
| function createNoneVerifier() { | |
| return function verify(thing, signature) { | |
| return signature === ''; | |
| } | |
| } | |
| module.exports = function jwa(algorithm) { | |
| var signerFactories = { | |
| hs: createHmacSigner, | |
| rs: createKeySigner, | |
| ps: createPSSKeySigner, | |
| es: createECDSASigner, | |
| none: createNoneSigner, | |
| } | |
| var verifierFactories = { | |
| hs: createHmacVerifier, | |
| rs: createKeyVerifier, | |
| ps: createPSSKeyVerifier, | |
| es: createECDSAVerifer, | |
| none: createNoneVerifier, | |
| } | |
| var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/); | |
| if (!match) | |
| throw typeError(MSG_INVALID_ALGORITHM, algorithm); | |
| var algo = (match[1] || match[3]).toLowerCase(); | |
| var bits = match[2]; | |
| return { | |
| sign: signerFactories[algo](bits), | |
| verify: verifierFactories[algo](bits), | |
| } | |
| }; | |
Xet Storage Details
- Size:
- 6.8 kB
- Xet hash:
- 64f5e40dc1843ea3d1a52e5be3cd664055b4fc3ea39da4455147984f46efa6a9
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.