Diff

Differences From Artifact [b0e4dd691b]:

To Artifact [145025308e]:


     1      1   #ifdef __cplusplus
     2      2   extern "C" {
     3      3   #endif
     4      4   
     5      5   #include <unistd.h>
     6      6   #include <stdlib.h>
            7  +#include <string.h>
            8  +#include <stdio.h>
     7      9   
     8     10   #include "mypkcs11.h"
     9     11   #include "cackey-chrome.h"
    10     12   
    11     13   struct cackey_chrome_id {
    12         -	unsigned char *id;
           14  +	void *id;
    13     15   	size_t idLen;
           16  +	int initialized;
    14     17   };
    15     18   
    16     19   static CK_FUNCTION_LIST_PTR moduleFunctionList = NULL;
    17     20   
    18     21   static CK_RV cackey_chrome_init(void) {
    19     22   	CK_C_INITIALIZE_ARGS initargs;
    20     23   	CK_RV chk_rv;
................................................................................
    38     41   	chk_rv = moduleFunctionList->C_Initialize(&initargs);
    39     42   	if (chk_rv != CKR_OK) {
    40     43   		return(chk_rv);
    41     44   	}
    42     45   
    43     46   	return(CKR_OK);
    44     47   }
           48  +
           49  +void cackey_chrome_terminate(void) {
           50  +	if (!moduleFunctionList) {
           51  +		return;
           52  +	}
           53  +
           54  +	moduleFunctionList->C_Finalize(NULL);
           55  +
           56  +	free(moduleFunctionList);
           57  +
           58  +	moduleFunctionList = NULL;
           59  +
           60  +	return;
           61  +}
           62  +
           63  +static CK_RV cackey_chrome_GetAttributesFromTemplate(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE *attrTemplate, CK_ULONG attrTemplateCount) {
           64  +	CK_RV chk_rv;
           65  + 	CK_ATTRIBUTE *currAttr;
           66  +	CK_ULONG currAttrIndex;
           67  +
           68  +	for (currAttrIndex = 0; currAttrIndex < attrTemplateCount; currAttrIndex++) {
           69  +		currAttr = &attrTemplate[currAttrIndex];
           70  +
           71  +		currAttr->pValue = NULL;
           72  +		currAttr->ulValueLen = 0;
           73  +	}
           74  +
           75  +	chk_rv = moduleFunctionList->C_GetAttributeValue(hSession, hObject, attrTemplate, attrTemplateCount);
           76  +	if (chk_rv == CKR_ATTRIBUTE_TYPE_INVALID || chk_rv == CKR_ATTRIBUTE_SENSITIVE || chk_rv == CKR_BUFFER_TOO_SMALL) {
           77  +		chk_rv = CKR_OK;
           78  +	}
           79  +
           80  +	if (chk_rv != CKR_OK) {
           81  +		return(chk_rv);
           82  +	}
           83  +
           84  +	for (currAttrIndex = 0; currAttrIndex < attrTemplateCount; currAttrIndex++) {
           85  +		currAttr = &attrTemplate[currAttrIndex];
           86  +
           87  +		if (currAttr->ulValueLen == 0) {
           88  +			continue;
           89  +		}
           90  +
           91  +		if (((CK_LONG) currAttr->ulValueLen) == ((CK_LONG) -1)) {
           92  +			continue;
           93  +		}
           94  +
           95  +		currAttr->pValue = malloc(currAttr->ulValueLen);
           96  +	}
           97  +
           98  +	chk_rv = moduleFunctionList->C_GetAttributeValue(hSession, hObject, attrTemplate, attrTemplateCount);
           99  +	if (chk_rv != CKR_OK) {
          100  +		free(currAttr->pValue);
          101  +
          102  +		return(chk_rv);
          103  +	}
          104  +
          105  +	return(CKR_OK);
          106  +}
    45    107   
    46    108   int cackey_chrome_listCertificates(struct cackey_certificate **certificates) {
    47    109   	CK_RV chk_rv;
    48    110   	CK_ULONG numSlots, currSlot;
    49    111   	CK_SLOT_ID_PTR slots;
    50    112   	CK_SLOT_INFO slotInfo;
    51    113   	CK_SESSION_HANDLE hSession;
................................................................................
    54    116   	CK_ATTRIBUTE searchTemplatePrivateKeys[] = {
    55    117   		{CKA_CLASS, NULL, sizeof(CK_OBJECT_CLASS)}
    56    118   	};
    57    119   	CK_ATTRIBUTE searchTemplateCertificates[] = {
    58    120   		{CKA_CLASS, NULL, sizeof(CK_OBJECT_CLASS)},
    59    121   		{CKA_ID, NULL, 0}
    60    122   	};
    61         -	CK_ATTRIBUTE attrTemplate[] = {
          123  +	CK_ATTRIBUTE attrTemplatePrivateKey[] = {
    62    124   		{CKA_ID, NULL, 0}
    63         -	}, *currAttr;
    64         -	CK_ULONG currAttrIndex;
          125  +	};
          126  +	CK_ATTRIBUTE attrTemplateCertificate[] = {
          127  +		{CKA_VALUE, NULL, 0}
          128  +	};
    65    129   	CK_OBJECT_CLASS objectClassPrivateKey = CKO_PRIVATE_KEY;
          130  +	CK_OBJECT_CLASS objectClassCertificate = CKO_CERTIFICATE;
          131  +	struct cackey_chrome_id *ids;
          132  +	int idsCount, currId;
          133  +	int foundCertificates, certificatesCount;
          134  +
          135  +	*certificates = NULL;
    66    136   
    67    137   	chk_rv = cackey_chrome_init();
    68    138   	if (chk_rv != CKR_OK) {
    69    139   		return(0);
    70    140   	}
    71    141   
    72    142   	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, NULL, &numSlots);
................................................................................
    74    144   		return(0);
    75    145   	}
    76    146   
    77    147   	slots = malloc(sizeof(*slots) * numSlots);
    78    148   
    79    149   	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, slots, &numSlots);
    80    150   	if (chk_rv != CKR_OK) {
          151  +		free(slots);
          152  +
    81    153   		return(0);
    82    154   	}
    83    155   
    84    156   	searchTemplatePrivateKeys[0].pValue = &objectClassPrivateKey;
          157  +	searchTemplateCertificates[0].pValue = &objectClassCertificate;
          158  +
          159  +	foundCertificates = 0;
          160  +	certificatesCount = 10;
          161  +	*certificates = malloc(sizeof(**certificates) * certificatesCount);
          162  +
          163  +	idsCount = 10;
          164  +	ids = malloc(sizeof(*ids) * idsCount);
          165  +
          166  +	for (currId = 0; currId < idsCount; currId++) {
          167  +		ids[currId].initialized = 0;
          168  +	}
    85    169   
    86    170   	for (currSlot = 0; currSlot < numSlots; currSlot++) {
    87    171   		chk_rv = moduleFunctionList->C_GetSlotInfo(slots[currSlot], &slotInfo);
    88    172   		if (chk_rv != CKR_OK) {
    89    173   			continue;
    90    174   		}
    91    175   
................................................................................
   100    184   
   101    185   		chk_rv = moduleFunctionList->C_FindObjectsInit(hSession, searchTemplatePrivateKeys, sizeof(searchTemplatePrivateKeys) / sizeof(searchTemplatePrivateKeys[0])); 
   102    186   		if (chk_rv != CKR_OK) {
   103    187   			moduleFunctionList->C_CloseSession(hSession);
   104    188   
   105    189   			continue;
   106    190   		}
          191  +
          192  +		for (currId = 0; currId < idsCount; currId++) {
          193  +			if (!ids[currId].initialized) {
          194  +				continue;
          195  +			}
          196  +
          197  +			free(ids[currId].id);
          198  +
          199  +			ids[currId].initialized = 0;
          200  +		}
          201  +
          202  +		currId = 0;
          203  +
          204  +		while (1) {
          205  +			chk_rv = moduleFunctionList->C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
          206  +			if (chk_rv != CKR_OK) {
          207  +				break;
          208  +			}
          209  +
          210  +			if (ulObjectCount == 0) {
          211  +				break;
          212  +			}
          213  +
          214  +			if (ulObjectCount != 1) {
          215  +				break;
          216  +			}
          217  +
          218  +			chk_rv = cackey_chrome_GetAttributesFromTemplate(hSession, hObject, attrTemplatePrivateKey, sizeof(attrTemplatePrivateKey) / sizeof(attrTemplatePrivateKey[0]));
          219  +			if (chk_rv != CKR_OK) {
          220  +				continue;
          221  +			}
          222  +
          223  +			if (currId >= idsCount) {
          224  +				idsCount *= 2;
          225  +
          226  +				ids = realloc(ids, sizeof(*ids) * idsCount);
          227  +			}
          228  +
          229  +			ids[currId].idLen = attrTemplatePrivateKey[0].ulValueLen;
          230  +			ids[currId].id = attrTemplatePrivateKey[0].pValue;
          231  +			ids[currId].initialized = 1;
          232  +			currId++;
          233  +		}
          234  +
          235  +		moduleFunctionList->C_FindObjectsFinal(hSession);
          236  +
          237  +		for (currId = 0; currId < idsCount; currId++) {
          238  +			if (!ids[currId].initialized) {
          239  +				continue;
          240  +			}
          241  +
          242  +			searchTemplateCertificates[1].pValue = ids[currId].id;
          243  +			searchTemplateCertificates[1].ulValueLen = ids[currId].idLen;
          244  +
          245  +			chk_rv = moduleFunctionList->C_FindObjectsInit(hSession, searchTemplateCertificates, sizeof(searchTemplateCertificates) / sizeof(searchTemplateCertificates[0])); 
          246  +			if (chk_rv != CKR_OK) {
          247  +				free(ids[currId].id);
          248  +
          249  +				ids[currId].initialized = 0;
          250  +
          251  +				continue;
          252  +			}
          253  +
          254  +			while (1) {
          255  +				chk_rv = moduleFunctionList->C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
          256  +				if (chk_rv != CKR_OK) {
          257  +					break;
          258  +				}
          259  +
          260  +				if (ulObjectCount == 0) {
          261  +					break;
          262  +				}
          263  +
          264  +				if (ulObjectCount != 1) {
          265  +					break;
          266  +				}
          267  +
          268  +				chk_rv = cackey_chrome_GetAttributesFromTemplate(hSession, hObject, attrTemplateCertificate, sizeof(attrTemplateCertificate) / sizeof(attrTemplateCertificate[0]));
          269  +				if (chk_rv != CKR_OK) {
          270  +					continue;
          271  +				}
          272  +
          273  +				if (foundCertificates >= certificatesCount) {
          274  +					certificatesCount *= 2;
          275  +					*certificates = realloc(*certificates, sizeof(**certificates) * certificatesCount);
          276  +				}
          277  +
          278  +				(*certificates)[foundCertificates].certificate = malloc(attrTemplateCertificate[0].ulValueLen);
          279  +				memcpy((*certificates)[foundCertificates].certificate, attrTemplateCertificate[0].pValue, attrTemplateCertificate[0].ulValueLen);
          280  +				(*certificates)[foundCertificates].certificate_len = attrTemplateCertificate[0].ulValueLen;
          281  +
          282  +				free(attrTemplateCertificate[0].pValue);
          283  +
          284  +				foundCertificates++;
          285  +			}
          286  +
          287  +			moduleFunctionList->C_FindObjectsFinal(hSession);
          288  +
          289  +			free(ids[currId].id);
          290  +
          291  +			ids[currId].initialized = 0;
          292  +		}
          293  +
          294  +		moduleFunctionList->C_CloseSession(hSession);
          295  +	}
          296  +
          297  +	for (currId = 0; currId < idsCount; currId++) {
          298  +		if (!ids[currId].initialized) {
          299  +			continue;
          300  +		}
          301  +
          302  +		free(ids[currId].id);
          303  +
          304  +		ids[currId].initialized = 0;
          305  +	}
          306  +
          307  +	free(ids);
          308  +
          309  +	free(slots);
          310  +
          311  +	return(foundCertificates);
          312  +}
          313  +
          314  +void cackey_chrome_freeCertificates(struct cackey_certificate *certificates, int certificatesCount) {
          315  +	int idx;
          316  +
          317  +	if (certificates == NULL) {
          318  +		return;
          319  +	}
          320  +
          321  +	for (idx = 0; idx < certificatesCount; idx++) {
          322  +		if (certificates[idx].certificate) {
          323  +			free(certificates[idx].certificate);
          324  +		}
          325  +	}
          326  +
          327  +	free(certificates);
          328  +
          329  +	return;
          330  +}
          331  +
          332  +cackey_chrome_returnType cackey_chrome_signMessage(struct cackey_certificate *certificate, void *data, unsigned long dataLength, unsigned char *destination, unsigned long *destinationLength, char **pinPrompt, char *pin) {
          333  +	CK_RV chk_rv;
          334  +	CK_ULONG numSlots, currSlot;
          335  +	CK_SLOT_ID_PTR slots;
          336  +	CK_SLOT_INFO slotInfo;
          337  +	CK_SESSION_HANDLE hSession;
          338  +	CK_OBJECT_HANDLE hObject, hKey;
          339  +	CK_ULONG ulObjectCount;
          340  +	CK_ATTRIBUTE searchTemplateCertificates[] = {
          341  +		{CKA_CLASS, NULL, sizeof(CK_OBJECT_CLASS)},
          342  +		{CKA_VALUE, NULL, 0}
          343  +	};
          344  +	CK_ATTRIBUTE searchTemplatePrivateKeys[] = {
          345  +		{CKA_CLASS, NULL, sizeof(CK_OBJECT_CLASS)},
          346  +		{CKA_ID, NULL, 0}
          347  +	};
          348  +	CK_ATTRIBUTE attrTemplateCertificate[] = {
          349  +		{CKA_ID, NULL, 0},
          350  +		{CKA_LABEL, NULL, 0}
          351  +	};
          352  +	CK_MECHANISM signMechanism = {CKM_RSA_PKCS, NULL, 0}; 
          353  +	CK_OBJECT_CLASS objectClassPrivateKey = CKO_PRIVATE_KEY;
          354  +	CK_OBJECT_CLASS objectClassCertificate = CKO_CERTIFICATE;
          355  +	CK_TOKEN_INFO tokenInfo;
          356  +	CK_ULONG tmpDestinationLength;
          357  +	char *certificateLabel;
          358  +	int foundPrivateKeyObject;
          359  +	cackey_chrome_returnType retval;
          360  +
          361  +	*pinPrompt = NULL;
          362  +
          363  +	retval = CACKEY_CHROME_ERROR;
          364  +
          365  +	chk_rv = cackey_chrome_init();
          366  +	if (chk_rv != CKR_OK) {
          367  +		return(retval);
          368  +	}
          369  +
          370  +	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, NULL, &numSlots);
          371  +	if (chk_rv != CKR_OK) {
          372  +		return(retval);
          373  +	}
          374  +
          375  +	slots = malloc(sizeof(*slots) * numSlots);
          376  +
          377  +	chk_rv = moduleFunctionList->C_GetSlotList(FALSE, slots, &numSlots);
          378  +	if (chk_rv != CKR_OK) {
          379  +		free(slots);
          380  +
          381  +		return(retval);
          382  +	}
          383  +
          384  +	searchTemplateCertificates[0].pValue = &objectClassCertificate;
          385  +	searchTemplatePrivateKeys[0].pValue = &objectClassPrivateKey;
          386  +
          387  +	searchTemplateCertificates[1].pValue = certificate->certificate;
          388  +	searchTemplateCertificates[1].ulValueLen = certificate->certificate_len;
          389  +
          390  +	foundPrivateKeyObject = 0;
          391  +
          392  +	certificateLabel = NULL;
          393  +
          394  +	for (currSlot = 0; currSlot < numSlots; currSlot++) {
          395  +		chk_rv = moduleFunctionList->C_GetSlotInfo(slots[currSlot], &slotInfo);
          396  +		if (chk_rv != CKR_OK) {
          397  +			continue;
          398  +		}
          399  +
          400  +		if ((slotInfo.flags & CKF_TOKEN_PRESENT) != CKF_TOKEN_PRESENT) {
          401  +			continue;
          402  +		}
          403  +
          404  +		chk_rv = moduleFunctionList->C_OpenSession(slots[currSlot], CKF_SERIAL_SESSION, NULL, NULL, &hSession);
          405  +		if (chk_rv != CKR_OK) {
          406  +			continue;
          407  +		}
          408  +
          409  +		chk_rv = moduleFunctionList->C_FindObjectsInit(hSession, searchTemplateCertificates, sizeof(searchTemplateCertificates) / sizeof(searchTemplateCertificates[0])); 
          410  +		if (chk_rv != CKR_OK) {
          411  +			moduleFunctionList->C_CloseSession(hSession);
          412  +
          413  +			continue;
          414  +		}
   107    415   
   108    416   		while (1) {
   109    417   			chk_rv = moduleFunctionList->C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
   110    418   			if (chk_rv != CKR_OK) {
   111    419   				break;
   112    420   			}
   113    421   
................................................................................
   115    423   				break;
   116    424   			}
   117    425   
   118    426   			if (ulObjectCount != 1) {
   119    427   				break;
   120    428   			}
   121    429   
   122         -			for (currAttrIndex = 0; currAttrIndex < (sizeof(attrTemplate) / sizeof(attrTemplate[0])); currAttrIndex++) {
   123         -				currAttr = &attrTemplate[currAttrIndex];
   124         -
   125         -				currAttr->pValue = NULL;
   126         -				currAttr->ulValueLen = 0;
   127         -			}
   128         -
   129         -			chk_rv = C_GetAttributeValue(hSession, hObject, attrTemplate, sizeof(attrTemplate) / sizeof(attrTemplate[0]));
   130         -			if (chk_rv == CKR_ATTRIBUTE_TYPE_INVALID || chk_rv == CKR_ATTRIBUTE_SENSITIVE || chk_rv == CKR_BUFFER_TOO_SMALL) {
   131         -				chk_rv = CKR_OK;
   132         -			}
   133         -
          430  +			chk_rv = cackey_chrome_GetAttributesFromTemplate(hSession, hObject, attrTemplateCertificate, sizeof(attrTemplateCertificate) / sizeof(attrTemplateCertificate[0]));
   134    431   			if (chk_rv != CKR_OK) {
   135    432   				continue;
   136    433   			}
   137    434   
   138         -			for (currAttrIndex = 0; currAttrIndex < (sizeof(attrTemplate) / sizeof(attrTemplate[0])); currAttrIndex++) {
   139         -				currAttr = &attrTemplate[currAttrIndex];
          435  +			searchTemplatePrivateKeys[1].pValue = attrTemplateCertificate[0].pValue;
          436  +			searchTemplatePrivateKeys[1].ulValueLen = attrTemplateCertificate[0].ulValueLen;
   140    437   
   141         -				if (currAttr->ulValueLen == 0) {
   142         -					continue;
   143         -				}
   144         -
   145         -				if (((CK_LONG) currAttr->ulValueLen) == ((CK_LONG) -1)) {
   146         -					continue;
   147         -				}
   148         -
   149         -				currAttr->pValue = malloc(currAttr->ulValueLen);
          438  +			if (attrTemplateCertificate[1].ulValueLen > 0 && attrTemplateCertificate[1].pValue != NULL) {
          439  +				certificateLabel = malloc(attrTemplateCertificate[1].ulValueLen + 1);
          440  +				memcpy(certificateLabel, attrTemplateCertificate[1].pValue, attrTemplateCertificate[1].ulValueLen);
          441  +				certificateLabel[attrTemplateCertificate[1].ulValueLen] = '\0';
   150    442   			}
   151    443   
   152         -			chk_rv = C_GetAttributeValue(hSession, hObject, attrTemplate, sizeof(attrTemplate) / sizeof(attrTemplate[0]));
   153         -			if (chk_rv != CKR_OK) {
   154         -				continue;
   155         -			}
   156         -
          444  +			break;
   157    445   		}
   158    446   
   159    447   		moduleFunctionList->C_FindObjectsFinal(hSession);
          448  +
          449  +		if (searchTemplatePrivateKeys[1].pValue != NULL) {
          450  +			chk_rv = moduleFunctionList->C_FindObjectsInit(hSession, searchTemplateCertificates, sizeof(searchTemplateCertificates) / sizeof(searchTemplateCertificates[0])); 
          451  +			if (chk_rv == CKR_OK) {
          452  +				while (1) {
          453  +					chk_rv = moduleFunctionList->C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
          454  +					if (chk_rv != CKR_OK) {
          455  +						break;
          456  +					}
          457  +
          458  +					if (ulObjectCount == 0) {
          459  +						break;
          460  +					}
          461  +
          462  +					if (ulObjectCount != 1) {
          463  +						break;
          464  +					}
          465  +
          466  +					hKey = hObject;
          467  +
          468  +					foundPrivateKeyObject = 1;
          469  +
          470  +					break;
          471  +				}
          472  +
          473  +				moduleFunctionList->C_FindObjectsFinal(hSession);
          474  +			}
          475  +
          476  +			free(searchTemplatePrivateKeys[1].pValue);
          477  +
          478  +		}
          479  +
          480  +		if (foundPrivateKeyObject) {
          481  +			chk_rv = moduleFunctionList->C_SignInit(hSession, &signMechanism, hKey);
          482  +			if (chk_rv != CKR_OK) {
          483  +				break;
          484  +			}
          485  +
          486  +			tmpDestinationLength = *destinationLength;
          487  +			chk_rv = moduleFunctionList->C_Sign(hSession, data, dataLength, destination, &tmpDestinationLength);
          488  +			switch (chk_rv) {
          489  +				case CKR_OK:
          490  +					*destinationLength = tmpDestinationLength;
          491  +					retval = CACKEY_CHROME_OK;
          492  +					break;
          493  +				case CKR_USER_NOT_LOGGED_IN:
          494  +					chk_rv = moduleFunctionList->C_GetTokenInfo(slots[currSlot], &tokenInfo);
          495  +					if (chk_rv == CKR_OK) {
          496  +						if ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == CKF_PROTECTED_AUTHENTICATION_PATH) {
          497  +							retval = CACKEY_CHROME_NEEDPROTECTEDLOGIN;
          498  +						} else {
          499  +							retval = CACKEY_CHROME_NEEDLOGIN;
          500  +
          501  +							*pinPrompt = malloc(1024);
          502  +							if (certificateLabel) {
          503  +								snprintf(*pinPrompt, 1024, "Please enter the PIN for %s:%s", tokenInfo.label, certificateLabel);
          504  +							} else {
          505  +								snprintf(*pinPrompt, 1024, "Please enter the PIN for %s", tokenInfo.label);
          506  +							}
          507  +						}
          508  +					} else {
          509  +						retval = CACKEY_CHROME_NEEDLOGIN;
          510  +
          511  +						*pinPrompt = strdup("Please enter your Smartcard PIN");
          512  +					}
          513  +
          514  +					if (retval == CACKEY_CHROME_NEEDPROTECTEDLOGIN) {
          515  +						retval = CACKEY_CHROME_ERROR;
          516  +
          517  +						chk_rv = moduleFunctionList->C_Login(hSession, CKU_USER, NULL, 0);
          518  +					} else {
          519  +						if (pin) {
          520  +							retval = CACKEY_CHROME_ERROR;
          521  +
          522  +							free(*pinPrompt);
          523  +							*pinPrompt = NULL;
          524  +
          525  +							chk_rv = moduleFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR_PTR) pin, strlen(pin));
          526  +						} else {
          527  +							chk_rv = CKR_GENERAL_ERROR;
          528  +						}
          529  +					}
          530  +
          531  +					if (chk_rv == CKR_OK && retval == CACKEY_CHROME_ERROR) {
          532  +						chk_rv = moduleFunctionList->C_SignInit(hSession, &signMechanism, hKey);
          533  +						if (chk_rv != CKR_OK) {
          534  +							break;
          535  +						}
          536  +
          537  +						tmpDestinationLength = *destinationLength;
          538  +						chk_rv = moduleFunctionList->C_Sign(hSession, data, dataLength, destination, &tmpDestinationLength);
          539  +						switch (chk_rv) {
          540  +							case CKR_OK:
          541  +								*destinationLength = tmpDestinationLength;
          542  +								retval = CACKEY_CHROME_OK;
          543  +								break;
          544  +							case CKR_USER_NOT_LOGGED_IN:
          545  +								retval = CACKEY_CHROME_NEEDLOGIN;
          546  +								break;
          547  +							default:
          548  +								retval = CACKEY_CHROME_ERROR;
          549  +								break;
          550  +						}
          551  +					}
          552  +
          553  +					break;
          554  +				default:
          555  +					retval = CACKEY_CHROME_ERROR;
          556  +					break;
          557  +			}
          558  +
          559  +			break;
          560  +		}
   160    561   
   161    562   		moduleFunctionList->C_CloseSession(hSession);
   162    563   	}
   163    564   
   164         -	return(0);
          565  +	free(slots);
          566  +
          567  +	if (certificateLabel) {
          568  +		free(certificateLabel);
          569  +	}
          570  +
          571  +	return(retval);
   165    572   }
   166    573   
   167    574   #ifdef __cplusplus
   168    575   }
   169    576   #endif