/*************************************************************************** $RCSfile: rsacard.h,v $ ------------------- cvs : $Id: rsacard.h,v 1.14 2003/05/07 22:27:22 aquamaniac Exp $ begin : Sat Dec 14 2002 copyright : (C) 2002 by Martin Preuss email : martin@libchipcard.de *************************************************************************** * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * * MA 02111-1307 USA * * * ***************************************************************************/ /*___________________________________________________________________________ *AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA* * W A R N I N G ! ! * * * * This class is under heavy development, it might render your card * * useless !! * * For now this class implements all methods I will need to add support for * * this previously unsupported card to OpenHBCI. * * * * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY* */ #ifndef RSACARD_H #define RSACARD_H #include #include #include using namespace std; #define KEY_STATUS_ACTIVE 0x10 #define KEY_STATUS_INACTIVE_CERT 0x0a #define KEY_STATUS_INACTIVE_FREE 0x08 #define KEY_STATUS_INACTIVE_NEW 0x07 #define KEY_STATUS_ACTIVE_NEW 0x02 #define KEY_STATUS_ACTIVE_INCOMPLETE 0x01 #define KEY_STATUS_ACTIVE_INILETTER 0x00 #define KEY_STATUS_INTERNAL_UNUSED 0xff /** * * @ingroup scards */ class CHIPCARD_API RSACard: public CTProcessorCard { public: class BankDescription { private: bool _chg; int _country; string _bankName; string _userId; char _service; string _address; string _addressSuffix; string _bankId; string _systemId; public: BankDescription(); BankDescription(const string &data); ~BankDescription(); int country() const { return _country;}; void setCountry(int i) { _country=i;}; const string &bankName() const { return _bankName;}; void setBankName(const string &s) { _chg=true; _bankName=s;}; const string &userId() const { return _userId;}; void setUserId(const string &s) { _chg=true; _userId=s;}; char service() const { return _service;}; void setService(char c) { _chg=true; _service=c;}; const string &address() const { return _address;}; void setAddress(const string &s) { _chg=true; _address=s;}; const string &addressSuffix() const { return _addressSuffix;}; void setAddressSuffix(const string &s) { _chg=true; _addressSuffix=s;}; const string &bankId() const { return _bankId;}; void setBankId(const string &s) { _chg=true; _bankId=s;}; const string &systemId() const { return _systemId;}; void setSystemId(const string &s) { _chg=true; _systemId=s;}; string toString() const; bool changed() const {return _chg;}; string dump(); }; struct KeyLogStatus { unsigned maxEntries : 3; unsigned oldENfree : 1; unsigned entries : 3; unsigned oldDSfree : 1; }; public: class KeyDescriptor { private: bool _chg; unsigned int _status; bool _isSignKey; int _keynum; int _keyver; public: KeyDescriptor(); KeyDescriptor(unsigned int st, bool isSignKey, int keynum, int keyver); KeyDescriptor(const string &data); ~KeyDescriptor(); string toString() const; unsigned int status() const { return _status;}; void setStatus(unsigned int s) { _chg=true; _status=s;}; bool isSignKey() const { return _isSignKey;}; void setIsSignKey(bool b) { _chg=true; _isSignKey=b;}; int keyNumber() const { return _keynum;}; void setKeyNumber(int k) { _chg=true; _keynum=k;}; int keyVersion() const { return _keyver;}; void setKeyVersion(int k) { _chg=true; _keyver=k;}; bool changed() const {return _chg;}; string dump(); }; private: string _cmdReadFile; string _cmdUpdateBinary; string _cmdUpdateRecord; string _cmdGenerateKeyPair; string _cmdManageSE; string _cmdSelectPubKey; string _cmdSelectPrivKey; string _cmdPutHash; string _cmdSign; string _cmdVerify; string _cmdChallenge; string _cmdEncipher; string _cmdDecipher; string _cmdActivateKey; string _cmdVerifyPin; string _cmdSecureVerifyPin; string _cmdChangePin; string _cmdSecureChangePin; string _cmdPinStatus; string _firstPin; CTError _readFile(unsigned short fid, string &data); CTError _getInitialPin(string &pin); CTError _openCard(); /** * @return -1 if not found, key index otherwise */ int _findPublicKey(unsigned int kid); CTError _manageSE(int tmpl, int kids, int kidp, int ar); int _getKeyPos_EF_LOG(int kid); CTError _changePin(int pinid, const string &oldpin, const string &newpin); CTError _changePin(int pinid); CTError _verifyPin(int pinid, const string &pin); CTError _verifyPin(int pinid); public: /** @name Constructors and Destructors * * Methods to connect and disconnect the card. Most other methods * only work if the card is open. */ //@{ RSACard(const CTCard &c); ~RSACard(); //@} /** @name Opening and closing operations * * Methods to connect and disconnect the card. Most other methods * only work if the card is open. */ //@{ /** * When this method is called normally the card is already opened by * means of @ref openCard(). However, it is likely that openCard() has * been called assuming this card is only a CTCard() object, nothing * special. You may then call THIS method here on all known card classes * to check for the type of this card. * This method must assume that any file on the card is already selected, * so it is in most cases a good idea to select the MF as the first action * of this method. * If the executing class finds that the card inserted is not of a type * it can handle then it MUST return an error. */ virtual CTError reopenCard(); /** * Opens the card for usage. * This way the card is powered on. * This method does some basic checks and retrieves basic information * about the card (whether it is a memory card or a processor card, * the size of the memory etc). * When this method successfully returns the card may be used. * @author Martin Preuss * @return CTError object that holds the result (call isOk() to see if * there was an error) */ virtual CTError openCard(); /** * Call this if you have finished working with the card. After this * method is called you may safely remove the card from the reader. * @author Martin Preuss * @return CTError object that holds the result (call isOk() to see if * there was an error) */ virtual CTError closeCard(bool force=false); //@} /** @name Informational methods * * These methods tell you about the type and the status of the card. */ //@{ /** * This method returns a short name of the class which handles this card. * A HBCI card for example returns "HBCICard". So you can use this method * to check for the type of the card. */ virtual string cardType(); /** * This method returns a comma separated list of all card types this card * inherits including the type of this card, e.g. a HBCI card would * return "CTProcessorCard, HBCICard". If you overload this method in your * own class (you SHOULD) you simply have to call this method of the * class it directly inherits. That class will then do the same, so that * there is a list upon return. */ virtual string cardTypes(); /** * Returns the initial pin of a pristine card. * On such a card verifying the pin does not work as long as you did not * change the pin using @ref changePin(). The initial pin (which MUST be * changed) is the serial number of the card stored in one of the files * on it. With this method here you get that number. * This method is only valid after @ref openCard() has been called * successfully. */ const string &initialPin() const { return _firstPin;}; /** * Returns the cards serial number. */ string cardNumber() const { return CTMisc::bin2hex(_firstPin);}; //@} /** @name Pin Verification and Changes * * These method allow verifying and changing the pin. There are methods * for terminals with keypads, too. On these you can enter the pin * directly into the card readers keypad (secure mode). */ //@{ /** * Verifies the pin without using the keypad. If your reader has a * key pad I recommend using the secure method !! * @return error code * @param kid key id (0x90 for Keyholder pin, 0x91 for device pin) * @param pin pin (ASCII) */ CTError verifyPin(int kid, const string &pin); /** * Changes the pin without using the keypad. If your reader has a * keypad I recommend using the secure method !! * @return error code * @param kid key id (0x90 for Keyholder pin, 0x91 for device pin) * @param oldpin old pin (ASCII) * @param newpin new pin (ASCII) */ CTError changePin(int kid, const string &oldpin, const string &newpin); /** * Changes the pin using the keypad of your reader. This is the recommended * method of changing the pin, since no trojan horse can spy out your * pin ! * @return error code * @param kid key id (0x90 for Keyholder pin, 0x91 for device pin) */ CTError changePin(int kid); /** * Verifies the pin using the keypad of your reader. This is the recommended * method of verifying the pin, since no trojan horse can spy out your * pin ! * @return error code * @param kid key id (0x90 for Keyholder pin, 0x91 for device pin) */ CTError verifyPin(int kid); /** * Get the pin status of the card. * @param maxerr reference to an integer to receive the maximum number of * bad tries for pin verification * @param errleft reference to an integer to receive the number of * bad tries left for pin verification */ CTError pinStatus(int &maxerr, int &errleft); //@} /** * @name Key Management * * This group contains methods to create, read, write, inspect and update * keys on the card. */ //@{ /** * Deletes a key descriptor. This allows overwriting a key stored on the * card. * @param kid key id */ CTError deleteKeyDescriptor(int kid); /** * Reads the key status for the given key. */ unsigned int readKeyStatus(int kid); /** * Updates the key status for the given key. */ CTError writeKeyStatus(int kid, unsigned int st); /** * This method updates a full 8 byte key descriptor. */ CTError writeKeyDescriptor(int kid, const string &kd); /** * Reads a fully 8 byte key descriptor. */ string readKeyDescriptor(int kid); /** * Reads the modulus of a public key. The exponent is defined to be * always 0x010001. */ string readPublicKey(int kid); /** * Updates the modulus of a public key. This is used to store the partners * public keys on the card (like the pulic keys of the bank). */ CTError writePublicKey(int kid, const string &modulus); /** * Creates a keypair for the given key id. This can take some seconds * (up to a minute). The key pair created is not automatically activated. * @return modulus of the key created */ string createKey(int kid,bool overwrite); /** * This activates a previously created key pair. After this method has been * called the new keys are stored at their final destination and used by * all subsequent calls to cryptographic methods with this key id. */ CTError activateKey(int kid, int num, int ver); /** * Checks whether the given key id belongs to a partner of to us. */ bool isBankKey(int kid); /** * Checks whether the given key id belongs to a signature key. */ bool isSignKey(int kid); /** * Translates the given information about a key into a key id which can then * be used for the other methods of this class. */ int getKeyId(int bank, bool pub, bool sign); /** * The keylog status contains information about how many bank descriptions * are in use and about whether there are newly generated but not yet * activated keys. */ KeyLogStatus readKeyLogStatus(); /** * Updates the keylog status. */ CTError writeKeyLogStatus(KeyLogStatus st); //@} /** * @name Bank Descriptions * * Methods of this group read, delete and update bank descriptions on the * card. */ //@{ BankDescription readBankDescription(int idx); CTError writeBankDescription(int idx, const BankDescription &bd); CTError deleteBankDescription(int idx); int findFreeBankDescription(); //@} /** * @name Cryptographic Methods * * Methods of this group allow signing, verifying a signature, encrypting * and decrypting data. */ //@{ string getRandom(int s); string sign(int kid, const string &data); CTError verify(int kid, const string &data, const string &signature); string encrypt(int kid, const string &data); string decrypt(int kid, const string &data); //@} /** * @name Signature Sequence Counter * * This group contains methods concerning the signature sequence counter. * This can only be read (not written) and is updated automatically upon * @ref sign(). When creating keys for a bank context then this counter * is reset to 0. */ //@{ unsigned int readSeq(int bank); CTError writeSeq(int bank, unsigned int seq); //@} }; #endif