v4_credentials.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. var AWS = require('../core');
  2. /**
  3. * @api private
  4. */
  5. var cachedSecret = {};
  6. /**
  7. * @api private
  8. */
  9. var cacheQueue = [];
  10. /**
  11. * @api private
  12. */
  13. var maxCacheEntries = 50;
  14. /**
  15. * @api private
  16. */
  17. var v4Identifier = 'aws4_request';
  18. /**
  19. * @api private
  20. */
  21. module.exports = {
  22. /**
  23. * @api private
  24. *
  25. * @param date [String]
  26. * @param region [String]
  27. * @param serviceName [String]
  28. * @return [String]
  29. */
  30. createScope: function createScope(date, region, serviceName) {
  31. return [
  32. date.substr(0, 8),
  33. region,
  34. serviceName,
  35. v4Identifier
  36. ].join('/');
  37. },
  38. /**
  39. * @api private
  40. *
  41. * @param credentials [Credentials]
  42. * @param date [String]
  43. * @param region [String]
  44. * @param service [String]
  45. * @param shouldCache [Boolean]
  46. * @return [String]
  47. */
  48. getSigningKey: function getSigningKey(
  49. credentials,
  50. date,
  51. region,
  52. service,
  53. shouldCache
  54. ) {
  55. var credsIdentifier = AWS.util.crypto
  56. .hmac(credentials.secretAccessKey, credentials.accessKeyId, 'base64');
  57. var cacheKey = [credsIdentifier, date, region, service].join('_');
  58. shouldCache = shouldCache !== false;
  59. if (shouldCache && (cacheKey in cachedSecret)) {
  60. return cachedSecret[cacheKey];
  61. }
  62. var kDate = AWS.util.crypto.hmac(
  63. 'AWS4' + credentials.secretAccessKey,
  64. date,
  65. 'buffer'
  66. );
  67. var kRegion = AWS.util.crypto.hmac(kDate, region, 'buffer');
  68. var kService = AWS.util.crypto.hmac(kRegion, service, 'buffer');
  69. var signingKey = AWS.util.crypto.hmac(kService, v4Identifier, 'buffer');
  70. if (shouldCache) {
  71. cachedSecret[cacheKey] = signingKey;
  72. cacheQueue.push(cacheKey);
  73. if (cacheQueue.length > maxCacheEntries) {
  74. // remove the oldest entry (not the least recently used)
  75. delete cachedSecret[cacheQueue.shift()];
  76. }
  77. }
  78. return signingKey;
  79. },
  80. /**
  81. * @api private
  82. *
  83. * Empties the derived signing key cache. Made available for testing purposes
  84. * only.
  85. */
  86. emptyCache: function emptyCache() {
  87. cachedSecret = {};
  88. cacheQueue = [];
  89. }
  90. };