Overview
Comment: | Added routines for reading certificates
Updated OpenSession to use PC/SC certificates Comment and debugging update Updated to read in larger chunks to improve speed |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 06e07b8f0d3c1eeaa1618082d4f00bba6219717d |
User & Date: | rkeene on 2010-05-12 21:52:55 |
Other Links: | manifest | tags |
Context
2010-05-12
| ||
23:58 |
Moved certificate examination to occur during search initialization
Added support for logging in via PC/SC in C_Login() check-in: 0c536f15c1 user: rkeene tags: trunk | |
21:52 |
Added routines for reading certificates
Updated OpenSession to use PC/SC certificates Comment and debugging update Updated to read in larger chunks to improve speed check-in: 06e07b8f0d user: rkeene tags: trunk | |
19:35 |
Updated ignores
Updated read_tlv to return a list Added a free_tlv function Updated value->str conversion functions to be more flexible/direct Added sample code to select all PKI applets/files Simplified TLV entity check-in: 330efa4f3b user: rkeene tags: trunk | |
Changes
Modified cackey.c from [e9e3a11241] to [80414011fe].
53 53 # define CKA_TRUST_CODE_SIGNING 0xce53635a 54 54 #endif 55 55 #ifndef CKA_TRUST_EMAIL_PROTECTION 56 56 # define CKA_TRUST_EMAIL_PROTECTION 0xce53635b 57 57 #endif 58 58 59 59 /* GSC-IS v2.1 Definitions */ 60 +/** Classes **/ 60 61 #define GSCIS_CLASS_ISO7816 0x00 61 62 #define GSCIS_CLASS_GLOBAL_PLATFORM 0x80 62 63 64 +/** Instructions **/ 63 65 #define GSCIS_INSTR_GET_RESPONSE 0xC0 64 66 #define GSCIS_INSTR_READ_BINARY 0xB0 65 67 #define GSCIS_INSTR_UPDATE_BINARY 0xD6 66 68 #define GSCIS_INSTR_SELECT 0xA4 67 69 #define GSCIS_INSTR_EXTERNAL_AUTH 0x82 68 70 #define GSCIS_INSTR_GET_CHALLENGE 0x84 69 71 #define GSCIS_INSTR_INTERNAL_AUTH 0x88 ................................................................................ 72 74 #define GSCIS_INSTR_GET_PROP 0x56 73 75 #define GSCIS_INSTR_GET_ACR 0x4C 74 76 #define GSCIS_INSTR_READ_BUFFER 0x52 75 77 #define GSCIS_INSTR_SIGNDECRYPT 0x42 76 78 77 79 #define GSCIS_PARAM_SELECT_APPLET 0x04 78 80 79 -/* CCC */ 81 +/** Tags **/ 82 +/*** CCC Tags ***/ 80 83 #define GSCIS_TAG_CARDID 0xF0 81 84 #define GSCIS_TAG_CCC_VER 0xF1 82 85 #define GSCIS_TAG_CCG_VER 0xF2 83 86 #define GSCIS_TAG_CARDURL 0xF3 84 87 #define GSCIS_TAG_PKCS15 0xF4 85 88 #define GSCIS_TAG_REG_DATA_MODEL 0xF5 86 89 #define GSCIS_TAG_ACR_TABLE 0xF6 87 90 #define GSCIS_TAG_CARD_APDU 0xF7 88 91 #define GSCIS_TAG_REDIRECTION 0xFA 89 92 #define GSCIS_TAG_CT 0xFB 90 93 #define GSCIS_TAG_ST 0xFC 91 94 #define GSCIS_TAG_NEXTCCC 0xFD 92 95 93 -/* General - EF 2200 */ 96 +/*** General - EF 2200 ***/ 94 97 #define GSCIS_TAG_FNAME 0x01 95 98 #define GSCIS_TAG_MNAME 0x02 96 99 #define GSCIS_TAG_LNAME 0x03 97 100 #define GSCIS_TAG_SUFFIX 0x04 98 101 #define GSCIS_TAG_GOVT_AGENCY 0x05 99 102 #define GSCIS_TAG_BUREAU 0x06 100 103 #define GSCIS_TAG_BUREAU_CODE 0x07 ................................................................................ 111 114 #define GSCIS_TAG_OFFICE_PHONE_EXT 0x18 112 115 #define GSCIS_TAG_OFFICE_FAX 0x19 113 116 #define GSCIS_TAG_OFFICE_EMAIL 0x1A 114 117 #define GSCIS_TAG_OFFICE_ROOM 0x1B 115 118 #define GSCIS_TAG_NONGOV_AGENCY 0x1C 116 119 #define GSCIS_TAG_SSN_DESIGNATOR 0x1D 117 120 118 -/* PII - EF 2100 */ 121 +/*** PII - EF 2100 ***/ 119 122 #define GSCIS_TAG_SSN 0x20 120 123 #define GSCIS_TAG_DOB 0x21 121 124 #define GSCIS_TAG_GENDER 0x22 122 125 123 -/* Login Information - EF 4000 */ 126 +/*** Login Information - EF 4000 ***/ 124 127 #define GSCIS_TAG_USERID 0x40 125 128 #define GSCIS_TAG_DOMAIN 0x41 126 129 #define GSCIS_TAG_PASSWORD 0x42 127 130 128 -/* Card Information - EF 5000 */ 131 +/*** Card Information - EF 5000 ***/ 129 132 #define GSCIS_TAG_ISSUERID 0x50 130 133 #define GSCIS_TAG_SERNO 0x51 131 134 #define GSCIS_TAG_ISSUE_DATE 0x52 132 135 #define GSCIS_TAG_EXPIRE_DATE 0x53 133 136 #define GSCIS_TAG_CARD_TYPE 0x54 134 137 #define GSCIS_TAG_SECURITY_CODE 0x57 135 138 #define GSCIS_TAG_CARDID_AID 0x58 136 139 137 -/* PKI Information - EF 7000 */ 140 +/*** PKI Information - EF 7000 ***/ 138 141 #define GSCIS_TAG_CERTIFICATE 0x70 139 142 #define GSCIS_TAG_CERT_ISSUE_DATE 0x71 140 143 #define GSCIS_TAG_CERT_EXPIRE_DATE 0x72 141 144 145 +/** Applet IDs **/ 146 +#define GSCIS_AID_CCC 0xA0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00 147 + 142 148 #ifdef CACKEY_DEBUG 143 149 # ifdef HAVE_STDIO_H 144 150 # include <stdio.h> 145 151 # endif 146 152 147 153 # define CACKEY_DEBUG_PRINTF(x...) { fprintf(stderr, "%s(): ", __func__); fprintf(stderr, x); fprintf(stderr, "\n"); } 148 154 # define CACKEY_DEBUG_PRINTBUF(f, x, y) { unsigned char *buf; unsigned long idx; buf = (unsigned char *) (x); fprintf(stderr, "%s(): %s (%s/%lu = {%02x", __func__, f, #x, (unsigned long) (y), buf[0]); for (idx = 1; idx < (y); idx++) { fprintf(stderr, ", %02x", buf[idx]); }; fprintf(stderr, "})\n"); } ................................................................................ 386 392 } 387 393 388 394 return("UNKNOWN"); 389 395 } 390 396 391 397 static const char *CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(uint8_t apptype) { 392 398 switch (apptype) { 399 + case 0x00: 400 + return("NONE"); 393 401 case 0x01: 394 402 return("CACKEY_TLV_APP_GENERIC"); 395 403 case 0x02: 396 404 return("CACKEY_TLV_APP_SKI"); 397 405 case 0x03: 398 406 return("CACKEY_TLV_APP_GENERIC | CACKEY_TLV_APP_SKI"); 399 407 case 0x04: ................................................................................ 416 424 # define CACKEY_DEBUG_PRINTBUF(f, x, y) /**/ 417 425 # define CACKEY_DEBUG_PERROR(x) /**/ 418 426 # define CACKEY_DEBUG_FUNC_TAG_TO_STR(x) "DEBUG_DISABLED" 419 427 # define CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(x) "DEBUG_DISABLED" 420 428 # define CACKEY_DEBUG_FUNC_OBJID_TO_STR(x) "DEBUG_DISABLED" 421 429 # define CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(x) "DEBUG_DISABLED" 422 430 #endif 431 + 432 +struct cackey_pcsc_identity { 433 + unsigned char applet[7]; 434 + uint16_t file; 435 + 436 + unsigned char *label; 437 + 438 + size_t certificate_len; 439 + unsigned char *certificate; 440 +}; 423 441 424 442 struct cackey_identity { 443 + struct cackey_pcsc_identity *identity; 444 + 425 445 CK_ATTRIBUTE *attributes; 426 446 CK_ULONG attributes_count; 427 447 }; 428 448 429 449 struct cackey_session { 430 450 int active; 431 451 ................................................................................ 813 833 814 834 static ssize_t cackey_read_buffer(struct cackey_slot *slot, unsigned char *buffer, size_t count, unsigned char t_or_v, size_t initial_offset) { 815 835 size_t offset = 0, max_offset, max_count; 816 836 unsigned char cmd[2]; 817 837 uint16_t respcode; 818 838 int send_ret; 819 839 820 - CACKEY_DEBUG_PRINTF("Called"); 840 + CACKEY_DEBUG_PRINTF("Called."); 821 841 822 842 max_offset = count; 823 - max_count = 64; 843 + max_count = 252; 824 844 825 845 cmd[0] = t_or_v; 826 846 827 847 while (1) { 828 848 if (offset >= max_offset) { 829 849 CACKEY_DEBUG_PRINTF("Buffer too small, returning what we got..."); 830 850 ................................................................................ 868 888 869 889 return(offset); 870 890 } 871 891 872 892 static int cackey_select_applet(struct cackey_slot *slot, unsigned char *aid, size_t aid_len) { 873 893 int send_ret; 874 894 875 - CACKEY_DEBUG_PRINTF("Called"); 895 + CACKEY_DEBUG_PRINTF("Called."); 876 896 877 897 CACKEY_DEBUG_PRINTBUF("Selecting applet:", aid, aid_len); 878 898 879 899 send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_SELECT, GSCIS_PARAM_SELECT_APPLET, 0x0C, aid_len, aid, 0x00, NULL, NULL, NULL); 880 900 if (send_ret < 0) { 881 901 CACKEY_DEBUG_PRINTF("Failed to open applet, returning in failure"); 882 902 ................................................................................ 888 908 return(0); 889 909 } 890 910 891 911 static int cackey_select_file(struct cackey_slot *slot, uint16_t ef) { 892 912 unsigned char fid_buf[2]; 893 913 int send_ret; 894 914 895 - CACKEY_DEBUG_PRINTF("Called"); 915 + CACKEY_DEBUG_PRINTF("Called."); 896 916 897 917 /* Open the elementary file */ 898 918 fid_buf[0] = (ef >> 8) & 0xff; 899 919 fid_buf[1] = ef & 0xff; 920 + 921 + CACKEY_DEBUG_PRINTF("Selecting file: %04lx", (unsigned long) ef); 900 922 901 923 send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_SELECT, 0x02, 0x0C, sizeof(fid_buf), fid_buf, 0x00, NULL, NULL, NULL); 902 924 if (send_ret < 0) { 903 925 CACKEY_DEBUG_PRINTF("Failed to open file, returning in failure"); 904 926 905 927 return(-1); 906 928 } ................................................................................ 908 930 CACKEY_DEBUG_PRINTF("Successfully selected file"); 909 931 910 932 return(0); 911 933 } 912 934 913 935 static void cackey_free_tlv(struct cackey_tlv_entity *root) { 914 936 struct cackey_tlv_entity *curr, *next; 937 + 938 + if (root == NULL) { 939 + return; 940 + } 915 941 916 942 for (curr = root; curr; curr = next) { 917 943 next = curr->_next; 918 944 919 945 switch (curr->tag) { 920 946 case GSCIS_TAG_ACR_TABLE: 947 + case GSCIS_TAG_CERTIFICATE: 921 948 if (curr->value) { 922 949 free(curr->value); 923 950 } 924 951 break; 925 952 case GSCIS_TAG_CARDURL: 926 953 if (curr->value_cardurl) { 927 954 free(curr->value_cardurl); ................................................................................ 942 969 unsigned char *tmpbuf; 943 970 ssize_t tlen, vlen; 944 971 ssize_t read_ret; 945 972 size_t offset_t = 0, offset_v = 0; 946 973 unsigned char tag; 947 974 size_t length; 948 975 949 - CACKEY_DEBUG_PRINTF("Called"); 976 + CACKEY_DEBUG_PRINTF("Called."); 950 977 951 978 read_ret = cackey_read_buffer(slot, tlen_buf, sizeof(tlen_buf), 1, offset_t); 952 979 if (read_ret != sizeof(tlen_buf)) { 953 980 CACKEY_DEBUG_PRINTF("Read failed, returning in failure"); 954 981 955 982 return(NULL); 956 983 } ................................................................................ 1044 1071 memcpy(tmpbuf, vval, length); 1045 1072 1046 1073 curr_entity->tag = tag; 1047 1074 curr_entity->length = length; 1048 1075 curr_entity->value = tmpbuf; 1049 1076 curr_entity->_next = NULL; 1050 1077 1078 + break; 1079 + case GSCIS_TAG_CERTIFICATE: 1080 + curr_entity = malloc(sizeof(*curr_entity)); 1081 + tmpbuf = malloc(length); 1082 + 1083 + memcpy(tmpbuf, vval, length); 1084 + 1085 + curr_entity->tag = tag; 1086 + curr_entity->length = length; 1087 + curr_entity->value = tmpbuf; 1088 + curr_entity->_next = NULL; 1089 + 1051 1090 break; 1052 1091 case GSCIS_TAG_PKCS15: 1053 1092 curr_entity = malloc(sizeof(*curr_entity)); 1054 1093 1055 1094 curr_entity->tag = tag; 1056 1095 curr_entity->value_byte = vval[0]; 1057 1096 curr_entity->_next = NULL; ................................................................................ 1070 1109 1071 1110 last = curr_entity; 1072 1111 } 1073 1112 } 1074 1113 1075 1114 return(root); 1076 1115 } 1116 + 1117 +static void cackey_free_certs(struct cackey_pcsc_identity *start, size_t count, int free_start) { 1118 + size_t idx; 1119 + 1120 + for (idx = 0; idx < count; idx++) { 1121 + if (start[idx].certificate) { 1122 + free(start[idx].certificate); 1123 + } 1124 + } 1125 + 1126 + if (free_start) { 1127 + free(start); 1128 + } 1129 + 1130 + return; 1131 +} 1132 + 1133 +static struct cackey_pcsc_identity *cackey_read_certs(struct cackey_slot *slot, struct cackey_pcsc_identity *certs, unsigned long *count) { 1134 + struct cackey_pcsc_identity *curr_id; 1135 + struct cackey_tlv_entity *ccc_tlv, *ccc_curr, *app_tlv, *app_curr; 1136 + unsigned char ccc_aid[] = {GSCIS_AID_CCC}; 1137 + unsigned char curr_aid[7]; 1138 + unsigned long outidx = 0; 1139 + int certs_resizable; 1140 + int send_ret, select_ret; 1141 + 1142 + CACKEY_DEBUG_PRINTF("Called."); 1143 + 1144 + if (count == NULL) { 1145 + CACKEY_DEBUG_PRINTF("count is NULL, returning in failure"); 1146 + 1147 + return(NULL); 1148 + } 1149 + 1150 + if (*count == 0) { 1151 + if (certs != NULL) { 1152 + CACKEY_DEBUG_PRINTF("Requested we return 0 objects, short-circuit"); 1153 + 1154 + return(certs); 1155 + } 1156 + } 1157 + 1158 + if (certs == NULL) { 1159 + certs = malloc(sizeof(*certs) * 5); 1160 + *count = 5; 1161 + certs_resizable = 1; 1162 + } else { 1163 + certs_resizable = 0; 1164 + } 1165 + 1166 + /* Select the CCC Applet */ 1167 + send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid)); 1168 + if (send_ret < 0) { 1169 + CACKEY_DEBUG_PRINTF("Unable to select CCC Applet, returning in failure"); 1170 + 1171 + return(NULL); 1172 + } 1173 + 1174 + /* Read all the applets from the CCC's TLV */ 1175 + ccc_tlv = cackey_read_tlv(slot); 1176 + 1177 + /* Look for CARDURLs that coorespond to PKI applets */ 1178 + for (ccc_curr = ccc_tlv; ccc_curr; ccc_curr = ccc_curr->_next) { 1179 + CACKEY_DEBUG_PRINTF("Found tag: %s ... ", CACKEY_DEBUG_FUNC_TAG_TO_STR(ccc_curr->tag)); 1180 + 1181 + if (ccc_curr->tag != GSCIS_TAG_CARDURL) { 1182 + CACKEY_DEBUG_PRINTF(" ... skipping it (we only care about CARDURLs)"); 1183 + 1184 + continue; 1185 + } 1186 + 1187 + if ((ccc_curr->value_cardurl->apptype & CACKEY_TLV_APP_PKI) != CACKEY_TLV_APP_PKI) { 1188 + CACKEY_DEBUG_PRINTF(" ... skipping it (we only care about PKI applets, this applet supports: %s/%02x)", CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(ccc_curr->value_cardurl->apptype), (unsigned int) ccc_curr->value_cardurl->apptype); 1189 + 1190 + continue; 1191 + } 1192 + 1193 + CACKEY_DEBUG_PRINTBUF("RID:", ccc_curr->value_cardurl->rid, sizeof(ccc_curr->value_cardurl->rid)); 1194 + CACKEY_DEBUG_PRINTF("AppID = %s/%04lx", CACKEY_DEBUG_FUNC_OBJID_TO_STR(ccc_curr->value_cardurl->appid), (unsigned long) ccc_curr->value_cardurl->appid); 1195 + CACKEY_DEBUG_PRINTF("ObjectID = %s/%04lx", CACKEY_DEBUG_FUNC_OBJID_TO_STR(ccc_curr->value_cardurl->objectid), (unsigned long) ccc_curr->value_cardurl->objectid); 1196 + 1197 + memcpy(curr_aid, ccc_curr->value_cardurl->rid, sizeof(ccc_curr->value_cardurl->rid)); 1198 + curr_aid[sizeof(curr_aid) - 2] = (ccc_curr->value_cardurl->appid >> 8) & 0xff; 1199 + curr_aid[sizeof(curr_aid) - 1] = ccc_curr->value_cardurl->appid & 0xff; 1200 + 1201 + /* Select found applet ... */ 1202 + select_ret = cackey_select_applet(slot, curr_aid, sizeof(curr_aid)); 1203 + if (select_ret < 0) { 1204 + CACKEY_DEBUG_PRINTF("Failed to select applet, skipping processing of this object"); 1205 + 1206 + continue; 1207 + } 1208 + 1209 + /* ... and object (file) */ 1210 + select_ret = cackey_select_file(slot, ccc_curr->value_cardurl->objectid); 1211 + if (select_ret < 0) { 1212 + CACKEY_DEBUG_PRINTF("Failed to select file, skipping processing of this object"); 1213 + 1214 + continue; 1215 + } 1216 + 1217 + /* Process this file's TLV looking for certificates */ 1218 + app_tlv = cackey_read_tlv(slot); 1219 + 1220 + for (app_curr = app_tlv; app_curr; app_curr = app_curr->_next) { 1221 + CACKEY_DEBUG_PRINTF("Found tag: %s", CACKEY_DEBUG_FUNC_TAG_TO_STR(app_curr->tag)); 1222 + if (app_curr->tag != GSCIS_TAG_CERTIFICATE) { 1223 + CACKEY_DEBUG_PRINTF(" ... skipping it (we only care about CERTIFICATEs)"); 1224 + 1225 + continue; 1226 + } 1227 + 1228 + curr_id = &certs[outidx]; 1229 + outidx++; 1230 + 1231 + memcpy(curr_id->applet, curr_aid, sizeof(curr_id->applet)); 1232 + curr_id->file = ccc_curr->value_cardurl->objectid; 1233 + curr_id->label = NULL; 1234 + 1235 + curr_id->certificate_len = app_curr->length; 1236 + 1237 + curr_id->certificate = malloc(curr_id->certificate_len); 1238 + memcpy(curr_id->certificate, app_curr->value, curr_id->certificate_len); 1239 + 1240 + if (outidx >= *count) { 1241 + if (certs_resizable) { 1242 + *count *= 2; 1243 + certs = realloc(certs, sizeof(*certs) * (*count)); 1244 + } else { 1245 + break; 1246 + } 1247 + } 1248 + } 1249 + 1250 + cackey_free_tlv(app_tlv); 1251 + 1252 + if (outidx >= *count) { 1253 + break; 1254 + } 1255 + } 1256 + 1257 + cackey_free_tlv(ccc_tlv); 1258 + 1259 + *count = outidx; 1260 + 1261 + if (certs_resizable) { 1262 + certs = realloc(certs, sizeof(*certs) * (*count)); 1263 + } 1264 + 1265 + return(certs); 1266 +} 1077 1267 1078 1268 /* Returns 1 if a token is in the specified slot, 0 otherwise */ 1079 1269 static int cackey_token_present(struct cackey_slot *slot) { 1080 - struct cackey_tlv_entity *tlvs, *curr; 1081 - unsigned char ccc_aid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00}; 1082 - unsigned char curr_aid[7]; 1270 + unsigned char ccc_aid[] = {GSCIS_AID_CCC}; 1083 1271 int send_ret; 1084 1272 1085 1273 /* Select the CCC Applet */ 1086 1274 send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid)); 1087 1275 if (send_ret < 0) { 1088 1276 return(0); 1089 1277 } 1090 1278 1091 - tlvs = cackey_read_tlv(slot); 1092 - 1093 - for (curr = tlvs; curr; curr = curr->_next) { 1094 - CACKEY_DEBUG_PRINTF("Found tag: %s", CACKEY_DEBUG_FUNC_TAG_TO_STR(curr->tag)); 1095 - switch (curr->tag) { 1096 - case GSCIS_TAG_CARDURL: 1097 - if ((curr->value_cardurl->apptype & CACKEY_TLV_APP_PKI) == CACKEY_TLV_APP_PKI) { 1098 - CACKEY_DEBUG_PRINTBUF("RID:", curr->value_cardurl->rid, sizeof(curr->value_cardurl->rid)); 1099 - CACKEY_DEBUG_PRINTF("AppID = %s/%04lx", CACKEY_DEBUG_FUNC_OBJID_TO_STR(curr->value_cardurl->appid), (unsigned long) curr->value_cardurl->appid); 1100 - CACKEY_DEBUG_PRINTF("ObjectID = %s/%04lx", CACKEY_DEBUG_FUNC_OBJID_TO_STR(curr->value_cardurl->objectid), (unsigned long) curr->value_cardurl->objectid); 1101 - 1102 - memcpy(curr_aid, curr->value_cardurl->rid, sizeof(curr->value_cardurl->rid)); 1103 - curr_aid[sizeof(curr_aid) - 2] = (curr->value_cardurl->appid >> 8) & 0xff; 1104 - curr_aid[sizeof(curr_aid) - 1] = curr->value_cardurl->appid & 0xff; 1105 - 1106 - cackey_select_applet(slot, curr_aid, sizeof(curr_aid)); 1107 - cackey_select_file(slot, curr->value_cardurl->objectid); 1108 - } 1109 - break; 1110 - } 1111 - } 1112 - 1113 - cackey_free_tlv(tlvs); 1114 - 1115 1279 return(1); 1116 1280 } 1117 1281 1118 1282 /* Returns 0 on success */ 1119 1283 static int cackey_mutex_create(void **mutex) { 1120 1284 pthread_mutex_t *pthread_mutex; 1121 1285 int pthread_retval; ................................................................................ 1220 1384 } 1221 1385 1222 1386 CACKEY_DEBUG_PRINTF("Returning sucessfully (0)"); 1223 1387 1224 1388 return(0); 1225 1389 } 1226 1390 1227 -static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, void *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) { 1391 +static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, struct cackey_pcsc_identity *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) { 1228 1392 static CK_BBOOL ck_true = 1; 1229 1393 static CK_BBOOL ck_false = 0; 1230 1394 CK_ULONG numattrs = 0, retval_count; 1231 1395 CK_ATTRIBUTE_TYPE curr_attr_type; 1232 1396 CK_ATTRIBUTE curr_attr, *retval; 1233 1397 CK_VOID_PTR pValue; 1234 1398 CK_ULONG ulValueLen; ................................................................................ 2121 2285 2122 2286 CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED); 2123 2287 2124 2288 return(CKR_FUNCTION_NOT_SUPPORTED); 2125 2289 } 2126 2290 2127 2291 CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession) { 2292 + struct cackey_pcsc_identity *pcsc_identities; 2128 2293 struct cackey_identity *identities; 2129 2294 unsigned long idx, num_ids, id_idx, curr_id_type; 2130 -#if 0 2131 - CK_BYTE sigbuf[1024]; 2132 - ssize_t sigbuflen; 2133 -#endif 2295 + unsigned long num_certs, cert_idx; 2134 2296 int mutex_retval; 2135 2297 int found_session = 0; 2136 2298 2137 2299 CACKEY_DEBUG_PRINTF("Called."); 2138 2300 2139 2301 if (slotID < 0 || slotID >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) { 2140 2302 CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), outside of valid range", slotID); ................................................................................ 2155 2317 if (!cackey_initialized) { 2156 2318 CACKEY_DEBUG_PRINTF("Error. Not initialized."); 2157 2319 2158 2320 return(CKR_CRYPTOKI_NOT_INITIALIZED); 2159 2321 } 2160 2322 2161 2323 /* Verify that the card is actually in the slot. */ 2162 - /* XXX: Talk to card */ 2163 - if (0) { 2164 - if (0) { 2324 + if (!cackey_token_present(&cackey_slots[slotID])) { 2165 2325 CACKEY_DEBUG_PRINTF("Error. Card not present. Returning CKR_DEVICE_REMOVED"); 2166 2326 2167 2327 return(CKR_DEVICE_REMOVED); 2168 2328 } 2169 - } 2170 2329 2171 2330 mutex_retval = cackey_mutex_lock(cackey_biglock); 2172 2331 if (mutex_retval != 0) { 2173 2332 CACKEY_DEBUG_PRINTF("Error. Locking failed."); 2174 2333 2175 2334 return(CKR_GENERAL_ERROR); 2176 2335 } ................................................................................ 2188 2347 cackey_sessions[idx].ulDeviceError = 0; 2189 2348 cackey_sessions[idx].pApplication = pApplication; 2190 2349 cackey_sessions[idx].Notify = notify; 2191 2350 2192 2351 cackey_sessions[idx].identities = NULL; 2193 2352 cackey_sessions[idx].identities_count = 0; 2194 2353 2195 - if (0) { 2196 - num_ids = 0; 2197 - /* XXX: Determine number of IDs */ 2198 - 2354 + pcsc_identities = cackey_read_certs(&cackey_slots[slotID], NULL, &num_certs); 2355 + if (pcsc_identities != NULL) { 2199 2356 /* Convert number of IDs to number of objects */ 2200 - num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_ids; 2357 + num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs; 2201 2358 2202 2359 identities = malloc(num_ids * sizeof(*identities)); 2203 2360 2204 2361 id_idx = 0; 2205 - for (;;) { 2362 + for (cert_idx = 0; cert_idx < num_certs; cert_idx++) { 2206 2363 for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) { 2207 - /* XXX: Determine base index */ 2208 - 2209 - identities[id_idx].attributes = cackey_get_attributes(curr_id_type, NULL, -1, &identities[id_idx].attributes_count); 2364 + identities[id_idx].attributes = cackey_get_attributes(curr_id_type, &pcsc_identities[cert_idx], -1, &identities[id_idx].attributes_count); 2210 2365 2211 2366 if (identities[id_idx].attributes == NULL) { 2212 2367 identities[id_idx].attributes_count = 0; 2213 2368 } 2214 2369 2215 2370 id_idx++; 2216 2371 } 2217 2372 } 2218 2373 2219 2374 cackey_sessions[idx].identities = identities; 2220 2375 cackey_sessions[idx].identities_count = num_ids; 2376 + 2377 + cackey_free_certs(pcsc_identities, num_certs, 1); 2221 2378 } 2222 2379 2223 2380 cackey_sessions[idx].search_active = 0; 2224 2381 2225 2382 cackey_sessions[idx].sign_active = 0; 2226 2383 2227 2384 cackey_sessions[idx].decrypt_active = 0;