Overview
Comment: | Simplified some slot disconnect logic and updated to store an ID type hint on the slot itself so that if we reinitialize we treat it as the same type of device |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | fdd66a54cd37656c39bdcdb06e698840f89d4a02 |
User & Date: | rkeene on 2016-02-16 23:24:33 |
Other Links: | manifest | tags |
Context
2016-02-19
| ||
13:30 | ChromeOS: Added package icon check-in: e1dc965e9b user: rkeene tags: trunk | |
2016-02-16
| ||
23:24 | Simplified some slot disconnect logic and updated to store an ID type hint on the slot itself so that if we reinitialize we treat it as the same type of device check-in: fdd66a54cd user: rkeene tags: trunk | |
17:04 | Added workaround for Google's PCSC where we cannot determine the amount of space required to hold the reader list automatically check-in: 6218cc54fc user: rkeene tags: trunk | |
Changes
Modified cackey.c from [ebe379d38c] to [6db8eb96eb].
813 813 814 814 unsigned char *label; 815 815 816 816 DWORD protocol; 817 817 818 818 unsigned int cached_certs_count; 819 819 struct cackey_pcsc_identity *cached_certs; 820 + 821 + cackey_pcsc_id_type id_type_hint; 820 822 }; 821 823 822 824 typedef enum { 823 825 CACKEY_TLV_APP_GENERIC = 0x01, 824 826 CACKEY_TLV_APP_SKI = 0x02, 825 827 CACKEY_TLV_APP_PKI = 0x04 826 828 } cackey_tlv_apptype; ................................................................................ 934 936 935 937 return(retval); 936 938 } 937 939 938 940 /* PC/SC Related Functions */ 939 941 /* 940 942 * SYNPOSIS 941 - * void cackey_slots_disconnect_all(void); 943 + * void cackey_slots_disconnect_all(int unitialize_all_readers); 942 944 * 943 945 * ARGUMENTS 944 - * None 946 + * int unitialize_all_readers Free the "pcsc_reader" object associated with 947 + * each slot (boolean) 945 948 * 946 949 * RETURN VALUE 947 950 * None 948 951 * 949 952 * NOTES 950 953 * This function disconnects from all cards. 951 954 * 952 955 */ 953 -static void cackey_slots_disconnect_all(void) { 956 +static void cackey_slots_disconnect_all(int unitialize_all_readers) { 954 957 uint32_t idx; 955 958 956 959 CACKEY_DEBUG_PRINTF("Called."); 957 960 958 961 for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { 959 962 if (cackey_slots[idx].internal) { 960 963 /* Skip internal slots */ ................................................................................ 968 971 } 969 972 970 973 if (cackey_slots[idx].label) { 971 974 free(cackey_slots[idx].label); 972 975 973 976 cackey_slots[idx].label = NULL; 974 977 } 978 + 979 + if (unitialize_all_readers || !cackey_slots[idx].active) { 980 + if (cackey_slots[idx].pcsc_reader) { 981 + free(cackey_slots[idx].pcsc_reader); 982 + 983 + cackey_slots[idx].pcsc_reader = NULL; 984 + } 985 + 986 + cackey_slots[idx].transaction_need_hw_lock = 0; 987 + cackey_slots[idx].transaction_depth = 0; 988 + cackey_slots[idx].id_type_hint = CACKEY_ID_TYPE_UNKNOWN; 989 + } else { 990 + if (cackey_slots[idx].transaction_depth > 0) { 991 + cackey_slots[idx].transaction_need_hw_lock = 1; 992 + } 993 + } 975 994 976 995 cackey_slots[idx].pcsc_card_connected = 0; 977 - cackey_slots[idx].transaction_depth = 0; 978 - cackey_slots[idx].transaction_need_hw_lock = 0; 979 996 980 997 if (cackey_slots[idx].active) { 981 998 CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx); 999 + 1000 + cackey_slots[idx].slot_reset = 1; 982 1001 } 983 - 984 - cackey_slots[idx].slot_reset = 1; 985 1002 } 986 1003 987 1004 CACKEY_DEBUG_PRINTF("Returning"); 988 1005 989 1006 return; 990 1007 } 991 1008 ................................................................................ 1014 1031 CACKEY_DEBUG_PRINTF("Called."); 1015 1032 1016 1033 if (cackey_pcsc_handle == NULL) { 1017 1034 cackey_pcsc_handle = malloc(sizeof(*cackey_pcsc_handle)); 1018 1035 if (cackey_pcsc_handle == NULL) { 1019 1036 CACKEY_DEBUG_PRINTF("Call to malloc() failed, returning in failure"); 1020 1037 1021 - cackey_slots_disconnect_all(); 1038 + cackey_slots_disconnect_all(0); 1022 1039 1023 1040 return(CACKEY_PCSC_E_GENERIC); 1024 1041 } 1025 1042 1026 1043 CACKEY_DEBUG_PRINTF("SCardEstablishContext() called"); 1027 1044 scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle); 1028 1045 if (scard_est_context_ret != SCARD_S_SUCCESS) { 1029 1046 CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret); 1030 1047 1031 1048 free(cackey_pcsc_handle); 1032 1049 cackey_pcsc_handle = NULL; 1033 1050 1034 - cackey_slots_disconnect_all(); 1051 + cackey_slots_disconnect_all(0); 1035 1052 1036 1053 return(CACKEY_PCSC_E_GENERIC); 1037 1054 } 1038 1055 } 1039 1056 1040 1057 #ifdef HAVE_SCARDISVALIDCONTEXT 1041 1058 CACKEY_DEBUG_PRINTF("SCardIsValidContext() called"); ................................................................................ 1047 1064 scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle); 1048 1065 if (scard_est_context_ret != SCARD_S_SUCCESS) { 1049 1066 CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret); 1050 1067 1051 1068 free(cackey_pcsc_handle); 1052 1069 cackey_pcsc_handle = NULL; 1053 1070 1054 - cackey_slots_disconnect_all(); 1071 + cackey_slots_disconnect_all(0); 1055 1072 1056 1073 return(CACKEY_PCSC_E_GENERIC); 1057 1074 } 1058 1075 1059 1076 CACKEY_DEBUG_PRINTF("Handle has been re-established"); 1060 1077 } 1061 1078 #endif ................................................................................ 1097 1114 1098 1115 cackey_pcsc_handle = NULL; 1099 1116 } 1100 1117 1101 1118 if (scard_rel_context_ret != SCARD_S_SUCCESS) { 1102 1119 return(CACKEY_PCSC_E_GENERIC); 1103 1120 } 1121 + 1122 + cackey_slots_disconnect_all(0); 1104 1123 1105 1124 return(CACKEY_PCSC_S_OK); 1106 1125 } 1107 1126 1108 1127 /* 1109 1128 * SYNPOSIS 1110 1129 * void cackey_mark_slot_reset(struct cackey_slot *slot); ................................................................................ 1490 1509 CACKEY_DEBUG_PRINTF("Called."); 1491 1510 1492 1511 if (!slot) { 1493 1512 CACKEY_DEBUG_PRINTF("Invalid slot specified."); 1494 1513 1495 1514 return(CACKEY_PCSC_E_GENERIC); 1496 1515 } 1516 + 1517 + if (respcode) { 1518 + *respcode = 0xffff; 1519 + } 1497 1520 1498 1521 pcsc_connect_ret = cackey_connect_card(slot); 1499 1522 if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { 1500 1523 CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in failure"); 1501 1524 1502 1525 return(CACKEY_PCSC_E_GENERIC); 1503 1526 } ................................................................................ 2138 2161 cackey_pcsc_id_type try_types[2], try_type; 2139 2162 int send_ret; 2140 2163 int idx; 2141 2164 2142 2165 CACKEY_DEBUG_PRINTF("Reselecting the root applet"); 2143 2166 2144 2167 if (type_hint == CACKEY_ID_TYPE_UNKNOWN) { 2145 - if (slot->cached_certs && slot->cached_certs_count > 0) { 2146 - type_hint = slot->cached_certs[0].id_type; 2147 - } 2168 + type_hint = slot->id_type_hint; 2148 2169 } 2170 + 2171 + slot->id_type_hint = CACKEY_ID_TYPE_UNKNOWN; 2149 2172 2150 2173 switch (type_hint) { 2151 2174 case CACKEY_ID_TYPE_PIV: 2152 2175 CACKEY_DEBUG_PRINTF("Trying to reselect the PIV root applet first"); 2153 2176 2154 2177 try_types[0] = CACKEY_ID_TYPE_PIV; 2155 2178 try_types[1] = CACKEY_ID_TYPE_CAC; ................................................................................ 2184 2207 2185 2208 if (send_ret == CACKEY_PCSC_S_OK) { 2186 2209 CACKEY_DEBUG_PRINTF("Successfully selected the %s applet -- setting the \"LOGIN REQUIRED\" flag on the token", 2187 2210 try_type == CACKEY_ID_TYPE_CAC ? "CAC" : "PIV" 2188 2211 ); 2189 2212 2190 2213 slot->token_flags = CKF_LOGIN_REQUIRED; 2214 + 2215 + slot->id_type_hint = try_type; 2191 2216 2192 2217 return(try_type); 2193 2218 } 2194 2219 } 2195 2220 2196 2221 CACKEY_DEBUG_PRINTF("Unable to select any applet, returning in failure"); 2197 2222 ................................................................................ 3158 3183 3159 3184 return(CACKEY_PCSC_E_TOKENABSENT); 3160 3185 } 3161 3186 3162 3187 CACKEY_DEBUG_PRINTF("Something went wrong during signing, resetting the slot and hoping for the best."); 3163 3188 3164 3189 cackey_pcsc_disconnect(); 3190 + 3165 3191 cackey_pcsc_connect(); 3192 + 3193 + cackey_detect_and_select_root_applet(slot, CACKEY_ID_TYPE_UNKNOWN); 3166 3194 3167 3195 return(CACKEY_PCSC_E_GENERIC); 3168 3196 } 3169 3197 3170 3198 tmpbuf += bytes_to_send; 3171 3199 tmpbuflen -= bytes_to_send; 3172 3200 ................................................................................ 4583 4611 cackey_slots[idx].pcsc_reader = NULL; 4584 4612 cackey_slots[idx].transaction_depth = 0; 4585 4613 cackey_slots[idx].transaction_need_hw_lock = 0; 4586 4614 cackey_slots[idx].slot_reset = 0; 4587 4615 cackey_slots[idx].token_flags = 0; 4588 4616 cackey_slots[idx].label = NULL; 4589 4617 cackey_slots[idx].internal = 0; 4618 + cackey_slots[idx].id_type_hint = CACKEY_ID_TYPE_UNKNOWN; 4590 4619 } 4591 4620 4592 4621 #ifdef CACKEY_NO_EXTRA_CERTS 4593 4622 if (getenv("CACKEY_EXTRA_CERTS") != NULL) { 4594 4623 include_dod_certs = 1; 4595 4624 } else { 4596 4625 include_dod_certs = 0; ................................................................................ 4702 4731 4703 4732 for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) { 4704 4733 if (cackey_sessions[idx].active) { 4705 4734 C_CloseSession(idx); 4706 4735 } 4707 4736 } 4708 4737 4709 - cackey_slots_disconnect_all(); 4738 + cackey_slots_disconnect_all(1); 4710 4739 4711 4740 for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { 4712 4741 if (cackey_slots[idx].internal) { 4713 4742 continue; 4714 4743 } 4715 4744 4716 - if (cackey_slots[idx].pcsc_reader) { 4717 - free(cackey_slots[idx].pcsc_reader); 4718 - } 4719 - 4720 4745 if (cackey_slots[idx].cached_certs) { 4721 4746 cackey_free_certs(cackey_slots[idx].cached_certs, cackey_slots[idx].cached_certs_count, 1); 4722 4747 4723 4748 cackey_slots[idx].cached_certs = NULL; 4724 4749 } 4725 4750 } 4726 4751 ................................................................................ 4851 4876 } 4852 4877 } 4853 4878 4854 4879 if (slot_reset) { 4855 4880 CACKEY_DEBUG_PRINTF("Purging all slot information."); 4856 4881 4857 4882 /* Only update the list of slots if we are actually being supply the slot information */ 4858 - cackey_slots_disconnect_all(); 4883 + cackey_slots_disconnect_all(1); 4859 4884 4860 4885 for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { 4861 4886 if (cackey_slots[currslot].internal) { 4862 4887 continue; 4863 4888 } 4864 4889 4865 - if (cackey_slots[currslot].pcsc_reader) { 4866 - free(cackey_slots[currslot].pcsc_reader); 4867 - 4868 - cackey_slots[currslot].pcsc_reader = NULL; 4869 - } 4870 - 4871 - if (cackey_slots[currslot].label) { 4872 - free(cackey_slots[currslot].label); 4873 - 4874 - cackey_slots[currslot].label = NULL; 4875 - } 4876 - 4877 4890 cackey_slots[currslot].active = 0; 4878 4891 } 4879 4892 } 4880 4893 } 4881 4894 4882 4895 /* Determine list of readers */ 4883 4896 pcsc_connect_ret = cackey_pcsc_connect();