OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview Handles web page requests for gnubby enrollment. | 6 * @fileoverview Handles web page requests for gnubby enrollment. |
7 */ | 7 */ |
8 | 8 |
9 'use strict'; | 9 'use strict'; |
10 | 10 |
11 /** | 11 /** |
12 * Handles a U2F enroll request. | 12 * Handles a U2F enroll request. |
13 * @param {MessageSender} messageSender The message sender. | 13 * @param {MessageSender} messageSender The message sender. |
14 * @param {Object} request The web page's enroll request. | 14 * @param {Object} request The web page's enroll request. |
15 * @param {Function} sendResponse Called back with the result of the enroll. | 15 * @param {Function} sendResponse Called back with the result of the enroll. |
16 * @return {Closeable} A handler object to be closed when the browser channel | 16 * @return {Closeable} A handler object to be closed when the browser channel |
17 * closes. | 17 * closes. |
18 */ | 18 */ |
19 function handleU2fEnrollRequest(messageSender, request, sendResponse) { | 19 function handleU2fEnrollRequest(messageSender, request, sendResponse) { |
20 var sentResponse = false; | 20 var sentResponse = false; |
21 var closeable = null; | 21 var closeable = null; |
22 | 22 |
23 function sendErrorResponse(error) { | 23 function sendErrorResponse(error) { |
24 var response = makeU2fErrorResponse(request, error.errorCode, | 24 var response = |
25 error.errorMessage); | 25 makeU2fErrorResponse(request, error.errorCode, error.errorMessage); |
26 sendResponseOnce(sentResponse, closeable, response, sendResponse); | 26 sendResponseOnce(sentResponse, closeable, response, sendResponse); |
27 } | 27 } |
28 | 28 |
29 function sendSuccessResponse(u2fVersion, info, clientData) { | 29 function sendSuccessResponse(u2fVersion, info, clientData) { |
30 var enrollChallenges = request['registerRequests']; | 30 var enrollChallenges = request['registerRequests']; |
31 var enrollChallenge = | 31 var enrollChallenge = |
32 findEnrollChallengeOfVersion(enrollChallenges, u2fVersion); | 32 findEnrollChallengeOfVersion(enrollChallenges, u2fVersion); |
33 if (!enrollChallenge) { | 33 if (!enrollChallenge) { |
34 sendErrorResponse({errorCode: ErrorCodes.OTHER_ERROR}); | 34 sendErrorResponse({errorCode: ErrorCodes.OTHER_ERROR}); |
35 return; | 35 return; |
(...skipping 22 matching lines...) Expand all Loading... |
58 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST}); | 58 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST}); |
59 return null; | 59 return null; |
60 } | 60 } |
61 | 61 |
62 var timeoutValueSeconds = getTimeoutValueFromRequest(request); | 62 var timeoutValueSeconds = getTimeoutValueFromRequest(request); |
63 // Attenuate watchdog timeout value less than the enroller's timeout, so the | 63 // Attenuate watchdog timeout value less than the enroller's timeout, so the |
64 // watchdog only fires after the enroller could reasonably have called back, | 64 // watchdog only fires after the enroller could reasonably have called back, |
65 // not before. | 65 // not before. |
66 var watchdogTimeoutValueSeconds = attenuateTimeoutInSeconds( | 66 var watchdogTimeoutValueSeconds = attenuateTimeoutInSeconds( |
67 timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2); | 67 timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2); |
68 var watchdog = new WatchdogRequestHandler(watchdogTimeoutValueSeconds, | 68 var watchdog = |
69 timeout); | 69 new WatchdogRequestHandler(watchdogTimeoutValueSeconds, timeout); |
70 var wrappedErrorCb = watchdog.wrapCallback(sendErrorResponse); | 70 var wrappedErrorCb = watchdog.wrapCallback(sendErrorResponse); |
71 var wrappedSuccessCb = watchdog.wrapCallback(sendSuccessResponse); | 71 var wrappedSuccessCb = watchdog.wrapCallback(sendSuccessResponse); |
72 | 72 |
73 var timer = createAttenuatedTimer( | 73 var timer = createAttenuatedTimer( |
74 FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds); | 74 FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds); |
75 var logMsgUrl = request['logMsgUrl']; | 75 var logMsgUrl = request['logMsgUrl']; |
76 var enroller = new Enroller(timer, sender, sendErrorResponse, | 76 var enroller = new Enroller( |
77 sendSuccessResponse, logMsgUrl); | 77 timer, sender, sendErrorResponse, sendSuccessResponse, logMsgUrl); |
78 watchdog.setCloseable(/** @type {!Closeable} */ (enroller)); | 78 watchdog.setCloseable(/** @type {!Closeable} */ (enroller)); |
79 closeable = watchdog; | 79 closeable = watchdog; |
80 | 80 |
81 var registerRequests = request['registerRequests']; | 81 var registerRequests = request['registerRequests']; |
82 var signRequests = getSignRequestsFromEnrollRequest(request); | 82 var signRequests = getSignRequestsFromEnrollRequest(request); |
83 enroller.doEnroll(registerRequests, signRequests, request['appId']); | 83 enroller.doEnroll(registerRequests, signRequests, request['appId']); |
84 | 84 |
85 return closeable; | 85 return closeable; |
86 } | 86 } |
87 | 87 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 175 |
176 /** | 176 /** |
177 * Makes a responseData object for the enroll request with the given parameters. | 177 * Makes a responseData object for the enroll request with the given parameters. |
178 * @param {EnrollChallenge} enrollChallenge The enroll challenge used to | 178 * @param {EnrollChallenge} enrollChallenge The enroll challenge used to |
179 * register. | 179 * register. |
180 * @param {string} u2fVersion Version of gnubby that enrolled. | 180 * @param {string} u2fVersion Version of gnubby that enrolled. |
181 * @param {string} registrationData The registration data. | 181 * @param {string} registrationData The registration data. |
182 * @param {string=} opt_clientData The client data, if available. | 182 * @param {string=} opt_clientData The client data, if available. |
183 * @return {Object} The responseData object. | 183 * @return {Object} The responseData object. |
184 */ | 184 */ |
185 function makeEnrollResponseData(enrollChallenge, u2fVersion, registrationData, | 185 function makeEnrollResponseData( |
186 opt_clientData) { | 186 enrollChallenge, u2fVersion, registrationData, opt_clientData) { |
187 var responseData = {}; | 187 var responseData = {}; |
188 responseData['registrationData'] = registrationData; | 188 responseData['registrationData'] = registrationData; |
189 // Echo the used challenge back in the reply. | 189 // Echo the used challenge back in the reply. |
190 for (var k in enrollChallenge) { | 190 for (var k in enrollChallenge) { |
191 responseData[k] = enrollChallenge[k]; | 191 responseData[k] = enrollChallenge[k]; |
192 } | 192 } |
193 if (u2fVersion == 'U2F_V2') { | 193 if (u2fVersion == 'U2F_V2') { |
194 // For U2F_V2, the challenge sent to the gnubby is modified to be the | 194 // For U2F_V2, the challenge sent to the gnubby is modified to be the |
195 // hash of the client data. Include the client data. | 195 // hash of the client data. Include the client data. |
196 responseData['clientData'] = opt_clientData; | 196 responseData['clientData'] = opt_clientData; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 */ | 271 */ |
272 Enroller.DEFAULT_TIMEOUT_MILLIS = 30 * 1000; | 272 Enroller.DEFAULT_TIMEOUT_MILLIS = 30 * 1000; |
273 | 273 |
274 /** | 274 /** |
275 * Performs an enroll request with the given enroll and sign challenges. | 275 * Performs an enroll request with the given enroll and sign challenges. |
276 * @param {Array<EnrollChallenge>} enrollChallenges A set of enroll challenges. | 276 * @param {Array<EnrollChallenge>} enrollChallenges A set of enroll challenges. |
277 * @param {Array<SignChallenge>} signChallenges A set of sign challenges for | 277 * @param {Array<SignChallenge>} signChallenges A set of sign challenges for |
278 * existing enrollments for this user and appId. | 278 * existing enrollments for this user and appId. |
279 * @param {string=} opt_appId The app id for the entire request. | 279 * @param {string=} opt_appId The app id for the entire request. |
280 */ | 280 */ |
281 Enroller.prototype.doEnroll = function(enrollChallenges, signChallenges, | 281 Enroller.prototype.doEnroll = function( |
282 opt_appId) { | 282 enrollChallenges, signChallenges, opt_appId) { |
283 /** @private {Array<EnrollChallenge>} */ | 283 /** @private {Array<EnrollChallenge>} */ |
284 this.enrollChallenges_ = enrollChallenges; | 284 this.enrollChallenges_ = enrollChallenges; |
285 /** @private {Array<SignChallenge>} */ | 285 /** @private {Array<SignChallenge>} */ |
286 this.signChallenges_ = signChallenges; | 286 this.signChallenges_ = signChallenges; |
287 /** @private {(string|undefined)} */ | 287 /** @private {(string|undefined)} */ |
288 this.appId_ = opt_appId; | 288 this.appId_ = opt_appId; |
289 var self = this; | 289 var self = this; |
290 getTabIdWhenPossible(this.sender_).then(function() { | 290 getTabIdWhenPossible(this.sender_) |
291 if (self.done_) return; | 291 .then( |
292 self.approveOrigin_(); | 292 function() { |
293 }, function() { | 293 if (self.done_) |
294 self.close(); | 294 return; |
295 self.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); | 295 self.approveOrigin_(); |
296 }); | 296 }, |
| 297 function() { |
| 298 self.close(); |
| 299 self.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); |
| 300 }); |
297 }; | 301 }; |
298 | 302 |
299 /** | 303 /** |
300 * Ensures the user has approved this origin to use security keys, sending | 304 * Ensures the user has approved this origin to use security keys, sending |
301 * to the request to the handler if/when the user has done so. | 305 * to the request to the handler if/when the user has done so. |
302 * @private | 306 * @private |
303 */ | 307 */ |
304 Enroller.prototype.approveOrigin_ = function() { | 308 Enroller.prototype.approveOrigin_ = function() { |
305 var self = this; | 309 var self = this; |
306 FACTORY_REGISTRY.getApprovedOrigins() | 310 FACTORY_REGISTRY.getApprovedOrigins() |
307 .isApprovedOrigin(this.sender_.origin, this.sender_.tabId) | 311 .isApprovedOrigin(this.sender_.origin, this.sender_.tabId) |
308 .then(function(result) { | 312 .then(function(result) { |
309 if (self.done_) return; | 313 if (self.done_) |
| 314 return; |
310 if (!result) { | 315 if (!result) { |
311 // Origin not approved: rather than give an explicit indication to | 316 // Origin not approved: rather than give an explicit indication to |
312 // the web page, let a timeout occur. | 317 // the web page, let a timeout occur. |
313 // NOTE: if you are looking at this in a debugger, this line will | 318 // NOTE: if you are looking at this in a debugger, this line will |
314 // always be false since the origin of the debugger is different | 319 // always be false since the origin of the debugger is different |
315 // than origin of requesting page | 320 // than origin of requesting page |
316 if (self.timer_.expired()) { | 321 if (self.timer_.expired()) { |
317 self.notifyTimeout_(); | 322 self.notifyTimeout_(); |
318 return; | 323 return; |
319 } | 324 } |
(...skipping 19 matching lines...) Expand all Loading... |
339 * by encoding them into a helper request and passing the resulting request to | 344 * by encoding them into a helper request and passing the resulting request to |
340 * the factory registry's helper. | 345 * the factory registry's helper. |
341 * @private | 346 * @private |
342 */ | 347 */ |
343 Enroller.prototype.sendEnrollRequestToHelper_ = function() { | 348 Enroller.prototype.sendEnrollRequestToHelper_ = function() { |
344 var encodedEnrollChallenges = | 349 var encodedEnrollChallenges = |
345 this.encodeEnrollChallenges_(this.enrollChallenges_, this.appId_); | 350 this.encodeEnrollChallenges_(this.enrollChallenges_, this.appId_); |
346 // If the request didn't contain a sign challenge, provide one. The value | 351 // If the request didn't contain a sign challenge, provide one. The value |
347 // doesn't matter. | 352 // doesn't matter. |
348 var defaultSignChallenge = ''; | 353 var defaultSignChallenge = ''; |
349 var encodedSignChallenges = | 354 var encodedSignChallenges = encodeSignChallenges( |
350 encodeSignChallenges(this.signChallenges_, defaultSignChallenge, | 355 this.signChallenges_, defaultSignChallenge, this.appId_); |
351 this.appId_); | |
352 var request = { | 356 var request = { |
353 type: 'enroll_helper_request', | 357 type: 'enroll_helper_request', |
354 enrollChallenges: encodedEnrollChallenges, | 358 enrollChallenges: encodedEnrollChallenges, |
355 signData: encodedSignChallenges, | 359 signData: encodedSignChallenges, |
356 logMsgUrl: this.logMsgUrl_ | 360 logMsgUrl: this.logMsgUrl_ |
357 }; | 361 }; |
358 if (!this.timer_.expired()) { | 362 if (!this.timer_.expired()) { |
359 request.timeout = this.timer_.millisecondsUntilExpired() / 1000.0; | 363 request.timeout = this.timer_.millisecondsUntilExpired() / 1000.0; |
360 request.timeoutSeconds = this.timer_.millisecondsUntilExpired() / 1000.0; | 364 request.timeoutSeconds = this.timer_.millisecondsUntilExpired() / 1000.0; |
361 } | 365 } |
362 | 366 |
363 // Begin fetching/checking the app ids. | 367 // Begin fetching/checking the app ids. |
364 var enrollAppIds = []; | 368 var enrollAppIds = []; |
365 if (this.appId_) { | 369 if (this.appId_) { |
366 enrollAppIds.push(this.appId_); | 370 enrollAppIds.push(this.appId_); |
367 } | 371 } |
368 for (var i = 0; i < this.enrollChallenges_.length; i++) { | 372 for (var i = 0; i < this.enrollChallenges_.length; i++) { |
369 if (this.enrollChallenges_[i].hasOwnProperty('appId')) { | 373 if (this.enrollChallenges_[i].hasOwnProperty('appId')) { |
370 enrollAppIds.push(this.enrollChallenges_[i]['appId']); | 374 enrollAppIds.push(this.enrollChallenges_[i]['appId']); |
371 } | 375 } |
372 } | 376 } |
373 // Sanity check | 377 // Sanity check |
374 if (!enrollAppIds.length) { | 378 if (!enrollAppIds.length) { |
375 console.warn(UTIL_fmt('empty enroll app ids?')); | 379 console.warn(UTIL_fmt('empty enroll app ids?')); |
376 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); | 380 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); |
377 return; | 381 return; |
378 } | 382 } |
379 var self = this; | 383 var self = this; |
380 this.checkAppIds_(enrollAppIds, function(result) { | 384 this.checkAppIds_(enrollAppIds, function(result) { |
381 if (self.done_) return; | 385 if (self.done_) |
| 386 return; |
382 if (result) { | 387 if (result) { |
383 self.handler_ = FACTORY_REGISTRY.getRequestHelper().getHandler(request); | 388 self.handler_ = FACTORY_REGISTRY.getRequestHelper().getHandler(request); |
384 if (self.handler_) { | 389 if (self.handler_) { |
385 var helperComplete = | 390 var helperComplete = |
386 /** @type {function(HelperReply)} */ | 391 /** @type {function(HelperReply)} */ |
387 (self.helperComplete_.bind(self)); | 392 (self.helperComplete_.bind(self)); |
388 self.handler_.run(helperComplete); | 393 self.handler_.run(helperComplete); |
389 } else { | 394 } else { |
390 self.notifyError_({errorCode: ErrorCodes.OTHER_ERROR}); | 395 self.notifyError_({errorCode: ErrorCodes.OTHER_ERROR}); |
391 } | 396 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 return /** @type {EnrollHelperChallenge} */ (encodedChallenge); | 432 return /** @type {EnrollHelperChallenge} */ (encodedChallenge); |
428 }; | 433 }; |
429 | 434 |
430 /** | 435 /** |
431 * Encodes the given enroll challenges using this enroller's state. | 436 * Encodes the given enroll challenges using this enroller's state. |
432 * @param {Array<EnrollChallenge>} enrollChallenges The enroll challenges. | 437 * @param {Array<EnrollChallenge>} enrollChallenges The enroll challenges. |
433 * @param {string=} opt_appId The app id for the entire request. | 438 * @param {string=} opt_appId The app id for the entire request. |
434 * @return {!Array<EnrollHelperChallenge>} The encoded enroll challenges. | 439 * @return {!Array<EnrollHelperChallenge>} The encoded enroll challenges. |
435 * @private | 440 * @private |
436 */ | 441 */ |
437 Enroller.prototype.encodeEnrollChallenges_ = function(enrollChallenges, | 442 Enroller.prototype.encodeEnrollChallenges_ = function( |
438 opt_appId) { | 443 enrollChallenges, opt_appId) { |
439 var challenges = []; | 444 var challenges = []; |
440 for (var i = 0; i < enrollChallenges.length; i++) { | 445 for (var i = 0; i < enrollChallenges.length; i++) { |
441 var enrollChallenge = enrollChallenges[i]; | 446 var enrollChallenge = enrollChallenges[i]; |
442 var version = enrollChallenge.version; | 447 var version = enrollChallenge.version; |
443 if (!version) { | 448 if (!version) { |
444 // Version is implicitly V1 if not specified. | 449 // Version is implicitly V1 if not specified. |
445 version = 'U2F_V1'; | 450 version = 'U2F_V1'; |
446 } | 451 } |
447 | 452 |
448 if (version == 'U2F_V2') { | 453 if (version == 'U2F_V2') { |
449 var modifiedChallenge = {}; | 454 var modifiedChallenge = {}; |
450 for (var k in enrollChallenge) { | 455 for (var k in enrollChallenge) { |
451 modifiedChallenge[k] = enrollChallenge[k]; | 456 modifiedChallenge[k] = enrollChallenge[k]; |
452 } | 457 } |
453 // V2 enroll responses contain signatures over a browser data object, | 458 // V2 enroll responses contain signatures over a browser data object, |
454 // which we're constructing here. The browser data object contains, among | 459 // which we're constructing here. The browser data object contains, among |
455 // other things, the server challenge. | 460 // other things, the server challenge. |
456 var serverChallenge = enrollChallenge['challenge']; | 461 var serverChallenge = enrollChallenge['challenge']; |
457 var browserData = makeEnrollBrowserData( | 462 var browserData = makeEnrollBrowserData( |
458 serverChallenge, this.sender_.origin, this.sender_.tlsChannelId); | 463 serverChallenge, this.sender_.origin, this.sender_.tlsChannelId); |
459 // Replace the challenge with the hash of the browser data. | 464 // Replace the challenge with the hash of the browser data. |
460 modifiedChallenge['challenge'] = | 465 modifiedChallenge['challenge'] = |
461 B64_encode(sha256HashOfString(browserData)); | 466 B64_encode(sha256HashOfString(browserData)); |
462 this.browserData_[version] = | 467 this.browserData_[version] = B64_encode(UTIL_StringToBytes(browserData)); |
463 B64_encode(UTIL_StringToBytes(browserData)); | |
464 challenges.push(Enroller.encodeEnrollChallenge_( | 468 challenges.push(Enroller.encodeEnrollChallenge_( |
465 /** @type {EnrollChallenge} */ (modifiedChallenge), opt_appId)); | 469 /** @type {EnrollChallenge} */ (modifiedChallenge), opt_appId)); |
466 } else { | 470 } else { |
467 challenges.push( | 471 challenges.push( |
468 Enroller.encodeEnrollChallenge_(enrollChallenge, opt_appId)); | 472 Enroller.encodeEnrollChallenge_(enrollChallenge, opt_appId)); |
469 } | 473 } |
470 } | 474 } |
471 return challenges; | 475 return challenges; |
472 }; | 476 }; |
473 | 477 |
(...skipping 21 matching lines...) Expand all Loading... |
495 * @param {function(boolean)} cb Called with the result of the check. | 499 * @param {function(boolean)} cb Called with the result of the check. |
496 * @param {boolean} result Whether the origin could claim the app ids. | 500 * @param {boolean} result Whether the origin could claim the app ids. |
497 * @private | 501 * @private |
498 */ | 502 */ |
499 Enroller.prototype.originChecked_ = function(appIds, cb, result) { | 503 Enroller.prototype.originChecked_ = function(appIds, cb, result) { |
500 if (!result) { | 504 if (!result) { |
501 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); | 505 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); |
502 return; | 506 return; |
503 } | 507 } |
504 var appIdChecker = FACTORY_REGISTRY.getAppIdCheckerFactory().create(); | 508 var appIdChecker = FACTORY_REGISTRY.getAppIdCheckerFactory().create(); |
505 appIdChecker. | 509 appIdChecker |
506 checkAppIds( | 510 .checkAppIds( |
507 this.timer_.clone(), this.sender_.origin, appIds, this.allowHttp_, | 511 this.timer_.clone(), this.sender_.origin, appIds, this.allowHttp_, |
508 this.logMsgUrl_) | 512 this.logMsgUrl_) |
509 .then(cb); | 513 .then(cb); |
510 }; | 514 }; |
511 | 515 |
512 /** Closes this enroller. */ | 516 /** Closes this enroller. */ |
513 Enroller.prototype.close = function() { | 517 Enroller.prototype.close = function() { |
514 if (this.handler_) { | 518 if (this.handler_) { |
515 this.handler_.close(); | 519 this.handler_.close(); |
516 this.handler_ = null; | 520 this.handler_ = null; |
(...skipping 14 matching lines...) Expand all Loading... |
531 this.errorCb_(error); | 535 this.errorCb_(error); |
532 }; | 536 }; |
533 | 537 |
534 /** | 538 /** |
535 * Notifies the caller of success with the provided response data. | 539 * Notifies the caller of success with the provided response data. |
536 * @param {string} u2fVersion Protocol version | 540 * @param {string} u2fVersion Protocol version |
537 * @param {string} info Response data | 541 * @param {string} info Response data |
538 * @param {string|undefined} opt_browserData Browser data used | 542 * @param {string|undefined} opt_browserData Browser data used |
539 * @private | 543 * @private |
540 */ | 544 */ |
541 Enroller.prototype.notifySuccess_ = | 545 Enroller.prototype.notifySuccess_ = function( |
542 function(u2fVersion, info, opt_browserData) { | 546 u2fVersion, info, opt_browserData) { |
543 if (this.done_) | 547 if (this.done_) |
544 return; | 548 return; |
545 this.close(); | 549 this.close(); |
546 this.done_ = true; | 550 this.done_ = true; |
547 this.successCb_(u2fVersion, info, opt_browserData); | 551 this.successCb_(u2fVersion, info, opt_browserData); |
548 }; | 552 }; |
549 | 553 |
550 /** | 554 /** |
551 * Called by the helper upon completion. | 555 * Called by the helper upon completion. |
552 * @param {EnrollHelperReply} reply The result of the enroll request. | 556 * @param {EnrollHelperReply} reply The result of the enroll request. |
553 * @private | 557 * @private |
554 */ | 558 */ |
555 Enroller.prototype.helperComplete_ = function(reply) { | 559 Enroller.prototype.helperComplete_ = function(reply) { |
556 if (reply.code) { | 560 if (reply.code) { |
557 var reportedError = mapDeviceStatusCodeToU2fError(reply.code); | 561 var reportedError = mapDeviceStatusCodeToU2fError(reply.code); |
558 console.log(UTIL_fmt('helper reported ' + reply.code.toString(16) + | 562 console.log(UTIL_fmt( |
559 ', returning ' + reportedError.errorCode)); | 563 'helper reported ' + reply.code.toString(16) + ', returning ' + |
| 564 reportedError.errorCode)); |
560 this.notifyError_(reportedError); | 565 this.notifyError_(reportedError); |
561 } else { | 566 } else { |
562 console.log(UTIL_fmt('Gnubby enrollment succeeded!!!!!')); | 567 console.log(UTIL_fmt('Gnubby enrollment succeeded!!!!!')); |
563 var browserData; | 568 var browserData; |
564 | 569 |
565 if (reply.version == 'U2F_V2') { | 570 if (reply.version == 'U2F_V2') { |
566 // For U2F_V2, the challenge sent to the gnubby is modified to be the hash | 571 // For U2F_V2, the challenge sent to the gnubby is modified to be the hash |
567 // of the browser data. Include the browser data. | 572 // of the browser data. Include the browser data. |
568 browserData = this.browserData_[reply.version]; | 573 browserData = this.browserData_[reply.version]; |
569 } | 574 } |
570 | 575 |
571 this.notifySuccess_(/** @type {string} */ (reply.version), | 576 this.notifySuccess_( |
572 /** @type {string} */ (reply.enrollData), | 577 /** @type {string} */ (reply.version), |
573 browserData); | 578 /** @type {string} */ (reply.enrollData), browserData); |
574 } | 579 } |
575 }; | 580 }; |
OLD | NEW |