/*************************************************************************** $RCSfile: hbcicard.cpp,v $ ------------------- cvs : $Id: hbcicard.cpp,v 1.35 2003/05/13 20:24:14 aquamaniac Exp $ begin : Fri Jun 07 2002 copyright : (C) 2002 by Martin Preuss email : martin@libchipcard.de **************************************************************************** * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ****************************************************************************/ /* Changes */ #ifdef HAVE_CONFIG_H # include #endif /* Internationalization */ #ifdef HAVE_GETTEXT_ENVIRONMENT # include # include # define I18N(m) gettext(m) #else # define I18N(m) m #endif #define I18NT(m) m #include #include #include #include #define k_PRG "hbcicard" #define k_PRG_VERSION_INFO \ "hbcicard v0.5.4 (part of libchipcard v"k_CHIPCARD_VERSION_STRING")\n"\ "(c) 2003 Martin Preuss\n" \ "This program is free software licensed under GPL.\n"\ "See COPYING for details.\n" void usage(string name) { fprintf(stderr,"%s%s%s%s", I18N("HBCICard - A tool to manipulate data on a Home Banking Card.\n" "(c) 2003 Martin Preuss\n" "This library is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU Lesser General Public\n" "License as published by the Free Software Foundation; either\n" "version 2.1 of the License, or (at your option) any later version.\n" "\n" "Usage:\n" "hbcicard COMMAND [OPTIONS]\n" " COMMAND may be one of these:\n" " type : shows the card type (either DDV or RSA)\n" " info : shows some general information about the card\n" " dump : dump entries on a card\n" " set : change an entry on a card\n" " chgpin : change the cardholder pin of a RSA card\n" " initpin : change the inital cardholder pin of a RSA card\n" " If you purchased a new RSA card then it uses an\n" " initial pin (the serial number of the card).\n" " You need THIS command to change that pin in order\n" " to use the card. \n" " The switch \"-k\" must not be used.\n" " keys : lists the keys stored on a RSA card.\n" " General Options:\n" " -C FILE - libchipcard configuration file to be used\n" " -i IDX - number of the card's entry to use \n" " If omitted and COMMAND is \"dump\" then all\n" " entries are shown\n" " -p PIN1 - pin 1 (used to get access to a card)\n" " -P PIN2 - pin 2 (new pin when changing the pin)\n" " -k - use keypad for secure pin input\n" " --logfile F - use given F as log file\n" " --logtype T - use given T as log type\n" " These are the valid types:\n" " stderr (log to standard error channel)\n" " file (log to the file given by --logfile)\n"), #ifdef HAVE_SYSLOG_H I18N(" syslog (log via syslog)\n"), #else "", #endif I18N(" Default is stderr\n" " --loglevel L - set the loglevel\n" " Valid levels are:\n" " emergency, alert, critical, error,\n" " warning, notice, info and debug\n" " Default is \"warning\".\n" "\n" " The following options can be used with the command \"set\"\n" " -s SERVER - server address to set\n" " -u USER - user id to set\n" " -c COUNTRY - country code (defaults to 280 for Germany)\n" " -b BANK - bank code (German Bankleitzahl)\n" " -q SEQ - signature counter, this one is checked by your bank,\n" " each signature needs a higher number than any \n" " signature before.\n" "\n" "The simplest usage of this program is:\n" " hbcicard dump -k\n" "This dumps all entries of the card.\n") , name.c_str()); } struct s_args { string server; // -s string user; // -u string pin; // -p string pin2; // -P bool keyPad; // -k int idx; // -i string bank; // -b int country; // -c int seq; // -q string configFile; // -C list params; string logFile; // --logfile LOGGER_LOGTYPE logType; // --logtype LOGGER_LEVEL logLevel; // --loglevel }; int checkArgs(s_args &args, int argc, char **argv) { int i; string tmp; i=1; args.idx=-1; args.country=-1; args.seq=-1; args.configFile=CHIPCARDC_CFGFILE; args.logFile="hbcicard.log"; args.logType=LoggerTypeConsole; args.logLevel=LoggerLevelWarning; args.keyPad=false; while (i=argc) return 1; args.idx=atoi(argv[i]); } else if (tmp=="-s") { i++; if (i>=argc) return 1; args.server=argv[i]; } else if (tmp=="-C") { i++; if (i>=argc) return 1; args.configFile=argv[i]; } else if (tmp=="-b") { i++; if (i>=argc) return 1; args.bank=argv[i]; } else if (tmp=="-c") { i++; if (i>=argc) return 1; args.country=atoi(argv[i]); } else if (tmp=="-q") { i++; if (i>=argc) return 1; args.seq=atoi(argv[i]); } else if (tmp=="-u") { i++; if (i>=argc) return 1; args.user=argv[i]; } else if (tmp=="-p") { i++; if (i>=argc) return 1; args.pin=argv[i]; } else if (tmp=="-P") { i++; if (i>=argc) return 1; args.pin2=argv[i]; } else if (tmp=="-k") { args.keyPad=true; } else if (tmp=="--logfile") { i++; if (i>=argc) return 1; args.logFile=argv[i]; } else if (tmp=="--logtype") { i++; if (i>=argc) return 1; if (strcmp(argv[i],"stderr")==0) args.logType=LoggerTypeConsole; else if (strcmp(argv[i],"file")==0) args.logType=LoggerTypeFile; #ifdef HAVE_SYSLOG_H else if (strcmp(argv[i],"syslog")==0) args.logType=LoggerTypeSyslog; #endif else { fprintf(stderr,I18N("Unknown log type \"%s\"\n"), argv[i]); return 1; } } else if (tmp=="--loglevel") { i++; if (i>=argc) return 1; if (strcmp(argv[i], "emergency")==0) args.logLevel=LoggerLevelEmergency; else if (strcmp(argv[i], "alert")==0) args.logLevel=LoggerLevelAlert; else if (strcmp(argv[i], "critical")==0) args.logLevel=LoggerLevelCritical; else if (strcmp(argv[i], "error")==0) args.logLevel=LoggerLevelError; else if (strcmp(argv[i], "warning")==0) args.logLevel=LoggerLevelWarning; else if (strcmp(argv[i], "notice")==0) args.logLevel=LoggerLevelNotice; else if (strcmp(argv[i], "info")==0) args.logLevel=LoggerLevelInfo; else if (strcmp(argv[i], "debug")==0) args.logLevel=LoggerLevelDebug; else { fprintf(stderr, I18N("Unknown log level \"%s\"\n"), argv[i]); return 1; } } else if (tmp=="-h" || tmp=="--help") { usage(argv[0]); return -1; } else if (tmp=="-V" || tmp=="--version") { fprintf(stdout,k_PRG_VERSION_INFO); return -1; } else // otherwise add param args.params.push_back(tmp); i++; } // while // that's it return 0; } bool _checkPinError(CTError err) { if (!err.isOk()) { if (err.code()==0) { if (err.subcode1()==0x63 && err.subcode2()>=0xc0) { switch(err.subcode2()-0xc0) { case 0: fprintf(stderr, I18N("VERY SERIOUS WARNING:\n" "=====================\n" "You already entered a false pin 3 times !\n" "If you enter a bad pin again " "then your card gets blocked!\n" "Please use now the last program which allowed you " "to successfully enter the pin in order to reset the\n" "error counter !\n")); break; case 1: fprintf(stderr, I18N("SERIOUS WARNING:\n" "=====================\n" "You already entered a false pin twice !\n" "There is only one bad try left, so please be carefull.\n" "Please use now the last program which allowed you " "to successfully enter the pin in order to reset the\n" "error counter !\n")); break; case 2: default: fprintf(stderr, I18N("WARNING:\n" "=====================\n" "You entered a false pin.\n" "There are only two bad tries left, " "so please be carefull.\n" "If you are very sure that the pin you entered is " "correct \n" "then please stop using this program and contact\n" " martin@libchipcard.de \n" "to report this incidence.\n" "If it is possible that you made a mistake, then please\n" "try again.\n")); break; } // switch } // if bad pin else if (err.subcode1()==0x69 && err.subcode2()>=0x83) fprintf(stderr, I18N("Sorry, but your card is blocked.\n" "The following reasons are possible:\n" "1)You entered a bad pin too often, so for security reasons\n" " the card blocked itself.\n" " Unfortunately you will have to ask your bank for another\n" " card.\n" "2)This is an unsupported card. You will not be able to use\n" " it with Libchipcard, sorry.\n") ); } else if (err.code()==k_CTERROR_API){ if (err.subcode1()==CHIPCARD_ERROR_NO_REQUEST) fprintf(stderr, I18N("Service unreachable, maybe chipcardd is not running?\n") ); } return false; } else return true; } int openCard(CTPointer &card) { CTPointer trader; CTError err; CTCard *cp; trader=new CTCardTrader(false, 0, 0, CHIPCARD_STATUS_INSERTED, CHIPCARD_STATUS_INSERTED | CHIPCARD_STATUS_LOCKED_BY_OTHER, CHIPCARD_STATUS_INSERTED); err=trader.ref().start(); if (!err.isOk()) { fprintf(stderr, I18N("Could not initialize trader\n")); return 2; } fprintf(stderr, I18N("Please insert your card into any reader\n")); // get the card err=trader.ref().getNext(cp, 30); if (!err.isOk()) { if (err.code()==k_CTERROR_API && (err.subcode1()==CHIPCARD_ERROR_NO_TRANSPORT || err.subcode1()==CHIPCARD_ERROR_NO_REQUEST)) { fprintf(stderr, I18N("Service unreachable, maybe \"chipcardd\" is not running?\n") ); return 2; } fprintf(stderr,I18N("No card inserted within some seconds, aborting.\n")); return 2; } err=trader.ref().stop(); if (!err.isOk()) { fprintf(stderr, I18N("Could not stop trader\n")); return 2; } card=cp; if (!(card.ref().isProcessorCard())) { fprintf(stderr, I18N("Not a HBCI card\n")); return 3; } fprintf(stderr,I18N("Card is inserted, working.\n")); err=card.ref().openCard(); if (!err.isOk()) { fprintf(stderr,"%s\n",err.errorString().c_str()); return 3; } return 0; } list _getList(CTPointer card, int idx) { int i; HBCICard::instituteData data; list l; CTError err; if (idx==-1) { for (i=1;i<6; i++) { try { data=card.ref().getInstituteData(i); l.push_back(data); } catch (CTError xerr) { break; } } // for } else { try { data=card.ref().getInstituteData(idx); l.push_back(data); } catch (CTError xerr) { } } return l; } int dumpDDV(const s_args &args, CTPointer card) { list::iterator it; list l; l=_getList(card,args.idx); for (it=l.begin(); it!=l.end(); it++) { fprintf(stdout, I18N("Country : %d\n"),(*it).country()); fprintf(stdout, I18N("Bank Name : %s\n"),(*it).name().c_str()); fprintf(stdout, I18N("Bank Code : %s\n"),(*it).code().c_str()); fprintf(stdout, I18N("Service Type : %s\n"), ((*it).service()==2)?"TCP" :"BTX"); fprintf(stdout, I18N("Service Address: %s\n"),(*it).address().c_str()); fprintf(stdout, I18N("Service Port : %s\n"),(*it).addressSuffix().c_str()); fprintf(stdout, I18N("User ID : %s\n"),(*it).user().c_str()); } // for return 0; } int setDDV(const s_args &args, CTPointer card) { CTError err; list l; HBCICard::instituteData d; bool chg; if (args.keyPad) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr,I18N("Please enter your pin into the reader's keypad:\n")); err=card.ref().verifyPin(); fprintf(stderr,I18N("Pin entered.\n")); } else { fprintf(stderr, I18N("Your reader has no keypad or it has been disabled.\n" "Please give the pin as an argument to this program.\n")); return 1; } } else { if (args.pin.empty()) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) fprintf(stderr, I18N("Your reader seems to have a keypad, so please\n" "use \"-k\" to enter the pin directly into the reader.\n")); else { fprintf(stderr, I18N("Please give the pin as an argument to this program.\n")); return 1; } } err=card.ref().verifyPin(args.pin); } if (!_checkPinError(err)) { fprintf(stderr,I18N("Could not verify pin: %s\n"),err.errorString().c_str()); return 3; } l=_getList(card,args.idx); if (l.empty()) { fprintf(stderr, I18N("No users prepared on this card. Maybe this is not a HBCI card ?\n")); return 2; } else { chg=false; d=l.front(); if (!args.server.empty()) { d.setAddress(args.server); d.setService(2); // TCP chg=true; } if (!args.user.empty()) { d.setUser(args.user); chg=true; } if (!args.bank.empty()) { d.setCode(args.bank); chg=true; } if (args.country!=-1) { d.setCountry(args.country); chg=true; } // write data if (chg) { if (args.idx==-1) { fprintf(stderr,I18N("ERROR: index number needed.\n")); card.ref().closeCard(); return 1; } err=card.ref().putInstituteData(args.idx,d); if (!err.isOk()) { fprintf(stderr,"%s\n",err.errorString().c_str()); return 3; } } // write SEQ if wanted if (args.seq!=-1) if (!card.ref().writeSEQ(args.seq)) { fprintf(stderr, I18N("Could not write SEQ to the card.\n")); return 3; } } // else return 0; } int dumpRSA(const s_args &args, CTPointer card) { list l; list::iterator it; CTError err; unsigned int i; if (args.keyPad) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("Please enter your pin into the reader's keypad:\n")); err=card.ref().verifyPin(0x90); fprintf(stderr,I18N("Pin entered.\n")); } else { fprintf(stderr, I18N("Your reader has no keypad or it has been disabled.\n" "Please give the pin as an argument to this program.\n")); return 1; } } else { if (args.pin.empty()) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("No pin. Your reader seems to have a keypad, so please\n" "use \"-k\" to enter the pin directly into the reader.\n")); return 1; } else { fprintf(stderr, I18N("Please give the pin as an argument to this program.\n")); return 1; } } else err=card.ref().verifyPin(0x90, args.pin); } if (!_checkPinError(err)) { fprintf(stderr, I18N("Could not verify pin: %s\n"),err.errorString().c_str()); return 3; } fprintf(stderr,I18N("Pin ok.\n")); try { RSACard::KeyLogStatus st; if (args.idx<1) { st=card.ref().readKeyLogStatus(); for (i=0; i card) { CTError err; bool chg; RSACard::BankDescription d; if (args.idx<1) { fprintf(stderr,I18N("You must specify an index number >0 !\n")); return 1; } try { if (args.keyPad) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("Please enter your pin into the reader's keypad:\n")); err=card.ref().verifyPin(0x90); fprintf(stderr,I18N("Pin entered.\n")); } else { fprintf(stderr, I18N("Your reader has no keypad or it has been disabled.\n" "Please give the pin as an argument to this program.\n")); return 1; } } else { if (args.pin.empty()) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) fprintf(stderr, I18N("Your reader seems to have a keypad, so please\n" "use \"-k\" to enter the pin directly into the reader.\n")); else { fprintf(stderr, I18N("Please give the pin as an argument to this program.\n")); return 1; } err=card.ref().verifyPin(0x90, args.pin); } } if (!_checkPinError(err)) { fprintf(stderr, I18N("Could not verify pin: %s\n"), err.errorString().c_str()); return 3; } err=card.ref().verifyPin(0x91, card.ref().initialPin()); if (!err.isOk()) { if (err.code()==0 && err.subcode1()==0x69 && err.subcode2()==0x85) { fprintf(stderr,"%s", I18N("WARNING:\n" "========\n" "Your RSA card does not allow me to verify the EG PIN.\n" "This makes it unusable with this tool and OpenHBCI.\n" "You should try it again, sorry.\n")); } else { fprintf(stderr,"%s\n",err.errorString().c_str()); fprintf(stderr, I18N("VERY SERIOUS WARNING:\n" "=====================\n" "Some application has set the EG pin, which normally\n" "is unset. So your stuck to that other program, please don't\n" "ever try any OpenHBCI based program with this card, it might\n" "make your card useles !\n")); } return 4; } d=card.ref().readBankDescription(args.idx-1); chg=false; if (!args.server.empty()) { d.setAddress(args.server); d.setService(2); // TCP chg=true; } if (!args.user.empty()) { d.setUserId(args.user); chg=true; } if (!args.bank.empty()) { d.setBankName(args.bank); chg=true; } if (args.country!=-1) { d.setCountry(args.country); chg=true; } // write data if (chg) { err=card.ref().writeBankDescription(args.idx-1,d); if (!err.isOk()) { fprintf(stderr,"%s\n",err.errorString().c_str()); return 3; } } // write SEQ if wanted if (args.seq!=-1) fprintf(stderr, I18N("Sorry, changing the SEQ is impossible for RSA cards.\n")); } // try catch (CTError xerr) { fprintf(stderr,I18N("Could not modify bank description: %s\n"), xerr.errorString().c_str()); return 3; } return 0; } int initPinRSA(const s_args &args, CTPointer card) { CTError err; try { if (args.keyPad) { fprintf(stderr, I18N("Changing the initial pin using the keypad is impossible,\n" "you must give the new pin via \"-p\".\n" "For paranoids with a keypad: You can change the inital pin\n" "to a temporary pin and later change that temporary pin to\n" "the pin you really like to use.\n" "This way no trojan horse could monitor your real pin.\n")); return 1; } fprintf(stderr,I18N("Changing initial pin.\n")); if (args.pin.empty()) { fprintf(stderr,I18N("New pin needed (-p PIN)\n")); return 1; } err=card.ref().changePin(0x90, card.ref().initialPin(), args.pin); if (!_checkPinError(err)) { fprintf(stderr, I18N("The pin of your card seems not to be the initial pin.\n" "Maybe you already changed that pin ?\n" "(Result was: %s)\n"), err.errorString().c_str()); return 3; } fprintf(stderr,I18N("Pin changed.\n")); } catch (CTError xerr) { fprintf(stderr,I18N("Could not change pin: %s\n"), xerr.errorString().c_str()); return 4; } return 0; } int chgPinRSA(const s_args &args, CTPointer card) { CTError err; try { if (args.pin.empty() && args.pin2.empty() && args.keyPad) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("Please enter both pins into the key pad:\n")); err=card.ref().changePin(0x90); } else { fprintf(stderr, I18N("Your reader seems not to have a keypad.\n" "Please give the pins as arguments to this program " "(-p PIN1 -P PIN2) and omit \"-k\".\n")); return 2; } } else if (!args.pin.empty() && !args.pin2.empty() && !args.keyPad) { err=card.ref().changePin(0x90,args.pin, args.pin2); } else { fprintf(stderr, I18N("Please give BOTH pins as arguments to this program " "(-p PIN1 -P PIN2) OR use \"-k\" to enter the pin\n" "into the reader's keypad.\n")); return 2; } if (!_checkPinError(err)) { fprintf(stderr, I18N("Could not verify pin: %s\n"), err.errorString().c_str()); return 3; } fprintf(stderr,I18N("Pin changed.\n")); } catch (CTError xerr) { fprintf(stderr,I18N("Could not change pin: %s\n"), xerr.errorString().c_str()); return 4; } return 0; } int keysRSA(const s_args &args, CTPointer card) { int i; int j; CTError err; j=0; if (args.keyPad) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("Please enter your pin into the reader's keypad:\n")); err=card.ref().verifyPin(0x90); fprintf(stderr,I18N("Pin entered.\n")); } else { fprintf(stderr, I18N("Your reader has no keypad or it has been disabled.\n" "Please give the pin as an argument to this program.\n")); return 1; } } else { if (args.pin.empty()) { if (card.ref().readerFlags() & CHIPCARD_READERFLAGS_KEYPAD) { fprintf(stderr, I18N("No pin. Your reader seems to have a keypad, so please\n" "use \"-k\" to enter the pin directly into the reader.\n")); return 1; } else { fprintf(stderr, I18N("Please give the pin as an argument to this program.\n")); return 1; } } else err=card.ref().verifyPin(0x90, args.pin); } if (!_checkPinError(err)) { fprintf(stderr, I18N("Could not verify pin: %s\n"), err.errorString().c_str()); return 3; } fprintf(stderr,I18N("Pin ok.\n")); try { for (i=0x81; i<0x8b; i++) { RSACard::KeyDescriptor key(card.ref().readKeyDescriptor(i)); if (key.status()!=0x08) { if (j<1) { fprintf(stdout, I18N("Key Id Status Number Version\n")); fprintf(stdout, "------------------------------\n"); } fprintf(stdout, "%3d %02x %02x %3d %3d\n", j+1, i, key.status(), key.keyNumber(), key.keyVersion()); j++; } } for (i=0x91; i<0x9b; i++) { RSACard::KeyDescriptor key(card.ref().readKeyDescriptor(i)); if (key.status()!=0x08) { if (j<1) { fprintf(stdout, I18N("Key Id Status Number Version\n")); fprintf(stdout, "------------------------------\n"); } fprintf(stdout, "%3d %02x %02x %3d %3d\n", j+1, i, key.status(), key.keyNumber(), key.keyVersion()); j++; } } } catch (CTError xerr) { fprintf(stderr,I18N("Could not check keys: %s\n"), xerr.errorString().c_str()); return 3; } if (j==0) fprintf(stdout,I18N("No keys on the card.\n")); return 0; } int pinStatusRSA(const s_args &args, CTPointer card) { CTError err; int maxerr; int errleft; err=card.ref().pinStatus(maxerr, errleft); if (!err.isOk()) { fprintf(stderr,I18N("Could not check PIN status: %s\n"), err.errorString().c_str()); return 3; } fprintf(stdout, I18N("Maximum bad tries: %d\nBad tries left: %d\n"), maxerr, errleft); return 0; } int main(int argc, char **argv) { s_args args; int rv; string cmd; CTPointer card; CTPointer hbcicard; CTPointer rsacard; CTError err; #ifdef HAVE_GETTEXT_ENVIRONMENT setlocale(LC_ALL,""); if (bindtextdomain("hbcicard", I18N_PATH)==0) { fprintf(stderr," Error bindtextdomain()\n"); } if (textdomain("hbcicard")==0) { fprintf(stderr," Error textdomain()\n"); } #endif rv=checkArgs(args,argc,argv); if (rv==-1) return 0; else if (rv) return rv; if (argc<2) { usage(argv[0]); return 1; } if (args.params.empty()) { usage(argv[0]); return 1; } try { if (Logger_Open("hbcicard", args.logFile.c_str(), args.logType, LoggerFacilityUser)) { fprintf(stderr, I18N("Could not start logging, aborting.\n")); return 2; } Logger_SetLevel(args.logLevel); rv=ChipCard_Init(args.configFile.c_str(),0); if (rv!=CHIPCARD_SUCCESS) { fprintf(stderr, I18N("Error initializing libchipcard (%d), aborting.\n"),rv); return 2; } fprintf(stderr,I18N("Opening card.\n")); rv=openCard(card); if (rv==0) { hbcicard=new HBCICard(card.ref()); card=0; err=hbcicard.ref().reopenCard(); if (err.isOk()) { // its a DDV card, so perform DDV commands cmd=args.params.front(); if (cmd=="dump") rv=dumpDDV(args, hbcicard); else if (cmd=="set") rv=setDDV(args, hbcicard); else if (cmd=="type") { HBCICard::CardData cd; rv=0; cd=hbcicard.ref().getCardId(); if (cd.cardType()==k_HBCICARD_TYPE_0) fprintf(stdout, I18N("Card type is: DDV-0 card\n")); else if (cd.cardType()==k_HBCICARD_TYPE_1) fprintf(stdout, I18N("Card type is: DDV-1 card\n")); else { fprintf(stderr,I18N("Unknown DDV card\n")); rv=2; } } else if (cmd=="info") { HBCICard::CardData cd; int y; rv=0; cd=hbcicard.ref().getCardId(); if (cd.cardType()==k_HBCICARD_TYPE_0) fprintf(stdout, I18N("Card Type : DDV-0\n")); else if (cd.cardType()==k_HBCICARD_TYPE_1) fprintf(stdout, I18N("Card Type : DDV-1\n")); else { fprintf(stderr,I18N("Unknown DDV card\n")); rv=2; } fprintf(stdout,I18N("Country Code : %d\n"),cd.countryCode()); fprintf(stdout,I18N("Industrial Key: %d\n"),cd.industrialKey()); fprintf(stdout,I18N("Institute Code: %d\n"),cd.shortInstituteCode()); fprintf(stdout,I18N("Card Number : %s\n"),cd.cardNumber().c_str()); y=cd.active_year(); if (y<100) { if (y<90) y+=2000; else y+=1900; } fprintf(stdout,I18N("Valid Since : %d.%d.%d\n"), cd.active_day(), cd.active_month(), y); y=cd.bestuntil_year(); if (y<100) { if (y<90) y+=2000; else y+=1900; } fprintf(stdout,I18N("Valid Until : %d/%d\n"), cd.bestuntil_month(), y); fprintf(stdout,I18N("Currency : %s\n"),cd.currency().c_str()); fprintf(stdout, I18N("ATR : %s\n"), CTMisc::bin2hex(hbcicard.ref().atr(),1).c_str()); } else { fprintf(stderr,I18N("Unknown command for DDV cards.\n")); usage(argv[0]); rv=1; } err=hbcicard.ref().closeCard(); if (!err.isOk(0x62)) { fprintf(stderr,"%s\n",err.errorString().c_str()); rv=2; } hbcicard=0; } else { rsacard=new RSACard(hbcicard.ref()); hbcicard=0; err=rsacard.ref().reopenCard(); if (err.isOk()) { // its a RSA card, so perform RSA commands cmd=args.params.front(); if (cmd=="dump") rv=dumpRSA(args, rsacard); else if (cmd=="set") rv=setRSA(args, rsacard); else if (cmd=="chgpin") rv=chgPinRSA(args, rsacard); else if (cmd=="initpin") rv=initPinRSA(args, rsacard); else if (cmd=="keys") { rv=keysRSA(args, rsacard); } else if (cmd=="type") { fprintf(stdout,I18N("Card type is: RSA card\n")); rv=0; } else if (cmd=="info") { fprintf(stdout,I18N("Card Type : RSA\n")); fprintf(stdout,I18N("Card Number : %s\n"), rsacard.ref().cardNumber().c_str()); fprintf(stdout, I18N("ATR : %s\n"), CTMisc::bin2hex(rsacard.ref().atr(),1).c_str()); rv=0; } else if (cmd=="pinstatus") { rv=pinStatusRSA(args, rsacard); } else { fprintf(stderr,I18N("Unknown command for RSA cards.\n")); usage(argv[0]); rv=1; } err=rsacard.ref().closeCard(); if (!err.isOk(0x62)) { fprintf(stderr,"%s\n",err.errorString().c_str()); rv=2; } rsacard=0; } else { fprintf(stderr, I18N("Sorry, this is neither a RSA nor a DDV card.\n")); err=rsacard.ref().closeCard(); if (!err.isOk(0x62)) { fprintf(stderr,"%s\n",err.errorString().c_str()); rv=2; } rsacard=0; } } Logger_Close(); } // if card open } // try catch (CTError xerr) { fprintf(stderr,"Exception: %s\n", xerr.errorString().c_str()); rv=3; } ChipCard_Fini(); return rv; }