Diff

Differences From Artifact [d291048f9c]:

To Artifact [dc80ae3ba4]:


   175    175   				return;
   176    176   			}
   177    177   
   178    178   			cackeyCertificateToPINMapUpdateLastUsed(null);
   179    179   		}, 900000);
   180    180   	}
   181    181   }
          182  +
          183  +/*
          184  + * Handle redispatching requests after receiving a PIN
          185  + */
          186  +function cackeyPINPromptCompleted(pinValue) {
          187  +	var tmpMessageEvent;
          188  +
          189  +	for (messageIdx = 0; messageIdx < cackeyMessagesToRetry.length; messageIdx++) {
          190  +		tmpMessageEvent = cackeyMessagesToRetry[messageIdx];
          191  +
          192  +		if (pinValue == "") {
          193  +			if (goog.DEBUG) {
          194  +				console.log("[cackey] The PIN dialog was closed without gathering a PIN, treating it as a failure.");
          195  +			}
          196  +
          197  +			tmpMessageEvent.data.status = "error";
          198  +			tmpMessageEvent.data.error = "PIN window closed without a PIN being provided";
          199  +
          200  +			cackeyMessageIncoming(tmpMessageEvent);
          201  +		} else {
          202  +			tmpMessageEvent.data.originalrequest.pin = pinValue;
          203  +
          204  +			cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)] = {}
          205  +			cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)].pin = pinValue;
          206  +			cackeyCertificateToPINMapUpdateLastUsed(cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate));
          207  +
          208  +			chromeCallback = null;
          209  +			if (tmpMessageEvent.data.id) {
          210  +				if (cackeyOutstandingCallbacks) {
          211  +					chromeCallback = cackeyOutstandingCallbacks[tmpMessageEvent.data.id];
          212  +				}
          213  +			}
          214  +
          215  +			cackeyInitPCSC(function() {
          216  +				cackeyHandle.postMessage(tmpMessageEvent.data.originalrequest);
          217  +			}, function() {
          218  +				if (chromeCallback) {
          219  +					chromeCallback();
          220  +				}
          221  +
          222  +				if (tmpMessageEvent.data.id && cackeyOutstandingCallbacks[tmpMessageEvent.data.id]) {
          223  +					delete cackeyOutstandingCallbacks[tmpMessageEvent.data.id];
          224  +				}
          225  +			});
          226  +		}
          227  +	}
          228  +
          229  +	/*
          230  +	 * Delete the existing handle and create a new one
          231  +	 */
          232  +	delete cackeyMessagesToRetry;
          233  +
          234  +	cackeyMessagesToRetry = [];
          235  +}
   182    236   
   183    237   /*
   184    238    * Handle an incoming message from the NaCl side and pass it off to
   185    239    * one of the handlers above for actual formatting and passing to
   186    240    * the callback
   187    241    *
   188    242    * If an error occured, invoke the callback with no arguments.
................................................................................
   258    312   
   259    313   			/*
   260    314   			 * Set the handle to an invalid (but non-null) value until the window
   261    315   			 * is created in case we are invoked again soon.
   262    316   			 */
   263    317   			pinWindowPreviousHandle = "invalid";
   264    318   
   265         -			chrome.app.window.create("pin.html", {
   266         -				"id": "cackeyPINEntry",
   267         -				"resizable": false,
   268         -				"alwaysOnTop": true,
   269         -				"focused": true,
   270         -				"visibleOnAllWorkspaces": true,
   271         -				"innerBounds": {
   272         -					"width": 350,
   273         -					"minWidth": 350,
   274         -					"height": 135,
   275         -					"minHeight": 135
   276         -				}
   277         -			}, function(pinWindow) {
   278         -				/*
   279         -				 * Set the PIN value to blank
   280         -				 */
   281         -				pinWindowPINValue = "";
   282         -
   283         -				if (!pinWindow) {
   284         -					console.error("[cackey] No window was provided for PIN entry, this will not go well.");
   285         -
   286         -					return;
   287         -				}
   288         -
   289         -				pinWindowPreviousHandle = pinWindow;
   290         -
   291         -				pinWindow.drawAttention();
   292         -				pinWindow.focus();
   293         -
   294         -				/*
   295         -				 * Register a handler to handle the window being closed without
   296         -				 * having sent anything
   297         -				 */
   298         -				pinWindow.onClosed.addListener(function() {
   299         -					var messageIdx;
   300         -					var chromeCallback;
   301         -
   302         -					pinWindowPreviousHandle = null;
   303         -
   304         -					for (messageIdx = 0; messageIdx < cackeyMessagesToRetry.length; messageIdx++) {
   305         -						var tmpMessageEvent;
   306         -
   307         -						tmpMessageEvent = cackeyMessagesToRetry[messageIdx];
   308         -
   309         -						if (pinWindowPINValue == "") {
   310         -							if (goog.DEBUG) {
   311         -								console.log("[cackey] The PIN dialog was closed without gathering a PIN, treating it as a failure.");
   312         -							}
   313         -
   314         -							tmpMessageEvent.data.status = "error";
   315         -							tmpMessageEvent.data.error = "PIN window closed without a PIN being provided";
   316         -
   317         -							cackeyMessageIncoming(tmpMessageEvent);
   318         -						} else {
   319         -							tmpMessageEvent.data.originalrequest.pin = pinWindowPINValue;
   320         -
   321         -							cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)] = {}
   322         -							cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)].pin = pinWindowPINValue;
   323         -
   324         -							cackeyCertificateToPINMapUpdateLastUsed(cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate));
   325         -
   326         -							chromeCallback = null;
   327         -							if (tmpMessageEvent.data.id) {
   328         -								if (cackeyOutstandingCallbacks) {
   329         -									chromeCallback = cackeyOutstandingCallbacks[tmpMessageEvent.data.id];
   330         -								}
   331         -							}
   332         -
   333         -							cackeyInitPCSC(function() {
   334         -								cackeyHandle.postMessage(tmpMessageEvent.data.originalrequest);
   335         -							}, function() {
   336         -								if (chromeCallback) {
   337         -									chromeCallback();
   338         -								}
   339         -
   340         -								if (tmpMessageEvent.data.id && cackeyOutstandingCallbacks[tmpMessageEvent.data.id]) {
   341         -									delete cackeyOutstandingCallbacks[tmpMessageEvent.data.id];
   342         -								}
   343         -							});
   344         -						}
          319  +			if (messageEvent.data.originalrequest.signRequestId === null) {
          320  +				chrome.app.window.create("pin.html", {
          321  +					"id": "cackeyPINEntry",
          322  +					"resizable": false,
          323  +					"alwaysOnTop": true,
          324  +					"focused": true,
          325  +					"visibleOnAllWorkspaces": true,
          326  +					"innerBounds": {
          327  +						"width": 350,
          328  +						"minWidth": 350,
          329  +						"height": 135,
          330  +						"minHeight": 135
   345    331   					}
   346         -
   347         -
          332  +				}, function(pinWindow) {
   348    333   					/*
   349         -					 * Delete the existing handle and create a new one
   350         -					 */
   351         -					delete cackeyMessagesToRetry;
   352         -
   353         -					cackeyMessagesToRetry = [];
   354         -
   355         -					/*
   356         -					 * We are done fetching the user PIN, clear the value
          334  +					 * Set the PIN value to blank
   357    335   					 */
   358    336   					pinWindowPINValue = "";
          337  +	
          338  +					if (!pinWindow) {
          339  +						console.error("[cackey] No window was provided for PIN entry, this will not go well.");
          340  +	
          341  +						return;
          342  +					}
          343  +	
          344  +					pinWindowPreviousHandle = pinWindow;
          345  +	
          346  +					pinWindow.drawAttention();
          347  +					pinWindow.focus();
          348  +	
          349  +					/*
          350  +					 * Register a handler to handle the window being closed without
          351  +					 * having sent anything
          352  +					 */
          353  +					pinWindow.onClosed.addListener(function() {
          354  +						var messageIdx;
          355  +						var chromeCallback;
          356  +						var pinValue;
          357  +	
          358  +						pinWindowPreviousHandle = null;
   359    359   
          360  +						/*
          361  +						 * We are done fetching the user PIN, clear the value
          362  +						 */
          363  +						pinValue = pinWindowPINValue;
          364  +						pinWindowPINValue = "";
          365  +
          366  +						cackeyPINPromptCompleted(pinValue);
          367  +	
          368  +						return;
          369  +					})
          370  +	
          371  +					/*
          372  +					 * Pass this message off to the other window so that it may resubmit the request.
          373  +					 */
          374  +					pinWindow.contentWindow.parentWindow = window;
          375  +					pinWindow.contentWindow.messageEvent = messageEvent;
          376  +	
   360    377   					return;
   361         -				})
          378  +				});
          379  +			} else {
          380  +				chrome.certificateProvider.requestPin({
          381  +					signRequestId: messageEvent.data.originalrequest.signRequestId,
          382  +					requestType: "PIN"
          383  +				}, function(userInfo) {
          384  +					chrome.certificateProvider.stopPinRequest({
          385  +						signRequestId: messageEvent.data.originalrequest.signRequestId
          386  +					}, function() {
          387  +						var pinValue = "";
   362    388   
   363         -				/*
   364         -				 * Pass this message off to the other window so that it may resubmit the request.
   365         -				 */
   366         -				pinWindow.contentWindow.parentWindow = window;
   367         -				pinWindow.contentWindow.messageEvent = messageEvent;
          389  +						pinWindowPreviousHandle = null;
   368    390   
   369         -				return;
   370         -			});
          391  +						if (userInfo && userInfo.userInput) {
          392  +							pinValue = userInfo.userInput;
          393  +						}
          394  +
          395  +						return(cackeyPINPromptCompleted(pinValue));
          396  +					});
          397  +				});
          398  +			}
   371    399   
   372    400   			/*
   373    401   			 * We return here instead of break to avoid deleting the callback
   374    402   			 * entry.
   375    403   			 */
   376    404   			return;
   377    405   		case "success":
................................................................................
   484    512    */
   485    513   function cackeySignMessage(signRequest, chromeCallback) {
   486    514   	var callbackId;
   487    515   	var command;
   488    516   	var certificateId;
   489    517   	var digest, digestHeader;
   490    518   	var promiseHandle = null, promiseResolve, promiseReject;
          519  +
          520  +	if (signRequest.signRequestId === undefined || signRequest.signRequestId === null) {
          521  +		signRequest.signRequestId = null;
          522  +	}
   491    523   
   492    524   	if (!chromeCallback) {
   493    525   		/*
   494    526   		 * If no callback supplied, arrange for a promise to be returned instead
   495    527   		 */
   496    528   		promiseHandle = new Promise(function(resolve, reject) {
   497    529   			promiseResolve = resolve;
................................................................................
   543    575   	}
   544    576   
   545    577   	callbackId = ++cackeyOutstandingCallbackCounter;
   546    578   
   547    579   	command = {
   548    580   		'target': "cackey",
   549    581   		'command': "sign",
          582  +		'signRequestId': signRequest.signRequestId,
   550    583   		'id': callbackId,
   551    584   		'certificate': signRequest.certificate,
   552    585   		'data': digest.buffer
   553    586   	};
   554    587   
   555    588   	certificateId = cackeyCertificateToPINID(command.certificate);
   556    589