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

Side by Side Diff: chrome/browser/resources/cryptotoken/singlesigner.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 A single gnubby signer wraps the process of opening a gnubby, 6 * @fileoverview A single gnubby signer wraps the process of opening a gnubby,
7 * signing each challenge in an array of challenges until a success condition 7 * signing each challenge in an array of challenges until a success condition
8 * is satisfied, and finally yielding the gnubby upon success. 8 * is satisfied, and finally yielding the gnubby upon success.
9 * 9 *
10 */ 10 */
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 * enroll operation. 43 * enroll operation.
44 * @param {function(SingleSignerResult)} 44 * @param {function(SingleSignerResult)}
45 * completeCb Called when this signer completes, i.e. no further results are 45 * completeCb Called when this signer completes, i.e. no further results are
46 * possible. 46 * possible.
47 * @param {Countdown} timer An advisory timer, beyond whose expiration the 47 * @param {Countdown} timer An advisory timer, beyond whose expiration the
48 * signer will not attempt any new operations, assuming the caller is no 48 * signer will not attempt any new operations, assuming the caller is no
49 * longer interested in the outcome. 49 * longer interested in the outcome.
50 * @param {string=} opt_logMsgUrl A URL to post log messages to. 50 * @param {string=} opt_logMsgUrl A URL to post log messages to.
51 * @constructor 51 * @constructor
52 */ 52 */
53 function SingleGnubbySigner(gnubbyId, forEnroll, completeCb, timer, 53 function SingleGnubbySigner(
54 opt_logMsgUrl) { 54 gnubbyId, forEnroll, completeCb, timer, opt_logMsgUrl) {
55 /** @private {GnubbyDeviceId} */ 55 /** @private {GnubbyDeviceId} */
56 this.gnubbyId_ = gnubbyId; 56 this.gnubbyId_ = gnubbyId;
57 /** @private {SingleGnubbySigner.State} */ 57 /** @private {SingleGnubbySigner.State} */
58 this.state_ = SingleGnubbySigner.State.INIT; 58 this.state_ = SingleGnubbySigner.State.INIT;
59 /** @private {boolean} */ 59 /** @private {boolean} */
60 this.forEnroll_ = forEnroll; 60 this.forEnroll_ = forEnroll;
61 /** @private {function(SingleSignerResult)} */ 61 /** @private {function(SingleSignerResult)} */
62 this.completeCb_ = completeCb; 62 this.completeCb_ = completeCb;
63 /** @private {Countdown} */ 63 /** @private {Countdown} */
64 this.timer_ = timer; 64 this.timer_ = timer;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 108
109 /** 109 /**
110 * Closes this signer's gnubby, if it's held. 110 * Closes this signer's gnubby, if it's held.
111 */ 111 */
112 SingleGnubbySigner.prototype.close = function() { 112 SingleGnubbySigner.prototype.close = function() {
113 if (this.state_ == SingleGnubbySigner.State.OPENING) { 113 if (this.state_ == SingleGnubbySigner.State.OPENING) {
114 if (this.openCanceller_) 114 if (this.openCanceller_)
115 this.openCanceller_(); 115 this.openCanceller_();
116 } 116 }
117 117
118 if (!this.gnubby_) return; 118 if (!this.gnubby_)
119 return;
119 this.state_ = SingleGnubbySigner.State.CLOSING; 120 this.state_ = SingleGnubbySigner.State.CLOSING;
120 this.gnubby_.closeWhenIdle(this.closed_.bind(this)); 121 this.gnubby_.closeWhenIdle(this.closed_.bind(this));
121 }; 122 };
122 123
123 /** 124 /**
124 * Called when this signer's gnubby is closed. 125 * Called when this signer's gnubby is closed.
125 * @private 126 * @private
126 */ 127 */
127 SingleGnubbySigner.prototype.closed_ = function() { 128 SingleGnubbySigner.prototype.closed_ = function() {
128 this.gnubby_ = null; 129 this.gnubby_ = null;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 */ 188 */
188 SingleGnubbySigner.prototype.open_ = function() { 189 SingleGnubbySigner.prototype.open_ = function() {
189 var appIdHash; 190 var appIdHash;
190 if (this.challenges_.length) { 191 if (this.challenges_.length) {
191 // Assume the first challenge's appId is representative of all of them. 192 // Assume the first challenge's appId is representative of all of them.
192 appIdHash = B64_encode(this.challenges_[0].appIdHash); 193 appIdHash = B64_encode(this.challenges_[0].appIdHash);
193 } 194 }
194 if (this.state_ == SingleGnubbySigner.State.INIT) { 195 if (this.state_ == SingleGnubbySigner.State.INIT) {
195 this.state_ = SingleGnubbySigner.State.OPENING; 196 this.state_ = SingleGnubbySigner.State.OPENING;
196 this.openCanceller_ = DEVICE_FACTORY_REGISTRY.getGnubbyFactory().openGnubby( 197 this.openCanceller_ = DEVICE_FACTORY_REGISTRY.getGnubbyFactory().openGnubby(
197 this.gnubbyId_, 198 this.gnubbyId_, this.forEnroll_, this.openCallback_.bind(this),
198 this.forEnroll_, 199 appIdHash, this.logMsgUrl_,
199 this.openCallback_.bind(this),
200 appIdHash,
201 this.logMsgUrl_,
202 'singlesigner.js:SingleGnubbySigner.prototype.open_'); 200 'singlesigner.js:SingleGnubbySigner.prototype.open_');
203 } 201 }
204 }; 202 };
205 203
206 /** 204 /**
207 * How long to delay retrying a failed open. 205 * How long to delay retrying a failed open.
208 */ 206 */
209 SingleGnubbySigner.OPEN_DELAY_MILLIS = 200; 207 SingleGnubbySigner.OPEN_DELAY_MILLIS = 200;
210 208
211 /** 209 /**
(...skipping 23 matching lines...) Expand all
235 } 233 }
236 break; 234 break;
237 case DeviceStatusCodes.BUSY_STATUS: 235 case DeviceStatusCodes.BUSY_STATUS:
238 this.gnubby_ = gnubby; 236 this.gnubby_ = gnubby;
239 this.state_ = SingleGnubbySigner.State.BUSY; 237 this.state_ = SingleGnubbySigner.State.BUSY;
240 // If there's still time, retry the open. 238 // If there's still time, retry the open.
241 if (!this.timer_ || !this.timer_.expired()) { 239 if (!this.timer_ || !this.timer_.expired()) {
242 var self = this; 240 var self = this;
243 window.setTimeout(function() { 241 window.setTimeout(function() {
244 if (self.gnubby_) { 242 if (self.gnubby_) {
245 this.openCanceller_ = DEVICE_FACTORY_REGISTRY 243 this.openCanceller_ =
246 .getGnubbyFactory().openGnubby( 244 DEVICE_FACTORY_REGISTRY.getGnubbyFactory().openGnubby(
247 self.gnubbyId_, 245 self.gnubbyId_, self.forEnroll_,
248 self.forEnroll_, 246 self.openCallback_.bind(self), self.logMsgUrl_,
249 self.openCallback_.bind(self), 247 'singlesigner.js:SingleGnubbySigner.prototype.openCallback_' );
250 self.logMsgUrl_,
251 'singlesigner.js:SingleGnubbySigner.prototype.openCallback_');
252 } 248 }
253 }, SingleGnubbySigner.OPEN_DELAY_MILLIS); 249 }, SingleGnubbySigner.OPEN_DELAY_MILLIS);
254 } else { 250 } else {
255 this.goToError_(DeviceStatusCodes.BUSY_STATUS); 251 this.goToError_(DeviceStatusCodes.BUSY_STATUS);
256 } 252 }
257 break; 253 break;
258 default: 254 default:
259 // TODO: This won't be confused with success, but should it be 255 // TODO: This won't be confused with success, but should it be
260 // part of the same namespace as the other error codes, which are 256 // part of the same namespace as the other error codes, which are
261 // always in DeviceStatusCodes.*? 257 // always in DeviceStatusCodes.*?
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 var appIdHash = challenge.appIdHash; 325 var appIdHash = challenge.appIdHash;
330 var keyHandle = challenge.keyHandle; 326 var keyHandle = challenge.keyHandle;
331 if (this.cachedError_.hasOwnProperty(keyHandle)) { 327 if (this.cachedError_.hasOwnProperty(keyHandle)) {
332 // Cache hit: return wrong data again. 328 // Cache hit: return wrong data again.
333 this.signCallback_(challengeIndex, this.cachedError_[keyHandle]); 329 this.signCallback_(challengeIndex, this.cachedError_[keyHandle]);
334 } else if (challenge.version && challenge.version != this.version_) { 330 } else if (challenge.version && challenge.version != this.version_) {
335 // Sign challenge for a different version of gnubby: return wrong data. 331 // Sign challenge for a different version of gnubby: return wrong data.
336 this.signCallback_(challengeIndex, DeviceStatusCodes.WRONG_DATA_STATUS); 332 this.signCallback_(challengeIndex, DeviceStatusCodes.WRONG_DATA_STATUS);
337 } else { 333 } else {
338 var nowink = false; 334 var nowink = false;
339 this.gnubby_.sign(challengeHash, appIdHash, keyHandle, 335 this.gnubby_.sign(
340 this.signCallback_.bind(this, challengeIndex), 336 challengeHash, appIdHash, keyHandle,
341 nowink); 337 this.signCallback_.bind(this, challengeIndex), nowink);
342 } 338 }
343 }; 339 };
344 340
345 /** 341 /**
346 * @param {number} code The result of a sign operation. 342 * @param {number} code The result of a sign operation.
347 * @return {boolean} Whether the error indicates the key handle is invalid 343 * @return {boolean} Whether the error indicates the key handle is invalid
348 * for this gnubby. 344 * for this gnubby.
349 */ 345 */
350 SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle = function(code) { 346 SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle = function(code) {
351 return (code == DeviceStatusCodes.WRONG_DATA_STATUS || 347 return (
348 code == DeviceStatusCodes.WRONG_DATA_STATUS ||
352 code == DeviceStatusCodes.WRONG_LENGTH_STATUS || 349 code == DeviceStatusCodes.WRONG_LENGTH_STATUS ||
353 code == DeviceStatusCodes.INVALID_DATA_STATUS); 350 code == DeviceStatusCodes.INVALID_DATA_STATUS);
354 }; 351 };
355 352
356 /** 353 /**
357 * Called with the result of a single sign operation. 354 * Called with the result of a single sign operation.
358 * @param {number} challengeIndex the index of the challenge just attempted 355 * @param {number} challengeIndex the index of the challenge just attempted
359 * @param {number} code the result of the sign operation 356 * @param {number} code the result of the sign operation
360 * @param {ArrayBuffer=} opt_info Optional result data 357 * @param {ArrayBuffer=} opt_info Optional result data
361 * @private 358 * @private
362 */ 359 */
363 SingleGnubbySigner.prototype.signCallback_ = 360 SingleGnubbySigner.prototype.signCallback_ = function(
364 function(challengeIndex, code, opt_info) { 361 challengeIndex, code, opt_info) {
365 console.log(UTIL_fmt('gnubby ' + JSON.stringify(this.gnubbyId_) + 362 console.log(UTIL_fmt(
366 ', challenge ' + challengeIndex + ' yielded ' + code.toString(16))); 363 'gnubby ' + JSON.stringify(this.gnubbyId_) + ', challenge ' +
364 challengeIndex + ' yielded ' + code.toString(16)));
367 if (this.state_ != SingleGnubbySigner.State.SIGNING) { 365 if (this.state_ != SingleGnubbySigner.State.SIGNING) {
368 console.log(UTIL_fmt('already done!')); 366 console.log(UTIL_fmt('already done!'));
369 // We're done, the caller's no longer interested. 367 // We're done, the caller's no longer interested.
370 return; 368 return;
371 } 369 }
372 370
373 // Cache certain idempotent errors, re-asking the gnubby to sign it 371 // Cache certain idempotent errors, re-asking the gnubby to sign it
374 // won't produce different results. 372 // won't produce different results.
375 if (SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle(code)) { 373 if (SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle(code)) {
376 if (challengeIndex < this.challenges_.length) { 374 if (challengeIndex < this.challenges_.length) {
(...skipping 15 matching lines...) Expand all
392 break; 390 break;
393 391
394 case DeviceStatusCodes.BUSY_STATUS: 392 case DeviceStatusCodes.BUSY_STATUS:
395 this.doSign_(this.challengeIndex_); 393 this.doSign_(this.challengeIndex_);
396 break; 394 break;
397 395
398 case DeviceStatusCodes.OK_STATUS: 396 case DeviceStatusCodes.OK_STATUS:
399 // Lower bound on the minimum length, signature length can vary. 397 // Lower bound on the minimum length, signature length can vary.
400 var MIN_SIGNATURE_LENGTH = 7; 398 var MIN_SIGNATURE_LENGTH = 7;
401 if (!opt_info || opt_info.byteLength < MIN_SIGNATURE_LENGTH) { 399 if (!opt_info || opt_info.byteLength < MIN_SIGNATURE_LENGTH) {
402 console.error(UTIL_fmt('Got short response to sign request (' + 400 console.error(UTIL_fmt(
401 'Got short response to sign request (' +
403 (opt_info ? opt_info.byteLength : 0) + ' bytes), WTF?')); 402 (opt_info ? opt_info.byteLength : 0) + ' bytes), WTF?'));
404 } 403 }
405 if (this.forEnroll_) { 404 if (this.forEnroll_) {
406 this.goToError_(code); 405 this.goToError_(code);
407 } else { 406 } else {
408 this.goToSuccess_(code, this.challenges_[challengeIndex], opt_info); 407 this.goToSuccess_(code, this.challenges_[challengeIndex], opt_info);
409 } 408 }
410 break; 409 break;
411 410
412 case DeviceStatusCodes.WAIT_TOUCH_STATUS: 411 case DeviceStatusCodes.WAIT_TOUCH_STATUS:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 /** 454 /**
456 * Switches to the error state, and notifies caller. 455 * Switches to the error state, and notifies caller.
457 * @param {number} code Error code 456 * @param {number} code Error code
458 * @param {boolean=} opt_warn Whether to warn in the console about the error. 457 * @param {boolean=} opt_warn Whether to warn in the console about the error.
459 * @private 458 * @private
460 */ 459 */
461 SingleGnubbySigner.prototype.goToError_ = function(code, opt_warn) { 460 SingleGnubbySigner.prototype.goToError_ = function(code, opt_warn) {
462 this.state_ = SingleGnubbySigner.State.COMPLETE; 461 this.state_ = SingleGnubbySigner.State.COMPLETE;
463 var logFn = opt_warn ? console.warn.bind(console) : console.log.bind(console); 462 var logFn = opt_warn ? console.warn.bind(console) : console.log.bind(console);
464 logFn(UTIL_fmt('failed (' + code.toString(16) + ')')); 463 logFn(UTIL_fmt('failed (' + code.toString(16) + ')'));
465 var result = { code: code }; 464 var result = {code: code};
466 if (!this.forEnroll_ && 465 if (!this.forEnroll_ &&
467 SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle(code)) { 466 SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle(code)) {
468 // When a device yields an idempotent bad key handle error to all sign 467 // When a device yields an idempotent bad key handle error to all sign
469 // challenges, and this is a sign request, we don't want to yield to the 468 // challenges, and this is a sign request, we don't want to yield to the
470 // web page that it's not enrolled just yet: we want the user to tap the 469 // web page that it's not enrolled just yet: we want the user to tap the
471 // device first. We'll report the gnubby to the caller and let it close it 470 // device first. We'll report the gnubby to the caller and let it close it
472 // instead of closing it here. 471 // instead of closing it here.
473 result.gnubby = this.gnubby_; 472 result.gnubby = this.gnubby_;
474 } else { 473 } else {
475 // Since this gnubby can no longer produce a useful result, go ahead and 474 // Since this gnubby can no longer produce a useful result, go ahead and
476 // close it. 475 // close it.
477 this.close(); 476 this.close();
478 } 477 }
479 this.completeCb_(result); 478 this.completeCb_(result);
480 }; 479 };
481 480
482 /** 481 /**
483 * Switches to the success state, and notifies caller. 482 * Switches to the success state, and notifies caller.
484 * @param {number} code Status code 483 * @param {number} code Status code
485 * @param {SignHelperChallenge=} opt_challenge The challenge signed 484 * @param {SignHelperChallenge=} opt_challenge The challenge signed
486 * @param {ArrayBuffer=} opt_info Optional result data 485 * @param {ArrayBuffer=} opt_info Optional result data
487 * @private 486 * @private
488 */ 487 */
489 SingleGnubbySigner.prototype.goToSuccess_ = 488 SingleGnubbySigner.prototype.goToSuccess_ = function(
490 function(code, opt_challenge, opt_info) { 489 code, opt_challenge, opt_info) {
491 this.state_ = SingleGnubbySigner.State.COMPLETE; 490 this.state_ = SingleGnubbySigner.State.COMPLETE;
492 console.log(UTIL_fmt('success (' + code.toString(16) + ')')); 491 console.log(UTIL_fmt('success (' + code.toString(16) + ')'));
493 var result = { code: code, gnubby: this.gnubby_ }; 492 var result = {code: code, gnubby: this.gnubby_};
494 if (opt_challenge || opt_info) { 493 if (opt_challenge || opt_info) {
495 if (opt_challenge) { 494 if (opt_challenge) {
496 result['challenge'] = opt_challenge; 495 result['challenge'] = opt_challenge;
497 } 496 }
498 if (opt_info) { 497 if (opt_info) {
499 result['info'] = opt_info; 498 result['info'] = opt_info;
500 } 499 }
501 } 500 }
502 this.completeCb_(result); 501 this.completeCb_(result);
503 // this.gnubby_ is now owned by completeCb_. 502 // this.gnubby_ is now owned by completeCb_.
504 this.gnubby_ = null; 503 this.gnubby_ = null;
505 }; 504 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698