Dodo67

Index

Feb 4th, 2022
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var bufferEqual = require('buffer-equal-constant-time');
  2. var Buffer = require('safe-buffer').Buffer;
  3. var crypto = require('crypto');
  4. var formatEcdsa = require('ecdsa-sig-formatter');
  5. var util = require('util');
  6.  
  7. 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".'
  8. var MSG_INVALID_SECRET = 'secret must be a string or buffer';
  9. var MSG_INVALID_VERIFIER_KEY = 'key must be a string or a buffer';
  10. var MSG_INVALID_SIGNER_KEY = 'key must be a string, a buffer or an object';
  11.  
  12. var supportsKeyObjects = typeof crypto.createPublicKey === 'function';
  13. if (supportsKeyObjects) {
  14.   MSG_INVALID_VERIFIER_KEY += ' or a KeyObject';
  15.   MSG_INVALID_SECRET += 'or a KeyObject';
  16. }
  17.  
  18. function checkIsPublicKey(key) {
  19.   if (Buffer.isBuffer(key)) {
  20.     return;
  21.   }
  22.  
  23.   if (typeof key === 'string') {
  24.     return;
  25.   }
  26.  
  27.   if (!supportsKeyObjects) {
  28.     throw typeError(MSG_INVALID_VERIFIER_KEY);
  29.   }
  30.  
  31.   if (typeof key !== 'object') {
  32.     throw typeError(MSG_INVALID_VERIFIER_KEY);
  33.   }
  34.  
  35.   if (typeof key.type !== 'string') {
  36.     throw typeError(MSG_INVALID_VERIFIER_KEY);
  37.   }
  38.  
  39.   if (typeof key.asymmetricKeyType !== 'string') {
  40.     throw typeError(MSG_INVALID_VERIFIER_KEY);
  41.   }
  42.  
  43.   if (typeof key.export !== 'function') {
  44.     throw typeError(MSG_INVALID_VERIFIER_KEY);
  45.   }
  46. };
  47.  
  48. function checkIsPrivateKey(key) {
  49.   if (Buffer.isBuffer(key)) {
  50.     return;
  51.   }
  52.  
  53.   if (typeof key === 'string') {
  54.     return;
  55.   }
  56.  
  57.   if (typeof key === 'object') {
  58.     return;
  59.   }
  60.  
  61.   throw typeError(MSG_INVALID_SIGNER_KEY);
  62. };
  63.  
  64. function checkIsSecretKey(key) {
  65.   if (Buffer.isBuffer(key)) {
  66.     return;
  67.   }
  68.  
  69.   if (typeof key === 'string') {
  70.     return key;
  71.   }
  72.  
  73.   if (!supportsKeyObjects) {
  74.     throw typeError(MSG_INVALID_SECRET);
  75.   }
  76.  
  77.   if (typeof key !== 'object') {
  78.     throw typeError(MSG_INVALID_SECRET);
  79.   }
  80.  
  81.   if (key.type !== 'secret') {
  82.     throw typeError(MSG_INVALID_SECRET);
  83.   }
  84.  
  85.   if (typeof key.export !== 'function') {
  86.     throw typeError(MSG_INVALID_SECRET);
  87.   }
  88. }
  89.  
  90. function fromBase64(base64) {
  91.   return base64
  92.     .replace(/=/g, '')
  93.     .replace(/\+/g, '-')
  94.     .replace(/\//g, '_');
  95. }
  96.  
  97. function toBase64(base64url) {
  98.   base64url = base64url.toString();
  99.  
  100.   var padding = 4 - base64url.length % 4;
  101.   if (padding !== 4) {
  102.     for (var i = 0; i < padding; ++i) {
  103.       base64url += '=';
  104.     }
  105.   }
  106.  
  107.   return base64url
  108.     .replace(/\-/g, '+')
  109.     .replace(/_/g, '/');
  110. }
  111.  
  112. function typeError(template) {
  113.   var args = [].slice.call(arguments, 1);
  114.   var errMsg = util.format.bind(util, template).apply(null, args);
  115.   return new TypeError(errMsg);
  116. }
  117.  
  118. function bufferOrString(obj) {
  119.   return Buffer.isBuffer(obj) || typeof obj === 'string';
  120. }
  121.  
  122. function normalizeInput(thing) {
  123.   if (!bufferOrString(thing))
  124.     thing = JSON.stringify(thing);
  125.   return thing;
  126. }
  127.  
  128. function createHmacSigner(bits) {
  129.   return function sign(thing, secret) {
  130.     checkIsSecretKey(secret);
  131.     thing = normalizeInput(thing);
  132.     var hmac = crypto.createHmac('sha' + bits, secret);
  133.     var sig = (hmac.update(thing), hmac.digest('base64'))
  134.     return fromBase64(sig);
  135.   }
  136. }
  137.  
  138. function createHmacVerifier(bits) {
  139.   return function verify(thing, signature, secret) {
  140.     var computedSig = createHmacSigner(bits)(thing, secret);
  141.     return bufferEqual(Buffer.from(signature), Buffer.from(computedSig));
  142.   }
  143. }
  144.  
  145. function createKeySigner(bits) {
  146.  return function sign(thing, privateKey) {
  147.     checkIsPrivateKey(privateKey);
  148.     thing = normalizeInput(thing);
  149.     // Even though we are specifying "RSA" here, this works with ECDSA
  150.     // keys as well.
  151.     var signer = crypto.createSign('RSA-SHA' + bits);
  152.     var sig = (signer.update(thing), signer.sign(privateKey, 'base64'));
  153.     return fromBase64(sig);
  154.   }
  155. }
  156.  
  157. function createKeyVerifier(bits) {
  158.   return function verify(thing, signature, publicKey) {
  159.     checkIsPublicKey(publicKey);
  160.     thing = normalizeInput(thing);
  161.     signature = toBase64(signature);
  162.     var verifier = crypto.createVerify('RSA-SHA' + bits);
  163.     verifier.update(thing);
  164.     return verifier.verify(publicKey, signature, 'base64');
  165.   }
  166. }
  167.  
  168. function createPSSKeySigner(bits) {
  169.   return function sign(thing, privateKey) {
  170.     checkIsPrivateKey(privateKey);
  171.     thing = normalizeInput(thing);
  172.     var signer = crypto.createSign('RSA-SHA' + bits);
  173.     var sig = (signer.update(thing), signer.sign({
  174.       key: privateKey,
  175.       padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
  176.       saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
  177.     }, 'base64'));
  178.     return fromBase64(sig);
  179.   }
  180. }
  181.  
  182. function createPSSKeyVerifier(bits) {
  183.   return function verify(thing, signature, publicKey) {
  184.     checkIsPublicKey(publicKey);
  185.     thing = normalizeInput(thing);
  186.     signature = toBase64(signature);
  187.     var verifier = crypto.createVerify('RSA-SHA' + bits);
  188.     verifier.update(thing);
  189.     return verifier.verify({
  190.       key: publicKey,
  191.       padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
  192.       saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST
  193.     }, signature, 'base64');
  194.   }
  195. }
  196.  
  197. function createECDSASigner(bits) {
  198.   var inner = createKeySigner(bits);
  199.   return function sign() {
  200.     var signature = inner.apply(null, arguments);
  201.     signature = formatEcdsa.derToJose(signature, 'ES' + bits);
  202.     return signature;
  203.   };
  204. }
  205.  
  206. function createECDSAVerifer(bits) {
  207.   var inner = createKeyVerifier(bits);
  208.   return function verify(thing, signature, publicKey) {
  209.     signature = formatEcdsa.joseToDer(signature, 'ES' + bits).toString('base64');
  210.     var result = inner(thing, signature, publicKey);
  211.     return result;
  212.   };
  213. }
  214.  
  215. function createNoneSigner() {
  216.   return function sign() {
  217.     return '';
  218.   }
  219. }
  220.  
  221. function createNoneVerifier() {
  222.   return function verify(thing, signature) {
  223.     return signature === '';
  224.   }
  225. }
  226.  
  227. module.exports = function jwa(algorithm) {
  228.   var signerFactories = {
  229.     hs: createHmacSigner,
  230.     rs: createKeySigner,
  231.     ps: createPSSKeySigner,
  232.     es: createECDSASigner,
  233.     none: createNoneSigner,
  234.   }
  235.   var verifierFactories = {
  236.     hs: createHmacVerifier,
  237.     rs: createKeyVerifier,
  238.     ps: createPSSKeyVerifier,
  239.     es: createECDSAVerifer,
  240.     none: createNoneVerifier,
  241.   }
  242.   var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i);
  243.   if (!match)
  244.     throw typeError(MSG_INVALID_ALGORITHM, algorithm);
  245.   var algo = (match[1] || match[3]).toLowerCase();
  246.   var bits = match[2];
  247.  
  248.   return {
  249.     sign: signerFactories[algo](bits),
  250.     verify: verifierFactories[algo](bits),
  251.   }
  252. };
  253.  
Add Comment
Please, Sign In to add comment