Overview
Comment: | Updated transactional support to recursive transactions |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 43170e1dd99babbfe0a27ad35c71934da6fff560 |
User & Date: | rkeene on 2010-05-14 03:28:41 |
Other Links: | manifest | tags |
Context
2010-05-14
| ||
03:32 | Updated transaction support check-in: c2e40da095 user: rkeene tags: trunk | |
03:28 | Updated transactional support to recursive transactions check-in: 43170e1dd9 user: rkeene tags: trunk | |
02:34 | Put all calls to functions that talk to the smartcard inside the big global mutex check-in: da2b17a36c user: rkeene tags: trunk | |
Changes
Modified cackey.c from [38178200a5] to [0fee951b43].
481 481 struct cackey_slot { 482 482 int active; 483 483 484 484 char *pcsc_reader; 485 485 486 486 int pcsc_card_connected; 487 487 SCARDHANDLE pcsc_card; 488 + 489 + int transaction_depth; 488 490 }; 489 491 490 492 typedef enum { 491 493 CACKEY_TLV_APP_GENERIC = 0x01, 492 494 CACKEY_TLV_APP_SKI = 0x02, 493 495 CACKEY_TLV_APP_PKI = 0x04 494 496 } cackey_tlv_apptype; ................................................................................ 738 740 if (scard_conn_ret != SCARD_S_SUCCESS) { 739 741 CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_conn_ret), (long) scard_conn_ret); 740 742 741 743 return(CACKEY_PCSC_E_GENERIC); 742 744 } 743 745 744 746 slot->pcsc_card_connected = 1; 747 + slot->transaction_depth = 0; 745 748 } 746 749 747 750 return(CACKEY_PCSC_S_OK); 748 751 } 749 752 750 753 /* 751 754 * SYNPOSIS ................................................................................ 771 774 772 775 cackey_conn_ret = cackey_connect_card(slot); 773 776 if (cackey_conn_ret != CACKEY_PCSC_S_OK) { 774 777 CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in error"); 775 778 776 779 return(CACKEY_PCSC_E_GENERIC); 777 780 } 781 + 782 + slot->transaction_depth++; 783 + 784 + if (slot->transaction_depth > 1) { 785 + CACKEY_DEBUG_PRINTF("Already in a transaction, performing no action (new depth = %i)", slot->transaction_depth); 786 + 787 + return(CACKEY_PCSC_S_OK); 788 + } 778 789 779 790 scard_trans_ret = SCardBeginTransaction(slot->pcsc_card); 780 791 if (scard_trans_ret != SCARD_S_SUCCESS) { 781 792 CACKEY_DEBUG_PRINTF("Unable to begin transaction, returning in error"); 782 793 783 794 return(CACKEY_PCSC_E_GENERIC); 784 795 } 796 + 797 + CACKEY_DEBUG_PRINTF("Sucessfully began transaction on slot (%s)", slot->pcsc_reader); 785 798 786 799 return(CACKEY_PCSC_S_OK); 787 800 } 788 801 789 802 /* 790 803 * SYNPOSIS 791 804 * cackey_ret cackey_end_transaction(struct cackey_slot *slot); ................................................................................ 808 821 CACKEY_DEBUG_PRINTF("Called."); 809 822 810 823 if (!slot->pcsc_card_connected) { 811 824 CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction"); 812 825 813 826 return(CACKEY_PCSC_E_GENERIC); 814 827 } 828 + 829 + if (slot->transaction_depth == 0) { 830 + CACKEY_DEBUG_PRINTF("Terminating a transaction that has not begun!"); 831 + 832 + return(CACKEY_PCSC_E_GENERIC); 833 + } 834 + 835 + slot->transaction_depth--; 836 + 837 + if (slot->transaction_depth > 0) { 838 + CACKEY_DEBUG_PRINTF("Transactions still in progress, not terminating on-card Transaction (current depth = %i)", slot->transaction_depth); 839 + 840 + return(CACKEY_PCSC_E_GENERIC); 841 + } 815 842 816 843 scard_trans_ret = SCardEndTransaction(slot->pcsc_card, SCARD_LEAVE_CARD); 817 844 if (scard_trans_ret != SCARD_S_SUCCESS) { 818 845 CACKEY_DEBUG_PRINTF("Unable to end transaction, returning in error"); 819 846 820 847 return(CACKEY_PCSC_E_GENERIC); 821 848 } 849 + 850 + CACKEY_DEBUG_PRINTF("Sucessfully terminated transaction on slot (%s)", slot->pcsc_reader); 822 851 823 852 return(CACKEY_PCSC_S_OK); 824 853 } 825 854 826 855 /* APDU Related Functions */ 827 856 /* 828 857 * SYNPOSIS ................................................................................ 927 956 xmit_buf[xmit_len++] = data[idx]; 928 957 } 929 958 } 930 959 931 960 if (le != 0x00) { 932 961 xmit_buf[xmit_len++] = le; 933 962 } 963 + 964 + /* Begin Smartcard Transaction */ 965 + cackey_begin_transaction(slot); 934 966 935 967 CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len); 936 968 937 969 recv_len = sizeof(recv_buf); 938 970 scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len); 939 971 if (scard_xmit_ret != SCARD_S_SUCCESS) { 940 972 CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret); 973 + 974 + slot->transaction_depth = 0; 941 975 942 976 if (scard_xmit_ret == SCARD_W_RESET_CARD) { 943 977 CACKEY_DEBUG_PRINTF("Reset required, please hold..."); 944 978 945 979 scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol); 946 980 if (scard_reconn_ret == SCARD_S_SUCCESS) { 981 + /* Re-establish transaction, if it was present */ 982 + if (slot->transaction_depth > 0) { 983 + slot->transaction_depth--; 984 + cackey_begin_transaction(slot); 985 + } 986 + 947 987 CACKEY_DEBUG_PRINTF("Reset successful, retransmitting"); 948 988 scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T0, recv_buf, &recv_len); 949 989 950 990 if (scard_xmit_ret != SCARD_S_SUCCESS) { 951 991 CACKEY_DEBUG_PRINTF("Retransmit failed, returning in failure after disconnecting the card (SCardTransmit = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (long) scard_xmit_ret); 952 992 953 993 SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); 954 994 slot->pcsc_card_connected = 0; 995 + 996 + /* End Smartcard Transaction */ 997 + slot->transaction_depth = 1; 998 + cackey_end_transaction(slot); 955 999 956 1000 return(CACKEY_PCSC_E_GENERIC); 957 1001 } 958 1002 } else { 959 1003 CACKEY_DEBUG_PRINTF("Disconnecting card"); 960 1004 961 1005 SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); 962 1006 slot->pcsc_card_connected = 0; 1007 + 1008 + /* End Smartcard Transaction */ 1009 + slot->transaction_depth = 1; 1010 + cackey_end_transaction(slot); 963 1011 964 1012 CACKEY_DEBUG_PRINTF("Returning in failure"); 965 1013 return(CACKEY_PCSC_E_GENERIC); 966 1014 } 967 1015 } else { 968 1016 CACKEY_DEBUG_PRINTF("Disconnecting card"); 969 1017 970 1018 SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); 971 1019 slot->pcsc_card_connected = 0; 1020 + 1021 + /* End Smartcard Transaction */ 1022 + slot->transaction_depth = 1; 1023 + cackey_end_transaction(slot); 972 1024 973 1025 CACKEY_DEBUG_PRINTF("Returning in failure"); 974 1026 return(CACKEY_PCSC_E_GENERIC); 975 1027 } 976 1028 } 977 1029 978 1030 CACKEY_DEBUG_PRINTBUF("Returned Value:", recv_buf, recv_len); 979 1031 980 1032 if (recv_len < 2) { 981 1033 /* Minimal response length is 2 bytes, returning in failure */ 982 1034 CACKEY_DEBUG_PRINTF("Response too small, returning in failure (recv_len = %lu)", (unsigned long) recv_len); 1035 + 1036 + /* End Smartcard Transaction */ 1037 + cackey_end_transaction(slot); 983 1038 984 1039 return(CACKEY_PCSC_E_GENERIC); 985 1040 } 986 1041 987 1042 /* Determine result code */ 988 1043 major_rc = recv_buf[recv_len - 2]; 989 1044 minor_rc = recv_buf[recv_len - 1]; ................................................................................ 1021 1076 if (major_rc == 0x61) { 1022 1077 /* We need to READ */ 1023 1078 CACKEY_DEBUG_PRINTF("Buffer read required"); 1024 1079 1025 1080 pcsc_getresp_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_GET_RESPONSE, 0x00, 0x00, 0, NULL, minor_rc, respcode, respdata, &tmp_respdata_len); 1026 1081 if (pcsc_getresp_ret != CACKEY_PCSC_S_OK) { 1027 1082 CACKEY_DEBUG_PRINTF("Buffer read failed! Returning in failure"); 1083 + 1084 + /* End Smartcard Transaction */ 1085 + cackey_end_transaction(slot); 1028 1086 1029 1087 return(CACKEY_PCSC_E_GENERIC); 1030 1088 } 1031 1089 1032 1090 if (respdata_len) { 1033 1091 *respdata_len += tmp_respdata_len; 1034 1092 } 1093 + 1094 + /* End Smartcard Transaction */ 1095 + cackey_end_transaction(slot); 1035 1096 1036 1097 CACKEY_DEBUG_PRINTF("Returning in success (buffer read complete)"); 1037 1098 return(CACKEY_PCSC_S_OK); 1038 1099 } 1100 + 1101 + /* End Smartcard Transaction */ 1102 + cackey_end_transaction(slot); 1039 1103 1040 1104 if (major_rc == 0x90) { 1041 1105 /* Success */ 1042 1106 CACKEY_DEBUG_PRINTF("Returning in success (major_rc = 0x90)"); 1043 1107 1044 1108 return(CACKEY_PCSC_S_OK); 1045 1109 } ................................................................................ 1488 1552 */ 1489 1553 static struct cackey_pcsc_identity *cackey_read_certs(struct cackey_slot *slot, struct cackey_pcsc_identity *certs, unsigned long *count) { 1490 1554 struct cackey_pcsc_identity *curr_id; 1491 1555 struct cackey_tlv_entity *ccc_tlv, *ccc_curr, *app_tlv, *app_curr; 1492 1556 unsigned char ccc_aid[] = {GSCIS_AID_CCC}; 1493 1557 unsigned char curr_aid[7]; 1494 1558 unsigned long outidx = 0; 1559 + cackey_ret transaction_ret; 1495 1560 int certs_resizable; 1496 1561 int send_ret, select_ret; 1497 1562 1498 1563 CACKEY_DEBUG_PRINTF("Called."); 1499 1564 1500 1565 if (count == NULL) { 1501 1566 CACKEY_DEBUG_PRINTF("count is NULL, returning in failure"); ................................................................................ 1508 1573 CACKEY_DEBUG_PRINTF("Requested we return 0 objects, short-circuit"); 1509 1574 1510 1575 return(certs); 1511 1576 } 1512 1577 } 1513 1578 1514 1579 /* Begin a SmartCard transaction */ 1515 - cackey_begin_transaction(slot); 1580 + transaction_ret = cackey_begin_transaction(slot); 1581 + if (transaction_ret != CACKEY_PCSC_S_OK) { 1582 + CACKEY_DEBUG_PRINTF("Unable begin transaction, returning in failure"); 1583 + 1584 + return(NULL); 1585 + } 1516 1586 1517 1587 if (certs == NULL) { 1518 1588 certs = malloc(sizeof(*certs) * 5); 1519 1589 *count = 5; 1520 1590 certs_resizable = 1; 1521 1591 } else { 1522 1592 certs_resizable = 0;