📄 card.c
字号:
/* * GNU POC (passwords on card) - manage passwords on smartcards * Copyright (C) 2001 Henning Koester <henning@crackinghacking.de> * * Please report bugs to bug-poc@gnu.org * * This file is part of POC. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $Id: card.c,v 1.7 2001/08/18 16:06:27 henning Exp $ */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <ctapi.h>#include "poc.h"#include "poc_types.h"#include "poc_macros.h"#include "card.h"#include "lang.h"#include "misc.h"extern bool verbose_flg; /****************************************************************************** * * This MACRO checks the return of a CT-API library call for success. If an * error is returned, it will print 'msg' and return POC_ERROR. * *****************************************************************************/#define CHECK_RETURN(msg) { \ if ((ret != OK) || (((response[lenr - 2] << 8) | \ (response[lenr-1])) != 0x9000)) { \ print_err(msg); \ if (verbose_flg) { \ fprintf(stderr, "CT_API command returned: "); \ process_return(ret); \ fprintf(stderr, "response trail = %04x\n", \ ((response[lenr-2]<<8)|(response[lenr-1]))); \ } \ return(POC_ERROR); /* fatal error!!! bail out!!! */ \ } \}/****************************************************************************** * * Function : process_return * * Description : This function checks the error code returned by a CT-API * call. * * Input : [1] type (int) * Error code. * * Return : nothing is returned. * *****************************************************************************/static voidprocess_return(const int type) { switch (type) { case ERR_INVALID: fprintf(stderr, "Invalid Data!\n"); break; case ERR_CT: fprintf(stderr, "CT Error!\n"); break; case ERR_TRANS: fprintf(stderr, "Transmission Error!\n"); break; case ERR_MEMORY: fprintf(stderr, "Memory Allocate Error!\n"); break; case ERR_HTSI: fprintf(stderr, "HTSI Error!\n"); break; default: fprintf(stderr, "Unknown Error (%i).\n", type); }}/****************************************************************************** * * Function : card_select_file * * Description : This function selects the card's memory, in order to access * the card's memory. * * Input : [1] ctn (u16) * Card-terminal handle. * * Return : POC_ERROR or POC_SUCCESS * *****************************************************************************/char card_select_file(const u16 ctn) { /* APDU for memory selection. */ u8 SELECT_FILE[] = { 0x00,0xA4,0x00,0x00,0x02,0x3f,0x00 }; u8 response[100]; /* Buffer to store CT-API response data. */ u8 sad, dad; /* Source/Destination addresses. */ u16 lenc, lenr; /* Length of command and response. */ char ret; /* Return of the CT-API call. */ #ifdef DEBUG printf("DEBUG: card_select_file(ctn [%i])\n", ctn);#endif sad = HOST; /* Source = Host */ dad = CARD; /* Destination = Card */ lenc = sizeof(SELECT_FILE); /* Command length. */ lenr = sizeof(response); /* Maximum response length. */ /* Send command. */ ret = CT_data(ctn, &dad, &sad, lenc, SELECT_FILE, &lenr, response); /* Check for error. */ CHECK_RETURN(STR_SELECT_FILE_ERR); return(POC_SUCCESS);}/****************************************************************************** * * Function : card_init_terminal * * Description : This function initializes the card terminal. * * Input : [1] ctn (u16) * Card-terminal handle. * [2] com_port (u16) * Com-Port * * Return : POC_ERROR or POC_SUCCESS * *****************************************************************************/boolcard_init_terminal(const u16 ctn, const u16 com_port) { char ret; /* CT-API return. */#ifdef DEBUG printf("DEBUG: card_init_terminal(ctn [%i], com_port [%i])\n", ctn,com_port);#endif ret = CT_init(ctn, com_port); /* Initialize terminal. */ if (ret != OK) { /* Return POC_ERROR if something went wrong. */ return(POC_ERROR); } /* Everything worked fine. */ return(POC_SUCCESS);}/****************************************************************************** * * Function : card_close_terminal * * Description : This function closes an initzialized terminal. * * Input : [1] ctn (u16) * Card-terminal handle. * * Return : nothing is returned * *****************************************************************************/void card_close_terminal(const u16 ctn) { char ret;#ifdef DEBUG printf("DEBUG: card_close_terminal(ctn [%i])\n", ctn);#endif ret = CT_close(ctn);}/****************************************************************************** * * Function : card_request_icc * * Description : This function requests the card. * * Input : [1] ctn (u16) * Card-terminal handle. * * Return : The responded ICC of the card is returned or POC_ERROR, if * an error occured. * *****************************************************************************/u16 card_request_icc(const u16 ctn) { /* APDU for ICC request. */ u8 REQUEST_ICC[] = { 0x20,0x12,0x01,0x00,0 }; u8 response[100]; /* Buffer for storing command response. */ u8 sad, dad; /* Source/Destination addresses. */ u16 lenc, lenr; /* Length of command and response. */ char ret; /* Return of the CT-API call. */#ifdef DEBUG printf("DEBUG: card_request_icc(ctn [%i])\n", ctn);#endif sad = HOST; /* Source = Host */ dad = TERMINAL; /* Destination = Card */ lenc = sizeof(REQUEST_ICC); /* Command's length. */ lenr = sizeof(response); /* Max response's length. */ /* Send command. */ ret = CT_data(ctn, &dad, &sad, lenc, REQUEST_ICC, &lenr, response); /* Check for error. */ CHECK_RETURN(STR_REQUEST_ICC_ERR); /* If everything went fine, the ICC of the card is returned. */ return((response[0] << 8) | response[1]);}/****************************************************************************** * * Function : card_reset_terminal * * Description : This function resets the terminal. * * Input : [1] ctn (u16) * Card-terminal handle. * * Return : POC_ERROR or POC_SUCCESS * *****************************************************************************/bool card_reset_terminal(const u16 ctn) { /* APDU for resetting terminal. */ u8 RESET_CT[] = { 0x20,0x11,0x00,0x00,0 }; u8 response[100]; /* not really used */ u8 sad, dad; /* Source/Destination adresses. */ u16 lenc, lenr; /* Length of command and response. */ char ret; /* CT-API return. */#ifdef DEBUG printf("DEBUG: card_reset_terminal(ctn [%i])\n", ctn);#endif sad = HOST; /* Source = Host */ dad = TERMINAL; /* Destination = Terminal */ lenc = sizeof(RESET_CT); /* Command's length. */ lenr = sizeof(response); /* Max. response length. */ /* Transmit the command. */ ret = CT_data(ctn, &dad, &sad, lenc, RESET_CT, &lenr, response); /* Check for error. */ CHECK_RETURN(STR_RESET_CT_ERR); return(POC_SUCCESS);}/****************************************************************************** * * Function : card_read_data * * Description : This function reads data from the card. * * Input : [1] ctn (u16) * Card-terminal handle. * [2] offset (u16) * Where to start reading. * [3] n_bytes (int) * Number of bytes to read. * [4] dest_buff (u8) * Where the read data will be stored. * * Return : POC_ERROR, POC_SUCCESS or POC_MEM_ERR. * *****************************************************************************/charcard_read_data(const u16 ctn, u16 offset, int n_bytes, u8 * const dest_buff) { /* Basic APDU for reading data from the card. */ u8 READ_BINARY[] = { 0x00,0xB0,0x00,0x00,0 }; u8 command[7]; /* Final command for reading data from the card. */ u8 *response; /* Pointer to memory where read data is temporarily stored. */ u8 sad, dad; /* Source/Destination addresses. */ u16 lenc, lenr; /* Length of command and response. */ u8 n; /* Contains number of to read bytes for each CT-API read call. */ u16 i = 0; /* Holds the current position for storing new data in 'dest_buff'. */ char ret; /* Holds returns of CT-API calls. */#ifdef DEBUG printf("DEBUG: card_read_data(ctn [%i], offset [%i], n_bytes [%i], dest_buff)\n", ctn, offset, n_bytes);#endif /* Allocate memory for storing read data. */ if ( (response = malloc(255 + 2)) == NULL) return(POC_MEM_ERR); /* * Because the commands are byte oriented the maximum number of * bytes we can read at once is 255. That is why we have to circle until * we've read all bytes. */ do { /* Set 'n' to the number of bytes to read for this call. If 'n_bytes' * is bigger than 255 we read 255. And if it's smaller it will be the * last loop and we will read the remaining bytes. */ if (n_bytes > 255) n = 255; else n = n_bytes; /* Correct the "counter". */ n_bytes -= 255; sad = HOST; /* Source = Host */ dad = CARD; /* Destination = Card */ lenc = sizeof(READ_BINARY); /* Command's length. */ lenr = n + 2; /* Length of the response (size of the number of bytes to read plus 2 bytes, response trail of the CT-API call. */ memcpy(command, READ_BINARY, lenc); /* Copy the basic to the work template. */ /* Setup the new offset for reading data. */ command[2] = (u8) (offset >> 8); /* High 8 bit. */ command[3] = (u8) (offset & 0x00ff); /* Low 8 bit. */ command[4] = n; /* Number of bytes to read. */#ifdef DEBUG printf("DEBUG: card_read_data(...)\n"); printf("\t\treading: %i (bytes), %i (offset)\n", n, offset);#endif /* GoGoGo. */ ret = CT_data(ctn, &dad, &sad, lenc, command, &lenr, response); /* Error? */ CHECK_RETURN(STR_READ_BINARY_ERR); /* Copy read data to 'dest_buff', which will contain all read data, after this function has finished. */ memcpy(&dest_buff[i], response, lenr - 2); /* New offset for storing read data in 'dest_buff' after the next "read" call. */ i += 255; /* Offset for reading data with the next loop. */ offset += 255; } while (n_bytes > 0); /* No more bytes to read? Finish then. */ /* Overwrite sensetive data. */ overwrite_buffer(response); /* Free allocated memory. */ drop_mbuffer(response); return(POC_SUCCESS);}/****************************************************************************** * * Function : card_write_data * * Description : This function writes data to the card. * * Input : [1] ctn (u16) * Card-terminal handle. * [2] offset (u16) * Where to start writing. * [3] n_bytes (int) * Number of bytes to write. * [4] source_buff (u8) * Buffer with data, which will be written to the card. * * Return : POC_ERROR, POC_SUCCESS or POC_MEM_ERR. * *****************************************************************************/char card_write_data(const u16 ctn, u16 offset, int n_bytes, u8 * const source_buff) { /* Basic APDU for writing data to the card. */ u8 UPDATE_BINARY[] = { 0x00,0xD6,0x00,0x00,0x00 }; u8 *command; /* Build command. */ u8 response[100]; /* Response from the card. (Only SW1 and SW2 are used.) */ u8 sad, dad; /* Source/Destination addresses. */ u16 lenc, lenr; /* Length of command and response. */ u8 n; /* Number of bytes to write to the card with each CT-API call. */ u16 i = 0; /* Keeps track of the position in 'source_buff' */ char ret; /* Holds returns of CT-API calls. */#ifdef DEBUG printf("DEBUG: card_read_data(ctn [%i], offset [%i], n_bytes [%i], source_buff)\n", ctn, offset, n_bytes);#endif /* * I don't think it's needed to explain it again cause there aren't much * differences between this function and the read function. */ if ( (command = malloc(255 + 5)) == NULL) return(POC_MEM_ERR); do { if (n_bytes > 255) n = 255; else n = n_bytes; n_bytes -= 255; sad = HOST; dad = CARD; lenc = n + sizeof(UPDATE_BINARY); lenr = sizeof(response); memcpy(command, UPDATE_BINARY, sizeof(UPDATE_BINARY)); command[2] = (u8) (offset >> 8); command[3] = (u8) (offset & 0x00ff); command[4] = (u8) n; memcpy(&command[5], &source_buff[i], (size_t) n);#ifdef DEBUG printf("DEBUG: card_read_data(...)\n"); printf("\t\twriting: %i (bytes), %i (offset)\n", n, offset);#endif ret = CT_data(ctn, &dad, &sad, lenc, command, &lenr, response); CHECK_RETURN(STR_UPDATE_BINARY_ERR); i += 255; offset += 255; } while (n_bytes > 0); overwrite_buffer(command); drop_mbuffer(command); return(POC_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -