/* $Id: MsgHandlerFirstKeyReq.java,v 1.6 2005/06/10 18:03:03 kleiner Exp $ This file is part of HBCI4Java Copyright (C) 2001-2005 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.server.msg; import java.security.interfaces.RSAPublicKey; import java.util.Arrays; import org.kapott.hbci.exceptions.HBCI_Exception; import org.kapott.hbci.manager.HBCIKey; import org.kapott.hbci.manager.HBCIUtils; import org.kapott.hbci.manager.HBCIUtilsInternal; import org.kapott.hbci.protocol.MSG; import org.kapott.hbci.server.Dialog; public class MsgHandlerFirstKeyReq extends MsgHandlerDialogInitAnon { public MsgHandlerFirstKeyReq(MSG cryptedMsg,MSG decryptedMsg,String decryptedMsgData,Dialog conn) { super(cryptedMsg,decryptedMsg,decryptedMsgData,conn); } protected void initMessageHandler() { super.initMessageHandler(); dialog.setFlag("signResponse",true); } protected boolean isMessageAllowed() { return !dialog.isInitialized() && dialog.getPassportType().equals("RDH"); } protected void handleMessageContent() { super.handleMessageContent(); if (globRetIsOk()) { // zwei keyrequests int reqsFound=0; int responseCounter=0; for (int i=0;i<2;i++) { String srcHeader=HBCIUtilsInternal.withCounter("KeyReq",i); String srcHeader2=srcHeader+".KeyName"; // wenn ein keyrequest da ist if (getData(srcHeader+".SegHead.code")!=null) { // schlsseldaten berprfen if (!getData(srcHeader2+".KIK.country").equals(getServerData().getCountry()) || !getData(srcHeader2+".KIK.blz").equals(getServerData().getBLZ())) { addGlobRet("9010","Verarbeitung nicht mglich",null); addSegRet(srcHeader,"4,1","9210","falsche KIK in Schlsseldaten",null); return; } // schlsseldaten extrahieren String keytype=getData(srcHeader2+".keytype"); String keynum=getData(srcHeader2+".keynum"); String keyversion=getData(srcHeader2+".keyversion"); // welcher inst.-schlssel wird hier abgefragt HBCIKey instKey; if (keytype.equals("S")) instKey=getServerData().getInstPublicRDHSigKey(); else instKey=getServerData().getInstPublicRDHEncKey(); // schlsselnummer/-version berprfen, ob update notwendig ist boolean needUpdate=false; // update ist ntig, wenn client die schlssel gar nicht kennt if (keynum.equals("999") && keyversion.equals("999")) { needUpdate=true; } else { // daten der dem client bekannten schlssel ermitteln int sentKeyNum=Integer.parseInt(keynum); int sentKeyVersion=Integer.parseInt(keyversion); // daten des entsprechenden instituts-schlssels ermitteln int sigKeyNum=Integer.parseInt(instKey.num); int sigKeyVersion=Integer.parseInt(instKey.version); // update ist ntig, wenn client-daten lter als inst-daten sind if (sentKeyNum<sigKeyNum || (sentKeyNum==sigKeyNum && sentKeyVersion<sigKeyVersion)) { needUpdate=true; } } if (needUpdate) { HBCIUtils.log("have to send data for "+keytype+" key",HBCIUtils.LOG_DEBUG); String dstHeader=HBCIUtilsInternal.withCounter("SendPubKey",responseCounter++); // signierschlssel abgefragt if (keytype.equals("S")) { if ((reqsFound&1)!=0) { addGlobRet("9010","Verarbeitung nicht mglich",null); addSegRet(srcHeader,null,"9210","Signaturschlssel zweimal abgefragt",null); return; } reqsFound|=1; setData(dstHeader+".KeyName.keytype","S"); setData(dstHeader+".PubKey.usage","6"); } else { // chiffrierschlssel abgefragt if ((reqsFound&2)!=0) { addGlobRet("9010","Verarbeitung nicht mglich",null); addSegRet(srcHeader,null,"9210","Chiffrierschlssel zweimal abgefragt",null); return; } reqsFound|=2; setData(dstHeader+".KeyName.keytype","V"); setData(dstHeader+".PubKey.usage","5"); } addGlobRet("3060","Teilweise liegen Warnungen oder Hinweise vor",null); addSegRet(srcHeader,null,"3050","Schlssel nicht mehr aktuell - neue Schlsseldaten werden bermittelt",null); setData(dstHeader+".SegHead.ref",getData(srcHeader+".SegHead.seq")); setData(dstHeader+".dialogid",dialog.getDialogId()); setData(dstHeader+".msgnum",dialog.getMsgNum()); HBCIUtils.log("adding key data",HBCIUtils.LOG_DEBUG); setData(dstHeader+".KeyName.KIK.country",getServerData().getCountry()); setData(dstHeader+".KeyName.KIK.blz",getServerData().getBLZ()); setData(dstHeader+".KeyName.userid",getServerData().getBLZ()); setData(dstHeader+".KeyName.keynum",instKey.num); setData(dstHeader+".KeyName.keyversion",instKey.version); setData(dstHeader+".PubKey.mode","16"); try { byte[] data=((RSAPublicKey)instKey.key).getModulus().toByteArray(); setData(dstHeader+".PubKey.modulus","B"+new String(checkFor96Bytes(data),"ISO-8859-1")); data=((RSAPublicKey)instKey.key).getPublicExponent().toByteArray(); setData(dstHeader+".PubKey.exponent","B"+new String(data,"ISO-8859-1")); } catch (Exception e) { throw new HBCI_Exception(e.getMessage(),e); } } else { HBCIUtils.log("data for key "+keytype+" does not need to be sent",HBCIUtils.LOG_DEBUG); addSegRet(srcHeader,null,"0020","angegebener Schlssel ist noch aktuell",null); } } else { // kein keyrequest gefunden /* das kann nur bei nicht-firstkeyreq-msgs passieren, weil nur bei diesen in der spez die request-segmente optional sind*/ HBCIUtils.log("optional keyrequest #"+(i+1)+" not found",HBCIUtils.LOG_DEBUG); } } } } private byte[] checkFor96Bytes(byte[] buffer) { byte[] result=buffer; if (buffer.length!=96) { if (buffer.length>96) { int diff=buffer.length-96; boolean ok=true; for (int i=0;i<diff;i++) { if (buffer[i]!=0x00) { ok=false; } } if (ok) { result=new byte[96]; System.arraycopy(buffer,diff,result,0,96); } } else if (buffer.length<96) { int diff=96-buffer.length; result=new byte[96]; Arrays.fill(result,(byte)0); System.arraycopy(buffer,0,result,diff,buffer.length); } } return result; } protected void postProcess() { super.postProcess(); if (globRetIsOk()) { dialog.setFlag("forceEnd",true); dialog.setFlag("endInSig",false); dialog.setFlag("endInCrypt",false); dialog.setFlag("endOutSig",false); dialog.setFlag("endOutCrypt",false); } } }