Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81146 views
1
// Load modules
2
3
var Crypto = require('crypto');
4
var Url = require('url');
5
var Utils = require('./utils');
6
7
8
// Declare internals
9
10
var internals = {};
11
12
13
// MAC normalization format version
14
15
exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats
16
17
18
// Supported HMAC algorithms
19
20
exports.algorithms = ['sha1', 'sha256'];
21
22
23
// Calculate the request MAC
24
25
/*
26
type: 'header', // 'header', 'bewit', 'response'
27
credentials: {
28
key: 'aoijedoaijsdlaksjdl',
29
algorithm: 'sha256' // 'sha1', 'sha256'
30
},
31
options: {
32
method: 'GET',
33
resource: '/resource?a=1&b=2',
34
host: 'example.com',
35
port: 8080,
36
ts: 1357718381034,
37
nonce: 'd3d345f',
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
42
}
43
*/
44
45
exports.calculateMac = function (type, credentials, options) {
46
47
var normalized = exports.generateNormalizedString(type, options);
48
49
var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized);
50
var digest = hmac.digest('base64');
51
return digest;
52
};
53
54
55
exports.generateNormalizedString = function (type, options) {
56
57
var resource = options.resource || '';
58
if (resource &&
59
resource[0] !== '/') {
60
61
var url = Url.parse(resource, false);
62
resource = url.path; // Includes query
63
}
64
65
var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
66
options.ts + '\n' +
67
options.nonce + '\n' +
68
(options.method || '').toUpperCase() + '\n' +
69
resource + '\n' +
70
options.host.toLowerCase() + '\n' +
71
options.port + '\n' +
72
(options.hash || '') + '\n';
73
74
if (options.ext) {
75
normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
76
}
77
78
normalized += '\n';
79
80
if (options.app) {
81
normalized += options.app + '\n' +
82
(options.dlg || '') + '\n';
83
}
84
85
return normalized;
86
};
87
88
89
exports.calculatePayloadHash = function (payload, algorithm, contentType) {
90
91
var hash = exports.initializePayloadHash(algorithm, contentType);
92
hash.update(payload || '');
93
return exports.finalizePayloadHash(hash);
94
};
95
96
97
exports.initializePayloadHash = function (algorithm, contentType) {
98
99
var hash = Crypto.createHash(algorithm);
100
hash.update('hawk.' + exports.headerVersion + '.payload\n');
101
hash.update(Utils.parseContentType(contentType) + '\n');
102
return hash;
103
};
104
105
106
exports.finalizePayloadHash = function (hash) {
107
108
hash.update('\n');
109
return hash.digest('base64');
110
};
111
112
113
exports.calculateTsMac = function (ts, credentials) {
114
115
var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
116
hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
117
return hmac.digest('base64');
118
};
119
120
121
exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
122
123
var now = Utils.nowSecs(localtimeOffsetMsec);
124
var tsm = exports.calculateTsMac(now, credentials);
125
return { ts: now, tsm: tsm };
126
};
127
128