summaryrefslogtreecommitdiff
path: root/smccSTAL/src
diff options
context:
space:
mode:
authorclemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2008-09-17 17:17:10 +0000
committerclemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2008-09-17 17:17:10 +0000
commitcf82096145bbdd548e388c1bc25f0e703b9b4624 (patch)
treeae08e610926dd5d5fa1b15df2856427df3e10060 /smccSTAL/src
parent6cafec9a3f05bb5e24c364e51a336326a63b8296 (diff)
downloadmocca-cf82096145bbdd548e388c1bc25f0e703b9b4624.tar.gz
mocca-cf82096145bbdd548e388c1bc25f0e703b9b4624.tar.bz2
mocca-cf82096145bbdd548e388c1bc25f0e703b9b4624.zip
hashdatainput digest verification
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@44 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'smccSTAL/src')
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java2
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/CashedHashDataInputResolver.java27
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java273
3 files changed, 240 insertions, 62 deletions
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 56c8340b..ac2b725c 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
@@ -45,7 +45,7 @@ public abstract class AbstractSMCCSTAL implements STAL {
static {
addRequestHandler(InfoboxReadRequest.class, new InfoBoxReadRequestHandler());
- addRequestHandler(SignRequest.class, new SignRequestHandler());
+// addRequestHandler(SignRequest.class, new SignRequestHandler());
}
/**
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/CashedHashDataInputResolver.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/CashedHashDataInputResolver.java
new file mode 100644
index 00000000..05af85d9
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/CashedHashDataInputResolver.java
@@ -0,0 +1,27 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package at.gv.egiz.bku.smccstal;
+
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.impl.ByteArrayHashDataInput;
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+import java.security.DigestException;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author clemens
+ */
+public interface CashedHashDataInputResolver {
+
+ /**
+ * implementations may verify the hashvalue
+ * @post-condition returned list != null
+ * @return
+ */
+ List<HashDataInput> getCashedHashDataInputs(List<ReferenceType> signedReferences) throws DigestException, Exception;
+}
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 d37d0551..59eed55f 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
@@ -21,8 +21,6 @@ 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;
@@ -43,21 +41,26 @@ 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.impl.ByteArrayHashDataInput;
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.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.security.DigestException;
+import java.security.DigestInputStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Set;
/**
* This class is NOT thread-safe.
* handleRequest() sets the SignedInfo which is used in providePIN.
*/
-public class SignRequestHandler extends AbstractRequestHandler implements
- PINProvider {
+public abstract class SignRequestHandler extends AbstractRequestHandler implements
+ CashedHashDataInputResolver {
private static Log log = LogFactory.getLog(SignRequestHandler.class);
private static JAXBContext jaxbContext;
@@ -71,10 +74,10 @@ public class SignRequestHandler extends AbstractRequestHandler implements
}
}
/** the SignedInfo of the current SignRequest */
- protected SignedInfoType signedInfo;
- protected List<HashDataInput> hashDataInputs;
+// protected SignedInfoType signedInfo;
+// protected List<ByteArrayHashDataInput> hashDataInputs;
- private int retryCounter = 0;
+// private int retryCounter = 0;
@SuppressWarnings("unchecked")
@Override
@@ -86,8 +89,7 @@ public class SignRequestHandler extends AbstractRequestHandler implements
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();
+ String signatureMethod = si.getValue().getSignatureMethod().getAlgorithm();
log.debug("Found signature method: " + signatureMethod);
String jceName = JCEAlgorithmNames.getJCEHashName(signatureMethod);
if (jceName == null) {
@@ -97,7 +99,7 @@ public class SignRequestHandler extends AbstractRequestHandler implements
MessageDigest md = MessageDigest.getInstance(jceName);
md.update(signReq.getSignedInfo());
KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
- byte[] resp = card.createSignature(md.digest(), kb, this);
+ byte[] resp = card.createSignature(md.digest(), kb, new STALPinProvider(si.getValue()));
if (resp == null) {
return new ErrorResponse(6001);
}
@@ -116,9 +118,7 @@ public class SignRequestHandler extends AbstractRequestHandler implements
} 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);
@@ -130,59 +130,210 @@ public class SignRequestHandler extends AbstractRequestHandler implements
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.size() == 0) {
- hashDataInputs = getHashDataInputs(signedInfo.getReference());
- }
- gui.showHashDataInputDialog(hashDataInputs, this, "ok");
- } 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 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.size() == 0) {
+// HashMap<String, ReferenceType> signedReferences = new HashMap<String, ReferenceType>();
+// for (ReferenceType reference : signedInfo.getReference()) {
+// //don't get Manifest, QualifyingProperties, ...
+// if (reference.getType() == null) {
+// signedReferences.put(reference.getId(), reference);
+// }
+// }
+// hashDataInputs = getHashDataInputs(signedReferences.keySet());
+// for (HashDataInput hashDataInput : hashDataInputs) {
+// ReferenceType reference = signedReferences.get(hashDataInput.getReferenceId());
+// String algorithm = reference.getDigestMethod().getAlgorithm();
+// MessageDigest md = MessageDigest.getInstance(algorithm);
+// DigestInputStream dis = new DigestInputStream(hashDataInput.getHashDataInput(), md);
+// while(dis.read() != -1) ;
+// byte[] digestValue = md.digest();
+// boolean valid = reference.getDigestValue().equals(digestValue);
+// }
+// }
+// gui.showHashDataInputDialog(hashDataInputs, this, "ok");
+// } 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
+// public SMCCSTALRequestHandler newInstance() {
+// return new SignRequestHandler();
+// }
/**
- * override by subclass
+ * implementations may verify the hashvalue
* @post-condition returned list != null
* @return
*/
- protected List<HashDataInput> getHashDataInputs(List<ReferenceType> signedReferences) throws Exception {
- //TODO
- log.warn("Return empty HashDataInput");
- return new ArrayList<HashDataInput>();
+ @Override
+ public abstract List<HashDataInput> getCashedHashDataInputs(List<ReferenceType> signedReferences) throws Exception;
+// {
+// //TODO
+// log.warn("Return empty HashDataInput");
+// return new ArrayList<HashDataInput>();
+// }
+
+
+
+// protected void validateHashDataInputs(List<ReferenceType> signedReferences, List<HashDataInput> hashDataInputs) {
+// if (hashDataInputs != null) {
+//
+// Map<String, HashDataInput> hashDataIdMap = new HashMap<String, HashDataInput>();
+// for (HashDataInput hdi : hashDataInputs) {
+// if (log.isTraceEnabled()) {
+// log.trace("Provided HashDataInput for reference " + hdi.getReferenceId());
+// }
+// hashDataIdMap.put(hdi.getReferenceId(), hdi);
+// }
+//
+// List<GetHashDataInputType.Reference> reqRefs = request.getReference();
+// for (GetHashDataInputType.Reference reqRef : reqRefs) {
+// String reqRefId = reqRef.getID();
+// HashDataInput reqHdi = hashDataIdMap.get(reqRefId);
+// if (reqHdi == null) {
+// String msg = "Failed to resolve HashDataInput for reference " + reqRefId;
+// log.error(msg);
+// GetHashDataInputFaultType faultInfo = new GetHashDataInputFaultType();
+// faultInfo.setErrorCode(1);
+// faultInfo.setErrorMessage(msg);
+// throw new GetHashDataInputFault(msg, faultInfo);
+// }
+//
+// InputStream hashDataIS = reqHdi.getHashDataInput();
+// if (hashDataIS == null) {
+// //HashDataInput not cached?
+// String msg = "Failed to obtain HashDataInput for reference " + reqRefId + ", reference not cached";
+// log.error(msg);
+// GetHashDataInputFaultType faultInfo = new GetHashDataInputFaultType();
+// faultInfo.setErrorCode(1);
+// faultInfo.setErrorMessage(msg);
+// throw new GetHashDataInputFault(msg, faultInfo);
+// }
+// ByteArrayOutputStream baos = null;
+// try {
+// if (log.isDebugEnabled()) {
+// log.debug("Resolved HashDataInput " + reqRefId + " (" + reqHdi.getMimeType() + ";charset=" + reqHdi.getEncoding() + ")");
+// }
+// baos = new ByteArrayOutputStream(hashDataIS.available());
+// int c;
+// while ((c = hashDataIS.read()) != -1) {
+// baos.write(c);
+// }
+// GetHashDataInputResponseType.Reference ref = new GetHashDataInputResponseType.Reference();
+// ref.setID(reqRefId);
+// ref.setMimeType(reqHdi.getMimeType());
+// ref.setEncoding(reqHdi.getEncoding());
+// ref.setValue(baos.toByteArray());
+// response.getReference().add(ref);
+// } catch (IOException ex) {
+// String msg = "Failed to get HashDataInput for reference " + reqRefId;
+// log.error(msg, ex);
+// GetHashDataInputFaultType faultInfo = new GetHashDataInputFaultType();
+// faultInfo.setErrorCode(1);
+// faultInfo.setErrorMessage(msg);
+// throw new GetHashDataInputFault(msg, faultInfo, ex);
+// } finally {
+// try {
+// baos.close();
+// } catch (IOException ex) {
+// }
+// }
+// }
+// return response;
+// }
+// for (ReferenceType reference : signedReferences) {
+// String algorithm = reference.getDigestMethod().getAlgorithm();
+//
+// }
+// }
+
+
+ /**
+ * cashes the HashDataInputs provided by SignRequestHandler.this.getHashDataInputs()
+ * (don't know whether outer class is LocalSignRequestHandler or WSSignRequestHandler, providing DataObjectHDI or ByteArrayHDI, resp)
+ */
+ class STALPinProvider implements PINProvider {
+
+ protected SignedInfoType signedInfo;
+ protected List<HashDataInput> hashDataInputs;
+ private int retryCounter = 0;
+
+ public STALPinProvider(SignedInfoType signedInfo) {
+ this.signedInfo = signedInfo;
+ }
+
+ @Override
+ public String providePIN(PINSpec spec, int retries) {
+ if (retryCounter++ > 0) {
+ log.info("PIN wrong retrying ...");
+ gui.showSignaturePINRetryDialog(spec, retries, SignRequestHandler.this, "sign", SignRequestHandler.this,
+ "cancel", SignRequestHandler.this, "hashData");
+ } else {
+ gui.showSignaturePINDialog(spec, SignRequestHandler.this, "sign", SignRequestHandler.this, "cancel", SignRequestHandler.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.size() == 0) {
+ hashDataInputs = getCashedHashDataInputs(signedInfo.getReference());
+ }
+ gui.showHashDataInputDialog(hashDataInputs, SignRequestHandler.this, "ok");
+ } catch (DigestException ex) {
+ log.error("Bad digest value: " + ex.getMessage());
+ gui.showErrorDialog(ex.getMessage());
+ } catch (Exception ex) {
+ //FIXME localize messages
+ log.error("Failed to obtain HashDataInputs: " + ex.getMessage());
+ gui.showErrorDialog("Failed to obtain HashDataInputs: " + ex.getMessage(), SignRequestHandler.this, "ok");
+ }
+ } else {
+ //FIXME get all hashdatainputs
+ gui.showErrorDialog("Failed to obtain HashDataInputs: No dsig:SignedInfo provided.", SignRequestHandler.this, "ok");
+ }
+ } else if (actionCommand.equals("sign")) {
+ return new String(gui.getPin());
+ } else if (actionCommand.equals("ok")) {
+ gui.showSignaturePINDialog(spec, SignRequestHandler.this, "sign", SignRequestHandler.this, "cancel", SignRequestHandler.this,
+ "hashData");
+ }
+ } while (true);
+ }
+ }
}