3 var Crypto = require('crypto');
4 var Url = require('url');
5 var Utils = require('./utils');
13 // MAC normalization format version
15 exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats
18 // Supported HMAC algorithms
20 exports.algorithms = ['sha1', 'sha256'];
23 // Calculate the request MAC
26 type: 'header', // 'header', 'bewit', 'response'
28 key: 'aoijedoaijsdlaksjdl',
29 algorithm: 'sha256' // 'sha1', 'sha256'
33 resource: '/resource?a=1&b=2',
38 hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=',
39 ext: 'app-specific-data',
40 app: 'hf48hd83qwkj', // Application id (Oz)
41 dlg: 'd8djwekds9cj' // Delegated by application id (Oz), requires options.app
45 exports.calculateMac = function (type, credentials, options) {
47 var normalized = exports.generateNormalizedString(type, options);
49 var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized);
50 var digest = hmac.digest('base64');
55 exports.generateNormalizedString = function (type, options) {
57 var resource = options.resource || '';
59 resource[0] !== '/') {
61 var url = Url.parse(resource, false);
62 resource = url.path; // Includes query
65 var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
67 options.nonce + '\n' +
68 (options.method || '').toUpperCase() + '\n' +
70 options.host.toLowerCase() + '\n' +
72 (options.hash || '') + '\n';
75 normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
81 normalized += options.app + '\n' +
82 (options.dlg || '') + '\n';
89 exports.calculatePayloadHash = function (payload, algorithm, contentType) {
91 var hash = exports.initializePayloadHash(algorithm, contentType);
92 hash.update(payload || '');
93 return exports.finalizePayloadHash(hash);
97 exports.initializePayloadHash = function (algorithm, contentType) {
99 var hash = Crypto.createHash(algorithm);
100 hash.update('hawk.' + exports.headerVersion + '.payload\n');
101 hash.update(Utils.parseContentType(contentType) + '\n');
106 exports.finalizePayloadHash = function (hash) {
109 return hash.digest('base64');
113 exports.calculateTsMac = function (ts, credentials) {
115 var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
116 hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
117 return hmac.digest('base64');
121 exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
123 var now = Utils.nowSecs(localtimeOffsetMsec);
124 var tsm = exports.calculateTsMac(now, credentials);
125 return { ts: now, tsm: tsm };