From 35b64892bad13c846f19260311c7625d88cef7a1 Mon Sep 17 00:00:00 2001
From: clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>
Date: Fri, 5 Sep 2008 13:39:53 +0000
Subject: HashDataInput

git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@23 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
---
 .../egiz/bku/smccstal/AbstractRequestHandler.java  | 139 +++++----
 .../at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java  | 196 ++++++------
 .../egiz/bku/smccstal/SMCCSTALRequestHandler.java  |  39 ++-
 .../gv/egiz/bku/smccstal/SignRequestHandler.java   | 337 ++++++++++++---------
 4 files changed, 371 insertions(+), 340 deletions(-)

(limited to 'smccSTAL/src/main/java/at')

diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractRequestHandler.java
index e5afa478..995e2b77 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractRequestHandler.java
@@ -14,73 +14,72 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.smccstal;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.SignatureCard;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-
-public abstract class AbstractRequestHandler implements SMCCSTALRequestHandler,
-    ActionListener {
-  private final static Log log = LogFactory
-      .getLog(AbstractRequestHandler.class);
-
-  protected SignatureCard card;
-  protected BKUGUIFacade gui;
-  protected static STALMessageConsumer messageConsumer = null;
-  protected String actionCommand;
-  protected boolean actionPerformed = false;
-
-  @Override
-  public abstract STALResponse handleRequest(STALRequest request);
-
-  @Override
-  public void init(SignatureCard sc, BKUGUIFacade gui) {
-    if ((sc == null) || (gui == null)) {
-      throw new NullPointerException("Parameter must not be set to null");
-    }
-    this.card = sc;
-    this.gui = gui;
-  }
-  
-  public static void setMessageConsumer(STALMessageConsumer messageConsumer) {
-    AbstractRequestHandler.messageConsumer = messageConsumer;
-  }
-
-  protected static void newSTALMessage(String caption, String message) {
-    if (messageConsumer != null) {
-      messageConsumer.consumeNewSTALMessage(caption, message);
-    }
-  }
-
-  protected synchronized void waitForAction() {
-    try {
-      while (!actionPerformed) {
-        wait();
-      }
-    } catch (InterruptedException e) {
-      log.info(e);
-    }
-    actionPerformed = false;
-  }
-
-  private synchronized void actionPerformed() {
-    actionPerformed = true;
-    notifyAll();
-  }
-  
-  @Override
-  public void actionPerformed(ActionEvent e) {
-    actionCommand = e.getActionCommand();
-    actionPerformed();
-  }
-
-}
+package at.gv.egiz.bku.smccstal;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+
+public abstract class AbstractRequestHandler implements SMCCSTALRequestHandler,
+    ActionListener {
+  private final static Log log = LogFactory
+      .getLog(AbstractRequestHandler.class);
+
+  protected SignatureCard card;
+  protected BKUGUIFacade gui;
+  protected static STALMessageConsumer messageConsumer = null;
+  protected String actionCommand;
+  protected boolean actionPerformed = false;
+
+  @Override
+  public abstract STALResponse handleRequest(STALRequest request);
+
+  @Override
+  public void init(SignatureCard sc, BKUGUIFacade gui) {
+    if ((sc == null) || (gui == null)) {
+      throw new NullPointerException("Parameter must not be set to null");
+    }
+    this.card = sc;
+    this.gui = gui;
+  }
+  
+  public static void setMessageConsumer(STALMessageConsumer messageConsumer) {
+    AbstractRequestHandler.messageConsumer = messageConsumer;
+  }
+
+  protected static void newSTALMessage(String caption, String message) {
+    if (messageConsumer != null) {
+      messageConsumer.consumeNewSTALMessage(caption, message);
+    }
+  }
+
+  protected synchronized void waitForAction() {
+    try {
+      while (!actionPerformed) {
+        wait();
+      }
+    } catch (InterruptedException e) {
+      log.info(e);
+    }
+    actionPerformed = false;
+  }
+
+  private synchronized void actionPerformed() {
+    actionPerformed = true;
+    notifyAll();
+  }
+  
+  @Override
+  public void actionPerformed(ActionEvent e) {
+    actionCommand = e.getActionCommand();
+    actionPerformed();
+  }
+
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java
index 7bd9e264..56c8340b 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java
@@ -14,103 +14,99 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.smccstal;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.SignatureCard;
-import at.gv.egiz.smcc.util.SMCCHelper;
-import at.gv.egiz.stal.ErrorResponse;
-import at.gv.egiz.stal.InfoboxReadRequest;
-import at.gv.egiz.stal.STAL;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-import at.gv.egiz.stal.SignRequest;
-
-public abstract class AbstractSMCCSTAL implements STAL {
-  private static Log log = LogFactory.getLog(AbstractSMCCSTAL.class);
-
-  protected Locale locale = Locale.getDefault();
-  protected SMCCHelper smccHelper = new SMCCHelper();
-  protected SignatureCard signatureCard = null;
-  protected static Map<String, SMCCSTALRequestHandler> handlerMap = new HashMap<String, SMCCSTALRequestHandler>();
-
-  static {
-    addRequestHandler(InfoboxReadRequest.class, new InfoBoxReadRequestHandler());
-    addRequestHandler(SignRequest.class, new SignRequestHandler());
-  }
-
-  public AbstractSMCCSTAL() {
-  }
-
-  /**
-   * Implementations must assign the signature card within this method.
-   * 
-   * @return if the user canceled
-   */
-  protected abstract boolean waitForCard();
-
-  protected abstract BKUGUIFacade getGUI();
-
-  @Override
-  public List<STALResponse> handleRequest(
-      List<STALRequest> requestList) {
-    log.debug("Got request list containing " + requestList.size()
-        + " STAL requests");
-    List<STALResponse> responseList = new ArrayList<STALResponse>(requestList
-        .size());
-    for (STALRequest request : requestList) {
-      log.info("Processing: " + request);
-      SMCCSTALRequestHandler handler = null;
-      handler = handlerMap.get(request.getClass().getSimpleName());
-      if (handler != null) {
-        if (handler.requireCard()) {
-          if (waitForCard()) {
-            responseList.add(new ErrorResponse(6001));
-            break;
-          }
-        }
-        try {
-          handler = handler.newInstance();
-          handler.init(signatureCard, getGUI());
-          responseList.add(handler.handleRequest(request));
-        } catch (Exception e) {
-          log.info("Error while handling STAL request:" + e);
-          responseList.add(new ErrorResponse(6000));
-        }
-      } else {
-        log.error("Cannot find a handler for STAL request: " + request);
-        responseList.add(new ErrorResponse());
-      }
-    }
-    return responseList;
-  }
-
-  public static void addRequestHandler(Class<? extends STALRequest> id,
-      SMCCSTALRequestHandler handler) {
-    log.debug("Registering STAL request handler: " + id.getSimpleName());
-    handlerMap.put(id.getSimpleName(), handler);
-  }
-
-  public static SMCCSTALRequestHandler getRequestHandler(
-      Class<? extends STALRequest> request) {
-    return handlerMap.get(request.getSimpleName());
-  }
-
-  @Override
-  public void setLocale(Locale locale) {
-    if (locale == null) {
-      throw new NullPointerException("Locale must not be set to null");
-    }
-    this.locale = locale;
-  }
-}
+package at.gv.egiz.bku.smccstal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.smcc.util.SMCCHelper;
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.InfoboxReadRequest;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.SignRequest;
+
+public abstract class AbstractSMCCSTAL implements STAL {
+  private static Log log = LogFactory.getLog(AbstractSMCCSTAL.class);
+
+  protected Locale locale = Locale.getDefault();
+  protected SMCCHelper smccHelper = new SMCCHelper();
+  protected SignatureCard signatureCard = null;
+  protected static Map<String, SMCCSTALRequestHandler> handlerMap = new HashMap<String, SMCCSTALRequestHandler>();
+
+  static {
+    addRequestHandler(InfoboxReadRequest.class, new InfoBoxReadRequestHandler());
+    addRequestHandler(SignRequest.class, new SignRequestHandler());
+  }
+
+  /**
+   * Implementations must assign the signature card within this method.
+   * 
+   * @return if the user canceled
+   */
+  protected abstract boolean waitForCard();
+
+  protected abstract BKUGUIFacade getGUI();
+
+  @Override
+  public List<STALResponse> handleRequest(
+      List<STALRequest> requestList) {
+    log.debug("Got request list containing " + requestList.size()
+        + " STAL requests");
+    List<STALResponse> responseList = new ArrayList<STALResponse>(requestList
+        .size());
+    for (STALRequest request : requestList) {
+      log.info("Processing: " + request);
+      SMCCSTALRequestHandler handler = null;
+      handler = handlerMap.get(request.getClass().getSimpleName());
+      if (handler != null) {
+        if (handler.requireCard()) {
+          if (waitForCard()) {
+            responseList.add(new ErrorResponse(6001));
+            break;
+          }
+        }
+        try {
+          handler = handler.newInstance();
+          handler.init(signatureCard, getGUI());
+          responseList.add(handler.handleRequest(request));
+        } catch (Exception e) {
+          log.info("Error while handling STAL request:" + e);
+          responseList.add(new ErrorResponse(6000));
+        }
+      } else {
+        log.error("Cannot find a handler for STAL request: " + request);
+        responseList.add(new ErrorResponse());
+      }
+    }
+    return responseList;
+  }
+
+  public static void addRequestHandler(Class<? extends STALRequest> id,
+      SMCCSTALRequestHandler handler) {
+    log.debug("Registering STAL request handler: " + id.getSimpleName());
+    handlerMap.put(id.getSimpleName(), handler);
+  }
+
+  public static SMCCSTALRequestHandler getRequestHandler(
+      Class<? extends STALRequest> request) {
+    return handlerMap.get(request.getSimpleName());
+  }
+
+  @Override
+  public void setLocale(Locale locale) {
+    if (locale == null) {
+      throw new NullPointerException("Locale must not be set to null");
+    }
+    this.locale = locale;
+  }
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SMCCSTALRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SMCCSTALRequestHandler.java
index 7badb2a0..6f303f76 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SMCCSTALRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SMCCSTALRequestHandler.java
@@ -14,23 +14,22 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-package at.gv.egiz.bku.smccstal;
-
-
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.SignatureCard;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-
-public interface SMCCSTALRequestHandler {
-  
-  public void init(SignatureCard sc, BKUGUIFacade gui);
-  
-  public STALResponse handleRequest(STALRequest request);
-  
-  public boolean requireCard();
-  
-  public SMCCSTALRequestHandler newInstance();
-
-}
+package at.gv.egiz.bku.smccstal;
+
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+
+public interface SMCCSTALRequestHandler {
+  
+  public void init(SignatureCard sc, BKUGUIFacade gui);
+  
+  public STALResponse handleRequest(STALRequest request);
+  
+  public boolean requireCard();
+  
+  public SMCCSTALRequestHandler newInstance();
+
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
index 6ae4fa01..2fe77c5d 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
@@ -1,151 +1,188 @@
 /*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.bku.smccstal;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import at.gv.egiz.smcc.CancelledException;
-import at.gv.egiz.smcc.PINProvider;
-import at.gv.egiz.smcc.PINSpec;
-import at.gv.egiz.smcc.SignatureCard;
-import at.gv.egiz.smcc.SignatureCardException;
-import at.gv.egiz.smcc.SignatureCard.KeyboxName;
-import at.gv.egiz.stal.ErrorResponse;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-import at.gv.egiz.stal.SignRequest;
-import at.gv.egiz.stal.SignResponse;
-import at.gv.egiz.stal.signedinfo.ObjectFactory;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
-import at.gv.egiz.stal.util.JCEAlgorithmNames;
-
-public class SignRequestHandler extends AbstractRequestHandler implements
-    PINProvider {
-  private static Log log = LogFactory.getLog(SignRequestHandler.class);
-
-  private static JAXBContext jaxbContext;
-
-  static {
-    try {
-      jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage()
-          .getName());
-    } catch (JAXBException e) {
-      log.fatal("Cannot init jaxbContext", e);
-    }
-  }
-
-  private int retryCounter = 0;
-
-  public SignRequestHandler() {
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public STALResponse handleRequest(STALRequest request) {
-    if (request instanceof SignRequest) {
-      SignRequest signReq = (SignRequest) request;
-      newSTALMessage("Message.RequestCaption", "Message.SignRequest");
-      try {
-        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-        InputStream is = new ByteArrayInputStream(signReq.getSignedInfo());
-        JAXBElement<SignedInfoType> signedInfo = (JAXBElement<SignedInfoType>) unmarshaller
-            .unmarshal(is);
-        String signatureMethod = signedInfo.getValue().getSignatureMethod()
-            .getAlgorithm();
-        log.debug("Found signature method: " + signatureMethod);
-        String jceName = JCEAlgorithmNames.getJCEHashName(signatureMethod);
-        if (jceName == null) {
-          log.error("Hash algorithm not supported:");
-          return new ErrorResponse(1000);
-        }
-        MessageDigest md = MessageDigest.getInstance(jceName);
-        md.update(signReq.getSignedInfo());
-        KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq
-            .getKeyIdentifier());
-        byte[] resp = card.createSignature(md.digest(), kb, this);
-        if (resp == null) {
-          return new ErrorResponse(6001);
-        }
-        SignResponse stalResp = new SignResponse();
-        stalResp.setSignatureValue(resp);
-        return stalResp;
-      } catch (CancelledException cx) {
-        log.debug("User cancelled request");
-        return new ErrorResponse(6001);
-      } catch (SignatureCardException e) {
-        log.error("Error while creating signature: " + e);
-        return new ErrorResponse(4000);
-      } catch (JAXBException e) {
-        log.error("Cannot unmarshall signed info", e);
-        return new ErrorResponse(1000);
-      } catch (NoSuchAlgorithmException e) {
-        log.error(e);
-        return new ErrorResponse(1000);
-      }
-    } else {
-      log.fatal("Got unexpected STAL request: " + request);
-      return new ErrorResponse(1000);
-    }
-  }
-
-  @Override
-  public boolean requireCard() {
-    return true;
-  }
-
-  @Override
-  public String providePIN(PINSpec spec, int retries) {
-    if (retryCounter++ > 0) {
-      log.info("PIN wrong retrying ...");
-      gui.showSignaturePINRetryDialog(spec, retries, this, "sign", this,
-          "cancel", this, "hashData");
-    } else {
-      gui.showSignaturePINDialog(spec, this, "sign", this, "cancel", this,
-          "hashData");
-    }
-    do {
-      waitForAction();
-      if (actionCommand.equals("cancel")) {
-        return null;
-      } else if (actionCommand.equals("hashData")) {
-        // FIXME provide hashdata input
-        gui.showHashDataInputDialog(null, this, "ok");
-      } else if (actionCommand.equals("sign")) {
-        return new String(gui.getPin());
-      } else if (actionCommand.equals("ok")) {
-        gui.showSignaturePINDialog(spec, this, "sign", this, "cancel", this,
-        "hashData"); 
-      }
-    } while (true);
-  }
-
-  @Override
-  public SMCCSTALRequestHandler newInstance() {
-    return new SignRequestHandler();
-  }
-}
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.bku.smccstal;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PINProvider;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.SignatureCard.KeyboxName;
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.SignRequest;
+import at.gv.egiz.stal.SignResponse;
+import at.gv.egiz.stal.signedinfo.ObjectFactory;
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import at.gv.egiz.stal.util.JCEAlgorithmNames;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is NOT thread-safe. 
+ * handleRequest() sets the SignedInfo which is used in providePIN.
+ */
+public class SignRequestHandler extends AbstractRequestHandler implements
+  PINProvider {
+
+    private static Log log = LogFactory.getLog(SignRequestHandler.class);
+    private static JAXBContext jaxbContext;
+    
+
+    static {
+        try {
+            jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
+        } catch (JAXBException e) {
+            log.fatal("Cannot init jaxbContext", e);
+        }
+    }
+    /** the SignedInfo of the current SignRequest */
+    protected SignedInfoType signedInfo;
+    protected List<HashDataInput> hashDataInputs;
+    
+    private int retryCounter = 0;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public STALResponse handleRequest(STALRequest request) {
+        if (request instanceof SignRequest) {
+            SignRequest signReq = (SignRequest) request;
+            newSTALMessage("Message.RequestCaption", "Message.SignRequest");
+            try {
+                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+                InputStream is = new ByteArrayInputStream(signReq.getSignedInfo());
+                JAXBElement<SignedInfoType> si = (JAXBElement<SignedInfoType>) unmarshaller.unmarshal(is);
+                signedInfo = si.getValue();
+                String signatureMethod = signedInfo.getSignatureMethod().getAlgorithm();
+                log.debug("Found signature method: " + signatureMethod);
+                String jceName = JCEAlgorithmNames.getJCEHashName(signatureMethod);
+                if (jceName == null) {
+                    log.error("Hash algorithm not supported:");
+                    return new ErrorResponse(1000);
+                }
+                MessageDigest md = MessageDigest.getInstance(jceName);
+                md.update(signReq.getSignedInfo());
+                KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
+                byte[] resp = card.createSignature(md.digest(), kb, this);
+                if (resp == null) {
+                    return new ErrorResponse(6001);
+                }
+                SignResponse stalResp = new SignResponse();
+                stalResp.setSignatureValue(resp);
+                return stalResp;
+            } catch (CancelledException cx) {
+                log.debug("User cancelled request");
+                return new ErrorResponse(6001);
+            } catch (SignatureCardException e) {
+                log.error("Error while creating signature: " + e);
+                return new ErrorResponse(4000);
+            } catch (JAXBException e) {
+                log.error("Cannot unmarshall signed info", e);
+                return new ErrorResponse(1000);
+            } catch (NoSuchAlgorithmException e) {
+                log.error(e);
+                return new ErrorResponse(1000);
+            } finally {
+                signedInfo = null;
+            }
+        } else {
+            log.fatal("Got unexpected STAL request: " + request);
+            return new ErrorResponse(1000);
+        }
+    }
+
+    @Override
+    public boolean requireCard() {
+        return true;
+    }
+
+    @Override
+    public String providePIN(PINSpec spec, int retries) {
+        if (retryCounter++ > 0) {
+            log.info("PIN wrong retrying ...");
+            gui.showSignaturePINRetryDialog(spec, retries, this, "sign", this,
+              "cancel", this, "hashData");
+        } else {
+            gui.showSignaturePINDialog(spec, this, "sign", this, "cancel", this,
+              "hashData");
+        }
+        do {
+            waitForAction();
+            if (actionCommand.equals("cancel")) {
+                return null;
+            } else if (actionCommand.equals("hashData")) {
+                if (signedInfo != null) {
+                    try {
+                        gui.showWaitDialog(null);
+                        if (hashDataInputs == null) {
+                            hashDataInputs = getHashDataInputs(signedInfo.getReference());
+                        }
+                        gui.showHashDataInputDialog(hashDataInputs, this, "ok");
+                        waitForAction();
+                        gui.showSignaturePINDialog(spec, this, "sign", this, "cancel", this,
+                            "hashData");
+                    } catch (Exception ex) {
+                        //FIXME localize messages
+                        log.error("Failed to obtain HashDataInputs: " + ex.getMessage());
+                        gui.showErrorDialog("Failed to obtain HashDataInputs: " + ex.getMessage(), this, "ok");
+                    }
+                } else {
+                    //FIXME get all hashdatainputs
+                    gui.showErrorDialog("Failed to obtain HashDataInputs: No dsig:SignedInfo provided.", this, "ok");
+                }
+            } else if (actionCommand.equals("sign")) {
+                return new String(gui.getPin());
+            } else if (actionCommand.equals("ok")) {
+                gui.showSignaturePINDialog(spec, this, "sign", this, "cancel", this,
+                  "hashData");
+            }
+        } while (true);
+    }
+
+    @Override
+    public SMCCSTALRequestHandler newInstance() {
+        return new SignRequestHandler();
+    }
+
+    /**
+     * override by subclass
+     * @return
+     */
+    protected List<HashDataInput> getHashDataInputs(List<ReferenceType> signedReferences) throws Exception {
+        //TODO
+        log.warn("Return empty HashDataInput");
+        return new ArrayList<HashDataInput>();
+    }
+}
-- 
cgit v1.2.3