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: |
fdd66a54cd37656c39bdcdb06e698840 |
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 814 815 816 817 818 819 820 821 822 823 824 825 826 | unsigned char *label; DWORD protocol; unsigned int cached_certs_count; struct cackey_pcsc_identity *cached_certs; }; typedef enum { CACKEY_TLV_APP_GENERIC = 0x01, CACKEY_TLV_APP_SKI = 0x02, CACKEY_TLV_APP_PKI = 0x04 } cackey_tlv_apptype; | > > | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 | unsigned char *label; DWORD protocol; unsigned int cached_certs_count; struct cackey_pcsc_identity *cached_certs; cackey_pcsc_id_type id_type_hint; }; typedef enum { CACKEY_TLV_APP_GENERIC = 0x01, CACKEY_TLV_APP_SKI = 0x02, CACKEY_TLV_APP_PKI = 0x04 } cackey_tlv_apptype; |
︙ | ︙ | |||
934 935 936 937 938 939 940 | return(retval); } /* PC/SC Related Functions */ /* * SYNPOSIS | | > | | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 | return(retval); } /* PC/SC Related Functions */ /* * SYNPOSIS * void cackey_slots_disconnect_all(int unitialize_all_readers); * * ARGUMENTS * int unitialize_all_readers Free the "pcsc_reader" object associated with * each slot (boolean) * * RETURN VALUE * None * * NOTES * This function disconnects from all cards. * */ static void cackey_slots_disconnect_all(int unitialize_all_readers) { uint32_t idx; CACKEY_DEBUG_PRINTF("Called."); for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { if (cackey_slots[idx].internal) { /* Skip internal slots */ |
︙ | ︙ | |||
968 969 970 971 972 973 974 975 | } if (cackey_slots[idx].label) { free(cackey_slots[idx].label); cackey_slots[idx].label = NULL; } | > > > > | > > > | > > > | > > > > | < | > | 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | } if (cackey_slots[idx].label) { free(cackey_slots[idx].label); cackey_slots[idx].label = NULL; } if (unitialize_all_readers || !cackey_slots[idx].active) { if (cackey_slots[idx].pcsc_reader) { free(cackey_slots[idx].pcsc_reader); cackey_slots[idx].pcsc_reader = NULL; } cackey_slots[idx].transaction_need_hw_lock = 0; cackey_slots[idx].transaction_depth = 0; cackey_slots[idx].id_type_hint = CACKEY_ID_TYPE_UNKNOWN; } else { if (cackey_slots[idx].transaction_depth > 0) { cackey_slots[idx].transaction_need_hw_lock = 1; } } cackey_slots[idx].pcsc_card_connected = 0; if (cackey_slots[idx].active) { CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx); cackey_slots[idx].slot_reset = 1; } } CACKEY_DEBUG_PRINTF("Returning"); return; } |
︙ | ︙ | |||
1014 1015 1016 1017 1018 1019 1020 | CACKEY_DEBUG_PRINTF("Called."); if (cackey_pcsc_handle == NULL) { cackey_pcsc_handle = malloc(sizeof(*cackey_pcsc_handle)); if (cackey_pcsc_handle == NULL) { CACKEY_DEBUG_PRINTF("Call to malloc() failed, returning in failure"); | | | | | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 | CACKEY_DEBUG_PRINTF("Called."); if (cackey_pcsc_handle == NULL) { cackey_pcsc_handle = malloc(sizeof(*cackey_pcsc_handle)); if (cackey_pcsc_handle == NULL) { CACKEY_DEBUG_PRINTF("Call to malloc() failed, returning in failure"); cackey_slots_disconnect_all(0); return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("SCardEstablishContext() called"); scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle); if (scard_est_context_ret != SCARD_S_SUCCESS) { 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); free(cackey_pcsc_handle); cackey_pcsc_handle = NULL; cackey_slots_disconnect_all(0); return(CACKEY_PCSC_E_GENERIC); } } #ifdef HAVE_SCARDISVALIDCONTEXT CACKEY_DEBUG_PRINTF("SCardIsValidContext() called"); scard_isvalid_ret = SCardIsValidContext(*cackey_pcsc_handle); if (scard_isvalid_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %s/%li), trying to re-establish...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_isvalid_ret), (long) scard_isvalid_ret); CACKEY_DEBUG_PRINTF("SCardEstablishContext() called"); scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle); if (scard_est_context_ret != SCARD_S_SUCCESS) { 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); free(cackey_pcsc_handle); cackey_pcsc_handle = NULL; cackey_slots_disconnect_all(0); return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("Handle has been re-established"); } #endif |
︙ | ︙ | |||
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 | cackey_pcsc_handle = NULL; } if (scard_rel_context_ret != SCARD_S_SUCCESS) { return(CACKEY_PCSC_E_GENERIC); } return(CACKEY_PCSC_S_OK); } /* * SYNPOSIS * void cackey_mark_slot_reset(struct cackey_slot *slot); | > > | 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 | cackey_pcsc_handle = NULL; } if (scard_rel_context_ret != SCARD_S_SUCCESS) { return(CACKEY_PCSC_E_GENERIC); } cackey_slots_disconnect_all(0); return(CACKEY_PCSC_S_OK); } /* * SYNPOSIS * void cackey_mark_slot_reset(struct cackey_slot *slot); |
︙ | ︙ | |||
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | CACKEY_DEBUG_PRINTF("Called."); if (!slot) { CACKEY_DEBUG_PRINTF("Invalid slot specified."); return(CACKEY_PCSC_E_GENERIC); } pcsc_connect_ret = cackey_connect_card(slot); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in failure"); return(CACKEY_PCSC_E_GENERIC); } | > > > > | 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | CACKEY_DEBUG_PRINTF("Called."); if (!slot) { CACKEY_DEBUG_PRINTF("Invalid slot specified."); return(CACKEY_PCSC_E_GENERIC); } if (respcode) { *respcode = 0xffff; } pcsc_connect_ret = cackey_connect_card(slot); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in failure"); return(CACKEY_PCSC_E_GENERIC); } |
︙ | ︙ | |||
2138 2139 2140 2141 2142 2143 2144 | cackey_pcsc_id_type try_types[2], try_type; int send_ret; int idx; CACKEY_DEBUG_PRINTF("Reselecting the root applet"); if (type_hint == CACKEY_ID_TYPE_UNKNOWN) { | < | | | > | 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 | cackey_pcsc_id_type try_types[2], try_type; int send_ret; int idx; CACKEY_DEBUG_PRINTF("Reselecting the root applet"); if (type_hint == CACKEY_ID_TYPE_UNKNOWN) { type_hint = slot->id_type_hint; } slot->id_type_hint = CACKEY_ID_TYPE_UNKNOWN; switch (type_hint) { case CACKEY_ID_TYPE_PIV: CACKEY_DEBUG_PRINTF("Trying to reselect the PIV root applet first"); try_types[0] = CACKEY_ID_TYPE_PIV; try_types[1] = CACKEY_ID_TYPE_CAC; |
︙ | ︙ | |||
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 | if (send_ret == CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Successfully selected the %s applet -- setting the \"LOGIN REQUIRED\" flag on the token", try_type == CACKEY_ID_TYPE_CAC ? "CAC" : "PIV" ); slot->token_flags = CKF_LOGIN_REQUIRED; return(try_type); } } CACKEY_DEBUG_PRINTF("Unable to select any applet, returning in failure"); | > > | 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 | if (send_ret == CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Successfully selected the %s applet -- setting the \"LOGIN REQUIRED\" flag on the token", try_type == CACKEY_ID_TYPE_CAC ? "CAC" : "PIV" ); slot->token_flags = CKF_LOGIN_REQUIRED; slot->id_type_hint = try_type; return(try_type); } } CACKEY_DEBUG_PRINTF("Unable to select any applet, returning in failure"); |
︙ | ︙ | |||
3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 | return(CACKEY_PCSC_E_TOKENABSENT); } CACKEY_DEBUG_PRINTF("Something went wrong during signing, resetting the slot and hoping for the best."); cackey_pcsc_disconnect(); cackey_pcsc_connect(); return(CACKEY_PCSC_E_GENERIC); } tmpbuf += bytes_to_send; tmpbuflen -= bytes_to_send; | > > > | 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 | return(CACKEY_PCSC_E_TOKENABSENT); } CACKEY_DEBUG_PRINTF("Something went wrong during signing, resetting the slot and hoping for the best."); cackey_pcsc_disconnect(); cackey_pcsc_connect(); cackey_detect_and_select_root_applet(slot, CACKEY_ID_TYPE_UNKNOWN); return(CACKEY_PCSC_E_GENERIC); } tmpbuf += bytes_to_send; tmpbuflen -= bytes_to_send; |
︙ | ︙ | |||
4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 | cackey_slots[idx].pcsc_reader = NULL; cackey_slots[idx].transaction_depth = 0; cackey_slots[idx].transaction_need_hw_lock = 0; cackey_slots[idx].slot_reset = 0; cackey_slots[idx].token_flags = 0; cackey_slots[idx].label = NULL; cackey_slots[idx].internal = 0; } #ifdef CACKEY_NO_EXTRA_CERTS if (getenv("CACKEY_EXTRA_CERTS") != NULL) { include_dod_certs = 1; } else { include_dod_certs = 0; | > | 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 | cackey_slots[idx].pcsc_reader = NULL; cackey_slots[idx].transaction_depth = 0; cackey_slots[idx].transaction_need_hw_lock = 0; cackey_slots[idx].slot_reset = 0; cackey_slots[idx].token_flags = 0; cackey_slots[idx].label = NULL; cackey_slots[idx].internal = 0; cackey_slots[idx].id_type_hint = CACKEY_ID_TYPE_UNKNOWN; } #ifdef CACKEY_NO_EXTRA_CERTS if (getenv("CACKEY_EXTRA_CERTS") != NULL) { include_dod_certs = 1; } else { include_dod_certs = 0; |
︙ | ︙ | |||
4702 4703 4704 4705 4706 4707 4708 | for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) { if (cackey_sessions[idx].active) { C_CloseSession(idx); } } | | < < < < | 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 | for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) { if (cackey_sessions[idx].active) { C_CloseSession(idx); } } cackey_slots_disconnect_all(1); for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { if (cackey_slots[idx].internal) { continue; } if (cackey_slots[idx].cached_certs) { cackey_free_certs(cackey_slots[idx].cached_certs, cackey_slots[idx].cached_certs_count, 1); cackey_slots[idx].cached_certs = NULL; } } |
︙ | ︙ | |||
4851 4852 4853 4854 4855 4856 4857 | } } if (slot_reset) { CACKEY_DEBUG_PRINTF("Purging all slot information."); /* Only update the list of slots if we are actually being supply the slot information */ | | < < < < < < < < < < < < | 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 | } } if (slot_reset) { CACKEY_DEBUG_PRINTF("Purging all slot information."); /* Only update the list of slots if we are actually being supply the slot information */ cackey_slots_disconnect_all(1); for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { if (cackey_slots[currslot].internal) { continue; } cackey_slots[currslot].active = 0; } } } /* Determine list of readers */ pcsc_connect_ret = cackey_pcsc_connect(); |
︙ | ︙ |