Package org.kapott.hbci.passport

Source Code of org.kapott.hbci.passport.HBCIPassportRSA

/**
*
*/
package org.kapott.hbci.passport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CardTerminals;
import javax.smartcardio.TerminalFactory;

import org.kapott.cryptalgs.SignatureParamSpec;
import org.kapott.hbci.callback.HBCICallback;
import org.kapott.hbci.datatypes.SyntaxCtr;
import org.kapott.hbci.exceptions.HBCI_Exception;
import org.kapott.hbci.exceptions.InvalidPassphraseException;
import org.kapott.hbci.manager.HBCIKey;
import org.kapott.hbci.manager.HBCIUtils;
import org.kapott.hbci.manager.HBCIUtilsInternal;
import org.kapott.hbci.manager.LogFilter;
import org.kapott.hbci.smartcardio.RSABankData;
import org.kapott.hbci.smartcardio.RSACardService;
import org.kapott.hbci.smartcardio.RSAKeyData;

/**
* HBCI-Passport fuer RDH-Chipkarten.
*/
public class HBCIPassportRSA extends AbstractRDHPassport implements HBCIPassportChipcard
{

    protected final static byte[] CIPHER_SALT={(byte) 0x56, (byte) 0xbc, (byte) 0x1c, (byte) 0x88,
                                               (byte) 0x1f, (byte) 0xe3, (byte) 0x73, (byte) 0xcc};
    protected final static int CIPHER_ITERATIONS=987;
   
    private final static int KEY_INST_SIG = 0;
    private final static int KEY_INST_ENC = 1;
    private final static int KEY_MY_PUBLIC_SIG = 2;
    private final static int KEY_MY_PUBLIC_ENC = 3;
   
    private String filename;
    private HBCIKey[] keys;
    private String cardid;
    private boolean pinEntered;
    private int useSoftPin;
    private byte[] softPin;
    private SecretKey passportKey;
    private int entryIdx;
    private String forcedProfileVersion;
    private String bankId;
    private String defaultCustomerId;
   
    private Card smartCard;
    private RSACardService cardService;
   
    /**
     * ct.
     * @param init
     * @param dummy
     */
    public HBCIPassportRSA(Object init, int dummy)
    {
        super(init);
       
        setParamHeader("client.passport.RSA");
       
        this.forcedProfileVersion = null;
       
        keys = new HBCIKey[4];
        for (int n = 0; n < 4; n++) {
            keys[n] = null;
        }
    }
   
    /**
     * ct.
     * @param init
     */
    public HBCIPassportRSA(Object init)
    {
        this(init, 0);
       
        ObjectInputStream is = null;
       
        try {
            ////////////////////////////////////////////////////////////////////////
            // set parameters for initializing card
            //setUseBio(Integer.parseInt(HBCIUtils.getParam(getParamHeader() + ".usebio", "-1")));
            setUseSoftPin(Integer.parseInt(HBCIUtils.getParam(getParamHeader() + ".softpin", "-1")));
            setSoftPin(new byte[0]);
            setPINEntered(false);
            setEntryIdx(Integer.parseInt(HBCIUtils.getParam(getParamHeader() + ".entryidx", "1")));
            //
            ////////////////////////////////////////////////////////////////////////
           
            ////////////////////////////////////////////////////////////////////////
            // init card
            HBCIUtils.log("initializing javax.smartcardio", HBCIUtils.LOG_DEBUG);
            HBCIUtilsInternal.getCallback().callback(this, HBCICallback.NEED_CHIPCARD, HBCIUtilsInternal.getLocMsg("CALLB_NEED_CHIPCARD"), HBCICallback.TYPE_NONE, null);
           
            initCT();
            HBCIUtilsInternal.getCallback().callback(this, HBCICallback.HAVE_CHIPCARD, "", HBCICallback.TYPE_NONE, null);
            //
            ////////////////////////////////////////////////////////////////////////
           
            ////////////////////////////////////////////////////////////////////////
            // init basic bank data
            setPort(new Integer(3000));
            setFilterType("None");
            try {
                readBankData();
                readKeyData();
            } catch (HBCI_Exception e) {
                throw e;
            } catch (Exception e) {
                throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INSTDATAERR"), e);
            }
            //
            ////////////////////////////////////////////////////////////////////////
           
            ////////////////////////////////////////////////////////////////////////
            // read passport file
            String path = HBCIUtils.getParam(getParamHeader() + ".path", "./");
            setFileName(HBCIUtilsInternal.withCounter(path + getCardId(), getEntryIdx() - 1));
            HBCIUtils.log("loading passport data from file " + getFileName(), HBCIUtils.LOG_DEBUG);
           
            File file = new File(getFileName());
           
            if (!file.exists() || !file.isFile() || !file.canRead()) {
                HBCIUtils.log("have to create new passport file", HBCIUtils.LOG_WARN);
                askForMissingData(true, true, true, false, false, true, true);
                saveChanges();
            }
           
            int retries = Integer.parseInt(HBCIUtils.getParam("client.retries.passphrase", "3"));
           
            while (true) { // loop for entering the correct passphrase
                if (getPassportKey() == null)
                    setPassportKey(calculatePassportKey(FOR_LOAD));
               
                PBEParameterSpec paramspec = new PBEParameterSpec(CIPHER_SALT, CIPHER_ITERATIONS);
                Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
                cipher.init(Cipher.DECRYPT_MODE, getPassportKey(), paramspec);
               
                try {
                    is = new ObjectInputStream(new CipherInputStream(new FileInputStream(file), cipher));
                } catch (StreamCorruptedException e) {
                    setPassportKey(null); // Passwort resetten
                    retries--;
                    if (retries<=0)
                        throw new InvalidPassphraseException();
                } catch (Exception e) {
                    throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_READERR"), e);
                }
               
                // wir habens
                if (is != null) {
                    setBPD((Properties) is.readObject());
                    setUPD((Properties) is.readObject());
                    setHBCIVersion((String) is.readObject());
                    // this could be stored on the chipcard, but we use the file
                    setSysId((String) is.readObject());
                    setCustomerId((String) is.readObject());
                    break;
                }
            }
            //
            ////////////////////////////////////////////////////////////////////////
        } catch (Exception e) {
            // Im Fehlerfall wieder schliessen
            try {
                closeCT();
            } catch (Exception ex) {
                HBCIUtils.log(ex);
            }
           
            if (e instanceof HBCI_Exception)
                throw (HBCI_Exception) e;
           
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_CTERR"), e);
        } finally {
            // Close Passport-File
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    HBCIUtils.log(e);
                }
            }
        }
    }
   
    @Override
    public String getCustomerId() {
        if (getStoredCustomerId() == null || getStoredCustomerId().length() == 0) {
            if (getDefaultCustomerId() == null || getDefaultCustomerId().length() == 0) {
                return getUserId();
            } else {
                return getDefaultCustomerId();
            }
        } else {
            return getStoredCustomerId();
        }
    }
   
    public String getDefaultCustomerId() {
        return defaultCustomerId;
    }

    public void setDefaultCustomerId(String defaultCustomerId) {
        this.defaultCustomerId = defaultCustomerId;
    }

    public void setBankId(String bankId) {
        this.bankId = bankId;
    }
   
    public String getBankId() {
        return bankId;
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportChipcard#setFileName(java.lang.String)
     */
    @Override
    public void setFileName(String filename)
    {
        this.filename = filename;
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportChipcard#getFileName()
     */
    @Override
    public String getFileName()
    {
        return filename;
    }
   
    public void setCardId(String cardid) {
        this.cardid = cardid;
    }
   
    public String getCardId() {
        return cardid;
    }
   
    public void setPINEntered(boolean pinEntered) {
        this.pinEntered = pinEntered;
    }
   
    public boolean isPINEntered() {
        return pinEntered;
    }
   
    public void setUseSoftPin(int useSoftPin) {
        this.useSoftPin = useSoftPin;
    }
   
    public int getUseSoftPin() {
        return useSoftPin;
    }
   
    public void setSoftPin(byte[] softPin) {
        LogFilter.getInstance().addSecretData(new String(softPin), "X", LogFilter.FILTER_SECRETS);
        this.softPin = softPin;
    }
   
    public byte[] getSoftPin() {
        return softPin;
    }
   
    protected void setPassportKey(SecretKey passportKey) {
        this.passportKey = passportKey;
    }
   
    protected SecretKey getPassportKey() {
        return passportKey;
    }
   
    public void setEntryIdx(int entryIdx) {
        this.entryIdx = entryIdx;
    }
   
    public int getEntryIdx() {
        return entryIdx;
    }
   
    @Override
    public void setProfileVersion(String version) {
        if (version != null) {
            Integer.parseInt(version);   // check for valid integer value
        }
        this.forcedProfileVersion = version;
    }
   
    @Override
    public String getProfileVersion() {
        String result = this.forcedProfileVersion;
       
        if (result == null) {
            HBCIUtils.log("no RDH profile version explicity specified - starting autodetection", HBCIUtils.LOG_DEBUG);
           
            /* TODO: do not use the hbci-version stored in the passport, but the
             * hbci version of the current HBCIHandler associated with this passport.
             * This will be easy in HBCI4Java-3, but in HBCI4Java-2 this is an
             * ugly problem - broken by design */
            if (getHBCIVersion().length() != 0 && !getHBCIVersion().startsWith("3")) { // TODO: support FinTS-4, too
                result = "1";
                setProfileVersion(result);
                HBCIUtils.log("this is HBCI version '" + getHBCIVersion() + "', which only supports RDH-1", HBCIUtils.LOG_DEBUG);
            } else {
                HBCIKey key = getMyPublicSigKey();
                if (key != null) {
                    // profil-erkennung anhand schluesselnummer
                    result = key.num;
                    setProfileVersion(result);
                    HBCIUtils.log("using user sig key num '" + result + "' as profile version", HBCIUtils.LOG_DEBUG);
                } else {
                    key = getInstEncKey();
                    if (key != null && (key.num.equals("1") || key.num.equals("2") || key.num.equals("10"))) {
                        // found a sig key with a valid key num - so we use this as the profile version
                        result = key.num;
                        HBCIUtils.log("using inst enc key num '" + result + "' as RDH profile version", HBCIUtils.LOG_DEBUG);
                    } else {
                        // neither user keys nor inst keys present - using highest available profile
                        HBCIUtils.log(
                            "no keys found in passport - so we use the highest available profile",
                            HBCIUtils.LOG_DEBUG);

                        // es gibt noch gar keine schl�ssel - also nehmen wir die
                        // h�chste unterst�tzte profil-nummer

                        String[][] methods = getSuppSecMethods();
                        int        maxVersion = 0;
                        for (int i = 0; i < methods.length; i++) {
                            String method = methods[i][0];
                            int version = Integer.parseInt(methods[i][1]);
   
                            if (method.equals("RDH") &&
                                    (version == 1 || version == 2 || version == 10)) {
                                // es werden nur RDH-1, RDH-2 und RDH-10 betrachtet, weil
                                // alle anderen rdh-profile nicht f�r software-l�sungen
                                // zugelassen sind
                                if (version > maxVersion) {
                                    maxVersion = version;
                                }
                            }
                        }
   
                        if (maxVersion != 0) {
                            result = Integer.toString(maxVersion);
                            setProfileVersion(result);
                        }
                        HBCIUtils.log(
                            "using RDH profile '" + result + "' taken from supported profiles (BPD)",
                            HBCIUtils.LOG_DEBUG);
                    }
                }
            }
        } else {
            HBCIUtils.log("using forced RDH profile version '" + result + "'", HBCIUtils.LOG_DEBUG);
        }
       
        return result;
    }

    private void setKey(int i, HBCIKey key) {
        // System.out.println("passportDDV: setting key "+i+" to "+(key==null?"null":key.country+":"+key.blz+":"+key.cid+":"+key.num+":"+key.version));
        keys[i] = key;
    }

    private HBCIKey getKey(int i) {
        return keys[i];
    }

    @Override
    public void setInstSigKey(HBCIKey key) {
        setKey(KEY_INST_SIG, key);
    }

    @Override
    public void setInstEncKey(HBCIKey key) {
        setKey(KEY_INST_ENC, key);
    }

    @Override
    public void setMyPublicSigKey(HBCIKey key) {
        setKey(KEY_MY_PUBLIC_SIG, key);
    }

    @Override
    public void setMyPrivateSigKey(HBCIKey key) {
    }

    @Override
    public void setMyPublicEncKey(HBCIKey key) {
        setKey(KEY_MY_PUBLIC_ENC, key);
    }

    @Override
    public void setMyPrivateEncKey(HBCIKey key) {
    }

    @Override
    public void setMyPublicDigKey(HBCIKey key) {
    }

    @Override
    public void setMyPrivateDigKey(HBCIKey key) {
    }

    @Override
    public String getInstSigKeyName() {
        return getInstSigKey() != null ? getInstSigKey().userid : null;
    }

    @Override
    public String getInstSigKeyNum() {
        return getInstSigKey() != null ? getInstSigKey().num : null;
    }

    @Override
    public String getInstSigKeyVersion() {
        return getInstSigKey() != null ? getInstSigKey().version : null;
    }

    @Override
    public String getInstEncKeyName() {
        return getInstEncKey() != null ? getInstEncKey().userid : null;
    }

    @Override
    public String getInstEncKeyNum() {
        return getInstEncKey() != null ? getInstEncKey().num : null;
    }

    @Override
    public String getInstEncKeyVersion() {
        return getInstEncKey() != null ? getInstEncKey().version : null;
    }

    @Override
    public String getMySigKeyName() {
        return getMyPublicSigKey() != null ? getMyPublicSigKey().userid : null;
    }

    @Override
    public String getMySigKeyNum() {
        return getMyPublicSigKey() != null ? getMyPublicSigKey().num : null;
    }

    @Override
    public String getMySigKeyVersion() {
        return getMyPublicSigKey() != null ? getMyPublicSigKey().version : null;
    }

    @Override
    public String getMyEncKeyName() {
        return getMyPublicEncKey() != null ? getMyPublicEncKey().userid : null;
    }

    @Override
    public String getMyEncKeyNum() {
        return getMyPublicEncKey() != null ? getMyPublicEncKey().num : null;
    }

    @Override
    public String getMyEncKeyVersion() {
        return getMyPublicEncKey() != null ? getMyPublicEncKey().version : null;
    }

    @Override
    public byte[] hash(byte[] data) {
        data = super.hash(data);
       
        SignatureParamSpec sps = getSignatureParamSpec();
        MessageDigest dig;
        try {
            dig = MessageDigest.getInstance(sps.getHashAlg(), sps.getProvider());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (NoSuchProviderException e) {
            throw new RuntimeException(e);
        }
        return dig.digest(data);
    }

    @Override
    public byte[] sign(byte[] data) {
        checkPIN();
        return ctSign(data);
    }

    @Override
    public boolean verify(byte[] data, byte[] sig) {
        checkPIN();
        return ctVerify(data, sig);
    }

    private byte[] encryptMessage(byte[] plainMsg, SecretKey msgkey) {
        try {
            Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
            byte[] iv = new byte[8];
            Arrays.fill(iv, (byte) 0);
            IvParameterSpec spec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, msgkey, spec);

            return cipher.doFinal(plainMsg);
        } catch (Exception ex) {
            throw new HBCI_Exception("*** can not encrypt message", ex);
        }
    }
   
    private byte[] encryptKey(SecretKey msgkey) {
        try {
            // schluessel als byte-array abspeichern
            SecretKeyFactory factory=SecretKeyFactory.getInstance("DESede");
            DESedeKeySpec spec=(DESedeKeySpec)(factory.getKeySpec(msgkey,DESedeKeySpec.class));
            byte[] plainKey=spec.getKey(); // plainKey ist der DESede-Key

            // abh�ngig von der L�nge des inst-enc-keys
            int    cryptDataSize=getCryptDataSize(getInstEncKey().key);
            byte[] plainText=new byte[cryptDataSize];
            Arrays.fill(plainText,(byte)(0));
            System.arraycopy(plainKey,0,plainText,plainText.length-16,16);
           
            byte[] result = ctEncipher(plainText);
           
            result=checkForCryptDataSize(result, cryptDataSize);
            return result;
        } catch (Exception ex) {
            throw new HBCI_Exception("*** can not encrypt message key", ex);
        }
    }

    @Override
    public byte[][] encrypt(byte[] plainMsg) {
        try {
            SecretKey msgkey = createMsgKey();
            byte[] cryptMsg = encryptMessage(plainMsg, msgkey);
            byte[] cryptKey = encryptKey(msgkey);

            byte[][] ret = new byte[2][];
            ret[0] = cryptKey;
            ret[1] = cryptMsg;

            return ret;
        } catch (Exception ex) {
            throw new HBCI_Exception("*** error while encrypting", ex);
        }
    }

    @Override
    public byte[] decrypt(byte[] cryptedKey, byte[] cryptedMsg) {
        try {
            // key entschluesseln
            byte[] plainKey = ctDecipher(cryptedKey);

            byte[] realPlainKey=new byte[24];
            System.arraycopy(plainKey,plainKey.length-16,realPlainKey,0,16);
            System.arraycopy(plainKey,plainKey.length-16,realPlainKey,16,8);

            DESedeKeySpec spec=new DESedeKeySpec(realPlainKey);
            SecretKeyFactory fac=SecretKeyFactory.getInstance("DESede");
            SecretKey key=fac.generateSecret(spec);

            // nachricht entschluesseln
            Cipher cipher=Cipher.getInstance("DESede/CBC/NoPadding");
            byte[] ivarray=new byte[8];
            Arrays.fill(ivarray,(byte)(0));
            IvParameterSpec iv=new IvParameterSpec(ivarray);
            cipher.init(Cipher.DECRYPT_MODE,key,iv);
            return cipher.doFinal(cryptedMsg);
        } catch (Exception ex) {
            throw new HBCI_Exception("*** error while decrypting message",ex);
        }
    }
   
    @Override
    public void close() {
        super.close();
       
        resetPassphrase();
        setPINEntered(false);
        closeCT();
    }

    /**
     * @see org.kapott.hbci.passport.HBCIPassportChipcard#saveBankData()
     */
    @Override
    public void saveBankData()
    {
        try {
            checkPIN();
            ctSaveBankData();
        } catch (Exception e) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INSTSAVEERR"),e);
        }
    }

   
    @Override
    public void resetPassphrase() {
        passportKey = null;
    }

    @Override
    public boolean hasInstSigKey() {
        return getInstSigKey() != null;
    }

    @Override
    public boolean hasInstEncKey() {
        return getInstEncKey() != null;
    }

    @Override
    public boolean hasMySigKey() {
        return getMyPublicSigKey() != null;
    }

    @Override
    public boolean hasMyEncKey() {
        return getMyPublicEncKey() != null;
    }

    @Override
    public HBCIKey getMyPublicSigKey() {
        return getKey(KEY_MY_PUBLIC_SIG);
    }

    @Override
    public HBCIKey getMyPublicEncKey() {
        return getKey(KEY_MY_PUBLIC_ENC);
    }

    @Override
    public HBCIKey getMyPublicDigKey() {
        return null;
    }

    @Override
    public HBCIKey getMyPrivateSigKey() {
        return getMyPublicSigKey();
    }

    @Override
    public HBCIKey getMyPrivateEncKey() {
        return getMyPublicEncKey();
    }

    @Override
    public HBCIKey getMyPrivateDigKey() {
        return getMyPublicDigKey();
    }

    @Override
    public HBCIKey getInstSigKey() {
        return getKey(KEY_INST_SIG);
    }

    @Override
    public HBCIKey getInstEncKey() {
        return getKey(KEY_INST_ENC);
    }

    @Override
    public void saveChanges() {
        try {
            checkPIN();
            ctSaveBankData();
            ctSaveSigId();

            if (passportKey == null)
                passportKey = calculatePassportKey(FOR_SAVE);
           
            File passportfile = new File(getFileName());
            File directory = passportfile.getAbsoluteFile().getParentFile();
            String prefix = passportfile.getName() + "_";
            File tempfile = File.createTempFile(prefix, "", directory);

            PBEParameterSpec paramspec = new PBEParameterSpec(CIPHER_SALT, CIPHER_ITERATIONS);
            Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
            cipher.init(Cipher.ENCRYPT_MODE, passportKey, paramspec);
            ObjectOutputStream o = new ObjectOutputStream(new CipherOutputStream(new FileOutputStream(tempfile), cipher));
           
            o.writeObject(getBPD());
            o.writeObject(getUPD());
            o.writeObject(getHBCIVersion());
            // this could be stored on the chipcard, but we use the file
            o.writeObject(getSysId());
            o.writeObject(getCustomerId());
           
            o.close();
            passportfile.delete();
            tempfile.renameTo(passportfile);
        } catch (Exception e) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_WRITEERR"), e);
        }
    }
   
    public void readBankData() {
        try {
            checkPIN();
            ctReadBankData();
        } catch (Exception e) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INSTSAVEERR"),e);
        }
    }
   
    public void readKeyData() {
        try {
            checkPIN();
            ctReadKeyData();
        } catch (Exception e) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INSTSAVEERR"),e);
        }
    }
   
    private void checkPIN() {
        try {
            if (!isPINEntered()) {
                if (getUseSoftPin() == 1) {
                    String pin = HBCIUtils.getParam(getParamHeader() + ".pin");
                   
                    if (pin == null || pin.length() == 0) {
                        StringBuffer temppin = new StringBuffer();
                        HBCIUtilsInternal.getCallback().callback(this,
                                                         HBCICallback.NEED_SOFTPIN,
                                                         HBCIUtilsInternal.getLocMsg("CALLB_NEED_SOFTPIN"),
                                                         HBCICallback.TYPE_SECRET,
                                                         temppin);
                        if (temppin.length() == 0)
                            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PINZERO"));
                        pin = temppin.toString();
                        LogFilter.getInstance().addSecretData(pin, "X", LogFilter.FILTER_SECRETS);
                    }
                   
                    setSoftPin(pin.getBytes("ISO-8859-1"));
                } else {
                    HBCIUtilsInternal.getCallback().callback(this,
                                                     HBCICallback.NEED_HARDPIN,
                                                     HBCIUtilsInternal.getLocMsg("CALLB_NEED_HARDPIN"),
                                                     HBCICallback.TYPE_NONE,
                                                     null);
                }

                try {
                    ctEnterPIN();
                    setPINEntered(true);
                } catch (Exception e) {
                    HBCIUtils.setParam(getParamHeader() + ".pin", null);
                    setSoftPin(new byte[0]);
                } finally {
                    if (getUseSoftPin() != 1) {
                        HBCIUtilsInternal.getCallback().callback(this,
                                                         HBCICallback.HAVE_HARDPIN,
                                                         null,
                                                         HBCICallback.TYPE_NONE,
                                                         null);
                    }
                }
            }
        } catch (Exception e) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PINERR"), e);
        }
    }
   
    protected void initCT() {
        try {
            TerminalFactory terminalFactory = TerminalFactory.getDefault();
            CardTerminals terminals = terminalFactory.terminals();
            if (terminals == null)
                throw new HBCI_Exception("Kein Kartenleser gefunden");
           
            List<CardTerminal> list = terminals.list();
            if (list == null || list.size() == 0)
                throw new HBCI_Exception("Kein Kartenleser gefunden");
           
            HBCIUtils.log("found card terminals:", HBCIUtils.LOG_INFO);
            for (CardTerminal t : list) {
                HBCIUtils.log("  " + t.getName(), HBCIUtils.LOG_INFO);
            }

            CardTerminal terminal = null;

            // Checken, ob der User einen konkreten Kartenleser vorgegeben hat
            String name = HBCIUtils.getParam(getParamHeader() + ".pcsc.name", null);
            if (name != null) {
                HBCIUtils.log("explicit terminal name given, trying to open terminal: " + name, HBCIUtils.LOG_DEBUG);
                terminal = terminals.getTerminal(name);
                if (terminal == null)
                    throw new HBCI_Exception("Kartenleser \"" + name + "\" nicht gefunden");
            } else {
                HBCIUtils.log("open first available card terminal", HBCIUtils.LOG_DEBUG);
                terminal = list.get(0);
            }
            HBCIUtils.log("using card terminal " + terminal.getName(), HBCIUtils.LOG_DEBUG);

            // wait for card
            if (!terminal.waitForCardPresent(60 * 1000L))
              throw new HBCI_Exception("Keine Chipkarte in Kartenleser " + terminal.getName() + " gefunden");

            this.smartCard = terminal.connect("T=1");
           
            this.cardService = new RSACardService();
            HBCIUtils.log(" using: " + this.cardService.getClass().getName(),HBCIUtils.LOG_INFO);
            this.cardService.init(this.smartCard);
           
            // getCID
            byte[] cid = this.cardService.getCID();
            this.setCID(new String(cid, "ISO-8859-1"));
           
            // extract card id
            StringBuffer cardId = new StringBuffer();
            for (int i = 0; i < cid.length; i++) {
                cardId.append((char) (((cid[i] >> 4) & 0x0F) + 0x30));
                cardId.append((char) ((cid[i] & 0x0F) + 0x30));
            }
            this.setCardId(cardId.toString());
        } catch (HBCI_Exception he) {
            throw he;
        } catch (Exception e) {
            throw new HBCI_Exception(e);
        }
    }
   
    protected void ctEnterPIN() {
        if (getUseSoftPin() == 1)
            cardService.verifySoftPIN(0x10, this.getSoftPin());
        else
            cardService.verifyHardPIN(0x10);
    }
   
    protected void ctReadBankData() {
        int idx = getEntryIdx() - 1;
       
        RSABankData bankData = cardService.readBankData(idx);
       
        setCountry(SyntaxCtr.getName(bankData.getCountry()));
        setBLZ(bankData.getBankCode());
        setHost(bankData.getComAddress());
        setUserId(bankData.getUserId());
        setBankId(bankData.getBankId());
        // this could be stored on the chipcard - use it for first initialization
        setSysId(bankData.getSystemId());
        setDefaultCustomerId(bankData.getCustomerId());
    }
   
    protected void ctSaveBankData() {
        int idx = getEntryIdx() - 1;
       
        RSABankData bankData = cardService.readBankData(idx);
       
        bankData.setCountry(SyntaxCtr.getCode(getCountry()));
        bankData.setBankCode(getBLZ());
        bankData.setComAddress(getHost());
        bankData.setUserId(getUserId());
        bankData.setBankId(getBankId());
        // this could be stored on the chipcard, but we use the file
        // bankData.setSystemId("0".equals(getSysId()) ? "" : getSysId());
       
        cardService.writeBankData(idx, bankData);
    }
   
    protected void ctReadKeyData() {
        int idx = getEntryIdx() - 1;
       
        setSigId(new Long(cardService.readSigId(idx)));
       
        // readKeyData
        RSAKeyData[] keyData = cardService.readKeyData(idx);
       
        if (keyData[0].getStatus() == 0x10 && keyData[0].getKeyType() == 0x53) {
            HBCIUtils.log("found valid instSigKey ", HBCIUtils.LOG_DEBUG);
            setInstSigKey(new HBCIKey(
                            getCountry(), getBLZ(), getBankId(),
                            Integer.toString(keyData[0].getKeyNum()), Integer.toString(keyData[0].getKeyVersion()),
                            keyData[0].getPublicKey()));
        }
       
        if (keyData[1].getStatus() == 0x10 && keyData[1].getKeyType() == 0x56) {
            HBCIUtils.log("found valid instEncKey ", HBCIUtils.LOG_DEBUG);
            setInstEncKey(new HBCIKey(
                            getCountry(), getBLZ(), getBankId(),
                            Integer.toString(keyData[1].getKeyNum()), Integer.toString(keyData[1].getKeyVersion()),
                            keyData[1].getPublicKey()));
        }
       
        if (keyData[2].getStatus() == 0x10 && keyData[2].getKeyType() == 0x53) {
            HBCIUtils.log("found valid myPublicSigKey ", HBCIUtils.LOG_DEBUG);
            setMyPublicSigKey(new HBCIKey(
                            getCountry(), getBLZ(), getUserId(),
                            Integer.toString(keyData[2].getKeyNum()), Integer.toString(keyData[2].getKeyVersion()),
                            keyData[2].getPublicKey()));
        }
       
        if (keyData[3].getStatus() == 0x10 && keyData[3].getKeyType() == 0x56) {
            HBCIUtils.log("found valid myPublicEncKey ", HBCIUtils.LOG_DEBUG);
            setMyPublicEncKey(new HBCIKey(
                            getCountry(), getBLZ(), getUserId(),
                            Integer.toString(keyData[3].getKeyNum()), Integer.toString(keyData[3].getKeyVersion()),
                            keyData[3].getPublicKey()));
        }
    }
   
    protected void ctSaveSigId() {
        int idx = getEntryIdx() - 1;
       
        cardService.writeSigId(idx, getSigId().intValue());
    }
   
    protected byte[] ctSign(byte[] data) {
        int idx = getEntryIdx() - 1;
       
        return cardService.sign(idx, data);
    }
   
    protected boolean ctVerify(byte[] data, byte[] sig) {
        int idx = getEntryIdx() - 1;
       
        return cardService.verify(idx, data, sig);
    }
   
    protected byte[] ctEncipher(byte[] data) {
        int idx = getEntryIdx() - 1;
       
        return cardService.encipher(idx, data);
    }
   
    protected byte[] ctDecipher(byte[] data) {
        int idx = getEntryIdx() - 1;
       
        return cardService.decipher(idx, data);
    }
   
    protected void closeCT() {
        try {
            if (smartCard!=null)
                smartCard.disconnect(false);
        } catch (HBCI_Exception e1) {
            throw e1;
        } catch (Exception e2) {
            throw new HBCI_Exception(e2);
        }
    }

}
TOP

Related Classes of org.kapott.hbci.passport.HBCIPassportRSA

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.