UNPKG

11.5 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports["default"] = void 0;
5
6var _buffer = require("buffer");
7
8var _core = _interopRequireDefault(require("crypto-js/core"));
9
10require("crypto-js/lib-typedarrays");
11
12var _sha = _interopRequireDefault(require("crypto-js/sha256"));
13
14var _hmacSha = _interopRequireDefault(require("crypto-js/hmac-sha256"));
15
16var _BigInteger = _interopRequireDefault(require("./BigInteger"));
17
18function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
19
20/*!
21 * Copyright 2016 Amazon.com,
22 * Inc. or its affiliates. All Rights Reserved.
23 *
24 * Licensed under the Amazon Software License (the "License").
25 * You may not use this file except in compliance with the
26 * License. A copy of the License is located at
27 *
28 * http://aws.amazon.com/asl/
29 *
30 * or in the "license" file accompanying this file. This file is
31 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
32 * CONDITIONS OF ANY KIND, express or implied. See the License
33 * for the specific language governing permissions and
34 * limitations under the License.
35 */
36// necessary for crypto js
37var randomBytes = function randomBytes(nBytes) {
38 return _buffer.Buffer.from(_core["default"].lib.WordArray.random(nBytes).toString(), 'hex');
39};
40
41var initN = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D' + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F' + '83655D23DCA3AD961C62F356208552BB9ED529077096966D' + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9' + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510' + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64' + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B' + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C' + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31' + '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF';
42var newPasswordRequiredChallengeUserAttributePrefix = 'userAttributes.';
43/** @class */
44
45var AuthenticationHelper = /*#__PURE__*/function () {
46 /**
47 * Constructs a new AuthenticationHelper object
48 * @param {string} PoolName Cognito user pool name.
49 */
50 function AuthenticationHelper(PoolName) {
51 this.N = new _BigInteger["default"](initN, 16);
52 this.g = new _BigInteger["default"]('2', 16);
53 this.k = new _BigInteger["default"](this.hexHash("00" + this.N.toString(16) + "0" + this.g.toString(16)), 16);
54 this.smallAValue = this.generateRandomSmallA();
55 this.getLargeAValue(function () {});
56 this.infoBits = _buffer.Buffer.from('Caldera Derived Key', 'utf8');
57 this.poolName = PoolName;
58 }
59 /**
60 * @returns {BigInteger} small A, a random number
61 */
62
63
64 var _proto = AuthenticationHelper.prototype;
65
66 _proto.getSmallAValue = function getSmallAValue() {
67 return this.smallAValue;
68 }
69 /**
70 * @param {nodeCallback<BigInteger>} callback Called with (err, largeAValue)
71 * @returns {void}
72 */
73 ;
74
75 _proto.getLargeAValue = function getLargeAValue(callback) {
76 var _this = this;
77
78 if (this.largeAValue) {
79 callback(null, this.largeAValue);
80 } else {
81 this.calculateA(this.smallAValue, function (err, largeAValue) {
82 if (err) {
83 callback(err, null);
84 }
85
86 _this.largeAValue = largeAValue;
87 callback(null, _this.largeAValue);
88 });
89 }
90 }
91 /**
92 * helper function to generate a random big integer
93 * @returns {BigInteger} a random value.
94 * @private
95 */
96 ;
97
98 _proto.generateRandomSmallA = function generateRandomSmallA() {
99 var hexRandom = randomBytes(128).toString('hex');
100 var randomBigInt = new _BigInteger["default"](hexRandom, 16);
101 var smallABigInt = randomBigInt.mod(this.N);
102 return smallABigInt;
103 }
104 /**
105 * helper function to generate a random string
106 * @returns {string} a random value.
107 * @private
108 */
109 ;
110
111 _proto.generateRandomString = function generateRandomString() {
112 return randomBytes(40).toString('base64');
113 }
114 /**
115 * @returns {string} Generated random value included in password hash.
116 */
117 ;
118
119 _proto.getRandomPassword = function getRandomPassword() {
120 return this.randomPassword;
121 }
122 /**
123 * @returns {string} Generated random value included in devices hash.
124 */
125 ;
126
127 _proto.getSaltDevices = function getSaltDevices() {
128 return this.SaltToHashDevices;
129 }
130 /**
131 * @returns {string} Value used to verify devices.
132 */
133 ;
134
135 _proto.getVerifierDevices = function getVerifierDevices() {
136 return this.verifierDevices;
137 }
138 /**
139 * Generate salts and compute verifier.
140 * @param {string} deviceGroupKey Devices to generate verifier for.
141 * @param {string} username User to generate verifier for.
142 * @param {nodeCallback<null>} callback Called with (err, null)
143 * @returns {void}
144 */
145 ;
146
147 _proto.generateHashDevice = function generateHashDevice(deviceGroupKey, username, callback) {
148 var _this2 = this;
149
150 this.randomPassword = this.generateRandomString();
151 var combinedString = "" + deviceGroupKey + username + ":" + this.randomPassword;
152 var hashedString = this.hash(combinedString);
153 var hexRandom = randomBytes(16).toString('hex');
154 this.SaltToHashDevices = this.padHex(new _BigInteger["default"](hexRandom, 16));
155 this.g.modPow(new _BigInteger["default"](this.hexHash(this.SaltToHashDevices + hashedString), 16), this.N, function (err, verifierDevicesNotPadded) {
156 if (err) {
157 callback(err, null);
158 }
159
160 _this2.verifierDevices = _this2.padHex(verifierDevicesNotPadded);
161 callback(null, null);
162 });
163 }
164 /**
165 * Calculate the client's public value A = g^a%N
166 * with the generated random number a
167 * @param {BigInteger} a Randomly generated small A.
168 * @param {nodeCallback<BigInteger>} callback Called with (err, largeAValue)
169 * @returns {void}
170 * @private
171 */
172 ;
173
174 _proto.calculateA = function calculateA(a, callback) {
175 var _this3 = this;
176
177 this.g.modPow(a, this.N, function (err, A) {
178 if (err) {
179 callback(err, null);
180 }
181
182 if (A.mod(_this3.N).equals(_BigInteger["default"].ZERO)) {
183 callback(new Error('Illegal paramater. A mod N cannot be 0.'), null);
184 }
185
186 callback(null, A);
187 });
188 }
189 /**
190 * Calculate the client's value U which is the hash of A and B
191 * @param {BigInteger} A Large A value.
192 * @param {BigInteger} B Server B value.
193 * @returns {BigInteger} Computed U value.
194 * @private
195 */
196 ;
197
198 _proto.calculateU = function calculateU(A, B) {
199 this.UHexHash = this.hexHash(this.padHex(A) + this.padHex(B));
200 var finalU = new _BigInteger["default"](this.UHexHash, 16);
201 return finalU;
202 }
203 /**
204 * Calculate a hash from a bitArray
205 * @param {Buffer} buf Value to hash.
206 * @returns {String} Hex-encoded hash.
207 * @private
208 */
209 ;
210
211 _proto.hash = function hash(buf) {
212 var str = buf instanceof _buffer.Buffer ? _core["default"].lib.WordArray.create(buf) : buf;
213 var hashHex = (0, _sha["default"])(str).toString();
214 return new Array(64 - hashHex.length).join('0') + hashHex;
215 }
216 /**
217 * Calculate a hash from a hex string
218 * @param {String} hexStr Value to hash.
219 * @returns {String} Hex-encoded hash.
220 * @private
221 */
222 ;
223
224 _proto.hexHash = function hexHash(hexStr) {
225 return this.hash(_buffer.Buffer.from(hexStr, 'hex'));
226 }
227 /**
228 * Standard hkdf algorithm
229 * @param {Buffer} ikm Input key material.
230 * @param {Buffer} salt Salt value.
231 * @returns {Buffer} Strong key material.
232 * @private
233 */
234 ;
235
236 _proto.computehkdf = function computehkdf(ikm, salt) {
237 var infoBitsWordArray = _core["default"].lib.WordArray.create(_buffer.Buffer.concat([this.infoBits, _buffer.Buffer.from(String.fromCharCode(1), 'utf8')]));
238
239 var ikmWordArray = ikm instanceof _buffer.Buffer ? _core["default"].lib.WordArray.create(ikm) : ikm;
240 var saltWordArray = salt instanceof _buffer.Buffer ? _core["default"].lib.WordArray.create(salt) : salt;
241 var prk = (0, _hmacSha["default"])(ikmWordArray, saltWordArray);
242 var hmac = (0, _hmacSha["default"])(infoBitsWordArray, prk);
243 return _buffer.Buffer.from(hmac.toString(), 'hex').slice(0, 16);
244 }
245 /**
246 * Calculates the final hkdf based on computed S value, and computed U value and the key
247 * @param {String} username Username.
248 * @param {String} password Password.
249 * @param {BigInteger} serverBValue Server B value.
250 * @param {BigInteger} salt Generated salt.
251 * @param {nodeCallback<Buffer>} callback Called with (err, hkdfValue)
252 * @returns {void}
253 */
254 ;
255
256 _proto.getPasswordAuthenticationKey = function getPasswordAuthenticationKey(username, password, serverBValue, salt, callback) {
257 var _this4 = this;
258
259 if (serverBValue.mod(this.N).equals(_BigInteger["default"].ZERO)) {
260 throw new Error('B cannot be zero.');
261 }
262
263 this.UValue = this.calculateU(this.largeAValue, serverBValue);
264
265 if (this.UValue.equals(_BigInteger["default"].ZERO)) {
266 throw new Error('U cannot be zero.');
267 }
268
269 var usernamePassword = "" + this.poolName + username + ":" + password;
270 var usernamePasswordHash = this.hash(usernamePassword);
271 var xValue = new _BigInteger["default"](this.hexHash(this.padHex(salt) + usernamePasswordHash), 16);
272 this.calculateS(xValue, serverBValue, function (err, sValue) {
273 if (err) {
274 callback(err, null);
275 }
276
277 var hkdf = _this4.computehkdf(_buffer.Buffer.from(_this4.padHex(sValue), 'hex'), _buffer.Buffer.from(_this4.padHex(_this4.UValue.toString(16)), 'hex'));
278
279 callback(null, hkdf);
280 });
281 }
282 /**
283 * Calculates the S value used in getPasswordAuthenticationKey
284 * @param {BigInteger} xValue Salted password hash value.
285 * @param {BigInteger} serverBValue Server B value.
286 * @param {nodeCallback<string>} callback Called on success or error.
287 * @returns {void}
288 */
289 ;
290
291 _proto.calculateS = function calculateS(xValue, serverBValue, callback) {
292 var _this5 = this;
293
294 this.g.modPow(xValue, this.N, function (err, gModPowXN) {
295 if (err) {
296 callback(err, null);
297 }
298
299 var intValue2 = serverBValue.subtract(_this5.k.multiply(gModPowXN));
300 intValue2.modPow(_this5.smallAValue.add(_this5.UValue.multiply(xValue)), _this5.N, function (err2, result) {
301 if (err2) {
302 callback(err2, null);
303 }
304
305 callback(null, result.mod(_this5.N));
306 });
307 });
308 }
309 /**
310 * Return constant newPasswordRequiredChallengeUserAttributePrefix
311 * @return {newPasswordRequiredChallengeUserAttributePrefix} constant prefix value
312 */
313 ;
314
315 _proto.getNewPasswordRequiredChallengeUserAttributePrefix = function getNewPasswordRequiredChallengeUserAttributePrefix() {
316 return newPasswordRequiredChallengeUserAttributePrefix;
317 }
318 /**
319 * Converts a BigInteger (or hex string) to hex format padded with zeroes for hashing
320 * @param {BigInteger|String} bigInt Number or string to pad.
321 * @returns {String} Padded hex string.
322 */
323 ;
324
325 _proto.padHex = function padHex(bigInt) {
326 var hashStr = bigInt.toString(16);
327
328 if (hashStr.length % 2 === 1) {
329 hashStr = "0" + hashStr;
330 } else if ('89ABCDEFabcdef'.indexOf(hashStr[0]) !== -1) {
331 hashStr = "00" + hashStr;
332 }
333
334 return hashStr;
335 };
336
337 return AuthenticationHelper;
338}();
339
340exports["default"] = AuthenticationHelper;
\No newline at end of file