| 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 Implements a sign handler using USB gnubbies. | 6 * @fileoverview Implements a sign handler using USB gnubbies. |
| 7 */ | 7 */ |
| 8 'use strict'; | 8 'use strict'; |
| 9 | 9 |
| 10 var CORRUPT_sign = false; | 10 var CORRUPT_sign = false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 if (this.cb_) { | 42 if (this.cb_) { |
| 43 // Can only handle one request. | 43 // Can only handle one request. |
| 44 return false; | 44 return false; |
| 45 } | 45 } |
| 46 /** @private {RequestHandlerCallback} */ | 46 /** @private {RequestHandlerCallback} */ |
| 47 this.cb_ = cb; | 47 this.cb_ = cb; |
| 48 if (!this.request_.signData || !this.request_.signData.length) { | 48 if (!this.request_.signData || !this.request_.signData.length) { |
| 49 // Fail a sign request with an empty set of challenges. | 49 // Fail a sign request with an empty set of challenges. |
| 50 return false; | 50 return false; |
| 51 } | 51 } |
| 52 var timeoutMillis = | 52 var timeoutMillis = this.request_.timeoutSeconds ? |
| 53 this.request_.timeoutSeconds ? | |
| 54 this.request_.timeoutSeconds * 1000 : | 53 this.request_.timeoutSeconds * 1000 : |
| 55 UsbSignHandler.DEFAULT_TIMEOUT_MILLIS; | 54 UsbSignHandler.DEFAULT_TIMEOUT_MILLIS; |
| 56 /** @private {MultipleGnubbySigner} */ | 55 /** @private {MultipleGnubbySigner} */ |
| 57 this.signer_ = new MultipleGnubbySigner( | 56 this.signer_ = new MultipleGnubbySigner( |
| 58 false /* forEnroll */, | 57 false /* forEnroll */, this.signerCompleted_.bind(this), |
| 59 this.signerCompleted_.bind(this), | 58 this.signerFoundGnubby_.bind(this), timeoutMillis, |
| 60 this.signerFoundGnubby_.bind(this), | |
| 61 timeoutMillis, | |
| 62 this.request_.logMsgUrl); | 59 this.request_.logMsgUrl); |
| 63 return this.signer_.doSign(this.request_.signData); | 60 return this.signer_.doSign(this.request_.signData); |
| 64 }; | 61 }; |
| 65 | 62 |
| 66 | 63 |
| 67 /** | 64 /** |
| 68 * Called when a MultipleGnubbySigner completes. | 65 * Called when a MultipleGnubbySigner completes. |
| 69 * @param {boolean} anyPending Whether any gnubbies are pending. | 66 * @param {boolean} anyPending Whether any gnubbies are pending. |
| 70 * @private | 67 * @private |
| 71 */ | 68 */ |
| 72 UsbSignHandler.prototype.signerCompleted_ = function(anyPending) { | 69 UsbSignHandler.prototype.signerCompleted_ = function(anyPending) { |
| 73 if (!this.anyGnubbiesFound_ || anyPending) { | 70 if (!this.anyGnubbiesFound_ || anyPending) { |
| 74 this.notifyError_(DeviceStatusCodes.TIMEOUT_STATUS); | 71 this.notifyError_(DeviceStatusCodes.TIMEOUT_STATUS); |
| 75 } else if (this.signerError_ !== undefined) { | 72 } else if (this.signerError_ !== undefined) { |
| 76 this.notifyError_(this.signerError_); | 73 this.notifyError_(this.signerError_); |
| 77 } else { | 74 } else { |
| 78 // Do nothing: signerFoundGnubby_ will have returned results from other | 75 // Do nothing: signerFoundGnubby_ will have returned results from other |
| 79 // gnubbies. | 76 // gnubbies. |
| 80 } | 77 } |
| 81 }; | 78 }; |
| 82 | 79 |
| 83 /** | 80 /** |
| 84 * Called when a MultipleGnubbySigner finds a gnubby that has completed signing | 81 * Called when a MultipleGnubbySigner finds a gnubby that has completed signing |
| 85 * its challenges. | 82 * its challenges. |
| 86 * @param {MultipleSignerResult} signResult Signer result object | 83 * @param {MultipleSignerResult} signResult Signer result object |
| 87 * @param {boolean} moreExpected Whether the signer expects to produce more | 84 * @param {boolean} moreExpected Whether the signer expects to produce more |
| 88 * results. | 85 * results. |
| 89 * @private | 86 * @private |
| 90 */ | 87 */ |
| 91 UsbSignHandler.prototype.signerFoundGnubby_ = | 88 UsbSignHandler.prototype.signerFoundGnubby_ = function( |
| 92 function(signResult, moreExpected) { | 89 signResult, moreExpected) { |
| 93 this.anyGnubbiesFound_ = true; | 90 this.anyGnubbiesFound_ = true; |
| 94 if (!signResult.code) { | 91 if (!signResult.code) { |
| 95 var gnubby = signResult['gnubby']; | 92 var gnubby = signResult['gnubby']; |
| 96 var challenge = signResult['challenge']; | 93 var challenge = signResult['challenge']; |
| 97 var info = new Uint8Array(signResult['info']); | 94 var info = new Uint8Array(signResult['info']); |
| 98 this.notifySuccess_(gnubby, challenge, info); | 95 this.notifySuccess_(gnubby, challenge, info); |
| 99 } else if (SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle( | 96 } else if (SingleGnubbySigner.signErrorIndicatesInvalidKeyHandle( |
| 100 signResult.code)) { | 97 signResult.code)) { |
| 101 var gnubby = signResult['gnubby']; | 98 var gnubby = signResult['gnubby']; |
| 102 this.notEnrolledGnubbies_.push(gnubby); | 99 this.notEnrolledGnubbies_.push(gnubby); |
| 103 this.sendBogusEnroll_(gnubby); | 100 this.sendBogusEnroll_(gnubby); |
| 104 } else if (!moreExpected) { | 101 } else if (!moreExpected) { |
| 105 // If the signer doesn't expect more results, return the error directly to | 102 // If the signer doesn't expect more results, return the error directly to |
| 106 // the caller. | 103 // the caller. |
| 107 this.notifyError_(signResult.code); | 104 this.notifyError_(signResult.code); |
| 108 } else { | 105 } else { |
| 109 // Record the last error, to report from the complete callback if no other | 106 // Record the last error, to report from the complete callback if no other |
| 110 // eligible gnubbies are found. | 107 // eligible gnubbies are found. |
| 111 /** @private {number} */ | 108 /** @private {number} */ |
| 112 this.signerError_ = signResult.code; | 109 this.signerError_ = signResult.code; |
| 113 } | 110 } |
| 114 }; | 111 }; |
| 115 | 112 |
| 116 /** @const */ | 113 /** @const */ |
| 117 UsbSignHandler.BOGUS_APP_ID_HASH = [ | 114 UsbSignHandler.BOGUS_APP_ID_HASH = [ |
| 118 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, | 115 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, |
| 119 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, | 116 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, |
| 120 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, | 117 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 |
| 121 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 | |
| 122 ]; | 118 ]; |
| 123 | 119 |
| 124 /** @const */ | 120 /** @const */ |
| 125 UsbSignHandler.BOGUS_CHALLENGE_V1 = [ | 121 UsbSignHandler.BOGUS_CHALLENGE_V1 = [ |
| 126 0x04, 0xA2, 0x24, 0x7D, 0x5C, 0x0B, 0x76, 0xF1, | 122 0x04, 0xA2, 0x24, 0x7D, 0x5C, 0x0B, 0x76, 0xF1, 0xDC, 0xCD, 0x44, 0xAF, 0x91, |
| 127 0xDC, 0xCD, 0x44, 0xAF, 0x91, 0x9A, 0xA2, 0x3F, | 123 0x9A, 0xA2, 0x3F, 0x3F, 0xBA, 0x65, 0x9F, 0x06, 0x78, 0x82, 0xFB, 0x93, 0x4B, |
| 128 0x3F, 0xBA, 0x65, 0x9F, 0x06, 0x78, 0x82, 0xFB, | 124 0xBF, 0x86, 0x55, 0x95, 0x66, 0x46, 0x76, 0x90, 0xDC, 0xE1, 0xE8, 0x6C, 0x86, |
| 129 0x93, 0x4B, 0xBF, 0x86, 0x55, 0x95, 0x66, 0x46, | 125 0x86, 0xC3, 0x03, 0x4E, 0x65, 0x52, 0x4C, 0x32, 0x6F, 0xB6, 0x44, 0x0D, 0x50, |
| 130 0x76, 0x90, 0xDC, 0xE1, 0xE8, 0x6C, 0x86, 0x86, | 126 0xF9, 0x16, 0xC0, 0xA3, 0xDA, 0x31, 0x4B, 0xD3, 0x3F, 0x94, 0xA5, 0xF1, 0xD3 |
| 131 0xC3, 0x03, 0x4E, 0x65, 0x52, 0x4C, 0x32, 0x6F, | |
| 132 0xB6, 0x44, 0x0D, 0x50, 0xF9, 0x16, 0xC0, 0xA3, | |
| 133 0xDA, 0x31, 0x4B, 0xD3, 0x3F, 0x94, 0xA5, 0xF1, | |
| 134 0xD3 | |
| 135 ]; | 127 ]; |
| 136 | 128 |
| 137 /** @const */ | 129 /** @const */ |
| 138 UsbSignHandler.BOGUS_CHALLENGE_V2 = [ | 130 UsbSignHandler.BOGUS_CHALLENGE_V2 = [ |
| 139 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, | 131 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, |
| 140 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, | 132 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, |
| 141 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, | 133 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 |
| 142 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42 | |
| 143 ]; | 134 ]; |
| 144 | 135 |
| 145 /** | 136 /** |
| 146 * Sends a bogus enroll command to the not-enrolled gnubby, to force the user | 137 * Sends a bogus enroll command to the not-enrolled gnubby, to force the user |
| 147 * to tap the gnubby before revealing its state to the caller. | 138 * to tap the gnubby before revealing its state to the caller. |
| 148 * @param {Gnubby} gnubby The gnubby to "enroll" on. | 139 * @param {Gnubby} gnubby The gnubby to "enroll" on. |
| 149 * @private | 140 * @private |
| 150 */ | 141 */ |
| 151 UsbSignHandler.prototype.sendBogusEnroll_ = function(gnubby) { | 142 UsbSignHandler.prototype.sendBogusEnroll_ = function(gnubby) { |
| 152 var self = this; | 143 var self = this; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 /** | 225 /** |
| 235 * Reports error to the caller. | 226 * Reports error to the caller. |
| 236 * @param {number} code error to report | 227 * @param {number} code error to report |
| 237 * @private | 228 * @private |
| 238 */ | 229 */ |
| 239 UsbSignHandler.prototype.notifyError_ = function(code) { | 230 UsbSignHandler.prototype.notifyError_ = function(code) { |
| 240 if (this.notified_) | 231 if (this.notified_) |
| 241 return; | 232 return; |
| 242 this.notified_ = true; | 233 this.notified_ = true; |
| 243 this.close(); | 234 this.close(); |
| 244 var reply = { | 235 var reply = {'type': 'sign_helper_reply', 'code': code}; |
| 245 'type': 'sign_helper_reply', | |
| 246 'code': code | |
| 247 }; | |
| 248 this.cb_(reply); | 236 this.cb_(reply); |
| 249 }; | 237 }; |
| 250 | 238 |
| 251 /** | 239 /** |
| 252 * Closes the MultipleGnubbySigner, if any. | 240 * Closes the MultipleGnubbySigner, if any. |
| 253 */ | 241 */ |
| 254 UsbSignHandler.prototype.close = function() { | 242 UsbSignHandler.prototype.close = function() { |
| 255 while (this.notEnrolledGnubbies_.length != 0) { | 243 while (this.notEnrolledGnubbies_.length != 0) { |
| 256 var gnubby = this.notEnrolledGnubbies_.shift(); | 244 var gnubby = this.notEnrolledGnubbies_.shift(); |
| 257 gnubby.closeWhenIdle(); | 245 gnubby.closeWhenIdle(); |
| 258 } | 246 } |
| 259 if (this.signer_) { | 247 if (this.signer_) { |
| 260 this.signer_.close(); | 248 this.signer_.close(); |
| 261 this.signer_ = null; | 249 this.signer_ = null; |
| 262 } | 250 } |
| 263 }; | 251 }; |
| OLD | NEW |