Differences From Artifact [b9a7131d32]:
- File
cackey.c
— part of check-in
[11bf77ef42]
at
2010-05-14 00:56:32
on branch trunk
— Added comments
Updated buffer name in PRINTBUF to avoid aliases (user: rkeene, size: 130498) [annotate] [blame] [check-ins using]
To Artifact [4f1f703fd4]:
- File
cackey.c
— part of check-in
[fab9cf1772]
at
2010-05-14 02:16:14
on branch trunk
— Added transaction support
Updated reading certs to be transactional
Added function to connect to card (user: rkeene, size: 133367) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
689 690 691 692 693 694 695 696 697 698 699 700 701 702 | } #endif CACKEY_DEBUG_PRINTF("Sucessfully connected to PC/SC, returning in success"); return(CACKEY_PCSC_S_OK); } /* APDU Related Functions */ /* * SYNPOSIS * cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len); * * ARGUMENTS | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | } #endif CACKEY_DEBUG_PRINTF("Sucessfully connected to PC/SC, returning in success"); return(CACKEY_PCSC_S_OK); } /* * SYNPOSIS * cackey_ret cackey_connect_card(struct cackey_slot *slot); * * ARGUMENTS * cackey_slot *slot * Slot to send commands to * * RETURN VALUE * CACKEY_PCSC_S_OK On success * CACKEY_PCSC_E_GENERIC On error * * NOTES * None * */ static cackey_ret cackey_connect_card(struct cackey_slot *slot) { cackey_ret pcsc_connect_ret; DWORD protocol; LONG scard_conn_ret; CACKEY_DEBUG_PRINTF("Called."); if (!slot) { CACKEY_DEBUG_PRINTF("Invalid slot specified, returning in failure"); return(CACKEY_PCSC_E_GENERIC); } pcsc_connect_ret = cackey_pcsc_connect(); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure"); return(CACKEY_PCSC_E_GENERIC); } /* Connect to reader, if needed */ if (!slot->pcsc_card_connected) { CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader); scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol); if (scard_conn_ret != SCARD_S_SUCCESS) { 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); return(CACKEY_PCSC_E_GENERIC); } slot->pcsc_card_connected = 1; } return(CACKEY_PCSC_S_OK); } /* * SYNPOSIS * cackey_ret cackey_begin_transaction(struct cackey_slot *slot); * * ARGUMENTS * cackey_slot *slot * Slot to send commands to * * RETURN VALUE * CACKEY_PCSC_S_OK On success * CACKEY_PCSC_E_GENERIC On error * * NOTES * The transaction should be terminated using "cackey_end_transaction" * */ static cackey_ret cackey_begin_transaction(struct cackey_slot *slot) { cackey_ret cackey_conn_ret; LONG scard_trans_ret; CACKEY_DEBUG_PRINTF("Called."); cackey_conn_ret = cackey_connect_card(slot); if (cackey_conn_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in error"); return(CACKEY_PCSC_E_GENERIC); } scard_trans_ret = SCardBeginTransaction(slot->pcsc_card); if (scard_trans_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Unable to begin transaction, returning in error"); return(CACKEY_PCSC_E_GENERIC); } return(CACKEY_PCSC_S_OK); } /* * SYNPOSIS * cackey_ret cackey_end_transaction(struct cackey_slot *slot); * * ARGUMENTS * cackey_slot *slot * Slot to send commands to * * RETURN VALUE * CACKEY_PCSC_S_OK On success * CACKEY_PCSC_E_GENERIC On error * * NOTES * This function requires "cackey_begin_transaction" to be called first * */ static cackey_ret cackey_end_transaction(struct cackey_slot *slot) { LONG scard_trans_ret; CACKEY_DEBUG_PRINTF("Called."); if (!slot->pcsc_card_connected) { CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction"); return(CACKEY_PCSC_E_GENERIC); } scard_trans_ret = SCardEndTransaction(slot->pcsc_card, SCARD_LEAVE_CARD); if (scard_trans_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Unable to end transaction, returning in error"); return(CACKEY_PCSC_E_GENERIC); } return(CACKEY_PCSC_S_OK); } /* APDU Related Functions */ /* * SYNPOSIS * cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len); * * ARGUMENTS |
︙ | ︙ | |||
762 763 764 765 766 767 768 | * */ static cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len) { uint8_t major_rc, minor_rc; size_t bytes_to_copy, tmp_respdata_len; DWORD protocol; DWORD xmit_len, recv_len; | | | | < < < < < < < < < < < < < < | 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | * */ static cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len) { uint8_t major_rc, minor_rc; size_t bytes_to_copy, tmp_respdata_len; DWORD protocol; DWORD xmit_len, recv_len; LONG scard_xmit_ret, scard_reconn_ret; BYTE xmit_buf[1024], recv_buf[1024]; int pcsc_connect_ret, pcsc_getresp_ret; int idx; 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); } /* Transmit */ xmit_len = 0; xmit_buf[xmit_len++] = class; xmit_buf[xmit_len++] = instruction; xmit_buf[xmit_len++] = p1; |
︙ | ︙ | |||
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 | if (certs != NULL) { CACKEY_DEBUG_PRINTF("Requested we return 0 objects, short-circuit"); return(certs); } } if (certs == NULL) { certs = malloc(sizeof(*certs) * 5); *count = 5; certs_resizable = 1; } else { certs_resizable = 0; } /* Select the CCC Applet */ send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid)); if (send_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to select CCC Applet, returning in failure"); return(NULL); } /* Read all the applets from the CCC's TLV */ ccc_tlv = cackey_read_tlv(slot); | > > > > > > | 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 | if (certs != NULL) { CACKEY_DEBUG_PRINTF("Requested we return 0 objects, short-circuit"); return(certs); } } /* Begin a SmartCard transaction */ cackey_begin_transaction(slot); if (certs == NULL) { certs = malloc(sizeof(*certs) * 5); *count = 5; certs_resizable = 1; } else { certs_resizable = 0; } /* Select the CCC Applet */ send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid)); if (send_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to select CCC Applet, returning in failure"); /* Terminate SmartCard Transaction */ cackey_end_transaction(slot); return(NULL); } /* Read all the applets from the CCC's TLV */ ccc_tlv = cackey_read_tlv(slot); |
︙ | ︙ | |||
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 | cackey_free_tlv(ccc_tlv); *count = outidx; if (certs_resizable) { certs = realloc(certs, sizeof(*certs) * (*count)); } return(certs); } /* * SYNPOSIS * ... | > > > | 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 | cackey_free_tlv(ccc_tlv); *count = outidx; if (certs_resizable) { certs = realloc(certs, sizeof(*certs) * (*count)); } /* Terminate SmartCard Transaction */ cackey_end_transaction(slot); return(certs); } /* * SYNPOSIS * ... |
︙ | ︙ |