Package org.kapott.hbci.passport

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

/*  $Id: AbstractHBCIPassport.java,v 1.4 2012/03/13 22:07:43 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.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

import org.kapott.hbci.callback.HBCICallback;
import org.kapott.hbci.comm.Comm;
import org.kapott.hbci.comm.Filter;
import org.kapott.hbci.exceptions.HBCI_Exception;
import org.kapott.hbci.exceptions.InvalidUserDataException;
import org.kapott.hbci.manager.HBCIDialog;
import org.kapott.hbci.manager.HBCIKey;
import org.kapott.hbci.manager.HBCIUtils;
import org.kapott.hbci.manager.HBCIUtilsInternal;
import org.kapott.hbci.manager.IHandlerData;
import org.kapott.hbci.manager.LogFilter;
import org.kapott.hbci.status.HBCIMsgStatus;
import org.kapott.hbci.structures.Konto;
import org.kapott.hbci.structures.Limit;
import org.kapott.hbci.structures.Value;

/** <p>Diese Klasse stellt die Basisklasse f�r alle "echten" Passport-Implementationen
    dar. Hier werden bereits einige Methoden implementiert sowie einige
    zus�tzliche Hilfsmethoden zur Verf�gung gestellt.</p><p>
    Aus einer HBCI-Anwendung heraus ist hier nur eine einzige Methode interessant,
    um eine Instanz eines bestimmtes Passports zu erzeugen</p> */
public abstract class AbstractHBCIPassport
    implements HBCIPassportInternal,Serializable
{
    private String     paramHeader;

    private Properties bpd;    
    private Properties upd;    
    private String     hbciversion;
    private String     country;
    private String     blz;    
    private String     host;   
    private Integer    port;
    private String     filterType;
    private String     userid;
    private String     customerid;
    private String     sysid;  
    private Long       sigid;
    private String     cid;
    private Comm       comm;
    private Hashtable<String, Object>  persistentData;
   
    private IHandlerData parentHandlerData;
   
    protected static final boolean FOR_SAVE=true;
    protected static final boolean FOR_LOAD=false;
   
    public AbstractHBCIPassport(Object init)
    {
        persistentData=new Hashtable<String, Object>();
        setClientData("init",init);
    }

    protected boolean askForMissingData(boolean needCountry,boolean needBLZ,
                                        boolean needHost,boolean needPort,
                                        boolean needFilter,
                                        boolean needUserId,boolean needCustomerId)
    {
        boolean dataChanged=false;

        if (needCountry &&
            (getCountry()==null || getCountry().length()==0)) {
            StringBuffer sb=new StringBuffer("DE");
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_COUNTRY,HBCIUtilsInternal.getLocMsg("COUNTRY"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("COUNTRY")));
            setCountry(sb.toString());
            dataChanged=true;
        }

        if (needBLZ &&
            (getBLZ()==null || getBLZ().length()==0)) {
            StringBuffer sb=new StringBuffer();
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_BLZ,HBCIUtilsInternal.getLocMsg("BLZ"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("BLZ")));
            setBLZ(sb.toString());
            dataChanged=true;
        }

        if (needHost &&
            (getHost()==null || getHost().length()==0))
        {
            StringBuffer sb;
           
            if (this instanceof AbstractPinTanPassport) {
                sb=new StringBuffer(HBCIUtils.getPinTanURLForBLZ(getBLZ()));
                if (sb.indexOf("https://")==0) {
                    sb.delete(0,8);
                }
            } else {
                sb=new StringBuffer(HBCIUtils.getHBCIHostForBLZ(getBLZ()));
            }
           
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_HOST,HBCIUtilsInternal.getLocMsg("HOST"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("HOST")));
            setHost(sb.toString());
            dataChanged=true;
        }

        if (needPort &&
            (getPort()==null || getPort().intValue()==0)) {
            StringBuffer sb=new StringBuffer((this instanceof AbstractPinTanPassport) ? "443" : "3000");
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_PORT,HBCIUtilsInternal.getLocMsg("PORT"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("PORT")));
            setPort(new Integer(sb.toString()));
            dataChanged=true;
        }

        if (needFilter &&
                (getFilterType()==null || getFilterType().length()==0)) {
            StringBuffer sb=new StringBuffer("Base64");
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_FILTER,HBCIUtilsInternal.getLocMsg("FILTER"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("FILTER")));
            setFilterType(sb.toString());
            dataChanged=true;
        }

        if (needUserId &&
            (getUserId()==null || getUserId().length()==0)) {
            StringBuffer sb=new StringBuffer();
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_USERID,HBCIUtilsInternal.getLocMsg("USERID"),HBCICallback.TYPE_TEXT,sb);
            if (sb.length()==0)
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_EMPTY_X",HBCIUtilsInternal.getLocMsg("USERID")));
            setUserId(sb.toString());
            dataChanged=true;
        }

        if (needCustomerId &&
            (getStoredCustomerId()==null || getStoredCustomerId().length()==0)) {
            StringBuffer sb=new StringBuffer(getCustomerId());
            HBCIUtilsInternal.getCallback().callback(this,HBCICallback.NEED_CUSTOMERID,HBCIUtilsInternal.getLocMsg("CUSTOMERID"),HBCICallback.TYPE_TEXT,sb);
            setCustomerId(sb.toString());
            dataChanged=true;
        }

        return dataChanged;
    }

    public final Comm getComm()
    {
        if (comm==null) {
            comm=getCommInstance();
        }
       
        return comm;
    }
   
    protected abstract Comm getCommInstance();
   
    public final Filter getCommFilter()
    {
        return Filter.getInstance(getFilterType());
    }
   
    public final void closeComm()
    {
        if (comm!=null) {
            comm.close();
            comm=null;
        }
    }

    public final Properties getBPD()
    {
        return bpd;
    }
   
    public final void setHBCIVersion(String hbciversion)
    {
        this.hbciversion=hbciversion;
    }
   
    public final String getHBCIVersion()
    {
        return (hbciversion!=null)?hbciversion:"";
    }
   
    public final Properties getUPD()
    {
        return upd;
    }

    public final String getBLZ()
    {
        return blz;
    }

    public final String getCountry()
    {
        return country;
    }
   
    public final Konto[] getAccounts()
    {
        ArrayList<Konto> ret=new ArrayList<Konto>();
       
        if (upd!=null) {
            for (int i=0;;i++) {
                String header=HBCIUtilsInternal.withCounter("KInfo",i);
                String number=upd.getProperty(header+".KTV.number");

                if (number==null)
                    break;

                Konto entry=new Konto();
                entry.blz=upd.getProperty(header+".KTV.KIK.blz");
                entry.country=upd.getProperty(header+".KTV.KIK.country");
                entry.number=number;
                entry.subnumber=upd.getProperty(header+".KTV.subnumber");
                entry.curr=upd.getProperty(header+".cur");
                entry.type=upd.getProperty(header+".konto");
                entry.customerid=upd.getProperty(header+".customerid");
                entry.name=upd.getProperty(header+".name1");
                entry.name2=upd.getProperty(header+".name2");
                entry.bic=upd.getProperty(header+".KTV.bic");
                entry.iban=upd.getProperty(header+".KTV.iban");
                entry.acctype=upd.getProperty(header+".acctype");
               
                String st;
                if ((st=upd.getProperty(header+".KLimit.limittype"))!=null) {
                    Limit limit=new Limit();
                    limit.type=st.charAt(0);
                    limit.value=new Value(upd.getProperty(header+".KLimit.BTG.value"),
                                          upd.getProperty(header+".KLimit.BTG.curr"));
                    if ((st=upd.getProperty(header+".KLimit.limitdays"))!=null)
                        limit.days=Integer.parseInt(st);
                }
               
                // allowedGVs
                ArrayList<String> codes = new ArrayList<String>();
                for (int j=0;;j++) {
                  String gvHeader = HBCIUtilsInternal.withCounter(header+".AllowedGV", j);
                  String code = upd.getProperty(gvHeader+".code");
                  if (code == null) break;
                  codes.add(code);
                }
                if (!codes.isEmpty()) entry.allowedGVs = codes;
               
                ret.add(entry);
            }
        }
       
        return ret.toArray(new Konto[ret.size()]);
    }
   
    public final void fillAccountInfo(Konto account)
    {
        String  number=HBCIUtilsInternal.stripLeadingZeroes(account.number);
        String  iban=HBCIUtilsInternal.stripLeadingZeroes(account.iban);
        boolean haveNumber=(number!=null && number.length()!=0);
        boolean haveIBAN=(iban!=null && iban.length()!=0);
       
        Konto[] accounts=getAccounts();
       
        for (int i=0;i<accounts.length;i++) {
            String temp_number=HBCIUtilsInternal.stripLeadingZeroes(accounts[i].number);
            String temp_iban=HBCIUtilsInternal.stripLeadingZeroes(accounts[i].iban);
           
            if (haveNumber && number.equals(temp_number) ||
                    haveIBAN && iban.equals(temp_iban))
            {
                account.blz=accounts[i].blz;
                account.country=accounts[i].country;
                account.number=accounts[i].number;
                account.subnumber=accounts[i].subnumber;
                account.type=accounts[i].type;
                account.curr=accounts[i].curr;
                account.customerid=accounts[i].customerid;
                account.name=accounts[i].name;
                account.bic=accounts[i].bic;
                account.iban=accounts[i].iban;
                account.acctype=accounts[i].acctype;
                break;
            }
        }
    }
   
    public final Konto getAccount(String number)
    {
        Konto ret=new Konto();
        ret.number=number;
        fillAccountInfo(ret);
       
        if (ret.blz==null) {
          // es wurde kein Konto-Objekt in getAccounts() gefunden
          ret.blz=getBLZ();
          ret.country=getCountry();
          ret.customerid=getCustomerId();
          // TODO: very dirty!
          ret.name=getCustomerId();
         
          // an dieser Stelle sind jetzt alle Werte gef�llt, die teilweise
          // zwingend ben�tigt werden
        }
       
        return ret;
    }

    public String getHost()
    {
        return host;
    }

    public final Integer getPort()
    {
        return (port!=null)?port:new Integer(0);
    }
   
    public final String getFilterType()
    {
        return filterType;
    }
   
    public String getUserId()
    {
        return userid;
    }

    public final String getCustomerId(int idx)
    {
        String header=HBCIUtilsInternal.withCounter("KInfo",idx)+".customerid";
        String c=(upd!=null)?upd.getProperty(header):customerid;
        return (c!=null)?c:getUserId();
    }
   
    public String getCustomerId()
    {
        return (customerid!=null && customerid.length()!=0)?customerid:getUserId();
    }
   
    public String getStoredCustomerId()
    {
        return customerid;
    }
   
    public String getSysId()
    {
        return (sysid!=null && sysid.length()!=0)?sysid:"0";
    }

    public final String getCID()
    {
        return cid!=null?cid:"";
    }

    public final void clearInstSigKey()
    {
        setInstSigKey(null);
    }

    public final void clearInstEncKey()
    {
        setInstEncKey(null);
    }

    public final void clearMySigKey()
    {
        setMyPublicSigKey(null);
        setMyPrivateSigKey(null);
    }

    public final void clearMyEncKey()
    {
        setMyPublicEncKey(null);
        setMyPrivateEncKey(null);
    }

    public final void clearMyDigKey()
    {
        setMyPublicDigKey(null);
        setMyPrivateDigKey(null);
    }
   
    public final String getBPDVersion()
    {
        String version=((bpd!=null)?bpd.getProperty("BPA.version"):null);
        return ((version!=null)?version:"0");
    }

    public final String getUPDVersion()
    {
        String version=((upd!=null)?upd.getProperty("UPA.version"):null);
        return ((version!=null)?version:"0");
    }

    public final String getInstName()
    {
        return (bpd!=null)?bpd.getProperty("BPA.kiname"):null;
    }

    public int getMaxGVperMsg()
    {
        return (bpd!=null)?Integer.parseInt(bpd.getProperty("BPA.numgva")):-1;
    }

    public final int getMaxMsgSizeKB()
    {
        return (bpd!=null)?Integer.parseInt(bpd.getProperty("BPA.maxmsgsize","0")):0;
    }

    public final String[] getSuppLangs()
    {
        String[] ret=new String[0];

        if (bpd!=null) {
            ArrayList<String> temp=new ArrayList<String>();
            String header;
            String value;
            int i=0;

            while ((header=HBCIUtilsInternal.withCounter("BPA.SuppLangs.lang",i))!=null &&
                   (value=bpd.getProperty(header))!=null) {
                temp.add(value);
                i++;
            }

            if (temp.size()!=0)
                ret=(temp.toArray(ret));
        }
   
        return ret;
    }

    public final String[] getSuppVersions()
    {
        String[] ret=new String[0];

        if (bpd!=null) {
            ArrayList<String> temp=new ArrayList<String>();
            String header;
            String value;
            int i=0;

            while ((header=HBCIUtilsInternal.withCounter("BPA.SuppVersions.version",i))!=null &&
                   (value=bpd.getProperty(header))!=null) {
                temp.add(value);
                i++;
            }

            if (temp.size()!=0)
                ret=(temp.toArray(ret));
        }
   
        return ret;
    }

    public final String getDefaultLang()
    {
        String value=(bpd!=null)?bpd.getProperty("CommListRes.deflang"):null;
        return (value!=null)?value:"0";
    }

    public final boolean canMixSecMethods()
    {
        boolean ret=false;

        if (bpd!=null) {
            String value=bpd.getProperty("SecMethod.mixing");

            if (value!=null && value.equals("J"))
                ret=true;
        }

        return ret;
    }

    public final String[][] getSuppSecMethods()
    {
        String[][] ret=new String[0][];

        if (bpd!=null) {
            ArrayList<String[]> temp=new ArrayList<String[]>();
            String header;
            String method;
            int i=0;

            while ((header=HBCIUtilsInternal.withCounter("SecMethod.SuppSecMethods",i))!=null &&
                   (method=bpd.getProperty(header+".method"))!=null) {

                String header2;
                String version;
                int    j=0;
               
                while ((header2=HBCIUtilsInternal.withCounter(header+".version",j))!=null &&
                        (version=bpd.getProperty(header2))!=null)
                {
                    String[] entry=new String[2];
                    entry[0]=method;
                    entry[1]=version;
                    temp.add(entry);
                    j++;
                }
               
                i++;
            }

            if (temp.size()!=0)
                ret=(temp.toArray(ret));
        }
           
        return ret;
    }

    public final String[][] getSuppCompMethods()
    {
        String[][] ret=new String[0][];

        if (bpd!=null) {
            ArrayList<String[]> temp=new ArrayList<String[]>();
            String header;
            String method;
            int i=0;

            while ((header=HBCIUtilsInternal.withCounter("CompMethod.SuppCompMethods",i))!=null &&
                   (method=bpd.getProperty(header+".func"))!=null) {

                String version=bpd.getProperty(header+".version");
                String[] entry=new String[2];
                entry[0]=method;
                entry[1]=version;
                temp.add(entry);
                i++;
            }

            if (temp.size()!=0)
                ret=(temp.toArray(ret));
        }
           
        return ret;
    }

    public final String getLang()
    {
        String value=(bpd!=null)?bpd.getProperty("CommListRes.deflang"):null;
        return (value!=null)?value:"0";
    }

    public final Long getSigId()
    {
        return sigid!=null?sigid:new Long(1);
    }

    public final void clearBPD()
    {
        setBPD(null);
    }

    public void setBPD(Properties bpd)
    {
        this.bpd=bpd;
    }
   
    public final void clearUPD()
    {
        setUPD(null);
    }

    public final void setUPD(Properties upd)
    {
        this.upd=upd;
    }

    public final void setCountry(String country)
    {
        this.country=country;
    }

    public final void setBLZ(String blz)
    {
      LogFilter.getInstance().addSecretData(blz,"X",LogFilter.FILTER_MOST);
        this.blz=blz;
    }

    public final void setHost(String host)
    {
        this.host=host;
    }

    public final void setPort(Integer port)
    {
        this.port=port;
    }
   
    public final void setFilterType(String filter)
    {
        this.filterType=filter;
    }
   
    public final void setUserId(String userid)
    {
      LogFilter.getInstance().addSecretData(userid,"X",LogFilter.FILTER_IDS);
        this.userid=userid;
    }

    public final void setCustomerId(String customerid)
    {
      LogFilter.getInstance().addSecretData(customerid,"X",LogFilter.FILTER_IDS);
        this.customerid=customerid;
    }   

    public final void setSigId(Long sigid)
    {
        this.sigid=sigid;
    }

    public final void setSysId(String sysid)
    {
        this.sysid=sysid;
    }

    public final void setCID(String cid)
    {
      LogFilter.getInstance().addSecretData(cid,"X",LogFilter.FILTER_IDS);
        this.cid=cid;
    }

    public void incSigId()
    {
        setSigId(new Long(getSigId().longValue()+1));
    }

    public final boolean onlyBPDGVs()
    {
        return getUPD().getProperty("UPA.usage").equals("0");
    }

    /** <p>Erzeugt eine Instanz eines HBCIPassports und gibt diese zur�ck. Der
        Typ der erzeugten Passport-Instanz wird durch den Parameter <code>name</code>
        bestimmt. G�ltige Werte sind zur Zeit
        <ul>
          <li>DDV</li>
          <li>RDHNew</li>
          <li>RDH (nicht mehr benutzen!)</li>
          <li>PinTan</li>
          <li>SIZRDHFile</li>
          <li>RDHXFile</li>
          <li>Anonymous</li>
        </ul></p>
        <p>Der zus�tzliche Parameter <code>init</code> gibt ein Objekt an, welches
        bereits w�hrend der Instanziierung des Passport-Objektes in dessen internen
        <code>clientData</code>-Datenstrukturen gespeichert wird
        (siehe {@link org.kapott.hbci.passport.HBCIPassport#setClientData(String,Object)}).
        Auf dieses Objekt kann dann mit
        {@link org.kapott.hbci.passport.HBCIPassport#getClientData(String) getClientData("init")}
        zugegriffen werden. Ist <code>init==null</code>), wo wird <code>init=name</code>
        gesetzt.</p>
        <p>Beim Erzeugen eines Passport-Objektes tritt i.d.R. der
        {@link org.kapott.hbci.callback.HBCICallback Callback} <code>NEED_PASSPHRASE</code>
        auf, um nach dem Passwort f�r das Einlesen der Schl�sseldatei zu fragen.
        Von der Callback-Methode eventuell zus�tzlich ben�tigte Daten zu diesem Passport
        konnten bis zu dieser Stelle noch nicht via <code>setClientData(...)</code>
        gesetzt werden, weil das Passport-Objekt noch gar nicht existierte. F�r diesen
        Zweck gibt es das <code>init</code>-Objekt, welches bereits beim Erzeugen
        des Passport-Objektes (und <em>vor</em> dem Aufrufen eines Callbacks) zu den
        zus�tzlichen Passport-Daten hinzugef�gt wird (mit der id "<code>init</code>").</p>
        <p>Eine beispielhafte (wenn auch nicht sehr praxisnahe) Anwendung dieses
        Features wird im Quelltext des Tools
        {@link org.kapott.hbci.tools.AnalyzeReportOfTransactions}
        gezeigt. Zumindest das Prinzip sollte damit jedoch klar werden.</p>
        @param name Typ der zu erzeugenden Passport-Instanz
        @param init Objekt, welches schon w�hrend der Passport-Erzeugung via
        <code>setClientData("init",init)</code> zu den Passport-Daten hinzugef�gt wird.
        @return Instanz eines HBCIPassports */
    public static HBCIPassport getInstance(String name,Object init)
    {
        if (name==null) {
            throw new NullPointerException("name of passport implementation must not be null");
        }
           
        String className = "org.kapott.hbci.passport.HBCIPassport"+name;
        try {
            if (init==null)
                init=name;
               
            HBCIUtils.log("creating new instance of a "+name+" passport",HBCIUtils.LOG_DEBUG);
            Class cl=Class.forName(className);
            Constructor con=cl.getConstructor(new Class[] {Object.class});
            HBCIPassport p=(HBCIPassport)(con.newInstance(new Object[] {init}));
            return p;
        }
        catch (ClassNotFoundException e)
        {
          throw new InvalidUserDataException("*** No passport implementation '"+name+"' found - there must be a class "+className);
        }
        catch (InvocationTargetException ite)
        {
          Throwable cause = ite.getCause();
          if (cause instanceof HBCI_Exception)
            throw (HBCI_Exception) cause;
         
          throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INST",name),ite);
        }
        catch (HBCI_Exception he)
        {
          throw he;
        }
        catch (Exception e)
        {
          throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_INST",name),e);
        }
    }

    /** Erzeugt eine Instanz eines HBCI-Passports. Der Typ der erzeugten
        Passport-Instanz wird hierbei dem Wert des HBCI-Parameters
        <code>client.passport.default</code> entnommen. G�ltige Werte f�r diesen
        HBCI-Parameter sind die gleichen wie beim Aufruf der Methode
        {@link #getInstance(String)}.
        @param init (siehe {@link #getInstance(String,Object)})
        @return Instanz eines HBCI-Passports */
    public static HBCIPassport getInstance(Object init)
    {
        String passportName=HBCIUtils.getParam("client.passport.default");
        if (passportName==null)
            throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_NODEFPASS"));

        return getInstance(passportName,init);
    }
   
    /** Entspricht {@link #getInstance(String,Object) getInstance(name,null)} */
    public static HBCIPassport getInstance(String name)
    {
        return getInstance(name,null);
    }
   
    /** Entspricht {@link #getInstance(Object) getInstance((Object)null)} */
    public static HBCIPassport getInstance()
    {
        return getInstance((Object)null);
    }

    public void close()
    {
        closeComm();
    }
   
    protected SecretKey calculatePassportKey(boolean forSaving)
    {
        try {
            StringBuffer passphrase=new StringBuffer();
            HBCIUtilsInternal.getCallback().callback(this,
                                             forSaving?HBCICallback.NEED_PASSPHRASE_SAVE
                                                      :HBCICallback.NEED_PASSPHRASE_LOAD,
                                             forSaving?HBCIUtilsInternal.getLocMsg("CALLB_NEED_PASS_NEW")
                                                      :HBCIUtilsInternal.getLocMsg("CALLB_NEED_PASS"),
                                             HBCICallback.TYPE_SECRET,
                                             passphrase);
            if (passphrase.length()==0) {
                throw new InvalidUserDataException(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSZERO"));
            }
            LogFilter.getInstance().addSecretData(passphrase.toString(),"X",LogFilter.FILTER_SECRETS);

            SecretKeyFactory fac=SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            PBEKeySpec keyspec=new PBEKeySpec(passphrase.toString().toCharArray());
            SecretKey passportKey=fac.generateSecret(keyspec);
            keyspec.clearPassword();
            passphrase=null;

            return passportKey;
        } catch (Exception ex) {
            throw new HBCI_Exception(HBCIUtilsInternal.getLocMsg("EXCMSG_PASSPORT_KEYCALCERR"),ex);
        }
    }
   
    public Properties getParamSegmentNames()
    {
        Properties ret=new Properties();
       
        for (Enumeration e=bpd.propertyNames();e.hasMoreElements();) {
            String key=(String)e.nextElement();
           
            if (key.startsWith("Params") &&
                key.endsWith(".SegHead.code")) {
                int dotPos=key.indexOf('.');
                int dotPos2=key.indexOf('.',dotPos+1);
               
                String gvname=key.substring(dotPos+1,dotPos2);
                int    len=gvname.length();
                int    versionPos=-1;
               
                for (int i=len-1;i>=0;i--) {
                    char ch=gvname.charAt(i);
                    if (!(ch>='0' && ch<='9')) {
                        versionPos=i+1;
                        break;
                    }
                }
               
                String version=gvname.substring(versionPos);
                if (version.length()!=0) {
                    gvname=gvname.substring(0,versionPos-3); // remove version and "Par"

                    String knownVersion=(String)ret.get(gvname);

                    if (knownVersion==null ||
                        Integer.parseInt(version)>Integer.parseInt(knownVersion)) {
                        ret.setProperty(gvname,version);
                    }
                }
            }
        }
       
        return ret;
    }

    public Properties getJobRestrictions(String specname)
    {
        int  versionPos=specname.length()-1;
        char ch;
       
        while ((ch=specname.charAt(versionPos))>='0' && ch<='9') {
            versionPos--;
        }
       
        return getJobRestrictions(
            specname.substring(0,versionPos+1),
            specname.substring(versionPos+1));
    }
   
    public Properties getJobRestrictions(String gvname,String version)
    {
        Properties result=new Properties();

        String searchstring=gvname+"Par"+version;
        for (Enumeration e=bpd.propertyNames();e.hasMoreElements();) {
            String key=(String)e.nextElement();

            if (key.startsWith("Params")&&
                key.indexOf("."+searchstring+".Par")!=-1) {
                int searchIdx=key.indexOf(searchstring);
                result.setProperty(key.substring(key.indexOf(".",
                                                             searchIdx+searchstring.length()+4)+1),
                                   bpd.getProperty(key));
            }
        }

        return result;
    }
   
    public void setPersistentData(String id,Object o)
    {
        if (o!=null)
            persistentData.put(id,o);
        else
            persistentData.remove(id);
    }
   
    public Object getPersistentData(String id)
    {
        return persistentData.get(id);
    }
   
    public void syncSigId()
    {
        setSigId(new Long("-1"));
    }
   
    public void syncSysId()
    {
        setSysId("0");
    }
   
    public void changePassphrase()
    {
        resetPassphrase();
        saveChanges();
    }
   
    public final void setClientData(String id,Object o)
    {
        setPersistentData("client_"+id,o);
    }
   
    public final Object getClientData(String id)
    {
        return getPersistentData("client_"+id);
    }
   
    public boolean isAnonymous()
    {
        return false;
    }

    protected void setParamHeader(String paramHeader)
    {
        this.paramHeader=paramHeader;
    }
   
    protected String getParamHeader()
    {
        return paramHeader;
    }
   
    public void setParentHandlerData(IHandlerData handler)
    {
        this.parentHandlerData=handler;
    }
   
    public IHandlerData getParentHandlerData()
    {
        return this.parentHandlerData;
    }
   
    public HBCIKey[][] generateNewUserKeys()
    {
      throw new HBCI_Exception("*** current passport does not know how to generate user keys");
    }

    public void setProfileMethod(String method)
    {
        throw new HBCI_Exception("*** overriding security profiles in passports not possible");
    }

    public void setProfileVersion(String version)
    {
        throw new HBCI_Exception("*** overriding security profiles in passports not possible");
    }
   
    public static byte[] checkForCryptDataSize(byte[] buffer, int size)
    {
        byte[] result=buffer;
       
        if (buffer.length!=size) {
            HBCIUtils.log("checking for crypted_data_length=="+size+"; current length is "+buffer.length,HBCIUtils.LOG_DEBUG);
            if (buffer.length>size) {
                int diff=buffer.length-size;
                boolean ok=true;

                for (int i=0;i<diff;i++) {
                    if (buffer[i]!=0x00) {
                        HBCIUtils.log("byte "+i+" in crypted_data is not zero, but it should be zero - please contact the author",HBCIUtils.LOG_WARN);
                        ok=false;
                    }
                }

                if (ok) {
                    HBCIUtils.log("removing "+diff+" unnecessary null-bytes from crypted_data",HBCIUtils.LOG_DEBUG);
                    result=new byte[size];
                    System.arraycopy(buffer,diff,result,0,size);
                }
            } else if (buffer.length<size) {
                int diff=size-buffer.length;
                HBCIUtils.log("prepending "+diff+" null bytes to crypted_data",HBCIUtils.LOG_WARN);
                result=new byte[size];
                Arrays.fill(result,(byte)0);
                System.arraycopy(buffer,0,result,diff,buffer.length);
            }
        }
       
        return result;
    }

    public boolean postInitResponseHook(HBCIMsgStatus msgStatus, boolean anonDialog)
    {
        // die default-Implementierung tut nichts und verlangt auch keine
        // erneute Dialog-Initialisierung
        return false;
    }

    public void beforeCustomDialogHook(HBCIDialog dialog)
    {
        // default implementation does nothing
    }
   
    public void afterCustomDialogInitHook(HBCIDialog dialog)
    {
        // default implementation does nothing - only PinTan variant will override this
    }
   
    public int getMaxGVSegsPerMsg()
    {
        return 0;
    }
}
TOP

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

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.