Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: chrome/browser/resources/cryptotoken/signer.js

Issue 2939273002: DO NOT SUBMIT: what chrome/browser/resources/ could eventually look like with clang-format (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 sign requests. 6 * @fileoverview Handles web page requests for gnubby sign requests.
7 * 7 *
8 */ 8 */
9 9
10 'use strict'; 10 'use strict';
11 11
12 var gnubbySignRequestQueue; 12 var gnubbySignRequestQueue;
13 13
14 function initRequestQueue() { 14 function initRequestQueue() {
15 gnubbySignRequestQueue = new OriginKeyedRequestQueue( 15 gnubbySignRequestQueue =
16 FACTORY_REGISTRY.getSystemTimer()); 16 new OriginKeyedRequestQueue(FACTORY_REGISTRY.getSystemTimer());
17 } 17 }
18 18
19 /** 19 /**
20 * Handles a U2F sign request. 20 * Handles a U2F sign request.
21 * @param {MessageSender} messageSender The message sender. 21 * @param {MessageSender} messageSender The message sender.
22 * @param {Object} request The web page's sign request. 22 * @param {Object} request The web page's sign request.
23 * @param {Function} sendResponse Called back with the result of the sign. 23 * @param {Function} sendResponse Called back with the result of the sign.
24 * @return {Closeable} Request handler that should be closed when the browser 24 * @return {Closeable} Request handler that should be closed when the browser
25 * message channel is closed. 25 * message channel is closed.
26 */ 26 */
27 function handleU2fSignRequest(messageSender, request, sendResponse) { 27 function handleU2fSignRequest(messageSender, request, sendResponse) {
28 var sentResponse = false; 28 var sentResponse = false;
29 var queuedSignRequest; 29 var queuedSignRequest;
30 30
31 function sendErrorResponse(error) { 31 function sendErrorResponse(error) {
32 sendResponseOnce(sentResponse, queuedSignRequest, 32 sendResponseOnce(
33 sentResponse, queuedSignRequest,
33 makeU2fErrorResponse(request, error.errorCode, error.errorMessage), 34 makeU2fErrorResponse(request, error.errorCode, error.errorMessage),
34 sendResponse); 35 sendResponse);
35 } 36 }
36 37
37 function sendSuccessResponse(challenge, info, browserData) { 38 function sendSuccessResponse(challenge, info, browserData) {
38 var responseData = makeU2fSignResponseDataFromChallenge(challenge); 39 var responseData = makeU2fSignResponseDataFromChallenge(challenge);
39 addSignatureAndBrowserDataToResponseData(responseData, info, browserData, 40 addSignatureAndBrowserDataToResponseData(
40 'clientData'); 41 responseData, info, browserData, 'clientData');
41 var response = makeU2fSuccessResponse(request, responseData); 42 var response = makeU2fSuccessResponse(request, responseData);
42 sendResponseOnce(sentResponse, queuedSignRequest, response, sendResponse); 43 sendResponseOnce(sentResponse, queuedSignRequest, response, sendResponse);
43 } 44 }
44 45
45 var sender = createSenderFromMessageSender(messageSender); 46 var sender = createSenderFromMessageSender(messageSender);
46 if (!sender) { 47 if (!sender) {
47 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST}); 48 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
48 return null; 49 return null;
49 } 50 }
50 if (sender.origin.indexOf('http://') == 0 && !HTTP_ORIGINS_ALLOWED) { 51 if (sender.origin.indexOf('http://') == 0 && !HTTP_ORIGINS_ALLOWED) {
51 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST}); 52 sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
52 return null; 53 return null;
53 } 54 }
54 55
55 queuedSignRequest = 56 queuedSignRequest = validateAndEnqueueSignRequest(
56 validateAndEnqueueSignRequest( 57 sender, request, sendErrorResponse, sendSuccessResponse);
57 sender, request, sendErrorResponse, sendSuccessResponse);
58 return queuedSignRequest; 58 return queuedSignRequest;
59 } 59 }
60 60
61 /** 61 /**
62 * Creates a base U2F responseData object from the server challenge. 62 * Creates a base U2F responseData object from the server challenge.
63 * @param {SignChallenge} challenge The server challenge. 63 * @param {SignChallenge} challenge The server challenge.
64 * @return {Object} The responseData object. 64 * @return {Object} The responseData object.
65 */ 65 */
66 function makeU2fSignResponseDataFromChallenge(challenge) { 66 function makeU2fSignResponseDataFromChallenge(challenge) {
67 var responseData = { 67 var responseData = {'keyHandle': challenge['keyHandle']};
68 'keyHandle': challenge['keyHandle']
69 };
70 return responseData; 68 return responseData;
71 } 69 }
72 70
73 /** 71 /**
74 * Adds the browser data and signature values to a responseData object. 72 * Adds the browser data and signature values to a responseData object.
75 * @param {Object} responseData The "base" responseData object. 73 * @param {Object} responseData The "base" responseData object.
76 * @param {string} signatureData The signature data. 74 * @param {string} signatureData The signature data.
77 * @param {string} browserData The browser data generated from the challenge. 75 * @param {string} browserData The browser data generated from the challenge.
78 * @param {string} browserDataName The name of the browser data key in the 76 * @param {string} browserDataName The name of the browser data key in the
79 * responseData object. 77 * responseData object.
80 */ 78 */
81 function addSignatureAndBrowserDataToResponseData(responseData, signatureData, 79 function addSignatureAndBrowserDataToResponseData(
82 browserData, browserDataName) { 80 responseData, signatureData, browserData, browserDataName) {
83 responseData[browserDataName] = B64_encode(UTIL_StringToBytes(browserData)); 81 responseData[browserDataName] = B64_encode(UTIL_StringToBytes(browserData));
84 responseData['signatureData'] = signatureData; 82 responseData['signatureData'] = signatureData;
85 } 83 }
86 84
87 /** 85 /**
88 * Validates a sign request using the given sign challenges name, and, if valid, 86 * Validates a sign request using the given sign challenges name, and, if valid,
89 * enqueues the sign request for eventual processing. 87 * enqueues the sign request for eventual processing.
90 * @param {WebRequestSender} sender The sender of the message. 88 * @param {WebRequestSender} sender The sender of the message.
91 * @param {Object} request The web page's sign request. 89 * @param {Object} request The web page's sign request.
92 * @param {function(U2fError)} errorCb Error callback. 90 * @param {function(U2fError)} errorCb Error callback.
93 * @param {function(SignChallenge, string, string)} successCb Success callback. 91 * @param {function(SignChallenge, string, string)} successCb Success callback.
94 * @return {Closeable} Request handler that should be closed when the browser 92 * @return {Closeable} Request handler that should be closed when the browser
95 * message channel is closed. 93 * message channel is closed.
96 */ 94 */
97 function validateAndEnqueueSignRequest(sender, request, errorCb, successCb) { 95 function validateAndEnqueueSignRequest(sender, request, errorCb, successCb) {
98 function timeout() { 96 function timeout() {
99 errorCb({errorCode: ErrorCodes.TIMEOUT}); 97 errorCb({errorCode: ErrorCodes.TIMEOUT});
100 } 98 }
101 99
102 if (!isValidSignRequest(request)) { 100 if (!isValidSignRequest(request)) {
103 errorCb({errorCode: ErrorCodes.BAD_REQUEST}); 101 errorCb({errorCode: ErrorCodes.BAD_REQUEST});
104 return null; 102 return null;
105 } 103 }
106 104
107 // The typecast is necessary because getSignChallenges can return undefined. 105 // The typecast is necessary because getSignChallenges can return undefined.
108 // On the other hand, a valid sign request can't contain an undefined sign 106 // On the other hand, a valid sign request can't contain an undefined sign
109 // challenge list, so the typecast is safe. 107 // challenge list, so the typecast is safe.
110 var signChallenges = /** @type {!Array<SignChallenge>} */ ( 108 var signChallenges =
111 getSignChallenges(request)); 109 /** @type {!Array<SignChallenge>} */ (getSignChallenges(request));
112 var appId; 110 var appId;
113 if (request['appId']) { 111 if (request['appId']) {
114 appId = request['appId']; 112 appId = request['appId'];
115 } else if (signChallenges.length) { 113 } else if (signChallenges.length) {
116 appId = signChallenges[0]['appId']; 114 appId = signChallenges[0]['appId'];
117 } 115 }
118 // Sanity check 116 // Sanity check
119 if (!appId) { 117 if (!appId) {
120 console.warn(UTIL_fmt('empty sign appId?')); 118 console.warn(UTIL_fmt('empty sign appId?'));
121 errorCb({errorCode: ErrorCodes.BAD_REQUEST}); 119 errorCb({errorCode: ErrorCodes.BAD_REQUEST});
122 return null; 120 return null;
123 } 121 }
124 var timeoutValueSeconds = getTimeoutValueFromRequest(request); 122 var timeoutValueSeconds = getTimeoutValueFromRequest(request);
125 // Attenuate watchdog timeout value less than the signer's timeout, so the 123 // Attenuate watchdog timeout value less than the signer's timeout, so the
126 // watchdog only fires after the signer could reasonably have called back, 124 // watchdog only fires after the signer could reasonably have called back,
127 // not before. 125 // not before.
128 timeoutValueSeconds = attenuateTimeoutInSeconds(timeoutValueSeconds, 126 timeoutValueSeconds = attenuateTimeoutInSeconds(
129 MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2); 127 timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
130 var watchdog = new WatchdogRequestHandler(timeoutValueSeconds, timeout); 128 var watchdog = new WatchdogRequestHandler(timeoutValueSeconds, timeout);
131 var wrappedErrorCb = watchdog.wrapCallback(errorCb); 129 var wrappedErrorCb = watchdog.wrapCallback(errorCb);
132 var wrappedSuccessCb = watchdog.wrapCallback(successCb); 130 var wrappedSuccessCb = watchdog.wrapCallback(successCb);
133 131
134 var timer = createAttenuatedTimer( 132 var timer = createAttenuatedTimer(
135 FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds); 133 FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
136 var logMsgUrl = request['logMsgUrl']; 134 var logMsgUrl = request['logMsgUrl'];
137 135
138 // Queue sign requests from the same origin, to protect against simultaneous 136 // Queue sign requests from the same origin, to protect against simultaneous
139 // sign-out on many tabs resulting in repeated sign-in requests. 137 // sign-out on many tabs resulting in repeated sign-in requests.
140 var queuedSignRequest = new QueuedSignRequest(signChallenges, 138 var queuedSignRequest = new QueuedSignRequest(
141 timer, sender, wrappedErrorCb, wrappedSuccessCb, request['challenge'], 139 signChallenges, timer, sender, wrappedErrorCb, wrappedSuccessCb,
142 appId, logMsgUrl); 140 request['challenge'], appId, logMsgUrl);
143 if (!gnubbySignRequestQueue) { 141 if (!gnubbySignRequestQueue) {
144 initRequestQueue(); 142 initRequestQueue();
145 } 143 }
146 var requestToken = gnubbySignRequestQueue.queueRequest(appId, sender.origin, 144 var requestToken = gnubbySignRequestQueue.queueRequest(
147 queuedSignRequest.begin.bind(queuedSignRequest), timer); 145 appId, sender.origin, queuedSignRequest.begin.bind(queuedSignRequest),
146 timer);
148 queuedSignRequest.setToken(requestToken); 147 queuedSignRequest.setToken(requestToken);
149 148
150 watchdog.setCloseable(queuedSignRequest); 149 watchdog.setCloseable(queuedSignRequest);
151 return watchdog; 150 return watchdog;
152 } 151 }
153 152
154 /** 153 /**
155 * Returns whether the request appears to be a valid sign request. 154 * Returns whether the request appears to be a valid sign request.
156 * @param {Object} request The request. 155 * @param {Object} request The request.
157 * @return {boolean} Whether the request appears valid. 156 * @return {boolean} Whether the request appears valid.
158 */ 157 */
159 function isValidSignRequest(request) { 158 function isValidSignRequest(request) {
160 var signChallenges = getSignChallenges(request); 159 var signChallenges = getSignChallenges(request);
161 if (!signChallenges) { 160 if (!signChallenges) {
162 return false; 161 return false;
163 } 162 }
164 var hasDefaultChallenge = request.hasOwnProperty('challenge'); 163 var hasDefaultChallenge = request.hasOwnProperty('challenge');
165 var hasAppId = request.hasOwnProperty('appId'); 164 var hasAppId = request.hasOwnProperty('appId');
166 // If the sign challenge array is empty, the global appId is required. 165 // If the sign challenge array is empty, the global appId is required.
167 if (!hasAppId && (!signChallenges || !signChallenges.length)) { 166 if (!hasAppId && (!signChallenges || !signChallenges.length)) {
168 return false; 167 return false;
169 } 168 }
170 return isValidSignChallengeArray(signChallenges, !hasDefaultChallenge, 169 return isValidSignChallengeArray(
171 !hasAppId); 170 signChallenges, !hasDefaultChallenge, !hasAppId);
172 } 171 }
173 172
174 /** 173 /**
175 * Adapter class representing a queued sign request. 174 * Adapter class representing a queued sign request.
176 * @param {!Array<SignChallenge>} signChallenges The sign challenges. 175 * @param {!Array<SignChallenge>} signChallenges The sign challenges.
177 * @param {Countdown} timer Timeout timer 176 * @param {Countdown} timer Timeout timer
178 * @param {WebRequestSender} sender Message sender. 177 * @param {WebRequestSender} sender Message sender.
179 * @param {function(U2fError)} errorCb Error callback 178 * @param {function(U2fError)} errorCb Error callback
180 * @param {function(SignChallenge, string, string)} successCb Success callback 179 * @param {function(SignChallenge, string, string)} successCb Success callback
181 * @param {string|undefined} opt_defaultChallenge A default sign challenge 180 * @param {string|undefined} opt_defaultChallenge A default sign challenge
182 * value, if a request does not provide one. 181 * value, if a request does not provide one.
183 * @param {string|undefined} opt_appId The app id for the entire request. 182 * @param {string|undefined} opt_appId The app id for the entire request.
184 * @param {string|undefined} opt_logMsgUrl Url to post log messages to 183 * @param {string|undefined} opt_logMsgUrl Url to post log messages to
185 * @constructor 184 * @constructor
186 * @implements {Closeable} 185 * @implements {Closeable}
187 */ 186 */
188 function QueuedSignRequest(signChallenges, timer, sender, errorCb, 187 function QueuedSignRequest(
189 successCb, opt_defaultChallenge, opt_appId, opt_logMsgUrl) { 188 signChallenges, timer, sender, errorCb, successCb, opt_defaultChallenge,
189 opt_appId, opt_logMsgUrl) {
190 /** @private {!Array<SignChallenge>} */ 190 /** @private {!Array<SignChallenge>} */
191 this.signChallenges_ = signChallenges; 191 this.signChallenges_ = signChallenges;
192 /** @private {Countdown} */ 192 /** @private {Countdown} */
193 this.timer_ = timer.clone(this.close.bind(this)); 193 this.timer_ = timer.clone(this.close.bind(this));
194 /** @private {WebRequestSender} */ 194 /** @private {WebRequestSender} */
195 this.sender_ = sender; 195 this.sender_ = sender;
196 /** @private {function(U2fError)} */ 196 /** @private {function(U2fError)} */
197 this.errorCb_ = errorCb; 197 this.errorCb_ = errorCb;
198 /** @private {function(SignChallenge, string, string)} */ 198 /** @private {function(SignChallenge, string, string)} */
199 this.successCb_ = successCb; 199 this.successCb_ = successCb;
200 /** @private {string|undefined} */ 200 /** @private {string|undefined} */
201 this.defaultChallenge_ = opt_defaultChallenge; 201 this.defaultChallenge_ = opt_defaultChallenge;
202 /** @private {string|undefined} */ 202 /** @private {string|undefined} */
203 this.appId_ = opt_appId; 203 this.appId_ = opt_appId;
204 /** @private {string|undefined} */ 204 /** @private {string|undefined} */
205 this.logMsgUrl_ = opt_logMsgUrl; 205 this.logMsgUrl_ = opt_logMsgUrl;
206 /** @private {boolean} */ 206 /** @private {boolean} */
207 this.begun_ = false; 207 this.begun_ = false;
208 /** @private {boolean} */ 208 /** @private {boolean} */
209 this.closed_ = false; 209 this.closed_ = false;
210 } 210 }
211 211
212 /** Closes this sign request. */ 212 /** Closes this sign request. */
213 QueuedSignRequest.prototype.close = function() { 213 QueuedSignRequest.prototype.close = function() {
214 if (this.closed_) return; 214 if (this.closed_)
215 return;
215 var hadBegunSigning = false; 216 var hadBegunSigning = false;
216 if (this.begun_ && this.signer_) { 217 if (this.begun_ && this.signer_) {
217 this.signer_.close(); 218 this.signer_.close();
218 hadBegunSigning = true; 219 hadBegunSigning = true;
219 } 220 }
220 if (this.token_) { 221 if (this.token_) {
221 if (hadBegunSigning) { 222 if (hadBegunSigning) {
222 console.log(UTIL_fmt('closing in-progress request')); 223 console.log(UTIL_fmt('closing in-progress request'));
223 } else { 224 } else {
224 console.log(UTIL_fmt('closing timed-out request before processing')); 225 console.log(UTIL_fmt('closing timed-out request before processing'));
(...skipping 17 matching lines...) Expand all
242 */ 243 */
243 QueuedSignRequest.prototype.begin = function(token) { 244 QueuedSignRequest.prototype.begin = function(token) {
244 if (this.timer_.expired()) { 245 if (this.timer_.expired()) {
245 console.log(UTIL_fmt('Queued request begun after timeout')); 246 console.log(UTIL_fmt('Queued request begun after timeout'));
246 this.close(); 247 this.close();
247 this.errorCb_({errorCode: ErrorCodes.TIMEOUT}); 248 this.errorCb_({errorCode: ErrorCodes.TIMEOUT});
248 return; 249 return;
249 } 250 }
250 this.begun_ = true; 251 this.begun_ = true;
251 this.setToken(token); 252 this.setToken(token);
252 this.signer_ = new Signer(this.timer_, this.sender_, 253 this.signer_ = new Signer(
253 this.signerFailed_.bind(this), this.signerSucceeded_.bind(this), 254 this.timer_, this.sender_, this.signerFailed_.bind(this),
254 this.logMsgUrl_); 255 this.signerSucceeded_.bind(this), this.logMsgUrl_);
255 if (!this.signer_.setChallenges(this.signChallenges_, this.defaultChallenge_, 256 if (!this.signer_.setChallenges(
256 this.appId_)) { 257 this.signChallenges_, this.defaultChallenge_, this.appId_)) {
257 token.complete(); 258 token.complete();
258 this.errorCb_({errorCode: ErrorCodes.BAD_REQUEST}); 259 this.errorCb_({errorCode: ErrorCodes.BAD_REQUEST});
259 } 260 }
260 // Signer now has responsibility for maintaining timeout. 261 // Signer now has responsibility for maintaining timeout.
261 this.timer_.clearTimeout(); 262 this.timer_.clearTimeout();
262 }; 263 };
263 264
264 /** 265 /**
265 * Called when this request's signer fails. 266 * Called when this request's signer fails.
266 * @param {U2fError} error The failure reported by the signer. 267 * @param {U2fError} error The failure reported by the signer.
267 * @private 268 * @private
268 */ 269 */
269 QueuedSignRequest.prototype.signerFailed_ = function(error) { 270 QueuedSignRequest.prototype.signerFailed_ = function(error) {
270 this.token_.complete(); 271 this.token_.complete();
271 this.errorCb_(error); 272 this.errorCb_(error);
272 }; 273 };
273 274
274 /** 275 /**
275 * Called when this request's signer succeeds. 276 * Called when this request's signer succeeds.
276 * @param {SignChallenge} challenge The challenge that was signed. 277 * @param {SignChallenge} challenge The challenge that was signed.
277 * @param {string} info The sign result. 278 * @param {string} info The sign result.
278 * @param {string} browserData Browser data JSON 279 * @param {string} browserData Browser data JSON
279 * @private 280 * @private
280 */ 281 */
281 QueuedSignRequest.prototype.signerSucceeded_ = 282 QueuedSignRequest.prototype.signerSucceeded_ = function(
282 function(challenge, info, browserData) { 283 challenge, info, browserData) {
283 this.token_.complete(); 284 this.token_.complete();
284 this.successCb_(challenge, info, browserData); 285 this.successCb_(challenge, info, browserData);
285 }; 286 };
286 287
287 /** 288 /**
288 * Creates an object to track signing with a gnubby. 289 * Creates an object to track signing with a gnubby.
289 * @param {Countdown} timer Timer for sign request. 290 * @param {Countdown} timer Timer for sign request.
290 * @param {WebRequestSender} sender The message sender. 291 * @param {WebRequestSender} sender The message sender.
291 * @param {function(U2fError)} errorCb Called when the sign operation fails. 292 * @param {function(U2fError)} errorCb Called when the sign operation fails.
292 * @param {function(SignChallenge, string, string)} successCb Called when the 293 * @param {function(SignChallenge, string, string)} successCb Called when the
(...skipping 18 matching lines...) Expand all
311 /** @private {boolean} */ 312 /** @private {boolean} */
312 this.done_ = false; 313 this.done_ = false;
313 314
314 /** @private {Object<string, string>} */ 315 /** @private {Object<string, string>} */
315 this.browserData_ = {}; 316 this.browserData_ = {};
316 /** @private {Object<string, SignChallenge>} */ 317 /** @private {Object<string, SignChallenge>} */
317 this.serverChallenges_ = {}; 318 this.serverChallenges_ = {};
318 // Allow http appIds for http origins. (Broken, but the caller deserves 319 // Allow http appIds for http origins. (Broken, but the caller deserves
319 // what they get.) 320 // what they get.)
320 /** @private {boolean} */ 321 /** @private {boolean} */
321 this.allowHttp_ = this.sender_.origin ? 322 this.allowHttp_ =
322 this.sender_.origin.indexOf('http://') == 0 : false; 323 this.sender_.origin ? this.sender_.origin.indexOf('http://') == 0 : false;
323 /** @private {Closeable} */ 324 /** @private {Closeable} */
324 this.handler_ = null; 325 this.handler_ = null;
325 } 326 }
326 327
327 /** 328 /**
328 * Sets the challenges to be signed. 329 * Sets the challenges to be signed.
329 * @param {Array<SignChallenge>} signChallenges The challenges to set. 330 * @param {Array<SignChallenge>} signChallenges The challenges to set.
330 * @param {string=} opt_defaultChallenge A default sign challenge 331 * @param {string=} opt_defaultChallenge A default sign challenge
331 * value, if a request does not provide one. 332 * value, if a request does not provide one.
332 * @param {string=} opt_appId The app id for the entire request. 333 * @param {string=} opt_appId The app id for the entire request.
333 * @return {boolean} Whether the challenges could be set. 334 * @return {boolean} Whether the challenges could be set.
334 */ 335 */
335 Signer.prototype.setChallenges = function(signChallenges, opt_defaultChallenge, 336 Signer.prototype.setChallenges = function(
336 opt_appId) { 337 signChallenges, opt_defaultChallenge, opt_appId) {
337 if (this.challengesSet_ || this.done_) 338 if (this.challengesSet_ || this.done_)
338 return false; 339 return false;
339 if (this.timer_.expired()) { 340 if (this.timer_.expired()) {
340 this.notifyError_({errorCode: ErrorCodes.TIMEOUT}); 341 this.notifyError_({errorCode: ErrorCodes.TIMEOUT});
341 return true; 342 return true;
342 } 343 }
343 /** @private {Array<SignChallenge>} */ 344 /** @private {Array<SignChallenge>} */
344 this.signChallenges_ = signChallenges; 345 this.signChallenges_ = signChallenges;
345 /** @private {string|undefined} */ 346 /** @private {string|undefined} */
346 this.defaultChallenge_ = opt_defaultChallenge; 347 this.defaultChallenge_ = opt_defaultChallenge;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 /** 379 /**
379 * Called with the result of checking the origin. When the origin is allowed 380 * Called with the result of checking the origin. When the origin is allowed
380 * to claim the app ids, begins checking whether the app ids also list the 381 * to claim the app ids, begins checking whether the app ids also list the
381 * origin. 382 * origin.
382 * @param {!Array<string>} appIds The app ids. 383 * @param {!Array<string>} appIds The app ids.
383 * @param {boolean} result Whether the origin could claim the app ids. 384 * @param {boolean} result Whether the origin could claim the app ids.
384 * @private 385 * @private
385 */ 386 */
386 Signer.prototype.originChecked_ = function(appIds, result) { 387 Signer.prototype.originChecked_ = function(appIds, result) {
387 if (!result) { 388 if (!result) {
388 var error = { 389 var error = {errorCode: ErrorCodes.BAD_REQUEST, errorMessage: 'bad appId'};
389 errorCode: ErrorCodes.BAD_REQUEST,
390 errorMessage: 'bad appId'
391 };
392 this.notifyError_(error); 390 this.notifyError_(error);
393 return; 391 return;
394 } 392 }
395 var appIdChecker = FACTORY_REGISTRY.getAppIdCheckerFactory().create(); 393 var appIdChecker = FACTORY_REGISTRY.getAppIdCheckerFactory().create();
396 appIdChecker. 394 appIdChecker
397 checkAppIds( 395 .checkAppIds(
398 this.timer_.clone(), this.sender_.origin, 396 this.timer_.clone(), this.sender_.origin,
399 /** @type {!Array<string>} */ (appIds), this.allowHttp_, 397 /** @type {!Array<string>} */ (appIds), this.allowHttp_,
400 this.logMsgUrl_) 398 this.logMsgUrl_)
401 .then(this.appIdChecked_.bind(this)); 399 .then(this.appIdChecked_.bind(this));
402 }; 400 };
403 401
404 /** 402 /**
405 * Called with the result of checking app ids. When the app ids are valid, 403 * Called with the result of checking app ids. When the app ids are valid,
406 * adds the sign challenges to those being signed. 404 * adds the sign challenges to those being signed.
407 * @param {boolean} result Whether the app ids are valid. 405 * @param {boolean} result Whether the app ids are valid.
408 * @private 406 * @private
409 */ 407 */
410 Signer.prototype.appIdChecked_ = function(result) { 408 Signer.prototype.appIdChecked_ = function(result) {
411 if (!result) { 409 if (!result) {
412 var error = { 410 var error = {errorCode: ErrorCodes.BAD_REQUEST, errorMessage: 'bad appId'};
413 errorCode: ErrorCodes.BAD_REQUEST,
414 errorMessage: 'bad appId'
415 };
416 this.notifyError_(error); 411 this.notifyError_(error);
417 return; 412 return;
418 } 413 }
419 if (!this.doSign_()) { 414 if (!this.doSign_()) {
420 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST}); 415 this.notifyError_({errorCode: ErrorCodes.BAD_REQUEST});
421 return; 416 return;
422 } 417 }
423 }; 418 };
424 419
425 /** 420 /**
(...skipping 10 matching lines...) Expand all
436 serverChallenge = challenge['challenge']; 431 serverChallenge = challenge['challenge'];
437 } else { 432 } else {
438 serverChallenge = this.defaultChallenge_; 433 serverChallenge = this.defaultChallenge_;
439 } 434 }
440 if (!serverChallenge) { 435 if (!serverChallenge) {
441 console.warn(UTIL_fmt('challenge missing')); 436 console.warn(UTIL_fmt('challenge missing'));
442 return false; 437 return false;
443 } 438 }
444 var keyHandle = challenge['keyHandle']; 439 var keyHandle = challenge['keyHandle'];
445 440
446 var browserData = 441 var browserData = makeSignBrowserData(
447 makeSignBrowserData(serverChallenge, this.sender_.origin, 442 serverChallenge, this.sender_.origin, this.sender_.tlsChannelId);
448 this.sender_.tlsChannelId);
449 this.browserData_[keyHandle] = browserData; 443 this.browserData_[keyHandle] = browserData;
450 this.serverChallenges_[keyHandle] = challenge; 444 this.serverChallenges_[keyHandle] = challenge;
451 } 445 }
452 446
453 var encodedChallenges = encodeSignChallenges(this.signChallenges_, 447 var encodedChallenges = encodeSignChallenges(
454 this.defaultChallenge_, this.appId_, this.getChallengeHash_.bind(this)); 448 this.signChallenges_, this.defaultChallenge_, this.appId_,
449 this.getChallengeHash_.bind(this));
455 450
456 var timeoutSeconds = this.timer_.millisecondsUntilExpired() / 1000.0; 451 var timeoutSeconds = this.timer_.millisecondsUntilExpired() / 1000.0;
457 var request = makeSignHelperRequest(encodedChallenges, timeoutSeconds, 452 var request =
458 this.logMsgUrl_); 453 makeSignHelperRequest(encodedChallenges, timeoutSeconds, this.logMsgUrl_);
459 this.handler_ = 454 this.handler_ = FACTORY_REGISTRY.getRequestHelper().getHandler(
460 FACTORY_REGISTRY.getRequestHelper() 455 /** @type {HelperRequest} */ (request));
461 .getHandler(/** @type {HelperRequest} */ (request));
462 if (!this.handler_) 456 if (!this.handler_)
463 return false; 457 return false;
464 return this.handler_.run(this.helperComplete_.bind(this)); 458 return this.handler_.run(this.helperComplete_.bind(this));
465 }; 459 };
466 460
467 /** 461 /**
468 * @param {string} keyHandle The key handle used with the challenge. 462 * @param {string} keyHandle The key handle used with the challenge.
469 * @param {string} challenge The challenge. 463 * @param {string} challenge The challenge.
470 * @return {string} The hashed challenge associated with the key 464 * @return {string} The hashed challenge associated with the key
471 * handle/challenge pair. 465 * handle/challenge pair.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 */ 528 */
535 Signer.prototype.helperComplete_ = function(helperReply, opt_source) { 529 Signer.prototype.helperComplete_ = function(helperReply, opt_source) {
536 if (helperReply.type != 'sign_helper_reply') { 530 if (helperReply.type != 'sign_helper_reply') {
537 this.notifyError_({errorCode: ErrorCodes.OTHER_ERROR}); 531 this.notifyError_({errorCode: ErrorCodes.OTHER_ERROR});
538 return; 532 return;
539 } 533 }
540 var reply = /** @type {SignHelperReply} */ (helperReply); 534 var reply = /** @type {SignHelperReply} */ (helperReply);
541 535
542 if (reply.code) { 536 if (reply.code) {
543 var reportedError = mapDeviceStatusCodeToU2fError(reply.code); 537 var reportedError = mapDeviceStatusCodeToU2fError(reply.code);
544 console.log(UTIL_fmt('helper reported ' + reply.code.toString(16) + 538 console.log(UTIL_fmt(
545 ', returning ' + reportedError.errorCode)); 539 'helper reported ' + reply.code.toString(16) + ', returning ' +
540 reportedError.errorCode));
546 this.notifyError_(reportedError); 541 this.notifyError_(reportedError);
547 } else { 542 } else {
548 if (this.logMsgUrl_ && opt_source) { 543 if (this.logMsgUrl_ && opt_source) {
549 var logMsg = 'signed&source=' + opt_source; 544 var logMsg = 'signed&source=' + opt_source;
550 logMessage(logMsg, this.logMsgUrl_); 545 logMessage(logMsg, this.logMsgUrl_);
551 } 546 }
552 547
553 var key = reply.responseData['keyHandle']; 548 var key = reply.responseData['keyHandle'];
554 var browserData = this.browserData_[key]; 549 var browserData = this.browserData_[key];
555 // Notify with server-provided challenge, not the encoded one: the 550 // Notify with server-provided challenge, not the encoded one: the
556 // server-provided challenge contains additional fields it relies on. 551 // server-provided challenge contains additional fields it relies on.
557 var serverChallenge = this.serverChallenges_[key]; 552 var serverChallenge = this.serverChallenges_[key];
558 this.notifySuccess_(serverChallenge, reply.responseData.signatureData, 553 this.notifySuccess_(
559 browserData); 554 serverChallenge, reply.responseData.signatureData, browserData);
560 } 555 }
561 }; 556 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698