Package org.kapott.hbci.passport

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

/*  $Id: HBCIPassportDDVPCSC.java,v 1.1 2011/11/24 21:59:37 willuhn Exp $

    This file is part of HBCI4Java
    Copyright (C) 2001-2008  Stefan Palme

    HBCI4Java 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.

    HBCI4Java 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
*/

package org.kapott.hbci.passport;

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;
import java.util.List;
import java.util.Properties;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.spec.PBEParameterSpec;
import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CardTerminals;
import javax.smartcardio.TerminalFactory;

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.smartcardio.DDVBankData;
import org.kapott.hbci.smartcardio.DDVCardService;
import org.kapott.hbci.smartcardio.DDVKeyData;

/**
* Implementierung eines DDV-Passports, welcher intern die neue Chipkarten-API
* "javax.smartcardio" von Java 6 verwendet. Die Implementierung basiert auf
* dem OCF-Code von HBCI4Java 2.5.8.
*/
public class HBCIPassportDDVPCSC extends HBCIPassportDDV
{
    private Card           smartCard;
    private DDVCardService cardService;
   
    /**
     * ct.
     * @param init
     * @param dummy
     */
    public HBCIPassportDDVPCSC(Object init, int dummy)
    {
      super(init,dummy);
    }

    /**
     * ct.
     * @param init
     */
    public HBCIPassportDDVPCSC(Object init)
    {
      this(init,0);
     
      ObjectInputStream is = null;
     
      try
      {
        ////////////////////////////////////////////////////////////////////////
        // set parameters for initializing card
        this.setUseBio(Integer.parseInt(HBCIUtils.getParam(getParamHeader()+".usebio","-1")));
        this.setUseSoftPin(Integer.parseInt(HBCIUtils.getParam(getParamHeader()+".softpin","-1")));
        this.setSoftPin(new byte[0]);
        this.setPINEntered(false);
        this.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);
       
        this.initCT();
        HBCIUtilsInternal.getCallback().callback(this,HBCICallback.HAVE_CHIPCARD,"",HBCICallback.TYPE_NONE,null);
        //
        ////////////////////////////////////////////////////////////////////////
       
        ////////////////////////////////////////////////////////////////////////
        // init basic bank data
        try {
          this.setPort(new Integer(3000));
          this.setFilterType("None");
          this.ctReadBankData();
           
          if (this.askForMissingData(true,true,true,false,false,true,false))
            this.saveBankData();
               
          this.ctReadKeyData();
        }
        catch (HBCI_Exception e1)
        {
          throw e1;
        }
        catch (Exception e)
        {
          throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INSTDATAERR"),e);
        }
        //
        ////////////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////////////
        // read passport file
        String path = HBCIUtils.getParam(getParamHeader()+".path","./");
        this.setFileName(HBCIUtilsInternal.withCounter(path+"pcsc"+getCardId(),getEntryIdx()-1));
        HBCIUtils.log("loading passport data from file "+getFileName(),HBCIUtils.LOG_DEBUG);
       
        File file = new File(this.getFileName());
        if (file.exists() && file.isFile() && file.canRead())
        {
          int retries = Integer.parseInt(HBCIUtils.getParam("client.retries.passphrase","3"));

          while (true) // loop for entering the correct passphrase
          {
            if (this.getPassportKey() == null)
              this.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 e1)
            {
              setPassportKey(null); // Passwort resetten
              retries--;
              if (retries<=0)
                throw new InvalidPassphraseException();
            }
            catch (Exception e2)
            {
              throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_READERR"),e2);
            }
           
            // wir habens
            if (is != null)
            {
              setBPD((Properties)(is.readObject()));
              setUPD((Properties)(is.readObject()));
              setHBCIVersion((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);
          }
        }
      }
    }

    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#initCT()
     */
    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");

        // Hier kann man gemaess
        // http://download.oracle.com/javase/6/docs/jre/api/security/smartcardio/spec/javax/smartcardio/CardTerminal.html#connect%28java.lang.String%29
        // auch "T=0" oder "T=1" angeben. Wir wissen allerdings noch nicht, von welchem
        // Typ die Karte ist. Daher nehmen wir "*" fuer jedes verfuegbare. Wenn wir die
        // Karte geoeffnet haben, kriegen wir dann auch das Protokoll raus.
        this.smartCard = terminal.connect("*");
        String type = this.smartCard.getProtocol();
        HBCIUtils.log(" card type: " + type,HBCIUtils.LOG_INFO);
       
        // Card-Service basierend auf dem Kartentyp erzeugen
        if (type == null || type.indexOf("=") == -1)
          throw new HBCI_Exception("Unbekannter Kartentyp");

        String id = type.substring(type.indexOf("=")+1);
        String serviceName = "org.kapott.hbci.smartcardio.DDVCardService" + id;
        HBCIUtils.log(" trying to load: " + serviceName,HBCIUtils.LOG_DEBUG);
        this.cardService = (DDVCardService) Class.forName(serviceName).newInstance();
        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<8;i++)
        {
          cardId.append((char)(((cid[i+1]>>4)&0x0F) + 0x30));
          cardId.append((char)((cid[i+1]&0x0F) + 0x30));
        }
        this.setCardId(cardId.toString());
      }
      catch (HBCI_Exception he)
      {
        throw he;
      }
      catch (Exception e)
      {
        throw new HBCI_Exception(e);
      }
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctReadBankData()
     */
    protected void ctReadBankData()
    {
      int idx = this.getEntryIdx()-1;
      DDVBankData bankData = this.cardService.readBankData(idx);
     
      this.setCountry(SyntaxCtr.getName(bankData.country));
      this.setBLZ(bankData.blz);
      this.setHost(bankData.commaddr);
      this.setUserId(bankData.userid);
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctReadKeyData()
     */
    protected void ctReadKeyData()
    {
      this.setSigId(new Long(cardService.readSigId()));
     
      // readKeyData
      DDVKeyData[] keyData=cardService.readKeyData();
     
      this.setInstSigKey(new HBCIKey(
          getCountry(), getBLZ(), getUserId(),
          Integer.toString(keyData[0].num), Integer.toString(keyData[0].version),
          null));
     
      this.setInstEncKey(new HBCIKey(
          getCountry(), getBLZ(), getUserId(),
          Integer.toString(keyData[1].num), Integer.toString(keyData[1].version),
          null));
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctEnterPIN()
     */
    protected void ctEnterPIN()
    {
      if (getUseSoftPin()==1)
        this.cardService.verifySoftPIN(1, this.getSoftPin());
      else
        this.cardService.verifyHardPIN(1);
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctSaveBankData()
     */
    protected void ctSaveBankData()
    {
      int idx = this.getEntryIdx()-1;
      DDVBankData bankData;
     
      bankData=cardService.readBankData(idx);
      bankData.country=SyntaxCtr.getCode(this.getCountry());
      bankData.blz=this.getBLZ();
      bankData.commaddr=this.getHost();
      bankData.userid=this.getUserId();
      cardService.writeBankData(idx,bankData);
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctSaveSigId()
     */
    protected void ctSaveSigId()
    {
      cardService.writeSigId(getSigId().intValue());
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctSign(byte[])
     */
    protected byte[] ctSign(byte[] data)
    {
      return cardService.sign(data);
    }

    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctEncrypt()
     */
    protected byte[][] ctEncrypt()
    {
      return cardService.getEncryptionKeys(Integer.parseInt(getInstEncKeyNum()));
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#ctDecrypt(byte[])
     */
    protected byte[] ctDecrypt(byte[] cryptedKey)
    {
      return cardService.decrypt(Integer.parseInt(getInstEncKeyNum()),cryptedKey);
    }
   
    /**
     * @see org.kapott.hbci.passport.HBCIPassportDDV#closeCT()
     */
    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.HBCIPassportDDVPCSC

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.