| Index: chrome/browser/resources/cryptotoken/enroller.js
|
| diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js
|
| index 1ee758e663560516c4c337de9f3c63596c10f306..d8ef537faf8d704e4a21e7a914ec1779d0f944d3 100644
|
| --- a/chrome/browser/resources/cryptotoken/enroller.js
|
| +++ b/chrome/browser/resources/cryptotoken/enroller.js
|
| @@ -41,22 +41,44 @@ function handleWebEnrollRequest(messageSender, request, sendResponse) {
|
| sendResponseOnce(sentResponse, closeable, response, sendResponse);
|
| }
|
|
|
| + function timeout() {
|
| + sendErrorResponse({errorCode: ErrorCodes.TIMEOUT});
|
| + }
|
| +
|
| var sender = createSenderFromMessageSender(messageSender);
|
| if (!sender) {
|
| sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
|
| return null;
|
| }
|
|
|
| - var enroller =
|
| - validateEnrollRequest(
|
| - sender, request, 'enrollChallenges', 'signData',
|
| - sendErrorResponse, sendSuccessResponse);
|
| - if (enroller) {
|
| - var registerRequests = request['enrollChallenges'];
|
| - var signRequests = getSignRequestsFromEnrollRequest(request, 'signData');
|
| - closeable = /** @type {Closeable} */ (enroller);
|
| - enroller.doEnroll(registerRequests, signRequests, request['appId']);
|
| + if (!isValidEnrollRequest(request, 'enrollChallenges', 'signData')) {
|
| + sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
|
| + return null;
|
| }
|
| +
|
| + var timeoutValueSeconds = getTimeoutValueFromRequest(request);
|
| + // Attenuate watchdog timeout value less than the enroller's timeout, so the
|
| + // watchdog only fires after the enroller could reasonably have called back,
|
| + // not before.
|
| + var watchdogTimeoutValueSeconds = attenuateTimeoutInSeconds(
|
| + timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
|
| + var watchdog = new WatchdogRequestHandler(watchdogTimeoutValueSeconds,
|
| + timeout);
|
| + var wrappedErrorCb = watchdog.wrapCallback(sendErrorResponse);
|
| + var wrappedSuccessCb = watchdog.wrapCallback(sendSuccessResponse);
|
| +
|
| + var timer = createAttenuatedTimer(
|
| + FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
|
| + var logMsgUrl = request['logMsgUrl'];
|
| + var enroller = new Enroller(timer, sender, wrappedErrorCb, wrappedSuccessCb,
|
| + logMsgUrl);
|
| + watchdog.setCloseable(/** @type {!Closeable} */ (enroller));
|
| + closeable = watchdog;
|
| +
|
| + var registerRequests = request['enrollChallenges'];
|
| + var signRequests = getSignRequestsFromEnrollRequest(request, 'signData');
|
| + enroller.doEnroll(registerRequests, signRequests, request['appId']);
|
| +
|
| return closeable;
|
| }
|
|
|
| @@ -93,57 +115,47 @@ function handleU2fEnrollRequest(messageSender, request, sendResponse) {
|
| sendResponseOnce(sentResponse, closeable, response, sendResponse);
|
| }
|
|
|
| + function timeout() {
|
| + sendErrorResponse({errorCode: ErrorCodes.TIMEOUT});
|
| + }
|
| +
|
| var sender = createSenderFromMessageSender(messageSender);
|
| if (!sender) {
|
| sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
|
| return null;
|
| }
|
|
|
| - var enroller =
|
| - validateEnrollRequest(
|
| - sender, request, 'registerRequests', 'signRequests',
|
| - sendErrorResponse, sendSuccessResponse, 'registeredKeys');
|
| - if (enroller) {
|
| - var registerRequests = request['registerRequests'];
|
| - var signRequests = getSignRequestsFromEnrollRequest(request,
|
| - 'signRequests', 'registeredKeys');
|
| - closeable = /** @type {Closeable} */ (enroller);
|
| - enroller.doEnroll(registerRequests, signRequests, request['appId']);
|
| - }
|
| - return closeable;
|
| -}
|
| -
|
| -/**
|
| - * Validates an enroll request using the given parameters.
|
| - * @param {WebRequestSender} sender The sender of the message.
|
| - * @param {Object} request The web page's enroll request.
|
| - * @param {string} enrollChallengesName The name of the enroll challenges value
|
| - * in the request.
|
| - * @param {string} signChallengesName The name of the sign challenges value in
|
| - * the request.
|
| - * @param {function(U2fError)} errorCb Error callback.
|
| - * @param {function(string, string, (string|undefined))} successCb Success
|
| - * callback.
|
| - * @param {string=} opt_registeredKeysName The name of the registered keys
|
| - * value in the request.
|
| - * @return {Enroller} Enroller object representing the request, if the request
|
| - * is valid, or null if the request is invalid.
|
| - */
|
| -function validateEnrollRequest(sender, request,
|
| - enrollChallengesName, signChallengesName, errorCb, successCb,
|
| - opt_registeredKeysName) {
|
| - if (!isValidEnrollRequest(request, enrollChallengesName,
|
| - signChallengesName, opt_registeredKeysName)) {
|
| - errorCb({errorCode: ErrorCodes.BAD_REQUEST});
|
| + if (!isValidEnrollRequest(request, 'registerRequests', 'signRequests',
|
| + 'registeredKeys')) {
|
| + sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
|
| return null;
|
| }
|
|
|
| var timeoutValueSeconds = getTimeoutValueFromRequest(request);
|
| + // Attenuate watchdog timeout value less than the enroller's timeout, so the
|
| + // watchdog only fires after the enroller could reasonably have called back,
|
| + // not before.
|
| + var watchdogTimeoutValueSeconds = attenuateTimeoutInSeconds(
|
| + timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
|
| + var watchdog = new WatchdogRequestHandler(watchdogTimeoutValueSeconds,
|
| + timeout);
|
| + var wrappedErrorCb = watchdog.wrapCallback(sendErrorResponse);
|
| + var wrappedSuccessCb = watchdog.wrapCallback(sendSuccessResponse);
|
| +
|
| var timer = createAttenuatedTimer(
|
| FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
|
| var logMsgUrl = request['logMsgUrl'];
|
| - var enroller = new Enroller(timer, sender, errorCb, successCb, logMsgUrl);
|
| - return enroller;
|
| + var enroller = new Enroller(timer, sender, sendErrorResponse,
|
| + sendSuccessResponse, logMsgUrl);
|
| + watchdog.setCloseable(/** @type {!Closeable} */ (enroller));
|
| + closeable = watchdog;
|
| +
|
| + var registerRequests = request['registerRequests'];
|
| + var signRequests = getSignRequestsFromEnrollRequest(request,
|
| + 'signRequests', 'registeredKeys');
|
| + enroller.doEnroll(registerRequests, signRequests, request['appId']);
|
| +
|
| + return closeable;
|
| }
|
|
|
| /**
|
| @@ -393,8 +405,15 @@ Enroller.prototype.approveOrigin_ = function() {
|
| .then(function(result) {
|
| if (self.done_) return;
|
| if (!result) {
|
| - // Origin not approved: fail the result.
|
| - self.notifyError_({errorCode: ErrorCodes.BAD_REQUEST});
|
| + // Origin not approved: rather than give an explicit indication to
|
| + // the web page, let a timeout occur.
|
| + if (self.timer_.expired()) {
|
| + self.notifyTimeout_();
|
| + return;
|
| + }
|
| + var newTimer = self.timer_.clone(self.notifyTimeout_.bind(self));
|
| + self.timer_.clearTimeout();
|
| + self.timer_ = newTimer;
|
| return;
|
| }
|
| self.sendEnrollRequestToHelper_();
|
| @@ -402,6 +421,14 @@ Enroller.prototype.approveOrigin_ = function() {
|
| };
|
|
|
| /**
|
| + * Notifies the caller of a timeout error.
|
| + * @private
|
| + */
|
| +Enroller.prototype.notifyTimeout_ = function() {
|
| + this.notifyError_({errorCode: ErrorCodes.TIMEOUT});
|
| +};
|
| +
|
| +/**
|
| * Performs an enroll request with this instance's enroll and sign challenges,
|
| * by encoding them into a helper request and passing the resulting request to
|
| * the factory registry's helper.
|
|
|