Check-in [64c4c68fa6]
Overview
SHA1:64c4c68fa6638b79e3f13da7a8c1f503b428b829
Date: 2016-03-09 04:30:30
User: rkeene
Comment:ChromeOS: Added support for listing smartcard readers
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2016-03-09
04:40
[40765d7728] ChromeOS: Fix issue where multiple calls made close together may have used the same ID (user: rkeene, tags: trunk)
04:30
[64c4c68fa6] ChromeOS: Added support for listing smartcard readers (user: rkeene, tags: trunk)
2016-03-08
21:02
[188c4d598f] ChromeOS: Added support for informing the user if we are a certificate provider or not (user: rkeene, tags: trunk)
Changes

Modified build/chrome/cackey-chrome-pkcs11.c from [c7ea100694] to [d840c2c357].

     1      1   #ifdef __cplusplus
     2      2   extern "C" {
     3      3   #endif
     4      4   
            5  +#include <stdbool.h>
     5      6   #include <unistd.h>
     6      7   #include <stdlib.h>
     7      8   #include <string.h>
     8      9   #include <stdio.h>
     9     10   
    10     11   #include "mypkcs11.h"
    11     12   #include "cackey-chrome.h"
................................................................................
   322    323   		if (certificates[idx].certificate) {
   323    324   			free(certificates[idx].certificate);
   324    325   		}
   325    326   	}
   326    327   
   327    328   	free(certificates);
   328    329   
          330  +	return;
          331  +}
          332  +
          333  +int cackey_chrome_listReaders(struct cackey_reader **readers) {
          334  +	CK_RV chk_rv;
          335  +	CK_ULONG numSlots, currSlot;
          336  +	CK_SLOT_ID_PTR slots;
          337  +	CK_SLOT_INFO slotInfo;
          338  +
          339  +	chk_rv = cackey_chrome_init();
          340  +	if (chk_rv != CKR_OK) {
          341  +		return(0);
          342  +	}
          343  +
          344  +	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, NULL, &numSlots);
          345  +	if (chk_rv != CKR_OK) {
          346  +		return(0);
          347  +	}
          348  +
          349  +	slots = malloc(sizeof(*slots) * numSlots);
          350  +
          351  +	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, slots, &numSlots);
          352  +	if (chk_rv != CKR_OK) {
          353  +		free(slots);
          354  +
          355  +		return(0);
          356  +	}
          357  +
          358  +	*readers = malloc(sizeof(**readers) * numSlots);
          359  +
          360  +	for (currSlot = 0; currSlot < numSlots; currSlot++) {
          361  +		chk_rv = moduleFunctionList->C_GetSlotInfo(slots[currSlot], &slotInfo);
          362  +		if (chk_rv != CKR_OK) {
          363  +			continue;
          364  +		}
          365  +
          366  +		(*readers)[currSlot].reader = malloc(sizeof(slotInfo.slotDescription) + 1);
          367  +		memcpy((*readers)[currSlot].reader, slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
          368  +		(*readers)[currSlot].reader[sizeof(slotInfo.slotDescription)] = '\0';
          369  +
          370  +		if ((slotInfo.flags & CKF_TOKEN_PRESENT) != CKF_TOKEN_PRESENT) {
          371  +			(*readers)[currSlot].cardInserted = false;
          372  +		} else {
          373  +			(*readers)[currSlot].cardInserted = true;
          374  +		}
          375  +	}
          376  +
          377  +	free(slots);
          378  +
          379  +	return(numSlots);
          380  +}
          381  +
          382  +void cackey_chrome_freeReaders(struct cackey_reader *readers, int readersCount) {
          383  +	int idx;
          384  +
          385  +	if (readers == NULL) {
          386  +		return;
          387  +	}
          388  +
          389  +	for (idx = 0; idx < readersCount; idx++) {
          390  +		if (readers[idx].reader) {
          391  +			free(readers[idx].reader);
          392  +		}
          393  +	}
          394  +
          395  +	free(readers);
          396  +
   329    397   	return;
   330    398   }
   331    399   
   332    400   cackey_chrome_returnType cackey_chrome_signMessage(struct cackey_certificate *certificate, void *data, unsigned long dataLength, void *destination, unsigned long *destinationLength, char **pinPrompt, const char *pin) {
   333    401   	CK_RV chk_rv;
   334    402   	CK_ULONG numSlots, currSlot;
   335    403   	CK_SLOT_ID_PTR slots;

Modified build/chrome/cackey-chrome-plugin.cc from [02273309f5] to [cf6e270a5f].

    33     33   		virtual void HandleMessageThread(pp::VarDictionary *message, pp::Var *messagePlain) {
    34     34   			cackey_chrome_returnType signRet;
    35     35   			char *pinPrompt = NULL;
    36     36   			const char *pin;
    37     37   			const char *smartcardManagerAppId = NULL;
    38     38   			unsigned char buffer[8192];
    39     39   			struct cackey_certificate *certificates, incomingCertificateCACKey;
    40         -			pp::VarDictionary *reply;
    41         -			pp::VarArray certificatesPPArray;
           40  +			struct cackey_reader *readers;
           41  +			pp::VarDictionary *reply, *readerInfo;
           42  +			pp::VarArray certificatesPPArray, readersPPArray;
    42     43   			pp::VarArrayBuffer *certificateContents, *incomingCertificateContents, *incomingData, *outgoingData;
    43     44   			pp::Var command;
    44         -			int numCertificates, i;
           45  +			int numCertificates, numReaders, i;
    45     46   			unsigned long outgoingDataLength;
    46     47   
    47     48   			/*
    48     49   			 * Extract the command
    49     50   			 */
    50     51   			command = message->Get("command");
    51     52   
................................................................................
    83     84   					delete certificateContents;
    84     85   				}
    85     86   
    86     87   				cackey_chrome_freeCertificates(certificates, numCertificates);
    87     88   
    88     89   				reply->Set("status", "success");
    89     90   				reply->Set("certificates", certificatesPPArray);
           91  +			} else if (command.AsString() == "listreaders") {
           92  +				numReaders = cackey_chrome_listReaders(&readers);
           93  +
           94  +				readersPPArray.SetLength(numReaders);
           95  +
           96  +				for (i = 0; i < numReaders; i++) {
           97  +					readerInfo = new pp::VarDictionary;
           98  +
           99  +					readerInfo->Set("readerName", readers[i].reader);
          100  +					readerInfo->Set("cardInserted", readers[i].cardInserted);
          101  +
          102  +					readersPPArray.Set(i, *readerInfo);
          103  +
          104  +					delete readerInfo;
          105  +				}
          106  +
          107  +				cackey_chrome_freeReaders(readers, numReaders);
          108  +
          109  +				reply->Set("status", "success");
          110  +				reply->Set("readers", readersPPArray);
    90    111   			} else if (command.AsString() == "sign") {
    91    112   				if (!message->HasKey("certificate")) {
    92    113   					reply->Set("status", "error");
    93    114   					reply->Set("error", "Certificate not supplied");
    94    115   				} else if (!message->HasKey("data")) {
    95    116   					reply->Set("status", "error");
    96    117   					reply->Set("error", "Data not supplied");

Modified build/chrome/cackey-chrome.h from [ef61e21c1b] to [0278509de3].

     7      7   
     8      8   #include <stddef.h>
     9      9   
    10     10   struct cackey_certificate {
    11     11   	size_t certificate_len;
    12     12   	void *certificate;
    13     13   };
           14  +
           15  +struct cackey_reader {
           16  +	char *reader;
           17  +	bool cardInserted;
           18  +};
    14     19   
    15     20   typedef enum {
    16     21   	CACKEY_CHROME_OK,
    17     22   	CACKEY_CHROME_ERROR,
    18     23   	CACKEY_CHROME_NEEDLOGIN,
    19     24   	CACKEY_CHROME_NEEDPROTECTEDLOGIN
    20     25   } cackey_chrome_returnType;
    21     26   
    22     27   int cackey_chrome_listCertificates(struct cackey_certificate **certificates);
    23     28   void cackey_chrome_freeCertificates(struct cackey_certificate *certificates, int certificatesCount);
    24     29   
           30  +int cackey_chrome_listReaders(struct cackey_reader **readers);
           31  +void cackey_chrome_freeReaders(struct cackey_reader *readers, int readersCount);
           32  +
    25     33   cackey_chrome_returnType cackey_chrome_signMessage(struct cackey_certificate *certificate, void *data, unsigned long dataLength, void *destination, unsigned long *destinationLength, char **pinPrompt, const char *pin);
    26     34   
    27     35   void cackey_chrome_terminate(void);
    28     36   
    29     37   #  ifdef __cplusplus
    30     38   }
    31     39   #  endif
    32     40   
    33     41   #endif

Modified build/chrome/cackey.js from [6f10afa9df] to [acab99bc2a].

    67     67   
    68     68   /*
    69     69    * Handle a response from the NaCl side regarding certificates available
    70     70    */
    71     71   function cackeyMessageIncomingListCertificates(message, chromeCallback) {
    72     72   	var idx;
    73     73   	var certificates = [];
           74  +
           75  +	if (!chromeCallback) {
           76  +		return;
           77  +	}
    74     78   
    75     79   	for (idx = 0; idx < message.certificates.length; idx++) {
    76     80   		certificates.push(
    77     81   			{
    78     82   				certificate: message.certificates[idx],
    79     83   				supportedHashes: ['SHA1', 'SHA256', 'MD5_SHA1']
    80     84   			}
................................................................................
    93     97   
    94     98   			return;
    95     99   		}
    96    100   	);
    97    101   
    98    102   	return;
    99    103   }
          104  +
          105  +/*
          106  + * Handle a response from the NaCl side regarding a list of readers
          107  + */
          108  +function cackeyMessageIncomingListReaders(message, chromeCallback) {
          109  +	if (!chromeCallback) {
          110  +		return;
          111  +	}
          112  +
          113  +	chromeCallback(message.readers);
          114  +
          115  +	return;
          116  +}
   100    117   
   101    118   /*
   102    119    * Handle a response from the NaCl side regarding signing a message
   103    120    */
   104    121   function cackeyMessageIncomingSignMessage(message, chromeCallback) {
   105    122   	var payload;
          123  +
          124  +	if (!chromeCallback) {
          125  +		return;
          126  +	}
   106    127   
   107    128   	payload = message.signedData;
   108    129   
   109    130   	chromeCallback(payload);
   110    131   
   111    132   	return;
   112    133   }
................................................................................
   353    374   			 */
   354    375   			return;
   355    376   		case "success":
   356    377   			switch (messageEvent.data.command) {
   357    378   				case "listcertificates":
   358    379   					nextFunction = cackeyMessageIncomingListCertificates;
   359    380   
          381  +					break;
          382  +				case "listreaders":
          383  +					nextFunction = cackeyMessageIncomingListReaders;
          384  +
   360    385   					break;
   361    386   				case "sign":
   362    387   					nextFunction = cackeyMessageIncomingSignMessage;
   363    388   
   364    389   					break;
   365    390   			}
   366    391   
................................................................................
   392    417   		cackeyHandle.postMessage(
   393    418   			{
   394    419   				'target': "cackey",
   395    420   				'command': "listcertificates",
   396    421   				'id': callbackId
   397    422   			}
   398    423   		);
          424  +
          425  +		cackeyOutstandingCallbackCounter = callbackId;
          426  +		cackeyOutstandingCallbacks[callbackId] = chromeCallback;
          427  +
          428  +		if (GoogleSmartCard.IS_DEBUG_BUILD) {
          429  +			console.log("[cackey] Thrown.");
          430  +		}
          431  +	}, chromeCallback);
          432  +
          433  +	return;
          434  +}
          435  +
          436  +/*
          437  + * Handler for messages from Chrome related to listing readers
          438  + */
          439  +function cackeyListReaders(chromeCallback) {
          440  +	var callbackId;
          441  +
          442  +	if (GoogleSmartCard.IS_DEBUG_BUILD) {
          443  +		console.log("[cackey] Asked to provide a list of readers -- throwing that request over to the NaCl side... ");
          444  +	}
          445  +
          446  +	callbackId = cackeyOutstandingCallbackCounter + 1;
          447  +
          448  +	cackeyInitPCSC(function() {
          449  +		cackeyHandle.postMessage(
          450  +			{
          451  +				'target': "cackey",
          452  +				'command': "listreaders",
          453  +				'id': callbackId
          454  +			}
          455  +		);
   399    456   
   400    457   		cackeyOutstandingCallbackCounter = callbackId;
   401    458   		cackeyOutstandingCallbacks[callbackId] = chromeCallback;
   402    459   
   403    460   		if (GoogleSmartCard.IS_DEBUG_BUILD) {
   404    461   			console.log("[cackey] Thrown.");
   405    462   		}