summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBonato, Martin <martin.bonato@prime-sign.com>2018-02-08 22:19:55 +0100
committerBonato, Martin <martin.bonato@prime-sign.com>2018-02-08 22:19:55 +0100
commitb9ccb62d35a755efb505d426ce924d5a8fbe937a (patch)
tree00d17aa7dc660eb0e90ae753e36a623d672fc0e0
parent84794c877062fe0424f357be0e83bdd045d75d52 (diff)
downloadmocca-b9ccb62d35a755efb505d426ce924d5a8fbe937a.tar.gz
mocca-b9ccb62d35a755efb505d426ce924d5a8fbe937a.tar.bz2
mocca-b9ccb62d35a755efb505d426ce924d5a8fbe937a.zip
BulkSignature implementationfb-bulksignature
-rw-r--r--BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java8
-rw-r--r--BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java100
-rw-r--r--BKUApplet/src/test/java/at/gv/egiz/stal/client/STALServiceTest.java4
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/GetCertificateBKUWorker.java2
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/HardwareInfoBKUWorker.java2
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/IdentityLinkBKUWorker.java2
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java21
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java257
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/hashdata/HashDataInputLoader.java16
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewer.java (renamed from smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SecureViewer.java)23
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java20
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties6
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_de.properties6
-rw-r--r--BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java2
-rw-r--r--BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java5
-rw-r--r--BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBulkSignRequestHandler.java82
-rw-r--r--BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalSecureViewer.java289
-rw-r--r--BKULocal/src/main/webapp/WEB-INF/applicationContext.xml15
-rw-r--r--BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java20
-rw-r--r--BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java42
-rw-r--r--BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml15
-rw-r--r--BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd19
-rw-r--r--BKUOnline/src/main/wsdl/stal-service.xsd17
-rw-r--r--BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java24
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/BulkSignRequest.java92
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/BulkSignResponse.java91
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java8
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/SignRequest.java56
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/SignatureInfo.java84
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/hashdata/StubHashDataInput.java101
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java126
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignRequestType.java68
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignResponseType.java69
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputType.java42
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestResponseType.java52
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestType.java58
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java40
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/RequestType.java3
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/ResponseType.java3
-rw-r--r--STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java87
-rw-r--r--STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java2
-rw-r--r--bkucommon/pom.xml5
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkCommand.java27
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkSignatureResult.java31
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandFactory.java40
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImpl.java439
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkSignatureResultImpl.java138
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImpl.java5
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkCollectionSecurityProvider.java114
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignature.java116
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignatureInfo.java104
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java49
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/ReferencedHashDataInput.java81
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java37
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java187
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java6
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java35
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/spring/URLDereferencerFactoryBean.java75
-rw-r--r--bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties3
-rw-r--r--bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties2
-rw-r--r--bkucommon/src/site/apt/configuration.apt4
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImplTest.java130
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImplTest.java33
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/cms/SignatureTest.java130
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java12
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java65
-rw-r--r--bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequest.xml34
-rw-r--r--bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequestWithReference.xml37
-rw-r--r--bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/testApplicationContext.xml9
-rw-r--r--pom.xml12
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/BulkSignException.java47
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/OverrulePinpadPINGUI.java7
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java4
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java10
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/card/CreateSignature.java3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/test/AbstractCardTest.java5
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/test/ecard/ECardG3InfoboxContainerTest.java3
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/BulkSignPINGUI.java172
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java8
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java13
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java4
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/BulkSignRequestHandler.java273
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java13
-rw-r--r--utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSDataObjectOptionalMetaType.java35
-rw-r--r--utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSReferenceObject.java46
-rw-r--r--utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CreateCMSSignatureRequestType.java36
-rw-r--r--utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/DigestAndRefType.java128
-rw-r--r--utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/ObjectFactory.java8
-rw-r--r--utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FileURLProtocolHandlerImpl.java63
-rw-r--r--utils/src/main/resources/at/gv/egiz/bku/slschema/Core-1.2.xsd2267
95 files changed, 5565 insertions, 1535 deletions
diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java
index 67c3f9af..d89611a6 100644
--- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java
+++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java
@@ -25,8 +25,10 @@
package at.gv.egiz.bku.online.applet;
import at.gv.egiz.bku.smccstal.AbstractBKUWorker;
+import at.gv.egiz.bku.smccstal.BulkSignRequestHandler;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.smccstal.SignRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.STALRequest;
import at.gv.egiz.stal.STALResponse;
import at.gv.egiz.stal.SignRequest;
@@ -85,6 +87,8 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable {
new AppletSecureViewer(gui, stalPort, sessionId);
addRequestHandler(SignRequest.class,
new SignRequestHandler(secureViewer));
+ addRequestHandler(BulkSignRequest.class,
+ new BulkSignRequestHandler(secureViewer));
GetNextRequestResponseType nextRequestResp = stalPort.connect(sessionId);
@@ -93,7 +97,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable {
List<JAXBElement<? extends ResponseType>> responses = new ArrayList<JAXBElement<? extends ResponseType>>();
try {
- requests = nextRequestResp.getInfoboxReadRequestOrSignRequestOrQuitRequest();
+ requests = nextRequestResp.getInfoboxReadRequestOrSignRequestOrBulkSignRequest();
responses.clear();
// (rather use validator)
@@ -167,7 +171,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable {
}
GetNextRequestType nextRequest = stalObjFactory.createGetNextRequestType();
nextRequest.setSessionId(sessionId);
- nextRequest.getInfoboxReadResponseOrSignResponseOrErrorResponse().addAll(responses);
+ nextRequest.getInfoboxReadResponseOrSignResponseOrBulkSignResponse().addAll(responses);
nextRequestResp = stalPort.getNextRequest(nextRequest);
}
}
diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java
index b2c084bd..9f7061b1 100644
--- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java
+++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java
@@ -32,27 +32,31 @@ import java.security.DigestException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.bku.smccstal.SecureViewer;
+import at.gv.egiz.bku.gui.hashdata.HashDataInputLoader;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.SignatureInfo;
+import at.gv.egiz.stal.hashdata.StubHashDataInput;
import at.gv.egiz.stal.impl.ByteArrayHashDataInput;
import at.gv.egiz.stal.service.GetHashDataInputFault;
import at.gv.egiz.stal.service.STALPortType;
import at.gv.egiz.stal.service.types.GetHashDataInputResponseType;
import at.gv.egiz.stal.service.types.GetHashDataInputType;
import at.gv.egiz.stal.signedinfo.ReferenceType;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
/**
*
* @author Clemens Orthacker &lt;clemens.orthacker@iaik.tugraz.at&gt;
*/
-public class AppletSecureViewer implements SecureViewer {
+public class AppletSecureViewer implements SecureViewer, HashDataInputLoader {
private static final Logger log = LoggerFactory.getLogger(AppletSecureViewer.class);
@@ -86,19 +90,19 @@ public class AppletSecureViewer implements SecureViewer {
* @throws java.lang.Exception
*/
@Override
- public void displayDataToBeSigned(SignedInfoType signedInfo,
+ public void displayDataToBeSigned(SignatureInfo signatureInfo,
ActionListener okListener, String okCommand)
throws DigestException, Exception {
if (verifiedDataToBeSigned == null) {
- log.info("Retrieve data to be signed for dsig:SignedInfo {}.", signedInfo.getId());
+ log.info("Retrieve data to be signed for dsig:SignedInfo {}.", signatureInfo.getId());
List<GetHashDataInputResponseType.Reference> hdi =
- getHashDataInput(signedInfo.getReference());
- verifiedDataToBeSigned = verifyHashDataInput(signedInfo.getReference(),
+ getHashDataInput(signatureInfo.getReference());
+ verifiedDataToBeSigned = verifyHashDataInput(signatureInfo.getReference(),
hdi);
}
if (verifiedDataToBeSigned.size() > 0) {
- gui.showSecureViewer(verifiedDataToBeSigned, okListener, okCommand);
+ gui.showSecureViewer(verifiedDataToBeSigned, okListener, okCommand, this);
} else {
throw new Exception("No data to be signed (apart from any QualifyingProperties or a Manifest)");
}
@@ -119,14 +123,16 @@ public class AppletSecureViewer implements SecureViewer {
//don't get Manifest, QualifyingProperties, ...
if (signedRef.getType() == null) {
String signedRefId = signedRef.getId();
- if (signedRefId != null) {
- log.trace("Requesting hashdata input for reference {}.", signedRefId);
+ byte[] digest = signedRef.getDigestValue();
+ if (signedRefId != null || digest != null) {
+ log.trace("Requesting hashdata input for reference {}.", new String(digest));
GetHashDataInputType.Reference ref = new GetHashDataInputType.Reference();
ref.setID(signedRefId);
+ ref.setDigest(digest);
request.getReference().add(ref);
} else {
- throw new Exception("Cannot resolve signature data for dsig:Reference without Id attribute");
+ throw new Exception("Cannot resolve signature data for dsig:Reference without Id or digest attribute");
}
}
}
@@ -259,4 +265,76 @@ public class AppletSecureViewer implements SecureViewer {
}
return md.digest(hashDataInput);
}
+
+ @Override
+ public void displayDataToBeSigned(List<SignatureInfo> signatureInfoList, ActionListener okListener, String okCommand)
+ throws DigestException, Exception {
+
+ log.trace("Creating referenceMap");
+
+ for (SignatureInfo signatureInfo : signatureInfoList) {
+ for (ReferenceType reference : signatureInfo.getReference()) {
+ log.trace("Adding entry {} : {} to referenceMap", reference.getDigestValue(), reference.getId());
+ }
+ }
+
+ ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
+
+ log.trace("Adding empty hashDataInputs to selectedHashDataInputs");
+ for (SignatureInfo nextSignatureInfo : signatureInfoList) {
+ log.trace("Adding {} : {} to selectedHashDataInputs", nextSignatureInfo.getId(), nextSignatureInfo.getReference().get(0).getDigestValue());
+ selectedHashDataInputs.addAll(addEmptyHashDataInputs(nextSignatureInfo));
+ }
+
+ log.trace("Show Secure Viewer for selectedHashDataInputs");
+ gui.showSecureViewer(selectedHashDataInputs, okListener, okCommand, this);
+
+ }
+
+
+ @Override
+ public HashDataInput getHashDataInput(HashDataInput hashDataInput) throws Exception {
+
+ if (hashDataInput instanceof StubHashDataInput) {
+
+ StubHashDataInput stabHashDataInput = (StubHashDataInput) hashDataInput;
+
+ ReferenceType reference = stabHashDataInput.getReference();
+
+ List<HashDataInput> hashDataInputs = new LinkedList<HashDataInput>();
+
+ if (reference != null) {
+ log.trace("Retrieve data to be signed for dsig:SignedInfo {}.", hashDataInput.getReferenceId());
+ List<GetHashDataInputResponseType.Reference> hdi = getHashDataInput(Arrays.asList(reference));
+ hashDataInputs = verifyHashDataInput(Arrays.asList(reference), hdi);
+
+ if (hashDataInputs.size() == 0) {
+ throw new Exception("No data to be signed (apart from any QualifyingProperties or a Manifest)");
+ }
+
+ return hashDataInputs.get(0);
+ }
+
+ throw new Exception("No reference found for hashDataInput with id " + hashDataInput.getReferenceId());
+ }
+ return hashDataInput;
+ }
+
+ private Collection<? extends HashDataInput> addEmptyHashDataInputs(SignatureInfo signedInfo) throws Exception {
+ if (signedInfo.getReference().size() == 0) {
+ log.error("No hashdata input selected to be displayed: null.");
+ throw new Exception("No HashData Input selected to be displayed.");
+ }
+
+ log.trace("Adding HashDataInputs from signedInfo");
+ ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
+ for (ReferenceType dsigRef : signedInfo.getReference()) {
+
+ if (dsigRef.getType() == null) {
+ log.trace("Adding HashDataInput with id {}, name {} of type {}",new Object[]{dsigRef.getId(), signedInfo.getDisplayName(), signedInfo.getMimeType()});
+ selectedHashDataInputs.add(new StubHashDataInput(dsigRef, signedInfo.getDisplayName(), signedInfo.getMimeType()));
+ }
+ }
+ return selectedHashDataInputs;
+ }
}
diff --git a/BKUApplet/src/test/java/at/gv/egiz/stal/client/STALServiceTest.java b/BKUApplet/src/test/java/at/gv/egiz/stal/client/STALServiceTest.java
index f3967619..057a9c90 100644
--- a/BKUApplet/src/test/java/at/gv/egiz/stal/client/STALServiceTest.java
+++ b/BKUApplet/src/test/java/at/gv/egiz/stal/client/STALServiceTest.java
@@ -69,8 +69,8 @@ public class STALServiceTest {
// req.getResponse().add(new ErrorResponse(1234));
GetNextRequestResponseType nrResp = port.getNextRequest(nrReq);
assertNotNull(nrResp);
- System.out.println("got response: " + nrResp.getInfoboxReadRequestOrSignRequestOrQuitRequest().size());
- for (JAXBElement<? extends RequestType> stalReqElt : nrResp.getInfoboxReadRequestOrSignRequestOrQuitRequest()) {
+ System.out.println("got response: " + nrResp.getInfoboxReadRequestOrSignRequestOrBulkSignRequest().size());
+ for (JAXBElement<? extends RequestType> stalReqElt : nrResp.getInfoboxReadRequestOrSignRequestOrBulkSignRequest()) {
RequestType stalReq = stalReqElt.getValue();
if (stalReq instanceof InfoboxReadRequestType) {
String ibid = ((InfoboxReadRequestType) stalReq).getInfoboxIdentifier();
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/GetCertificateBKUWorker.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/GetCertificateBKUWorker.java
index f05cccc4..f7fa584f 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/GetCertificateBKUWorker.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/GetCertificateBKUWorker.java
@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.gui.GetCertificateGUIFacade;
import at.gv.egiz.bku.smccstal.GetCertificateRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.QuitRequest;
@@ -53,6 +54,7 @@ public class GetCertificateBKUWorker extends AppletBKUWorker {
super(applet, gui);
removeRequestHandler(InfoboxReadRequest.class);
removeRequestHandler(SignRequest.class);
+ removeRequestHandler(BulkSignRequest.class);
addRequestHandler(GetCertificateRequest.class, new GetCertificateRequestHandler());
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/HardwareInfoBKUWorker.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/HardwareInfoBKUWorker.java
index 617b1612..15c584fe 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/HardwareInfoBKUWorker.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/HardwareInfoBKUWorker.java
@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.gui.GetHardwareInfoGUIFacade;
import at.gv.egiz.bku.smccstal.GetHardwareInfoRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.QuitRequest;
@@ -52,6 +53,7 @@ public class HardwareInfoBKUWorker extends AppletBKUWorker {
super(applet, gui);
removeRequestHandler(InfoboxReadRequest.class);
removeRequestHandler(SignRequest.class);
+ removeRequestHandler(BulkSignRequest.class);
addRequestHandler(GetHardwareInfoRequest.class, new GetHardwareInfoRequestHandler());
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/IdentityLinkBKUWorker.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/IdentityLinkBKUWorker.java
index 8ede2be1..1b5642ec 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/IdentityLinkBKUWorker.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/IdentityLinkBKUWorker.java
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.gui.IdentityLinkGUIFacade;
import at.gv.egiz.bku.smccstal.IdentityLinkRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.QuitRequest;
@@ -48,6 +49,7 @@ public class IdentityLinkBKUWorker extends AppletBKUWorker {
super(applet, gui);
removeRequestHandler(InfoboxReadRequest.class);
removeRequestHandler(SignRequest.class);
+ removeRequestHandler(BulkSignRequest.class);
addRequestHandler(IdentityLinkRequest.class, new IdentityLinkRequestHandler());
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
index 5de6a9e0..c128ceab 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIFacade.java
@@ -24,8 +24,10 @@
package at.gv.egiz.bku.gui;
- import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.bku.gui.hashdata.HashDataInputLoader;
import at.gv.egiz.smcc.PinInfo;
+ import at.gv.egiz.stal.HashDataInput;
+
import java.awt.Color;
import java.awt.event.ActionListener;
import java.util.List;
@@ -67,6 +69,7 @@ public interface BKUGUIFacade {
public static final String TITLE_INSERTCARD = "title.insertcard";
public static final String TITLE_CARD_NOT_SUPPORTED = "title.cardnotsupported";
public static final String TITLE_VERIFY_PIN = "title.verify.pin";
+ public static final String TITLE_OVERRULE_PINPAD = "title.overrule.pinpad";
public static final String TITLE_SIGN = "title.sign";
public static final String TITLE_VERIFY_PINPAD = "title.verify.pinpad";
public static final String TITLE_ERROR = "title.error";
@@ -74,6 +77,7 @@ public interface BKUGUIFacade {
public static final String TITLE_ENTRY_TIMEOUT = "title.entry.timeout";
public static final String TITLE_RETRY = "title.retry";
public static final String TITLE_WAIT = "title.wait";
+ public static final String TITLE_BULKSIGNATURE = "title.bulksign";
public static final String TITLE_SIGNATURE_DATA = "title.signature.data";
public static final String WINDOWTITLE_SAVE = "windowtitle.save";
public static final String WINDOWTITLE_ERROR = "windowtitle.error";
@@ -89,6 +93,7 @@ public interface BKUGUIFacade {
public static final String MESSAGE_CARD_NOT_SUPPORTED = "cardnotsupported";
public static final String MESSAGE_ENTERPIN = "enterpin";
public static final String MESSAGE_ENTERPIN_PINPAD = "enterpin.pinpad";
+ public static final String MESSAGE_OVERRULE_PINPAD = "overrule.pinpad";
public static final String MESSAGE_ENTERPIN_PINPAD_DIRECT = "enterpin.pinpad.direct";
public static final String MESSAGE_HASHDATALINK = "hashdatalink";
public static final String MESSAGE_HASHDATALINK_TINY = "hashdatalink.tiny";
@@ -103,6 +108,7 @@ public interface BKUGUIFacade {
public static final String MESSAGE_LAST_RETRY_PINPAD = "retries.pinpad.last";
public static final String MESSAGE_OVERWRITE = "overwrite";
public static final String MESSAGE_HELP = "help";
+ public static final String MESSAGE_BULKSIGN = "bulksign";
public static final String WARNING_XHTML = "warning.xhtml";
public static final String WARNING_CERT_NOTYETVALID = "warning.cert.notyetvalid";
@@ -165,6 +171,11 @@ public interface BKUGUIFacade {
ActionListener cancelListener, String cancelCommand,
ActionListener viewerListener, String viewerCommand);
+ public void showSignaturePINDialog(PinInfo pinSpec, int numRetries, int numSignatures,
+ ActionListener signListener, String signCommand,
+ ActionListener cancelListener, String cancelCommand,
+ ActionListener viewerListener, String viewerCommand);
+
public char[] getPin();
/**
@@ -176,7 +187,7 @@ public interface BKUGUIFacade {
* @param backCommand
*/
public void showSecureViewer(List<HashDataInput> dataToBeSigned,
- ActionListener backListener, String backCommand);
+ ActionListener backListener, String backCommand, HashDataInputLoader hashDataInputLoader);
public void showErrorDialog(String errorMsgKey, Object[] errorMsgParams,
ActionListener okListener, String okCommand);
@@ -196,8 +207,14 @@ public interface BKUGUIFacade {
public void showMessageDialog(String titleKey,
String msgKey, Object[] msgParams);
+ void updateMessageDialog(String titleKey,
+ String msgKey, Object[] msgParams, String buttonKey, ActionListener okListener, String okCommand);
+
public void showMessageDialog(String titleKey,
String msgKey);
public void getFocusFromBrowser();
+
+ public void showPinPadDeactivationDialog(ActionListener okListener, String okCommand,
+ ActionListener cancelListener, String cancelCommand);
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
index 82513a0e..13e330bf 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java
@@ -25,6 +25,7 @@
package at.gv.egiz.bku.gui;
+import at.gv.egiz.bku.gui.hashdata.HashDataInputLoader;
import at.gv.egiz.bku.gui.viewer.FontProviderException;
import at.gv.egiz.bku.gui.viewer.FontProvider;
import at.gv.egiz.bku.gui.viewer.SecureViewerSaveDialog;
@@ -67,6 +68,7 @@ import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.LayoutStyle;
+import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@@ -90,7 +92,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
}
protected Component primaryFocusHolder;
- protected SecureViewerDialog secureViewer;
+ protected SecureViewerDialog secureViewerDialog;
protected HelpListener helpListener;
protected FontProvider fontProvider;
@@ -155,7 +157,9 @@ public class BKUGUIImpl implements BKUGUIFacade {
// protected HashDataInput storedSelection;
protected List<HashDataInput> signedReferences;
protected Integer referenceIndex;
- private at.gv.egiz.bku.gui.BKUGUIImpl.SignedReferencesSelectionListener.SignedReferencesListDisplayer storedBackToListListener;
+ protected at.gv.egiz.bku.gui.BKUGUIImpl.SignedReferencesSelectionListener.SignedReferencesListDisplayer storedBackToListListener;
+
+ protected HashDataInputLoader hashDataInputLoader;
/**
* set contentPane init message bundle configure the style register the help
@@ -1205,6 +1209,15 @@ public class BKUGUIImpl implements BKUGUIFacade {
final ActionListener signListener, final String signCommand,
final ActionListener cancelListener, final String cancelCommand,
final ActionListener hashdataListener, final String hashdataCommand) {
+ showSignaturePINDialog(pinSpec, numRetries, 1, signListener, signCommand, cancelListener, cancelCommand,
+ hashdataListener, hashdataCommand);
+ }
+
+ @Override
+ public void showSignaturePINDialog(final PinInfo pinSpec, final int numRetries, final int numSignatures,
+ final ActionListener signListener, final String signCommand,
+ final ActionListener cancelListener, final String cancelCommand,
+ final ActionListener hashdataListener, final String hashdataCommand) {
log.debug("Scheduling signature-pin dialog.");
@@ -1228,7 +1241,9 @@ public class BKUGUIImpl implements BKUGUIFacade {
if (renderHeaderPanel) {
if (numRetries < 0) {
- titleLabel.setText(getMessage(TITLE_SIGN));
+ String msgPattern = getMessage(TITLE_SIGN);
+ String msg = MessageFormat.format(msgPattern, numSignatures);
+ titleLabel.setText(msg);
} else {
titleLabel.setText(getMessage(TITLE_RETRY));
}
@@ -1571,6 +1586,35 @@ public class BKUGUIImpl implements BKUGUIFacade {
showMessageDialog(titleKey, null, msgKey, msgParams, null, null, null);
}
+
+ @Override
+ public void updateMessageDialog(final String titleKey, final String msgKey,
+ final Object[] msgParams, String buttonKey,
+ final ActionListener okListener, final String okCommand) {
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ log.debug("[{}] Update message dialog.", Thread.currentThread().getName());
+
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(getMessage(titleKey));
+ }
+
+ helpListener.setHelpTopic(msgKey);
+
+ String msgPattern = getMessage(msgKey);
+ String msg = MessageFormat.format(msgPattern, msgParams);
+
+ msgLabel.setText(msg);
+
+ }
+ });
+ }
+
@Override
public void showMessageDialog(final String titleKey, final String msgKey) {
@@ -1718,6 +1762,158 @@ public class BKUGUIImpl implements BKUGUIFacade {
});
}
+
+ private void showOptionDialog(final String titleKey, final String msgKey, final Object[] msgParams,
+ final String cancelButtonKey, final String okButtonKey, final ActionListener cancelListener,
+ final String cancelCommand, final ActionListener okListener, final String okCommand) {
+
+ log.debug("Scheduling message dialog.");
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ log.debug("[{}] Show option dialog.", Thread.currentThread().getName());
+
+ log.debug("ButtonKey: {}.", okButtonKey);
+
+ log.debug("ButtonKey: {}.", cancelButtonKey);
+
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(getMessage(titleKey));
+ }
+
+ helpListener.setHelpTopic(msgKey);
+
+ String msgPattern = getMessage(msgKey);
+ String msg = MessageFormat.format(msgPattern, msgParams);
+
+ // we need to create a new JLabel object every time in order to
+ // ensure
+ // that screen reading software will read each updated label
+ msgLabel = new JLabel();
+
+ msgLabel.setFocusable(true);
+
+ msgLabel.setFont(msgLabel.getFont().deriveFont(
+ msgLabel.getFont().getStyle() & ~Font.BOLD));
+ msgLabel.setText(msg);
+
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.ParallelGroup mainHorizontal = mainPanelLayout
+ .createParallelGroup(GroupLayout.Alignment.LEADING);
+ GroupLayout.SequentialGroup mainVertical = mainPanelLayout
+ .createSequentialGroup();
+
+ String accessibleData = "";
+
+ if (!renderHeaderPanel) {
+ msgTitleLabel = new JLabel();
+ msgTitleLabel.setFont(msgTitleLabel.getFont().deriveFont(
+ msgTitleLabel.getFont().getStyle() | Font.BOLD));
+ msgTitleLabel.setText(getMessage(titleKey));
+
+ accessibleData = accessibleData + getMessage(titleKey);
+
+ GroupLayout.SequentialGroup titleHorizontal = mainPanelLayout
+ .createSequentialGroup()
+ .addComponent(msgTitleLabel);
+
+ GroupLayout.ParallelGroup titleVertical = mainPanelLayout
+ .createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(msgTitleLabel);
+
+ if (helpListener.implementsListener()) {
+ titleHorizontal.addPreferredGap(
+ LayoutStyle.ComponentPlacement.UNRELATED, 0,
+ Short.MAX_VALUE).addComponent(helpLabel);
+ titleVertical.addComponent(helpLabel);
+ }
+
+ mainHorizontal.addGroup(titleHorizontal);
+ mainVertical.addGroup(titleVertical);
+
+ } else {
+
+ accessibleData = accessibleData + titleLabel.getText();
+ }
+
+ msgLabel.getAccessibleContext().setAccessibleName(
+ accessibleData + msgLabel.getText());
+ msgLabel.getAccessibleContext().setAccessibleDescription(
+ accessibleData + msgLabel.getText());
+
+ mainPanelLayout.setHorizontalGroup(mainHorizontal
+ .addComponent(msgLabel));
+ mainPanelLayout.setVerticalGroup(mainVertical
+ .addComponent(msgLabel));
+
+
+ cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ cancelButton.setText(getMessage((cancelButtonKey != null) ? cancelButtonKey : BUTTON_CANCEL));
+ cancelButton.setActionCommand(okCommand);
+ cancelButton.addActionListener(okListener);
+
+ okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ okButton.setText(getMessage((okButtonKey != null) ? okButtonKey : BUTTON_OK));
+ okButton.setActionCommand(cancelCommand);
+ okButton.addActionListener(okListener);
+
+ primaryFocusHolder = okButton;
+
+ renderShowOptionDialogueButtonPanel();
+
+ GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
+ buttonPanel.setLayout(buttonPanelLayout);
+
+ buttonPanelLayout.setHorizontalGroup(buttonPanelLayout
+ .createSequentialGroup().addComponent(okButton,
+ GroupLayout.PREFERRED_SIZE, buttonSize,
+ GroupLayout.PREFERRED_SIZE));
+ buttonPanelLayout.setVerticalGroup(buttonPanelLayout
+ .createSequentialGroup().addComponent(okButton));
+
+ // okListener might be null (up to windowCloseAdapter what to do)
+ if (windowCloseAdapter != null) {
+ windowCloseAdapter.registerListener(okListener, okCommand);
+ }
+
+ updateMethodToRunAtResize("at.gv.egiz.bku.gui.BKUGUIImpl",
+ "renderShowOptionDialogueButtonPanel");
+
+ // put focus to msgLabel to guarantee that label is read by
+ // screen reader upon loading
+ msgLabel.requestFocus();
+ msgLabel.setFocusable(false);
+
+ contentPanel.validate();
+
+ resize();
+ }
+ });
+ }
+
+
+ public void renderShowOptionDialogueButtonPanel() {
+
+ GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
+ buttonPanel.setLayout(buttonPanelLayout);
+
+ buttonPanelLayout.setHorizontalGroup(buttonPanelLayout.createSequentialGroup()
+ .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
+ .addComponent(okButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(ComponentPlacement.UNRELATED));
+
+ buttonPanelLayout.setVerticalGroup(buttonPanelLayout.createParallelGroup().addComponent(cancelButton).addComponent(okButton));
+
+}
+
public void renderShowMessageDialogueButtonPanel() {
if (showMessageOKButton) {
@@ -1757,7 +1953,9 @@ public class BKUGUIImpl implements BKUGUIFacade {
*/
@Override
public void showSecureViewer(final List<HashDataInput> dataToBeSigned,
- final ActionListener backListener, final String backCommand) {
+ final ActionListener backListener, final String backCommand, HashDataInputLoader hashDataInputLoader) {
+
+ this.hashDataInputLoader = hashDataInputLoader;
if (dataToBeSigned == null) {
showErrorDialog(getMessage(ERR_NO_HASHDATA),
@@ -1819,7 +2017,7 @@ public class BKUGUIImpl implements BKUGUIFacade {
throws FontProviderException {
log.debug("[{}] Show secure viewer.", Thread.currentThread().getName());
- secureViewer = new SecureViewerDialog(null, messages, closeListener,
+ secureViewerDialog = new SecureViewerDialog(null, messages, closeListener,
closeCommand, fontProvider, helpListener, getResizeFactor());
// workaround for [#439]
@@ -1829,56 +2027,55 @@ public class BKUGUIImpl implements BKUGUIFacade {
//Window window = SwingUtilities.getWindowAncestor(contentPane);
//if (window != null && window.isAlwaysOnTop()) {
log.debug("Make secureViewer alwaysOnTop.");
- secureViewer.setAlwaysOnTop(true);
+ secureViewerDialog.setAlwaysOnTop(true);
//}
- secureViewer.setContent(dataToBeSigned);
+ secureViewerDialog.setContent(dataToBeSigned);
log.trace("Viewer setContent returned.");
}
private void openSecureViewerDialog() {
- final HashDataInput storedSelection = signedReferences.get(referenceIndex);
+ try {
+
+ log.trace("Opening SecureViewer dialog for list entry {}", referenceIndex);
+ final HashDataInput storedSelection = hashDataInputLoader.getHashDataInput(signedReferences.get(referenceIndex));
- if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(storedSelection
- .getMimeType())) {
+ if (SecureViewerDialog.SUPPORTED_MIME_TYPES.contains(storedSelection.getMimeType())) {
log.debug("[{}] Scheduling secure viewer dialog.", Thread.currentThread().getName());
- showMessageDialog(TITLE_SIGNATURE_DATA,
- MESSAGE_HASHDATA_VIEWER);
+ showMessageDialog(TITLE_SIGNATURE_DATA, MESSAGE_HASHDATA_VIEWER);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
- showSecureViewer(storedSelection, storedBackToListListener,
- null);
+ showSecureViewer(storedSelection, storedBackToListListener, null);
// SecureViewerDialog.showSecureViewer(selection,
// messages, fontProvider,
// helpMouseListener.getActionListener(),
// false);
} catch (FontProviderException ex) {
log.error("Failed to display secure viewer.", ex);
- showErrorDialog(BKUGUIFacade.ERR_VIEWER,
- new Object[] { ex.getMessage() },
- storedBackToListListener, null);
+ showErrorDialog(BKUGUIFacade.ERR_VIEWER, new Object[] { ex.getMessage() }, storedBackToListListener, null);
}
}
});
} else {
- log.debug("[{}] Mime-type not supported by secure viewer, " +
- "scheduling save dialog.", Thread.currentThread().getName());
- showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA,
- BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE,
+ log.debug("[{}] Mime-type not supported by secure viewer, " + "scheduling save dialog.", Thread.currentThread()
+ .getName());
+ showMessageDialog(BKUGUIFacade.TITLE_SIGNATURE_DATA, BKUGUIFacade.MESSAGE_UNSUPPORTED_MIMETYPE,
new Object[] { storedSelection.getMimeType() });
- SecureViewerSaveDialog.showSaveDialog(contentPane, storedSelection, messages,
- storedBackToListListener, null,
+ SecureViewerSaveDialog.showSaveDialog(contentPane, storedSelection, messages, storedBackToListListener, null,
(int) (baseFontSize * getResizeFactor()));
}
-
+ } catch (Exception ex) {
+ log.error("Failed to display secure viewer.", ex);
+ showErrorDialog(BKUGUIFacade.ERR_VIEWER, new Object[] { ex.getMessage() }, storedBackToListListener, null);
+ }
}
private void showSignedReferencesListDialog(
@@ -2446,9 +2643,9 @@ public class BKUGUIImpl implements BKUGUIFacade {
}
- if (secureViewer != null && secureViewer.isVisible()) {
+ if (secureViewerDialog != null && secureViewerDialog.isVisible()) {
- secureViewer.resize(factor);
+ secureViewerDialog.resize(factor);
}
try {
@@ -2682,4 +2879,12 @@ public class BKUGUIImpl implements BKUGUIFacade {
}
}
}
+
+ @Override
+ public void showPinPadDeactivationDialog(ActionListener okListener, String okCommand, ActionListener cancelListener,
+ String cancelCommand) {
+
+ showOptionDialog(TITLE_OVERRULE_PINPAD, MESSAGE_OVERRULE_PINPAD, null, null, null, cancelListener, cancelCommand, okListener, okCommand);
+
+ }
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/hashdata/HashDataInputLoader.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/hashdata/HashDataInputLoader.java
new file mode 100644
index 00000000..1946dd2d
--- /dev/null
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/hashdata/HashDataInputLoader.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.bku.gui.hashdata;
+
+import at.gv.egiz.stal.HashDataInput;
+
+public interface HashDataInputLoader {
+
+
+
+ /**
+ * Loads input data of referenced HashDataInput.
+ * @param hashDataInput HashDataInput without content that references a HashDataInput at server side with digest or referenceId.
+ * @return HashDataInput Referenced HashDataInput from server-side including content.
+ * @throws Exception
+ */
+ HashDataInput getHashDataInput(HashDataInput hashDataInput) throws Exception;
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SecureViewer.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewer.java
index ea279f40..02e0ceb8 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SecureViewer.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewer.java
@@ -22,15 +22,16 @@
*/
-package at.gv.egiz.bku.smccstal;
+package at.gv.egiz.bku.gui.viewer;
+
+import at.gv.egiz.stal.SignatureInfo;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
import java.awt.event.ActionListener;
-import java.security.DigestException;
+import java.util.List;
/**
*
- * @author Clemens Orthacker &lt;clemens.orthacker@iaik.tugraz.at&gt;
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
public interface SecureViewer {
@@ -40,14 +41,18 @@ public interface SecureViewer {
* (LocalSignRequestHandler operates on DataObjectHashDataInput,
* other SignRequestHandlers should cache the HashDataInputs obtained by webservice calls,
* or simply forward to a HashDataInputServlet.)
- * @param signedInfo The caller may select a subset of the references in SignedInfo to be displayed.
- * @param okListener
- * @param okCommand
+ * @param signedReferences The caller may select a subset of the references in SignedInfo to be displayed.
* @throws java.security.DigestException if digest values are verified and do not correspond
* (or any other digest computation error occurs)
* @throws java.lang.Exception
*/
- void displayDataToBeSigned(SignedInfoType signedInfo,
+ void displayDataToBeSigned(SignatureInfo signatureInfo,
ActionListener okListener, String okCommand)
- throws DigestException, Exception;
+ throws Exception;
+
+
+ void displayDataToBeSigned(List<SignatureInfo> signatureInfo,
+ ActionListener okListener, String okCommand)
+ throws Exception;
+
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java
index a28b3b56..ecf5f364 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java
@@ -41,6 +41,7 @@ public class ByteArrayHashDataInput implements HashDataInput {
private final Logger log = LoggerFactory.getLogger(ByteArrayHashDataInput.class);
protected byte[] hashData;
+ protected byte[] digest;
protected String id;
protected String mimeType;
protected String encoding;
@@ -57,6 +58,18 @@ public class ByteArrayHashDataInput implements HashDataInput {
this.filename = filename;
}
+ public ByteArrayHashDataInput(byte[] hashData, String id, String mimeType, String encoding, String filename, byte[] digest) {
+ if (hashData == null) {
+ throw new NullPointerException("HashDataInput not provided.");
+ }
+ this.hashData = hashData;
+ this.id = id;
+ this.mimeType = mimeType;
+ this.encoding = encoding;
+ this.filename = filename;
+ this.digest = digest;
+ }
+
/**
* caches the hashdata input's stream
* @param hdi to be cached
@@ -65,9 +78,9 @@ public class ByteArrayHashDataInput implements HashDataInput {
if (hdi == null) {
throw new NullPointerException("HashDataInput not provided.");
}
+ try {
InputStream is = hdi.getHashDataInput();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
byte[] buffer = new byte[1024];
for (int i = is.read(buffer); i > -1; i = is.read(buffer)) {
baos.write(buffer, 0, i);
@@ -111,5 +124,10 @@ public class ByteArrayHashDataInput implements HashDataInput {
return filename;
}
+ @Override
+ public byte[] getDigest() {
+ return digest;
+ }
+
}
diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
index 434798ee..f7907561 100644
--- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
+++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties
@@ -23,8 +23,10 @@ title.welcome=<html>Welcome</html>
title.insertcard=<html>No citizen card found</html>
title.cardnotsupported=<html>This card is not supported</html>
title.verify.pin=<html>Reading card</html>
-title.sign=<html>Create signature</html>
+title.sign=<html>Create {0,choice,1#signature|1<{0} signatures}</html>
+title.bulksign=<html>Create bulk signature</html>
title.verify.pinpad=<html>Enter PIN and confirm</html>
+title.overrule.pinpad=<html>Allow keyboard input</html>
title.error=<html>Error</html>
title.warning=<html>Warning</html>
title.entry.timeout=<html>Timeout</html>
@@ -41,11 +43,13 @@ windowtitle.help=Citizen card help
# removed message.* prefix to reuse keys as help keys
welcome=<html>Please wait...</html>
wait=<html>Please wait...</html>
+bulksign=<html>Signing document {0} of {1}</html>
insertcard=<html>Please insert your citizen card into the reader</html>
cardnotsupported=<html>Please insert your citizen card into the reader</html>
enterpin=<html>Enter {0}</html>
enterpin.pinpad=<html>Enter PIN on card reader pinpad and confirm</html>
enterpin.pinpad.direct=<html>Enter {0} ({1} digits) on card reader pinpad and confirm</html>
+overrule.pinpad=<html>Pin input on smart card reader is not supported for bulk signature requests.</html>
hashdatalink=<html><a href=\"anzeige\">Display signature data</a></html>
hashdatalink.tiny=<html><a href=\"anzeige\">signature data</a></html>
hashdatalink.focus=<html><a href=\"anzeige\">[Display signature data]</a></html>
diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_de.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_de.properties
index 72da80ce..5d3def07 100644
--- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_de.properties
+++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_de.properties
@@ -23,8 +23,10 @@ title.welcome=<html>Willkommen</html>
title.insertcard=<html>Keine B\u00fcrgerkarte gefunden</html>
title.cardnotsupported=<html>Die Karte wird nicht unterst\u00fctzt</html>
title.verify.pin=<html>Karte wird gelesen</html>
-title.sign=<html>Signatur erstellen</html>
+title.sign=<html>{0,choice,1#Signatur|1<{0} Signaturen} erstellen</html>
+title.bulksign=<html>Stapelsignatur erstellen</html>
title.verify.pinpad=<html>PIN eingeben und best\u00E4tigen</html>
+title.overrule.pinpad=<html>Tastatureingabe freigeben</html>
title.error=<html>Fehler</html>
title.warning=<html>Achtung</html>
title.entry.timeout=<html>Zeit\u00fcberschreitung</html>
@@ -41,11 +43,13 @@ windowtitle.help=Hilfe zur B\u00fcrgerkarte
# removed message.* prefix to reuse keys as help keys
welcome=<html>Bitte warten...</html>
wait=<html>Bitte warten...</html>
+bulksign=<html>Signiere Dokument {0} von {1}</html>
cardnotsupported=<html>Bitte die B\u00fcrgerkarte in den Kartenleser stecken</html>
insertcard=<html>Bitte die B\u00fcrgerkarte in den Kartenleser stecken</html>
enterpin=<html>{0} eingeben</html>
enterpin.pinpad=<html>PIN am Kartenleser eingeben und best\u00E4tigen</html>
enterpin.pinpad.direct=<html>{0} ({1} stellig) am Kartenleser eingeben und best\u00E4tigen</html>
+overrule.pinpad=<html>Die Stapelsignatur unterst\u00ftzt keine Pin Eingabe am Kartenleser.</html>
hashdatalink=<html><a href=\"anzeige\">Signaturdaten anzeigen</a></html>
hashdatalink.tiny=<html><a href=\"anzeige\">Signaturdaten</a></html>
hashdatalink.focus=<html><a href=\"anzeige\">[Signaturdaten anzeigen]</a></html>
diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
index 36e5ea0d..6866f51d 100644
--- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
+++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
@@ -120,7 +120,7 @@ public class BKUGUIWorker implements Runnable {
// signedRefs.add(signedRef4);
// signedRefs.add(signedRef4);
// signedRefs = Collections.singletonList(signedRef1);
- gui.showSecureViewer(signedRefs, returnListener, "return");
+ gui.showSecureViewer(signedRefs, returnListener, "return", null);
}
};
diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java
index afaad92d..c4125944 100644
--- a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java
+++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java
@@ -30,6 +30,7 @@ import at.gv.egiz.bku.smccstal.GetCertificateRequestHandler;
import at.gv.egiz.bku.smccstal.GetHardwareInfoRequestHandler;
import at.gv.egiz.bku.smccstal.PINManagementRequestHandler;
import at.gv.egiz.bku.smccstal.IdentityLinkRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.QuitRequest;
import at.gv.egiz.stal.STALRequest;
import at.gv.egiz.stal.STALResponse;
@@ -53,8 +54,8 @@ public class LocalBKUWorker extends AbstractBKUWorker {
public LocalBKUWorker(BKUGUIFacade gui, JFrame container) {
super(gui);
this.container = container;
- addRequestHandler(SignRequest.class,
- new LocalSignRequestHandler(new LocalSecureViewer(gui)));
+ addRequestHandler(SignRequest.class, new LocalSignRequestHandler(new LocalSecureViewer(gui)));
+ addRequestHandler(BulkSignRequest.class, new LocalBulkSignRequestHandler(new LocalSecureViewer(gui)));
addRequestHandler(PINManagementRequest.class, new PINManagementRequestHandler());
addRequestHandler(IdentityLinkRequest.class, new IdentityLinkRequestHandler());
addRequestHandler(GetCertificateRequest.class, new GetCertificateRequestHandler());
diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBulkSignRequestHandler.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBulkSignRequestHandler.java
new file mode 100644
index 00000000..6ae4496d
--- /dev/null
+++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBulkSignRequestHandler.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.bku.local.stal;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.smccstal.BulkSignRequestHandler;
+import at.gv.egiz.stal.BulkSignRequest;
+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;
+
+/**
+ *
+ * @author szoescher
+ */
+public class LocalBulkSignRequestHandler extends BulkSignRequestHandler {
+
+ private final Logger log = LoggerFactory.getLogger(LocalBulkSignRequestHandler.class);
+
+ public LocalBulkSignRequestHandler(LocalSecureViewer secureViewer) {
+ super(secureViewer);
+ }
+
+ /**
+ * If the request is a SIGN request, it contains a list of DataObjectHashDataInput
+ * providing the pre-digested input stream (that can be obtained repeatedly) if
+ * reference caching is enabled (or null otherwise).
+ * @param request
+ * @return
+ */
+ @Override
+ public STALResponse handleRequest(STALRequest request) throws InterruptedException {
+
+ if (request instanceof BulkSignRequest) {
+
+ BulkSignRequest bulkSignRequest = (BulkSignRequest) request;
+
+ List<HashDataInput> hashDataInputs = new LinkedList<HashDataInput>();
+
+ for(SignRequest signRequest : bulkSignRequest.getSignRequests()){
+
+ hashDataInputs.addAll(signRequest.getHashDataInput());
+ }
+
+ ((LocalSecureViewer) secureViewer).setDataToBeSigned(hashDataInputs);
+
+ return super.handleRequest(request);
+ } else {
+ log.error("Got unexpected STAL request: {}.", request);
+ ErrorResponse err = new ErrorResponse(1000);
+ err.setErrorMessage("Got unexpected STAL request: " + request);
+ return err;
+ }
+ }
+}
diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalSecureViewer.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalSecureViewer.java
index 5e346aba..25f30463 100644
--- a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalSecureViewer.java
+++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalSecureViewer.java
@@ -24,31 +24,43 @@
package at.gv.egiz.bku.local.stal;
-import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput;
-import at.gv.egiz.bku.smccstal.SecureViewer;
-import java.io.IOException;
-import java.util.ArrayList;
+import iaik.me.security.CryptoException;
+import iaik.me.security.MessageDigest;
-import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.stal.HashDataInput;
-import at.gv.egiz.stal.impl.ByteArrayHashDataInput;
-import at.gv.egiz.stal.signedinfo.ReferenceType;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.security.DigestException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+
+import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.hashdata.HashDataInputLoader;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
+import at.gv.egiz.bku.slcommands.impl.DataObjectHashDataInput;
+import at.gv.egiz.bku.slcommands.impl.cms.ReferencedHashDataInput;
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.SignatureInfo;
+import at.gv.egiz.stal.hashdata.StubHashDataInput;
+import at.gv.egiz.stal.impl.ByteArrayHashDataInput;
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+
/**
*
* @author Clemens Orthacker &lt;clemens.orthacker@iaik.tugraz.at&gt;
*/
-public class LocalSecureViewer implements SecureViewer {
+public class LocalSecureViewer implements SecureViewer, HashDataInputLoader {
- private final Logger log = LoggerFactory.getLogger(LocalSignRequestHandler.class);
+ private final Logger log = LoggerFactory.getLogger(LocalSecureViewer.class);
private List<HashDataInput> hashDataInputs = Collections.emptyList();
protected BKUGUIFacade gui;
@@ -69,48 +81,23 @@ public class LocalSecureViewer implements SecureViewer {
* @throws java.lang.Exception
*/
@Override
- public void displayDataToBeSigned(SignedInfoType signedInfo,
+ public void displayDataToBeSigned(SignatureInfo signedInfo,
ActionListener okListener, String okCommand)
throws Exception {
- if (signedInfo.getReference().size() == 0) {
- log.error("No hashdata input selected to be displayed: null.");
- throw new Exception("No HashData Input selected to be displayed.");
- }
+
+ log.info("Retrieve data to be signed for dsig:SignedInfo {}.", signedInfo.getId());
+ List<HashDataInput> hdi = getHashDataInputs(signedInfo);
+ List<HashDataInput> verifiedDataToBeSigned = verifyHashDataInput(signedInfo.getReference(), hdi.get(0));
ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
- for (ReferenceType dsigRef : signedInfo.getReference()) {
- // don't get Manifest, QualifyingProperties, ...
- if (dsigRef.getType() == null) {
- String dsigRefId = dsigRef.getId();
- if (dsigRefId != null) {
- boolean hdiAvailable = false;
- for (HashDataInput hashDataInput : hashDataInputs) {
- if (dsigRefId.equals(hashDataInput.getReferenceId())) {
- log.debug("Display hashdata input for dsig:SignedReference {}.",
- dsigRefId);
- selectedHashDataInputs.add(
- ensureCachedHashDataInput(hashDataInput));
- hdiAvailable = true;
- break;
- }
- }
- if (!hdiAvailable) {
- log.error("No hashdata input for dsig:SignedReference {}.", dsigRefId);
- throw new Exception(
- "No HashDataInput available for dsig:SignedReference " + dsigRefId);
- }
- } else {
- throw new Exception(
- "Cannot get HashDataInput for dsig:Reference without Id attribute");
- }
- }
- }
+ selectedHashDataInputs.addAll(verifiedDataToBeSigned);
+
if (selectedHashDataInputs.size() < 1) {
log.error("dsig:SignedInfo does not contain a data reference.");
throw new Exception("dsig:SignedInfo does not contain a data reference.");
}
- gui.showSecureViewer(selectedHashDataInputs, okListener, okCommand);
+ gui.showSecureViewer(selectedHashDataInputs, okListener, okCommand, this);
}
@@ -136,4 +123,218 @@ public class LocalSecureViewer implements SecureViewer {
return hashDataInput;
}
+ @Override
+ public void displayDataToBeSigned(List<SignatureInfo> signedInfo, ActionListener okListener, String okCommand)
+ throws DigestException, Exception {
+ log.warn("Called displayDataToBeSigned");
+ ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
+
+
+ for (SignatureInfo nextSignedInfo : signedInfo) {
+ selectedHashDataInputs.addAll(addEmptyHashDataInputs(nextSignedInfo));
+ }
+
+ gui.showSecureViewer(selectedHashDataInputs, okListener, okCommand, this);
+
+ }
+
+
+
+ private Collection<? extends HashDataInput> addEmptyHashDataInputs(SignatureInfo signedInfo) throws Exception {
+ if (signedInfo.getReference().size() == 0) {
+ log.error("No hashdata input selected to be displayed: null.");
+ throw new Exception("No HashData Input selected to be displayed.");
+ }
+
+ ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
+ for (ReferenceType dsigRef : signedInfo.getReference()) {
+
+ if (dsigRef.getType() == null) {
+ selectedHashDataInputs.add(new StubHashDataInput(dsigRef, signedInfo.getDisplayName(), signedInfo.getMimeType()));
+ }
+ }
+ return selectedHashDataInputs;
+ }
+
+ @Override
+ public HashDataInput getHashDataInput(HashDataInput hashDataInput) throws Exception {
+
+ if (hashDataInput instanceof StubHashDataInput) {
+ String referenceId = hashDataInput.getReferenceId();
+ byte[] digest = hashDataInput.getDigest();
+ if (referenceId != null || digest != null) {
+ boolean hdiAvailable = false;
+
+ for (HashDataInput currentHashDataInput : hashDataInputs) {
+
+ if (Arrays.equals(digest, currentHashDataInput.getDigest())) {
+ log.debug("Display hashdata input for dsig:SignedReference {}.", referenceId);
+
+ if (currentHashDataInput instanceof ReferencedHashDataInput) {
+
+ ReferenceType reference = ((StubHashDataInput) hashDataInput).getReference();
+ return verifyHashDataInput(Arrays.asList(reference), currentHashDataInput).get(0);
+
+ } else {
+ return (ensureCachedHashDataInput(currentHashDataInput));
+ }
+
+ }
+ }
+
+ if (!hdiAvailable) {
+ for (HashDataInput currentHashDataInput : hashDataInputs) {
+ if (referenceId.equals(hashDataInput.getReferenceId())) {
+ log.debug("Display hashdata input for dsig:SignedReference {}.", referenceId);
+ if (currentHashDataInput instanceof ReferencedHashDataInput) {
+
+ ReferenceType reference = ((StubHashDataInput) hashDataInput).getReference();
+ return verifyHashDataInput(Arrays.asList(reference), currentHashDataInput).get(0);
+
+ } else {
+ return (ensureCachedHashDataInput(currentHashDataInput));
+ }
+ }
+ }
+ }
+
+ if (!hdiAvailable) {
+ log.error("No hashdata input for dsig:SignedReference {}.", referenceId);
+ throw new Exception("No HashDataInput available for dsig:SignedReference " + referenceId);
+ }
+ } else {
+ throw new Exception("Cannot get HashDataInput for dsig:Reference without Id or digest attribute");
+ }
+ }
+ return hashDataInput;
+ }
+
+
+ public List<HashDataInput> getHashDataInputs(SignatureInfo signedInfo) throws Exception {
+
+ ArrayList<HashDataInput> selectedHashDataInputs = new ArrayList<HashDataInput>();
+
+ if (signedInfo.getReference().size() == 0) {
+ log.error("No hashdata input selected to be displayed: null.");
+ throw new Exception("No HashData Input selected to be displayed.");
+ }
+
+ for (ReferenceType dsigRef : signedInfo.getReference()) {
+ // don't get Manifest, QualifyingProperties, ...
+ if (dsigRef.getType() == null) {
+ HashDataInput emptyHashDataInput = new StubHashDataInput(dsigRef, signedInfo.getDisplayName(),
+ signedInfo.getMimeType());
+
+
+ selectedHashDataInputs.add(getHashDataInput(emptyHashDataInput));
+
+ }
+ }
+ return selectedHashDataInputs;
+ }
+
+ private List<HashDataInput> verifyHashDataInput(List<ReferenceType> signedReferences, HashDataInput hashDataInput)
+ throws DigestException, NoSuchAlgorithmException, Exception {
+
+ ArrayList<HashDataInput> verifiedHashDataInputs = new ArrayList<HashDataInput>();
+
+ for (ReferenceType signedRef : signedReferences) {
+ if (signedRef.getType() == null) {
+ log.info("Verifying digest for signed reference {}.", signedRef.getId());
+
+ String signedRefId = signedRef.getId();
+ byte[] signedDigest = signedRef.getDigestValue();
+ String signedDigestAlg = null;
+ if (signedRef.getDigestMethod() != null) {
+ signedDigestAlg = signedRef.getDigestMethod().getAlgorithm();
+ } else {
+ throw new NoSuchAlgorithmException("Failed to verify digest value for reference " + signedRefId + ": no digest algorithm");
+ }
+
+
+ if (hashDataInput == null) {
+ throw new Exception("No hashdata input for reference " + signedRefId + " returned by service");
+ }
+
+ byte[] hdi = null;
+
+ try {
+ hdi = IOUtils.toByteArray(hashDataInput.getHashDataInput());
+ } catch (IOException e) {
+ throw new Exception("No hashdata input for reference " + signedRefId + " provided by service.", e);
+ }
+
+ String mimeType = hashDataInput.getMimeType();
+ String encoding = hashDataInput.getEncoding();
+ String filename = hashDataInput.getFilename();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Digesting reference " + signedRefId + " (" + mimeType + ";" + encoding + ")");
+ }
+
+ byte[] hashDataInputDigest;
+ if ((signedRef.getURI() != null) && signedRef.getURI().startsWith("CMSExcludedByteRange:")) {
+ String range = signedRef.getURI().substring(21);
+ int sep = range.indexOf('-');
+ int from = Integer.parseInt(range.substring(0, sep));
+ int to = Integer.parseInt(range.substring(sep+1));
+
+ Arrays.fill(hdi, from, to+1, (byte)0);
+
+
+ byte[] hashData = new byte[hdi.length - ((to+1) - from)];
+ if (from > 0)
+ System.arraycopy(hdi, 0, hashData, 0, from);
+ if ((to+1) < hdi.length)
+ System.arraycopy(hdi, to+1, hashData, from, hdi.length - (to+1));
+ hashDataInputDigest = digest(hashData, signedDigestAlg);
+ } else {
+ hashDataInputDigest = digest(hdi, signedDigestAlg);
+ }
+
+ log.debug("Comparing digest to claimed digest value for reference {}.", signedRefId);
+ if (!Arrays.equals(hashDataInputDigest, signedDigest)) {
+ log.error("Bad digest value for reference {}.", signedRefId);
+ throw new DigestException("Bad digest value for reference " + signedRefId);
+ }
+
+ verifiedHashDataInputs.add(new ByteArrayHashDataInput(hdi, signedRefId, mimeType, encoding, filename));
+ }
+ }
+
+ return verifiedHashDataInputs;
+}
+
+ private byte[] digest(byte[] hashDataInput, String mdAlg) throws NoSuchAlgorithmException {
+ if ("http://www.w3.org/2000/09/xmldsig#sha1".equals(mdAlg)) {
+ mdAlg = "SHA-1";
+ } else if ("http://www.w3.org/2001/04/xmlenc#sha256".equals(mdAlg)) {
+ mdAlg = "SHA-256";
+ } else if ("http://www.w3.org/2001/04/xmlenc#sha224".equals(mdAlg)) {
+ mdAlg = "SHA-224";
+ } else if ("http://www.w3.org/2001/04/xmldsig-more#sha224".equals(mdAlg)) {
+ mdAlg = "SHA-224";
+ } else if ("http://www.w3.org/2001/04/xmldsig-more#sha384".equals(mdAlg)) {
+ mdAlg = "SHA-384";
+ } else if ("http://www.w3.org/2001/04/xmlenc#sha512".equals(mdAlg)) {
+ mdAlg = "SHA-512";
+ } else if ("http://www.w3.org/2001/04/xmldsig-more#md2".equals(mdAlg)) {
+ mdAlg = "MD2";
+ } else if ("http://www.w3.org/2001/04/xmldsig-more#md5".equals(mdAlg)) {
+ mdAlg = "MD5";
+ } else if ("http://www.w3.org/2001/04/xmlenc#ripemd160".equals(mdAlg)) {
+ mdAlg = "RIPEMD160";
+ } else {
+ throw new NoSuchAlgorithmException("Failed to verify digest value: unsupported digest algorithm " + mdAlg);
+ }
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance(mdAlg);
+ } catch (CryptoException e) {
+ throw new NoSuchAlgorithmException(e);
+ }
+ return md.digest(hashDataInput);
+ }
+
}
diff --git a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml
index 49d4f57f..304fecfc 100644
--- a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml
@@ -57,10 +57,10 @@
<property name="configuration" ref="configuration"/>
</bean>
- <bean id="urlDereferencer" class="at.gv.egiz.bku.utils.urldereferencer.URLDereferencerImpl"
- factory-method="getInstance">
- <property name="SSLSocketFactory" ref="sslSocketFactory"/>
+ <bean id="urlDereferencer" class="at.gv.egiz.bku.spring.URLDereferencerFactoryBean">
+ <property name="sslSocketFactory" ref="sslSocketFactory"/>
<property name="hostnameVerifier" ref="hostnameVerifier"/>
+ <property name="configuration" ref="configuration"/>
</bean>
<!-- security manager for the command invoker -->
@@ -156,6 +156,14 @@
value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
<constructor-arg value="CreateCMSSignatureRequest" />
</bean>
+ <bean id="bulkCommandFactory"
+ class="at.gv.egiz.bku.slcommands.impl.BulkCommandFactory"
+ parent="abstractCommandFactory" />
+ <bean id="bulkRequest" class="javax.xml.namespace.QName">
+ <constructor-arg
+ value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
+ <constructor-arg value="BulkRequest"/>
+ </bean>
<bean id="getStatusCommandFactory" class="at.gv.egiz.bku.slcommands.impl.GetStatusCommandFactory"
parent="abstractCommandFactory" />
<bean id="getStatusRequest" class="javax.xml.namespace.QName">
@@ -173,6 +181,7 @@
<entry key-ref="infoboxUpdateRequest" value-ref="infoboxUpdateCommandFactory" />
<entry key-ref="createXMLSignatureRequest" value-ref="createXMLSignatureCommandFactory" />
<entry key-ref="createCMSSignatureRequest" value-ref="createCMSSignatureCommandFactory" />
+ <entry key-ref="bulkRequest" value-ref="bulkCommandFactory" />
<entry key-ref="getStatusRequest" value-ref="getStatusCommandFactory" />
</map>
</property>
diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java
index eab5c62d..3746b8d1 100644
--- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java
+++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java
@@ -25,6 +25,7 @@
package at.gv.egiz.stal.service.impl;
+import at.gv.egiz.stal.BulkSignRequest;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.HashDataInput;
import at.gv.egiz.stal.QuitRequest;
@@ -115,8 +116,25 @@ public class STALRequestBrokerImpl implements STALRequestBroker {
// and getHashDataInput() accesses request obj
// (requests are cleared only when we receive the response)
// DataObjectHashDataInput with reference caching enabled DataObject
+
+ log.info("Adding HashdataInput with id {} and digsest {}", ((SignRequest) stalRequest).getHashDataInput()
+ .get(0).getReferenceId(), ((SignRequest) stalRequest).getHashDataInput().get(0).getDigest());
hashDataInputs.addAll(((SignRequest) stalRequest).getHashDataInput());
- } else if (stalRequest instanceof QuitRequest) {
+ }
+
+ if (stalRequest instanceof BulkSignRequest) {
+
+ BulkSignRequest bulkSignRequest = (BulkSignRequest) stalRequest;
+
+ for (SignRequest signRequest : bulkSignRequest.getSignRequests()) {
+ log.info("Adding HashdataInput with id {} and digsest {}", signRequest.getHashDataInput().get(0)
+ .getReferenceId(), signRequest.getHashDataInput().get(0).getDigest());
+ hashDataInputs.addAll(signRequest.getHashDataInput());
+ }
+
+ }
+
+ else if (stalRequest instanceof QuitRequest) {
log.trace("Received QuitRequest, do not wait for responses.");
log.trace("notifying request consumers");
requests.notify();
diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java
index 836d6538..1819074a 100644
--- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java
+++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java
@@ -120,7 +120,7 @@ public class STALServiceImpl implements STALPortType {
if (stal != null) {
List<JAXBElement<? extends RequestType>> requestsOut = ((STALRequestBroker) stal).connect();
- response.getInfoboxReadRequestOrSignRequestOrQuitRequest().addAll(requestsOut);
+ response.getInfoboxReadRequestOrSignRequestOrBulkSignRequest().addAll(requestsOut);
if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("Returning initial GetNextRequestResponse containing ");
@@ -136,7 +136,7 @@ public class STALServiceImpl implements STALPortType {
log.error("Failed to get STAL, returning QuitRequest.");
QuitRequestType quitT = stalObjFactory.createQuitRequestType();
JAXBElement<QuitRequestType> quit = stalObjFactory.createGetNextRequestResponseTypeQuitRequest(quitT);
- response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(quit);
+ response.getInfoboxReadRequestOrSignRequestOrBulkSignRequest().add(quit);
}
return response;
@@ -157,7 +157,7 @@ public class STALServiceImpl implements STALPortType {
try {
- List<JAXBElement<? extends ResponseType>> responsesIn = request.getInfoboxReadResponseOrSignResponseOrErrorResponse();
+ List<JAXBElement<? extends ResponseType>> responsesIn = request.getInfoboxReadResponseOrSignResponseOrBulkSignResponse();
if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("Received GetNextRequest containing ");
@@ -186,7 +186,7 @@ public class STALServiceImpl implements STALPortType {
if (stal != null) {
List<JAXBElement<? extends RequestType>> requestsOut = ((STALRequestBroker) stal).nextRequest(responsesIn);
- response.getInfoboxReadRequestOrSignRequestOrQuitRequest().addAll(requestsOut);
+ response.getInfoboxReadRequestOrSignRequestOrBulkSignRequest().addAll(requestsOut);
if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder("Returning GetNextRequestResponse containing ");
@@ -202,7 +202,7 @@ public class STALServiceImpl implements STALPortType {
log.error("Failed to get STAL, returning QuitRequest.");
QuitRequestType quitT = stalObjFactory.createQuitRequestType();
JAXBElement<QuitRequestType> quit = stalObjFactory.createGetNextRequestResponseTypeQuitRequest(quitT);
- response.getInfoboxReadRequestOrSignRequestOrQuitRequest().add(quit);
+ response.getInfoboxReadRequestOrSignRequestOrBulkSignRequest().add(quit);
}
return response;
@@ -242,27 +242,51 @@ public class STALServiceImpl implements STALPortType {
if (hashDataInputs != null) {
Map<String, HashDataInput> hashDataIdMap = new HashMap<String, HashDataInput>();
+ Map<String, HashDataInput> hashDataDigestMap = new HashMap<String, HashDataInput>();
for (HashDataInput hdi : hashDataInputs) {
if (log.isTraceEnabled()) {
log.trace("Provided HashDataInput for reference {}.", hdi.getReferenceId());
}
+
+
+ if(hdi.getDigest() != null) {
+ log.trace("Provided HashDataInput for digest {}.", hdi.getDigest());
+ hashDataDigestMap.put(new String(hdi.getDigest()), hdi);
+ }
+
+ 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);
+ String digest = new String(reqRef.getDigest());
+
+ log.info("looking for digest {}", digest);
+ HashDataInput reqHdi = hashDataDigestMap.get(digest);
+ if (reqHdi == null) {
+ log.info("looking for referenceId {}", reqRefId);
+ reqHdi = hashDataIdMap.get(reqRefId);
+ }
if (reqHdi == null) {
String msg = "Failed to resolve HashDataInput for reference " + reqRefId;
- log.error(msg);
+ log.info(msg);
GetHashDataInputFaultType faultInfo = new GetHashDataInputFaultType();
faultInfo.setErrorCode(1);
faultInfo.setErrorMessage(msg);
throw new GetHashDataInputFault(msg, faultInfo);
}
- InputStream hashDataIS = reqHdi.getHashDataInput();
+ InputStream hashDataIS;
+ try {
+ hashDataIS = reqHdi.getHashDataInput();
+ } catch (IOException e) {
+ GetHashDataInputFaultType faultInfo = new GetHashDataInputFaultType();
+ faultInfo.setErrorCode(1);
+ faultInfo.setErrorMessage(e.getMessage());
+ throw new GetHashDataInputFault(e.getMessage(), faultInfo);
+ }
if (hashDataIS == null) {
//HashDataInput not cached?
String msg = "Failed to obtain HashDataInput for reference " + reqRefId + ", reference not cached";
@@ -345,7 +369,7 @@ public class STALServiceImpl implements STALPortType {
GetNextRequestResponseType response = new GetNextRequestResponseType();
response.setSessionId(TEST_SESSION_ID.toString());
- List<JAXBElement<? extends RequestType>> reqs = response.getInfoboxReadRequestOrSignRequestOrQuitRequest();
+ List<JAXBElement<? extends RequestType>> reqs = response.getInfoboxReadRequestOrSignRequestOrBulkSignRequest();
if (responsesIn == null) {
log.info("[TestSession] CONNECT");
diff --git a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
index 7534a9c9..2ca9ce9c 100644
--- a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml
@@ -50,10 +50,10 @@
<property name="configuration" ref="configuration"/>
</bean>
- <bean id="urlDereferencer" class="at.gv.egiz.bku.utils.urldereferencer.URLDereferencerImpl"
- factory-method="getInstance">
- <property name="SSLSocketFactory" ref="sslSocketFactory"/>
+ <bean id="urlDereferencer" class="at.gv.egiz.bku.spring.URLDereferencerFactoryBean">
+ <property name="sslSocketFactory" ref="sslSocketFactory"/>
<property name="hostnameVerifier" ref="hostnameVerifier"/>
+ <property name="configuration" ref="configuration"/>
</bean>
<!-- security manager for the command invoker -->
@@ -144,6 +144,14 @@
value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
<constructor-arg value="CreateCMSSignatureRequest" />
</bean>
+ <bean id="bulkCommandFactory"
+ class="at.gv.egiz.bku.slcommands.impl.BulkCommandFactory"
+ parent="abstractCommandFactory" />
+ <bean id="bulkRequest" class="javax.xml.namespace.QName">
+ <constructor-arg
+ value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
+ <constructor-arg value="BulkRequest"/>
+ </bean>
<bean id="getStatusCommandFactory" class="at.gv.egiz.bku.slcommands.impl.GetStatusCommandFactory"
parent="abstractCommandFactory" />
<bean id="getStatusRequest" class="javax.xml.namespace.QName">
@@ -161,6 +169,7 @@
<entry key-ref="infoboxUpdateRequest" value-ref="infoboxUpdateCommandFactory" />
<entry key-ref="createXMLSignatureRequest" value-ref="createXMLSignatureCommandFactory" />
<entry key-ref="createCMSSignatureRequest" value-ref="createCMSSignatureCommandFactory" />
+ <entry key-ref="bulkRequest" value-ref="bulkCommandFactory" />
<entry key-ref="getStatusRequest" value-ref="getStatusCommandFactory" />
</map>
</property>
diff --git a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd
index 750cf355..8dc20ec7 100644
--- a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd
+++ b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd
@@ -38,6 +38,7 @@
<choice maxOccurs="unbounded">
<element name="InfoboxReadResponse" type="tns:InfoboxReadResponseType"/>
<element name="SignResponse" type="tns:SignResponseType"/>
+ <element name="BulkSignResponse" type="tns:BulkSignResponseType"/>
<element name="ErrorResponse" type="tns:ErrorResponseType"/>
<element name="StatusResponse" type="tns:StatusResponseType"/>
</choice>
@@ -87,6 +88,7 @@
<choice maxOccurs="unbounded">
<element name="InfoboxReadRequest" type="tns:InfoboxReadRequestType"/>
<element name="SignRequest" type="tns:SignRequestType"/>
+ <element name="BulkSignRequest" type="tns:BulkSignRequestType"/>
<element name="QuitRequest" type="tns:QuitRequestType"/>
<element name="StatusRequest" type="tns:StatusRequestType"/>
</choice>
@@ -134,6 +136,8 @@
</element>
<element name="SignatureMethod" type="string" minOccurs="0"/>
<element name="DigestMethod" type="string" minOccurs="0"/>
+ <element name="displayName" type="string" minOccurs="0"/>
+ <element name="mimeType" type="string" minOccurs="0"/>
<element name="ExcludedByteRange" minOccurs="0">
<complexType>
<attribute name="from" type="unsignedLong" use="required"/>
@@ -144,6 +148,20 @@
</extension>
</complexContent>
</complexType>
+
+ <complexType name="BulkSignRequestType">
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element name="SignResponse" type="tns:SignRequestType"/>
+ </sequence>
+ </complexType>
+
+
+ <complexType name="BulkSignResponseType">
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element name="SignResponse" type="tns:SignResponseType"/>
+ </sequence>
+ </complexType>
+
<complexType name="QuitRequestType">
<complexContent>
<extension base="tns:RequestType"/>
@@ -159,6 +177,7 @@
<element name="Reference" maxOccurs="unbounded">
<complexType>
<attribute name="ID" type="string"/>
+ <attribute use="optional" name="digest" type="base64Binary"/>
</complexType>
</element>
</sequence>
diff --git a/BKUOnline/src/main/wsdl/stal-service.xsd b/BKUOnline/src/main/wsdl/stal-service.xsd
index 59cebac6..0f452df9 100644
--- a/BKUOnline/src/main/wsdl/stal-service.xsd
+++ b/BKUOnline/src/main/wsdl/stal-service.xsd
@@ -47,6 +47,7 @@
<choice maxOccurs="unbounded">
<element name="InfoboxReadResponse" type="tns:InfoboxReadResponseType"/>
<element name="SignResponse" type="tns:SignResponseType"/>
+ <element name="BulkSignResponse" type="tns:BulkSignResponseType"/>
<element name="ErrorResponse" type="tns:ErrorResponseType"/>
<element name="StatusResponse" type="tns:StatusResponseType"/>
<element ref="tns:OtherResponse"/>
@@ -99,6 +100,7 @@
<choice maxOccurs="unbounded">
<element name="InfoboxReadRequest" type="tns:InfoboxReadRequestType"/>
<element name="SignRequest" type="tns:SignRequestType"/>
+ <element name="BulkSignRequest" type="tns:BulkSignRequestType"/>
<element name="QuitRequest" type="tns:QuitRequestType"/>
<element name="StatusRequest" type="tns:StatusRequestType"/>
<element ref="tns:OtherRequest"/>
@@ -143,6 +145,20 @@
</extension>
</complexContent>
</complexType>
+
+ <complexType name="BulkSignRequestType">
+ <sequence minOccurs="1" maxOccurs="unbounded" >
+ <element name="SignRequests" type="tns:SignRequestType"/>
+ </sequence>
+ </complexType>
+
+
+ <complexType name="BulkSignResponseType">
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element name="SignResponses" type="tns:SignResponseType"/>
+ </sequence>
+ </complexType>
+
<complexType name="QuitRequestType">
<complexContent>
<extension base="tns:RequestType"/>
@@ -158,6 +174,7 @@
<element name="Reference" maxOccurs="unbounded">
<complexType>
<attribute name="ID" type="string"/>
+ <attribute use="optional" name="digest" type="base64Binary"/>
</complexType>
</element>
</sequence>
diff --git a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java
index bfbff5a4..c096fa8f 100644
--- a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java
+++ b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java
@@ -143,6 +143,12 @@ public class STALRequestBrokerTest {
public String getFilename() {
return "file.txt";
}
+
+ @Override
+ public byte[] getDigest() {
+ return null;
+ }
+
};
r1.setHashDataInput(Collections.singletonList(hdi));
requests.add(r1);
@@ -196,6 +202,12 @@ public class STALRequestBrokerTest {
public String getFilename() {
return "file.txt";
}
+
+ @Override
+ public byte[] getDigest() {
+ return null;
+ }
+
};
r1.setHashDataInput(Collections.singletonList(hdi));
requests.add(r1);
@@ -262,6 +274,12 @@ public class STALRequestBrokerTest {
public String getFilename() {
return "file.txt";
}
+
+ @Override
+ public byte[] getDigest() {
+ return null;
+ }
+
};
r1.setHashDataInput(Collections.singletonList(hdi));
requests.add(r1);
@@ -297,6 +315,12 @@ public class STALRequestBrokerTest {
public String getFilename() {
return "file.xml";
}
+
+ @Override
+ public byte[] getDigest() {
+ return null;
+ }
+
};
r2.setHashDataInput(Collections.singletonList(hdi2));
requests2.add(r2);
diff --git a/STAL/src/main/java/at/gv/egiz/stal/BulkSignRequest.java b/STAL/src/main/java/at/gv/egiz/stal/BulkSignRequest.java
new file mode 100644
index 00000000..ce36a25c
--- /dev/null
+++ b/STAL/src/main/java/at/gv/egiz/stal/BulkSignRequest.java
@@ -0,0 +1,92 @@
+
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.stal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for BulkSignRequestType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="BulkSignRequestType">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;sequence maxOccurs="unbounded">
+ * &lt;element name="SignRequests" type="{http://www.egiz.gv.at/stal}SignRequestType"/>
+ * &lt;/sequence>
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BulkSignRequestType", propOrder = {
+ "signRequests"
+})
+public class BulkSignRequest extends STALRequest {
+
+ @XmlElement(name = "SignRequests", required = true)
+ protected List<SignRequest> signRequests;
+
+ /**
+ * Gets the value of the signRequests property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the signRequests property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getSignRequests().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link SignRequestType }
+ *
+ *
+ */
+ public List<SignRequest> getSignRequests() {
+ if (signRequests == null) {
+ signRequests = new ArrayList<SignRequest>();
+ }
+ return this.signRequests;
+ }
+
+}
diff --git a/STAL/src/main/java/at/gv/egiz/stal/BulkSignResponse.java b/STAL/src/main/java/at/gv/egiz/stal/BulkSignResponse.java
new file mode 100644
index 00000000..1cc6e73e
--- /dev/null
+++ b/STAL/src/main/java/at/gv/egiz/stal/BulkSignResponse.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.stal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for BulkSignResponseType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="BulkSignResponseType">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;sequence maxOccurs="unbounded">
+ * &lt;element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/>
+ * &lt;/sequence>
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BulkSignResponseType", propOrder = {
+ "signResponse"
+})
+public class BulkSignResponse extends STALResponse {
+
+ @XmlElement(name = "SignResponse", required = true)
+ protected List<SignResponse> signResponse;
+
+ /**
+ * Gets the value of the signResponse property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the signResponse property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>SignRequestType
+ * getSignResponse().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link SignResponseType }
+ *
+ *
+ */
+ public List<SignResponse> getSignResponse() {
+ if (signResponse == null) {
+ signResponse = new ArrayList<SignResponse>();
+ }
+ return this.signResponse;
+ }
+
+}
diff --git a/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java b/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java
index 05c9bf1e..06d47bc5 100644
--- a/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java
+++ b/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java
@@ -25,6 +25,7 @@
package at.gv.egiz.stal;
+import java.io.IOException;
import java.io.InputStream;
/**
@@ -34,7 +35,8 @@ import java.io.InputStream;
public interface HashDataInput {
public final static String CMS_DEF_REFERENCE_ID = "Reference-1";
-
+ public final static String DEFAULT_FILENAME = "SignatureData";
+
public String getReferenceId();
public String getMimeType();
@@ -42,7 +44,9 @@ public interface HashDataInput {
public String getEncoding();
public String getFilename();
+
+ public byte[] getDigest();
- public InputStream getHashDataInput();
+ public InputStream getHashDataInput() throws IOException;
}
diff --git a/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java b/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java
index d4212b24..37d43877 100644
--- a/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java
+++ b/STAL/src/main/java/at/gv/egiz/stal/SignRequest.java
@@ -59,6 +59,8 @@ import javax.xml.bind.annotation.XmlValue;
* &lt;/element&gt;
* &lt;element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
* &lt;element name="DigestMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
+ * &lt;element name="displayName" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"&gt;
+ * &lt;element name="mimeType" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/&gt;
* &lt;element name="ExcludedByteRange" minOccurs="0"&gt;
* &lt;complexType&gt;
* &lt;complexContent&gt;
@@ -83,6 +85,7 @@ import javax.xml.bind.annotation.XmlValue;
"signedInfo",
"signatureMethod",
"digestMethod",
+ "mimeType",
"excludedByteRange"
})
public class SignRequest
@@ -96,6 +99,10 @@ public class SignRequest
protected String signatureMethod;
@XmlElement(name = "DigestMethod")
protected String digestMethod;
+ @XmlElement(name = "displayName")
+ protected String displayName;
+ @XmlElement(name = "mimeType")
+ protected String mimeType;
@XmlElement(name = "ExcludedByteRange")
protected SignRequest.ExcludedByteRange excludedByteRange;
@XmlTransient
@@ -194,6 +201,55 @@ public class SignRequest
public void setDigestMethod(String value) {
this.digestMethod = value;
}
+
+ /**
+ * Sets the value of the displayName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setDisplayName(String value) {
+ this.displayName = value;
+ }
+
+ /**
+ * Gets the value of the displayName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Gets the value of the mimeType property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+
+ /**
+ * Sets the value of the mimeType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMimeType(String value) {
+ this.mimeType = value;
+ }
/**
* Gets the value of the excludedByteRange property.
diff --git a/STAL/src/main/java/at/gv/egiz/stal/SignatureInfo.java b/STAL/src/main/java/at/gv/egiz/stal/SignatureInfo.java
new file mode 100644
index 00000000..e0457b96
--- /dev/null
+++ b/STAL/src/main/java/at/gv/egiz/stal/SignatureInfo.java
@@ -0,0 +1,84 @@
+package at.gv.egiz.stal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+import at.gv.egiz.stal.signedinfo.SignatureMethodType;
+import at.gv.egiz.stal.signedinfo.SignedInfoType;
+
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+/**
+ * This class wraps a {@link SignatureInfo} and adds the additional parameters displayName and mimeType.
+ * @author szoescher
+ *
+ */
+public class SignatureInfo {
+
+ private SignedInfoType signedInfo;
+
+ private String displayName;
+
+ private String mimeType;
+
+ public SignatureInfo(SignedInfoType signedInfo, String displayName, String mimeType) {
+ this.signedInfo = signedInfo;
+ this.displayName = displayName;
+ this.mimeType = mimeType;
+ }
+
+ public SignedInfoType getSignedInfo() {
+ return signedInfo;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public SignatureMethodType getSignatureMethod() {
+ if (signedInfo != null) {
+ return signedInfo.getSignatureMethod();
+ }
+ return null;
+ }
+
+ public String getId() {
+ if (signedInfo != null) {
+ return signedInfo.getId();
+ }
+ return null;
+ }
+
+ public List<ReferenceType> getReference() {
+
+ if (signedInfo != null && signedInfo.getReference() != null) {
+
+ return signedInfo.getReference();
+ }
+ return new ArrayList<ReferenceType>();
+ }
+}
diff --git a/STAL/src/main/java/at/gv/egiz/stal/hashdata/StubHashDataInput.java b/STAL/src/main/java/at/gv/egiz/stal/hashdata/StubHashDataInput.java
new file mode 100644
index 00000000..3b74be50
--- /dev/null
+++ b/STAL/src/main/java/at/gv/egiz/stal/hashdata/StubHashDataInput.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.stal.hashdata;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+
+/**
+ * A StabHashDataInput is used as a placeholder at client side.
+ * The reference is used to load the corresponding HashDataInput from STAL.
+ * @author szoescher
+ */
+public class StubHashDataInput implements HashDataInput {
+
+ private byte[] data;
+ private String mimeType;
+ private ReferenceType reference;
+ private String fileName;
+
+
+ public StubHashDataInput(ReferenceType reference, String fileName, String mimeType) {
+ this.mimeType = mimeType;
+ this.fileName = fileName;
+ this.reference = reference;
+ }
+
+ @Override
+ public String getReferenceId() {
+ if (reference != null) {
+ return reference.getId();
+ }
+ return null;
+ }
+
+ @Override
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ @Override
+ public String getEncoding() {
+ return null;
+ }
+
+ @Override
+ public String getFilename() {
+ if (fileName != null) {
+ return fileName;
+ }
+ return DEFAULT_FILENAME;
+ }
+
+ @Override
+ public InputStream getHashDataInput() {
+
+ if (data != null) {
+ return new ByteArrayInputStream(data);
+ }
+
+ return null;
+ }
+
+ @Override
+ public byte[] getDigest() {
+ if (reference != null) {
+ return reference.getDigestValue();
+ }
+ return null;
+ }
+
+ public void setFilename(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public ReferenceType getReference() {
+ return reference;
+ }
+
+}
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java b/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java
index 3f3d52c0..2564f88d 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/translator/STALTranslator.java
@@ -34,6 +34,8 @@ import javax.xml.bind.JAXBElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.stal.BulkSignRequest;
+import at.gv.egiz.stal.BulkSignResponse;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.InfoboxReadResponse;
@@ -46,6 +48,8 @@ import at.gv.egiz.stal.SignRequest.SignedInfo;
import at.gv.egiz.stal.SignResponse;
import at.gv.egiz.stal.StatusRequest;
import at.gv.egiz.stal.StatusResponse;
+import at.gv.egiz.stal.service.types.BulkSignRequestType;
+import at.gv.egiz.stal.service.types.BulkSignResponseType;
import at.gv.egiz.stal.service.types.ErrorResponseType;
import at.gv.egiz.stal.service.types.InfoboxReadRequestType;
import at.gv.egiz.stal.service.types.InfoboxReadResponseType;
@@ -197,18 +201,22 @@ public class STALTranslator {
public List<Class<?>> getSupportedTypes() {
return Arrays.asList(new Class<?>[]{InfoboxReadRequest.class,
SignRequest.class,
+ BulkSignRequest.class,
QuitRequest.class,
StatusRequest.class,
InfoboxReadRequestType.class,
SignRequestType.class,
+ BulkSignRequestType.class,
QuitRequestType.class,
StatusRequestType.class,
InfoboxReadResponse.class,
SignResponse.class,
+ BulkSignResponse.class,
ErrorResponse.class,
StatusResponse.class,
InfoboxReadResponseType.class,
SignResponseType.class,
+ BulkSignResponseType.class,
ErrorResponseType.class,
StatusResponseType.class
});
@@ -218,22 +226,14 @@ public class STALTranslator {
public JAXBElement<? extends RequestType> translate(STALRequest request) throws TranslationException {
log.trace("translate " + request.getClass());
if (request instanceof SignRequest) {
- SignRequestType req = of.createSignRequestType();
- req.setKeyIdentifier(((SignRequest) request).getKeyIdentifier());
- SignRequestType.SignedInfo signedInfo = of.createSignRequestTypeSignedInfo();
- signedInfo.setValue(((SignRequest) request).getSignedInfo().getValue());
- signedInfo.setIsCMSSignedAttributes(((SignRequest) request).getSignedInfo().isIsCMSSignedAttributes());
- req.setSignedInfo(signedInfo);
- req.setSignatureMethod(((SignRequest) request).getSignatureMethod());
- req.setDigestMethod(((SignRequest) request).getDigestMethod());
- if (((SignRequest) request).getExcludedByteRange() != null) {
- SignRequestType.ExcludedByteRange excludedByteRange = of.createSignRequestTypeExcludedByteRange();
- excludedByteRange.setFrom(((SignRequest) request).getExcludedByteRange().getFrom());
- excludedByteRange.setTo(((SignRequest) request).getExcludedByteRange().getTo());
- req.setExcludedByteRange(excludedByteRange);
+ return translate((SignRequest) request);
+ } else if (request instanceof BulkSignRequest) {
+ BulkSignRequestType bulkReq = of.createBulkSignRequestType();
+ BulkSignRequest bulkSignRequest = (BulkSignRequest) request;
+ for (SignRequest signReq : bulkSignRequest.getSignRequests()) {
+ bulkReq.getSignRequests().add(translate(signReq).getValue());
}
- //TODO add hashdatainput (refactor signRequestType)
- return of.createGetNextRequestResponseTypeSignRequest(req);
+ return of.createGetNextRequestResponseTypeBulkSignRequest(bulkReq);
} else if (request instanceof InfoboxReadRequest) {
InfoboxReadRequestType req = of.createInfoboxReadRequestType();
req.setInfoboxIdentifier(((InfoboxReadRequest) request).getInfoboxIdentifier());
@@ -256,19 +256,12 @@ public class STALTranslator {
stalReq.setInfoboxIdentifier(((InfoboxReadRequestType) request).getInfoboxIdentifier());
return stalReq;
} else if (request instanceof SignRequestType) {
- SignRequest stalReq = new SignRequest();
- stalReq.setKeyIdentifier(((SignRequestType) request).getKeyIdentifier());
- SignedInfo signedInfo = new SignedInfo();
- signedInfo.setValue(((SignRequestType) request).getSignedInfo().getValue());
- signedInfo.setIsCMSSignedAttributes(((SignRequestType) request).getSignedInfo().isIsCMSSignedAttributes());
- stalReq.setSignedInfo(signedInfo);
- stalReq.setSignatureMethod(((SignRequestType) request).getSignatureMethod());
- stalReq.setDigestMethod(((SignRequestType) request).getDigestMethod());
- if (((SignRequestType) request).getExcludedByteRange() != null) {
- ExcludedByteRange excludedByteRange = new ExcludedByteRange();
- excludedByteRange.setFrom(((SignRequestType) request).getExcludedByteRange().getFrom());
- excludedByteRange.setTo(((SignRequestType) request).getExcludedByteRange().getTo());
- stalReq.setExcludedByteRange(excludedByteRange);
+ return translate((SignRequestType) request);
+ } else if (request instanceof BulkSignRequestType) {
+ BulkSignRequest stalReq = new BulkSignRequest();
+ BulkSignRequestType bulkSignRequestType = (BulkSignRequestType) request;
+ for (SignRequestType requestType : bulkSignRequestType.getSignRequests()) {
+ stalReq.getSignRequests().add(translate(requestType));
}
return stalReq;
} else if (request instanceof QuitRequestType) {
@@ -286,9 +279,14 @@ public class STALTranslator {
resp.setInfoboxValue(((InfoboxReadResponse) response).getInfoboxValue());
return of.createGetNextRequestTypeInfoboxReadResponse(resp);
} else if (response instanceof SignResponse) {
- SignResponseType resp = of.createSignResponseType();
- resp.setSignatureValue(((SignResponse) response).getSignatureValue());
- return of.createGetNextRequestTypeSignResponse(resp);
+ return translate((SignResponse) response);
+ } else if (response instanceof BulkSignResponse) {
+ BulkSignResponseType resp = of.createBulkSignResponseType();
+ BulkSignResponse bulkSignResponse = (BulkSignResponse) response;
+ for (SignResponse signResponse : bulkSignResponse.getSignResponse()) {
+ resp.getSignResponse().add(translate(signResponse).getValue());
+ }
+ return of.createGetNextRequestTypeBulkSignResponse(resp);
} else if (response instanceof ErrorResponse) {
ErrorResponseType resp = of.createErrorResponseType();
resp.setErrorCode(((ErrorResponse) response).getErrorCode());
@@ -309,8 +307,13 @@ public class STALTranslator {
stalResp.setInfoboxValue(((InfoboxReadResponseType) response).getInfoboxValue());
return stalResp;
} else if (response instanceof SignResponseType) {
- SignResponse stalResp = new SignResponse();
- stalResp.setSignatureValue(((SignResponseType) response).getSignatureValue());
+ return translate((SignResponseType) response);
+ } else if (response instanceof BulkSignResponseType) {
+ BulkSignResponse stalResp = new BulkSignResponse();
+ BulkSignResponseType bulkSignResponseType = (BulkSignResponseType) response;
+ for (SignResponseType responseType : bulkSignResponseType.getSignResponse()) {
+ stalResp.getSignResponse().add(translate(responseType));
+ }
return stalResp;
} else if (response instanceof ErrorResponseType) {
ErrorResponse stalResp = new ErrorResponse();
@@ -324,6 +327,63 @@ public class STALTranslator {
}
throw new TranslationException(response.getClass());
}
+
+ private JAXBElement<SignRequestType> translate(SignRequest request) {
+
+ SignRequestType req = of.createSignRequestType();
+ req.setKeyIdentifier(((SignRequest) request).getKeyIdentifier());
+ SignRequestType.SignedInfo signedInfo = of.createSignRequestTypeSignedInfo();
+ signedInfo.setValue(((SignRequest) request).getSignedInfo().getValue());
+ signedInfo.setIsCMSSignedAttributes(((SignRequest) request).getSignedInfo().isIsCMSSignedAttributes());
+ req.setSignedInfo(signedInfo);
+ req.setSignatureMethod(((SignRequest) request).getSignatureMethod());
+ req.setDigestMethod(((SignRequest) request).getDigestMethod());
+ req.setMimeType(((SignRequest) request).getMimeType());
+ req.setDisplayName(((SignRequest) request).getDisplayName());
+ if (((SignRequest) request).getExcludedByteRange() != null) {
+ SignRequestType.ExcludedByteRange excludedByteRange = of.createSignRequestTypeExcludedByteRange();
+ excludedByteRange.setFrom(((SignRequest) request).getExcludedByteRange().getFrom());
+ excludedByteRange.setTo(((SignRequest) request).getExcludedByteRange().getTo());
+ req.setExcludedByteRange(excludedByteRange);
+ }
+ return of.createGetNextRequestResponseTypeSignRequest(req);
+ }
+
+ private SignRequest translate(SignRequestType request) {
+
+ SignRequest stalReq = new SignRequest();
+ stalReq.setKeyIdentifier(request.getKeyIdentifier());
+ SignedInfo signedInfo = new SignedInfo();
+ signedInfo.setValue(request.getSignedInfo().getValue());
+ signedInfo.setIsCMSSignedAttributes(request.getSignedInfo().isIsCMSSignedAttributes());
+ stalReq.setSignedInfo(signedInfo);
+ stalReq.setSignatureMethod(request.getSignatureMethod());
+ stalReq.setDigestMethod(request.getDigestMethod());
+ stalReq.setDisplayName(request.getDisplayName());
+ stalReq.setMimeType(request.getMimeType());
+ if (request.getExcludedByteRange() != null) {
+ ExcludedByteRange excludedByteRange = new ExcludedByteRange();
+ excludedByteRange.setFrom(request.getExcludedByteRange().getFrom());
+ excludedByteRange.setTo(request.getExcludedByteRange().getTo());
+ stalReq.setExcludedByteRange(excludedByteRange);
+ }
+ return stalReq;
+
+ }
+
+
+ private JAXBElement<SignResponseType> translate(SignResponse response) {
+ SignResponseType resp = of.createSignResponseType();
+ resp.setSignatureValue(response.getSignatureValue());
+ return of.createGetNextRequestTypeSignResponse(resp);
+ }
+
+ private SignResponse translate(SignResponseType response) {
+ SignResponse stalResp = new SignResponse();
+ stalResp.setSignatureValue(response.getSignatureValue());
+ return stalResp;
+ }
+
}
}
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignRequestType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignRequestType.java
new file mode 100644
index 00000000..4086e254
--- /dev/null
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignRequestType.java
@@ -0,0 +1,68 @@
+package at.gv.egiz.stal.service.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for BulkSignRequestType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="BulkSignRequestType">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;sequence maxOccurs="unbounded">
+ * &lt;element name="SignRequests" type="{http://www.egiz.gv.at/stal}SignRequestType"/>
+ * &lt;/sequence>
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BulkSignRequestType", propOrder = {
+ "signRequests"
+})
+public class BulkSignRequestType extends RequestType {
+
+ @XmlElement(name = "SignRequests", required = true)
+ protected List<SignRequestType> signRequests;
+
+ /**
+ * Gets the value of the signRequests property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the signRequests property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>
+ * getSignRequests().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link SignRequestType }
+ *
+ *
+ */
+ public List<SignRequestType> getSignRequests() {
+ if (signRequests == null) {
+ signRequests = new ArrayList<SignRequestType>();
+ }
+ return this.signRequests;
+ }
+
+}
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignResponseType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignResponseType.java
new file mode 100644
index 00000000..fbdcbdc0
--- /dev/null
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/BulkSignResponseType.java
@@ -0,0 +1,69 @@
+
+package at.gv.egiz.stal.service.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for BulkSignResponseType complex type.
+ *
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ *
+ * <pre>
+ * &lt;complexType name="BulkSignResponseType">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;sequence maxOccurs="unbounded">
+ * &lt;element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/>
+ * &lt;/sequence>
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "BulkSignResponseType", propOrder = {
+ "signResponse"
+})
+public class BulkSignResponseType extends ResponseType {
+
+ @XmlElement(name = "SignResponse", required = true)
+ protected List<SignResponseType> signResponse;
+
+ /**
+ * Gets the value of the signResponse property.
+ *
+ * <p>
+ * This accessor method returns a reference to the live list,
+ * not a snapshot. Therefore any modification you make to the
+ * returned list will be present inside the JAXB object.
+ * This is why there is not a <CODE>set</CODE> method for the signResponse property.
+ *
+ * <p>
+ * For example, to add a new item, do as follows:
+ * <pre>SignRequestType
+ * getSignResponse().add(newItem);
+ * </pre>
+ *
+ *
+ * <p>
+ * Objects of the following type(s) are allowed in the list
+ * {@link SignResponseType }
+ *
+ *
+ */
+ public List<SignResponseType> getSignResponse() {
+ if (signResponse == null) {
+ signResponse = new ArrayList<SignResponseType>();
+ }
+ return this.signResponse;
+ }
+
+}
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputType.java
index 037e94eb..2a3a58bf 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputType.java
@@ -21,8 +21,6 @@
* that you distribute must include a readable copy of the "NOTICE" text file.
*/
-
-
package at.gv.egiz.stal.service.types;
import java.util.ArrayList;
@@ -49,6 +47,7 @@ import javax.xml.bind.annotation.XmlType;
* &lt;complexContent&gt;
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
* &lt;attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
+ * &lt;attribute name="digest" type="{http://www.w3.org/2001/XMLSchema}base64Binary" //&gt;
* &lt;/restriction&gt;
* &lt;/complexContent&gt;
* &lt;/complexType&gt;
@@ -133,13 +132,14 @@ public class GetHashDataInputType {
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
- * &lt;complexType&gt;
- * &lt;complexContent&gt;
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
- * &lt;attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
- * &lt;/restriction&gt;
- * &lt;/complexContent&gt;
- * &lt;/complexType&gt;
+ * &lt;complexType>
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" />
+ * &lt;attribute name="digest" type="{http://www.w3.org/2001/XMLSchema}base64Binary" />
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
* </pre>
*
*
@@ -150,6 +150,8 @@ public class GetHashDataInputType {
@XmlAttribute(name = "ID")
protected String id;
+ @XmlAttribute
+ protected byte[] digest;
/**
* Gets the value of the id property.
@@ -175,6 +177,28 @@ public class GetHashDataInputType {
this.id = value;
}
+ /**
+ * Gets the value of the digest property.
+ *
+ * @return
+ * possible object is
+ * byte[]
+ */
+ public byte[] getDigest() {
+ return digest;
+ }
+
+ /**
+ * Sets the value of the digest property.
+ *
+ * @param value
+ * allowed object is
+ * byte[]
+ */
+ public void setDigest(byte[] value) {
+ this.digest = ((byte[]) value);
+ }
+
}
}
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestResponseType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestResponseType.java
index 310190cc..9fcbe660 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestResponseType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestResponseType.java
@@ -1,27 +1,3 @@
-/*
- * Copyright 2011 by Graz University of Technology, Austria
- * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint
- * initiative of the Federal Chancellery Austria and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
package at.gv.egiz.stal.service.types;
@@ -49,6 +25,7 @@ import javax.xml.bind.annotation.XmlType;
* &lt;choice maxOccurs="unbounded"&gt;
* &lt;element name="InfoboxReadRequest" type="{http://www.egiz.gv.at/stal}InfoboxReadRequestType"/&gt;
* &lt;element name="SignRequest" type="{http://www.egiz.gv.at/stal}SignRequestType"/&gt;
+ * &lt;element name="BulkSignRequest" type="{http://www.egiz.gv.at/stal}BulkSignRequestType"/&gt;
* &lt;element name="QuitRequest" type="{http://www.egiz.gv.at/stal}QuitRequestType"/&gt;
* &lt;element name="StatusRequest" type="{http://www.egiz.gv.at/stal}StatusRequestType"/&gt;
* &lt;element ref="{http://www.egiz.gv.at/stal}OtherRequest"/&gt;
@@ -63,52 +40,55 @@ import javax.xml.bind.annotation.XmlType;
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GetNextRequestResponseType", propOrder = {
- "infoboxReadRequestOrSignRequestOrQuitRequest"
+ "infoboxReadRequestOrSignRequestOrBulkSignRequest"
})
public class GetNextRequestResponseType {
@XmlElementRefs({
- @XmlElementRef(name = "OtherRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
+ @XmlElementRef(name = "BulkSignRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
@XmlElementRef(name = "QuitRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
@XmlElementRef(name = "InfoboxReadRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
+ @XmlElementRef(name = "StatusRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
@XmlElementRef(name = "SignRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
- @XmlElementRef(name = "StatusRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class)
+ @XmlElementRef(name = "OtherRequest", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class)
})
- protected List<JAXBElement<? extends RequestType>> infoboxReadRequestOrSignRequestOrQuitRequest;
+ protected List<JAXBElement<? extends RequestType>> infoboxReadRequestOrSignRequestOrBulkSignRequest;
@XmlAttribute(name = "SessionId")
protected String sessionId;
/**
- * Gets the value of the infoboxReadRequestOrSignRequestOrQuitRequest property.
+ * Gets the value of the infoboxReadRequestOrSignRequestOrBulkSignRequest property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the infoboxReadRequestOrSignRequestOrQuitRequest property.
+ * This is why there is not a <CODE>set</CODE> method for the infoboxReadRequestOrSignRequestOrBulkSignRequest property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
- * getInfoboxReadRequestOrSignRequestOrQuitRequest().add(newItem);
+ * getInfoboxReadRequestOrSignRequestOrBulkSignRequest().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
- * {@link JAXBElement }{@code <}{@link RequestType }{@code >}
+ * {@link JAXBElement }{@code <}{@link BulkSignRequestType }{@code >}
* {@link JAXBElement }{@code <}{@link QuitRequestType }{@code >}
* {@link JAXBElement }{@code <}{@link InfoboxReadRequestType }{@code >}
* {@link JAXBElement }{@code <}{@link StatusRequestType }{@code >}
* {@link JAXBElement }{@code <}{@link SignRequestType }{@code >}
+ * {@link JAXBElement }{@code <}{@link ScriptType }{@code >}
+ * {@link JAXBElement }{@code <}{@link RequestType }{@code >}
*
*
*/
- public List<JAXBElement<? extends RequestType>> getInfoboxReadRequestOrSignRequestOrQuitRequest() {
- if (infoboxReadRequestOrSignRequestOrQuitRequest == null) {
- infoboxReadRequestOrSignRequestOrQuitRequest = new ArrayList<JAXBElement<? extends RequestType>>();
+ public List<JAXBElement<? extends RequestType>> getInfoboxReadRequestOrSignRequestOrBulkSignRequest() {
+ if (infoboxReadRequestOrSignRequestOrBulkSignRequest == null) {
+ infoboxReadRequestOrSignRequestOrBulkSignRequest = new ArrayList<JAXBElement<? extends RequestType>>();
}
- return this.infoboxReadRequestOrSignRequestOrQuitRequest;
+ return this.infoboxReadRequestOrSignRequestOrBulkSignRequest;
}
/**
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestType.java
index 4b392aed..635c0a71 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetNextRequestType.java
@@ -1,27 +1,3 @@
-/*
- * Copyright 2011 by Graz University of Technology, Austria
- * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint
- * initiative of the Federal Chancellery Austria and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the Licence.
- * You may obtain a copy of the Licence at:
- * http://www.osor.eu/eupl/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the Licence is distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Licence for the specific language governing permissions and
- * limitations under the Licence.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
- */
-
-
package at.gv.egiz.stal.service.types;
@@ -48,6 +24,7 @@ import javax.xml.bind.annotation.XmlType;
* &lt;choice maxOccurs="unbounded"&gt;
* &lt;element name="InfoboxReadResponse" type="{http://www.egiz.gv.at/stal}InfoboxReadResponseType"/&gt;
* &lt;element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/&gt;
+ * &lt;element name="BulkSignResponse" type="{http://www.egiz.gv.at/stal}BulkSignResponseType"/&gt;
* &lt;element name="ErrorResponse" type="{http://www.egiz.gv.at/stal}ErrorResponseType"/&gt;
* &lt;element name="StatusResponse" type="{http://www.egiz.gv.at/stal}StatusResponseType"/&gt;
* &lt;element ref="{http://www.egiz.gv.at/stal}OtherResponse"/&gt;
@@ -62,52 +39,55 @@ import javax.xml.bind.annotation.XmlType;
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GetNextRequestType", propOrder = {
- "infoboxReadResponseOrSignResponseOrErrorResponse"
+ "infoboxReadResponseOrSignResponseOrBulkSignResponse"
})
public class GetNextRequestType {
@XmlElementRefs({
- @XmlElementRef(name = "StatusResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
+ @XmlElementRef(name = "SignResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
@XmlElementRef(name = "InfoboxReadResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
- @XmlElementRef(name = "OtherResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
+ @XmlElementRef(name = "BulkSignResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
@XmlElementRef(name = "ErrorResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
- @XmlElementRef(name = "SignResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class)
+ @XmlElementRef(name = "StatusResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class),
+ @XmlElementRef(name = "OtherResponse", namespace = "http://www.egiz.gv.at/stal", type = JAXBElement.class)
})
- protected List<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>> infoboxReadResponseOrSignResponseOrErrorResponse;
+ protected List<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>> infoboxReadResponseOrSignResponseOrBulkSignResponse;
@XmlAttribute(name = "SessionId")
protected String sessionId;
/**
- * Gets the value of the infoboxReadResponseOrSignResponseOrErrorResponse property.
+ * Gets the value of the infoboxReadResponseOrSignResponseOrBulkSignResponse property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
- * This is why there is not a <CODE>set</CODE> method for the infoboxReadResponseOrSignResponseOrErrorResponse property.
+ * This is why there is not a <CODE>set</CODE> method for the infoboxReadResponseOrSignResponseOrBulkSignResponse property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
- * getInfoboxReadResponseOrSignResponseOrErrorResponse().add(newItem);
+ * getInfoboxReadResponseOrSignResponseOrBulkSignResponse().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
- * {@link JAXBElement }{@code <}{@link StatusResponseType }{@code >}
- * {@link JAXBElement }{@code <}{@link at.gv.egiz.stal.service.types.ResponseType }{@code >}
- * {@link JAXBElement }{@code <}{@link ErrorResponseType }{@code >}
* {@link JAXBElement }{@code <}{@link SignResponseType }{@code >}
* {@link JAXBElement }{@code <}{@link InfoboxReadResponseType }{@code >}
+ * {@link JAXBElement }{@code <}{@link BulkSignResponseType }{@code >}
+ * {@link JAXBElement }{@code <}{@link ErrorResponseType }{@code >}
+ * {@link JAXBElement }{@code <}{@link StatusResponseType }{@code >}
+ * {@link JAXBElement }{@code <}{@link at.buergerkarte.namespaces.cardchannel.service.ResponseType }{@code >}
+ * {@link JAXBElement }{@code <}{@link at.gv.egiz.stal.service.types.ResponseType }{@code >}
*
*
*/
- public List<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>> getInfoboxReadResponseOrSignResponseOrErrorResponse() {
- if (infoboxReadResponseOrSignResponseOrErrorResponse == null) {
- infoboxReadResponseOrSignResponseOrErrorResponse = new ArrayList<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>>();
+ public List<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>> getInfoboxReadResponseOrSignResponseOrBulkSignResponse() {
+ if (infoboxReadResponseOrSignResponseOrBulkSignResponse == null) {
+ infoboxReadResponseOrSignResponseOrBulkSignResponse = new ArrayList<JAXBElement<? extends at.gv.egiz.stal.service.types.ResponseType>>();
}
- return this.infoboxReadResponseOrSignResponseOrErrorResponse;
+ return this.infoboxReadResponseOrSignResponseOrBulkSignResponse;
}
/**
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java
index ea7ca837..e9b5ac92 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/ObjectFactory.java
@@ -64,6 +64,8 @@ public class ObjectFactory {
private final static QName _GetNextRequestTypeInfoboxReadResponse_QNAME = new QName("http://www.egiz.gv.at/stal", "InfoboxReadResponse");
private final static QName _GetNextRequestResponseTypeStatusRequest_QNAME = new QName("http://www.egiz.gv.at/stal", "StatusRequest");
private final static QName _GetNextRequestTypeStatusResponse_QNAME = new QName("http://www.egiz.gv.at/stal", "StatusResponse");
+ private final static QName _GetNextRequestTypeBulkSignResponse_QNAME = new QName("http://www.egiz.gv.at/stal", "BulkSignResponse");
+ private final static QName _GetNextRequestResponseTypeBulkSignRequest_QNAME = new QName("http://www.egiz.gv.at/stal", "BulkSignRequest");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: at.gv.egiz.stal.service.types
@@ -72,6 +74,15 @@ public class ObjectFactory {
public ObjectFactory() {
}
+
+ /**
+ * Create an instance of {@link BulkSignResponseType }
+ *
+ */
+ public BulkSignResponseType createBulkSignResponseType() {
+ return new BulkSignResponseType();
+ }
+
/**
* Create an instance of {@link StatusResponseType }
*
@@ -169,6 +180,15 @@ public class ObjectFactory {
}
/**
+ * Create an instance of {@link BulkSignRequestType }
+ *
+ */
+ public BulkSignRequestType createBulkSignRequestType() {
+ return new BulkSignRequestType();
+ }
+
+
+ /**
* Create an instance of {@link InfoboxReadRequestType }
*
*/
@@ -327,6 +347,15 @@ public class ObjectFactory {
}
/**
+ * Create an instance of {@link JAXBElement }{@code <}{@link BulkSignResponseType }{@code >}}
+ *
+ */
+ @XmlElementDecl(namespace = "http://www.egiz.gv.at/stal", name = "BulkSignResponse", scope = GetNextRequestType.class)
+ public JAXBElement<BulkSignResponseType> createGetNextRequestTypeBulkSignResponse(BulkSignResponseType value) {
+ return new JAXBElement<BulkSignResponseType>(_GetNextRequestTypeBulkSignResponse_QNAME, BulkSignResponseType.class, GetNextRequestType.class, value);
+ }
+
+ /**
* Create an instance of {@link JAXBElement }{@code <}{@link ErrorResponseType }{@code >}}
*
*/
@@ -344,6 +373,17 @@ public class ObjectFactory {
return new JAXBElement<SignResponseType>(_GetNextRequestTypeSignResponse_QNAME, SignResponseType.class, GetNextRequestType.class, value);
}
+
+ /**
+ * Create an instance of {@link JAXBElement }{@code <}{@link BulkSignRequestType }{@code >}}
+ *
+ */
+ @XmlElementDecl(namespace = "http://www.egiz.gv.at/stal", name = "BulkSignRequest", scope = GetNextRequestResponseType.class)
+ public JAXBElement<BulkSignRequestType> createGetNextRequestResponseTypeBulkSignRequest(BulkSignRequestType value) {
+ return new JAXBElement<BulkSignRequestType>(_GetNextRequestResponseTypeBulkSignRequest_QNAME, BulkSignRequestType.class, GetNextRequestResponseType.class, value);
+ }
+
+
/**
* Create an instance of {@link JAXBElement }{@code <}{@link InfoboxReadResponseType }{@code >}}
*
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/RequestType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/RequestType.java
index 2cf88988..fcefbd09 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/RequestType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/RequestType.java
@@ -55,7 +55,8 @@ import javax.xml.bind.annotation.XmlType;
SignRequestType.class,
InfoboxReadRequestType.class,
QuitRequestType.class,
- StatusRequestType.class
+ StatusRequestType.class,
+ BulkSignRequestType.class
})
public abstract class RequestType {
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/ResponseType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/ResponseType.java
index 02a91ef0..26c3de96 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/ResponseType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/ResponseType.java
@@ -54,7 +54,8 @@ import javax.xml.bind.annotation.XmlType;
ErrorResponseType.class,
InfoboxReadResponseType.class,
SignResponseType.class,
- StatusResponseType.class
+ StatusResponseType.class,
+ BulkSignResponseType.class
})
public abstract class ResponseType {
diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java
index 6688d720..b5920d0a 100644
--- a/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java
+++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/SignRequestType.java
@@ -65,6 +65,8 @@ import javax.xml.bind.annotation.XmlValue;
* &lt;/element&gt;
* &lt;element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
* &lt;element name="DigestMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
+ * &lt;element name="displayName" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/&gt;
+ * &lt;element name="mimeType" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/&gt;
* &lt;element name="ExcludedByteRange" minOccurs="0"&gt;
* &lt;complexType&gt;
* &lt;complexContent&gt;
@@ -89,6 +91,8 @@ import javax.xml.bind.annotation.XmlValue;
"signedInfo",
"signatureMethod",
"digestMethod",
+ "displayName",
+ "mimeType",
"excludedByteRange"
})
public class SignRequestType
@@ -103,6 +107,10 @@ public class SignRequestType
protected String signatureMethod;
@XmlElement(name = "DigestMethod")
protected String digestMethod;
+ @XmlElement(name = "displayName", required = true)
+ protected String displayName;
+ @XmlElement(name = "mimeType", required = true)
+ protected String mimeType;
@XmlElement(name = "ExcludedByteRange")
protected SignRequestType.ExcludedByteRange excludedByteRange;
@@ -191,6 +199,55 @@ public class SignRequestType
}
/**
+ * Sets the value of the displayName property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setDisplayName(String value) {
+ this.displayName = value;
+ }
+
+ /**
+ * Gets the value of the displayName property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Gets the value of the mimeType property.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+
+ /**
+ * Sets the value of the mimeType property.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setMimeType(String value) {
+ this.mimeType = value;
+ }
+
+ /**
* Sets the value of the digestMethod property.
*
* @param value
@@ -233,14 +290,14 @@ public class SignRequestType
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
- * &lt;complexType&gt;
- * &lt;complexContent&gt;
- * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
- * &lt;attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /&gt;
- * &lt;attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /&gt;
- * &lt;/restriction&gt;
- * &lt;/complexContent&gt;
- * &lt;/complexType&gt;
+ * &lt;complexType>
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * &lt;attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" />
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
* </pre>
*
*
@@ -313,13 +370,13 @@ public class SignRequestType
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
- * &lt;complexType&gt;
- * &lt;simpleContent&gt;
- * &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema&gt;base64Binary"&gt;
- * &lt;attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
- * &lt;/extension&gt;
- * &lt;/simpleContent&gt;
- * &lt;/complexType&gt;
+ * &lt;complexType>
+ * &lt;simpleContent>
+ * &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>base64Binary">
+ * &lt;attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
+ * &lt;/extension>
+ * &lt;/simpleContent>
+ * &lt;/complexType>
* </pre>
*
*
diff --git a/STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java b/STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java
index efe084d3..0bf7a0fc 100644
--- a/STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java
+++ b/STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java
@@ -91,7 +91,7 @@ public class STALServiceTest {
System.out.println("connecting to STAL WS [TestSession] ...");
GetNextRequestResponseType wsResponse = port.connect("TestSession");
- List<JAXBElement<? extends RequestType>> stalRequests = wsResponse.getInfoboxReadRequestOrSignRequestOrQuitRequest();
+ List<JAXBElement<? extends RequestType>> stalRequests = wsResponse.getInfoboxReadRequestOrSignRequestOrBulkSignRequest();
System.out.println("Received " + wsResponse.getClass() + " containing " + stalRequests.size() + " requests");
for (JAXBElement<? extends RequestType> jAXBElement : stalRequests) {
System.out.println(" STALRequest " + jAXBElement.getValue().getClass());
diff --git a/bkucommon/pom.xml b/bkucommon/pom.xml
index 9e036ec6..9038a26c 100644
--- a/bkucommon/pom.xml
+++ b/bkucommon/pom.xml
@@ -82,6 +82,11 @@
<scope>compile</scope>
</dependency>
<dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.5</version>
+ </dependency>
+ <dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</dependency>
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkCommand.java
new file mode 100644
index 00000000..7deb8e22
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkCommand.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 Datentechnik Innovation and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands;
+
+
+public interface BulkCommand extends SLCommand {
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkSignatureResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkSignatureResult.java
new file mode 100644
index 00000000..8670d635
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/BulkSignatureResult.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Datentechnik Innovation and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.bku.slcommands;
+
+import org.w3c.dom.Element;
+
+public interface BulkSignatureResult extends SLResult {
+
+ public Element getContent();
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandFactory.java
new file mode 100644
index 00000000..7f7d7f1e
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Datentechnik Innovation and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import javax.xml.bind.JAXBElement;
+
+import at.gv.egiz.bku.slcommands.AbstractSLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+
+public class BulkCommandFactory extends AbstractSLCommandFactory {
+
+ @Override
+ public SLCommand createSLCommand(JAXBElement<?> element) throws SLCommandException {
+ BulkCommandImpl command = new BulkCommandImpl();
+ command.init(element);
+ command.setConfiguration(configuration);
+ return command;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImpl.java
new file mode 100644
index 00000000..7094e284
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImpl.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import iaik.asn1.DerCoder;
+import iaik.asn1.INTEGER;
+import iaik.asn1.SEQUENCE;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.cms.CMSException;
+import iaik.cms.CMSSignatureException;
+import iaik.utils.Util;
+
+import java.math.BigInteger;
+import java.security.InvalidParameterException;
+import java.security.SignatureException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.BulkRequestType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.BulkRequestType.CreateSignatureRequest;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CreateCMSSignatureRequestType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+import at.gv.egiz.bku.slcommands.BulkCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.slcommands.impl.cms.BulkCollectionSecurityProvider;
+import at.gv.egiz.bku.slcommands.impl.cms.BulkSignature;
+import at.gv.egiz.bku.slcommands.impl.cms.BulkSignatureInfo;
+import at.gv.egiz.bku.slcommands.impl.cms.CMSHashDataInput;
+import at.gv.egiz.bku.slcommands.impl.xsect.STALSignatureException;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+import at.gv.egiz.bku.slexceptions.SLViewerException;
+import at.gv.egiz.stal.BulkSignRequest;
+import at.gv.egiz.stal.BulkSignResponse;
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.HashDataInput;
+import at.gv.egiz.stal.InfoboxReadRequest;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.SignRequest;
+import at.gv.egiz.stal.SignRequest.SignedInfo;
+
+/**
+ * This class implements the security layer command <code>BulkRequest</code>.
+ *
+ * @author szoescher
+ */
+public class BulkCommandImpl extends SLCommandImpl<BulkRequestType> implements BulkCommand {
+
+ private final static String ID_ECSIGTYPE = "1.2.840.10045.4";
+
+ /**
+ * Logging facility.
+ */
+ private final static Logger log = LoggerFactory.getLogger(BulkCommandImpl.class);
+
+ /**
+ * The signing certificate.
+ */
+ protected X509Certificate signingCertificate;
+
+ /**
+ * The keybox identifier of the key used for signing.
+ */
+ protected String keyboxIdentifier;
+
+ /**
+ * The configuration facade used to access the MOCCA configuration.
+ */
+ private ConfigurationFacade configurationFacade = new ConfigurationFacade();
+
+ private class ConfigurationFacade implements MoccaConfigurationFacade {
+ private Configuration configuration;
+
+ public static final String USE_STRONG_HASH = "UseStrongHash";
+
+ public void setConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ public boolean getUseStrongHash() {
+ return configuration.getBoolean(USE_STRONG_HASH, true);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "BulkRequest";
+ }
+
+ public void setConfiguration(Configuration configuration) {
+ configurationFacade.setConfiguration(configuration);
+ }
+
+ @Override
+ public SLResult execute(SLCommandContext commandContext) {
+
+ List<BulkSignature> signatures = new LinkedList<BulkSignature>();
+
+ try {
+
+ List<CreateSignatureRequest> signatureRequests = getRequestValue().getCreateSignatureRequest();
+
+
+ List<String> requestIds = new LinkedList<String>();
+
+ if (signatureRequests != null && signatureRequests.size() != 0) {
+
+ BulkCollectionSecurityProvider securityProvider = new BulkCollectionSecurityProvider();
+
+ log.debug("get keyboxIdentifier from BulkSingatureRequest");
+ keyboxIdentifier = setKeyboxIdentifier(signatureRequests);
+
+ log.info("Requesting signing certificate.");
+ signingCertificate = requestSigningCertificate(keyboxIdentifier, commandContext);
+ log.debug("Got signing certificate. {}", signingCertificate);
+
+
+ for (int i=0; i<signatureRequests.size(); i++) {
+
+ CreateSignatureRequest request = signatureRequests.get(i);
+ if (request.getCreateCMSSignatureRequest() != null) {
+ log.info("execute CMSSignature request.");
+
+ requestIds.add(request.getId());
+
+ BulkSignature signature = prepareCMSSignatureRequests(securityProvider, request.getCreateCMSSignatureRequest(),
+ commandContext);
+
+ signatures.add(signature);
+
+ for(HashDataInput hashDataInput : securityProvider.getBulkSignatureInfo().get(i).getHashDataInput()){
+
+ if(hashDataInput instanceof CMSHashDataInput) {
+ CMSHashDataInput cmsHashDataInput = (CMSHashDataInput) hashDataInput;
+ log.debug("setting fileName {}", getFileName(request, i+1));
+ cmsHashDataInput.setFilename(getFileName(request, i+1));
+ cmsHashDataInput.setDigest(signature.getSignerInfo().getDigest());
+ }
+
+
+ }
+ } else {
+ if (request.getCreateXMLSignatureRequest() != null) {
+ log.error("XML signature requests are currently not supported in bulk signature requests.");
+ throw new SLCommandException(4124);
+ }
+ }
+ }
+
+
+ return new BulkSignatureResultImpl(signBulkRequest(securityProvider.getBulkSignatureInfo(), commandContext,
+ signatures), requestIds);
+
+
+
+ }
+
+ } catch (SLException e) {
+ return new ErrorResultImpl(e, commandContext.getLocale());
+
+ } catch (CMSException e) {
+ log.error("Error reading message digest.",e);
+ }
+ return null;
+ }
+
+ private String getFileName(CreateSignatureRequest request, int requestCounter) {
+
+ String referenceURL = null;
+
+ if (request.getCreateCMSSignatureRequest().getDataObject() != null
+ && request.getCreateCMSSignatureRequest().getDataObject().getContent() != null) {
+ referenceURL = request.getCreateCMSSignatureRequest().getDataObject().getContent().getReference();
+ }
+
+ if (StringUtils.isNotEmpty(referenceURL)) {
+ return FilenameUtils.getBaseName(referenceURL);
+ } else {
+
+ StringBuilder fileNameBuilder = new StringBuilder();
+
+ if (StringUtils.isNotEmpty(request.getDisplayName())) {
+ fileNameBuilder.append(request.getDisplayName());
+ } else {
+ fileNameBuilder.append(HashDataInput.DEFAULT_FILENAME);
+ fileNameBuilder.append("_");
+ fileNameBuilder.append(requestCounter);
+ }
+
+ return fileNameBuilder.toString();
+ }
+ }
+
+ private List<byte[]> signBulkRequest(List<BulkSignatureInfo> bulkSignatureInfo, SLCommandContext commandContext,
+ List<BulkSignature> signatures) throws SLCommandException, SLRequestException {
+
+ try {
+
+ List<byte[]> signatureValues;
+
+ BulkSignRequest signRequest = getSTALSignRequest(bulkSignatureInfo);
+
+ // send BulkStalRequest
+ List<STALResponse> responses = commandContext.getSTAL().handleRequest(
+ Collections.singletonList((STALRequest) signRequest));
+
+ if (responses == null || responses.size() != 1) {
+ throw new SignatureException("Failed to access STAL.");
+ }
+
+ STALResponse response = responses.get(0);
+
+ // setSignatureValues from STALResponse
+ if (response instanceof BulkSignResponse) {
+ BulkSignResponse bulkSignatureResponse = ((BulkSignResponse) response);
+
+ signatureValues = new LinkedList<byte[]>();
+ for (int i = 0; i < bulkSignatureResponse.getSignResponse().size(); i++) {
+ byte[] sig = ((BulkSignResponse) response).getSignResponse().get(i).getSignatureValue();
+ log.debug("Got signature response: " + Util.toBase64String(sig));
+ signatures.get(i).getSignerInfo()
+ .setSignatureValue(wrapSignatureValue(sig, bulkSignatureInfo.get(i).getSignatureAlgorithm()));
+ signatureValues.add(signatures.get(i).getEncoded());
+ }
+
+ return signatureValues;
+
+ } else if (response instanceof ErrorResponse) {
+
+ ErrorResponse err = (ErrorResponse) response;
+ log.debug("Error signing bulk request. Error response code: " + err.getErrorCode() + " (" + err.getErrorMessage() + ").");
+ throw new SLCommandException(err.getErrorCode());
+ }
+
+ } catch (SignatureException e) {
+ log.error("Error creating CMSSignature", e);
+ throw new SLCommandException(4000);
+ } catch (CMSException e) {
+ log.error("Error creating CMSSignature", e);
+ }
+ return null;
+ }
+
+ private String setKeyboxIdentifier(List<CreateSignatureRequest> signatureRequests) throws SLCommandException {
+
+ String keyboxIdentifier = null;
+
+ for (CreateSignatureRequest request : signatureRequests) {
+ if (request.getCreateCMSSignatureRequest() != null) {
+
+ if (keyboxIdentifier == null) {
+ keyboxIdentifier = request.getCreateCMSSignatureRequest().getKeyboxIdentifier();
+ } else {
+ if (request.getCreateCMSSignatureRequest().getKeyboxIdentifier() == null) {
+ log.error("No keyboxIdentifier has been specified for this signature request.");
+ throw new SLCommandException(3003);
+
+ } else if (!request.getCreateCMSSignatureRequest().getKeyboxIdentifier().equals(keyboxIdentifier)) {
+
+ log.error("Error creating bulk signature. The bulkSignature value has to be the same fo all signature requests.");
+ throw new SLCommandException(3003);
+ }
+ }
+ }
+ }
+
+
+ return keyboxIdentifier;
+ }
+
+ private BulkSignature prepareCMSSignatureRequests(BulkCollectionSecurityProvider securityProvieder,
+ CreateCMSSignatureRequestType request, SLCommandContext commandContext) throws SLCommandException,
+ SLRequestException, SLViewerException {
+
+ BulkSignature signature;
+
+ // prepare the CMSSignature for signing
+ log.debug("Preparing CMS signature.");
+ signature = prepareCMSSignature(request, commandContext);
+
+ try {
+
+ // update securityProvieder with parameters of the given signature
+ securityProvieder.updateBulkCollectionSecurityProvider(keyboxIdentifier, signature.getHashDataInput(),
+ signature.getExcludedByteRange());
+
+ // prepare the CMSSignatures of the Bulk Request
+ log.debug("Signing CMS signature.");
+
+
+
+ return prepareStalRequest(securityProvieder, signature, commandContext);
+
+ } catch (Exception e) {
+ log.error("Error creating CMS Signature.", e);
+ throw new SLCommandException(4000);
+ }
+
+ }
+
+ private BulkSignature prepareCMSSignature(CreateCMSSignatureRequestType request, SLCommandContext commandContext)
+ throws SLCommandException, SLRequestException {
+
+ // DataObject, SigningCertificate, SigningTime
+ Date signingTime = new Date();
+ try {
+ return new BulkSignature(
+ request.getDataObject() != null ? request.getDataObject() : request.getReferenceObject(),
+ request.getStructure(), signingCertificate, signingTime, commandContext.getURLDereferencer(),
+ configurationFacade.getUseStrongHash());
+ } catch (SLCommandException e) {
+ log.error("Error creating CMS Signature.", e);
+ throw e;
+ } catch (InvalidParameterException e) {
+ log.error("Error creating CMS Signature.", e);
+ throw new SLCommandException(3004);
+ } catch (Exception e) {
+ log.error("Error creating CMS Signature.", e);
+ throw new SLCommandException(4000);
+ }
+ }
+
+ private BulkSignature prepareStalRequest(BulkCollectionSecurityProvider securityProvieder, BulkSignature signature,
+ SLCommandContext commandContext) throws SLCommandException, SLViewerException {
+
+ try {
+
+ signature.sign(securityProvieder, commandContext.getSTAL(), keyboxIdentifier);
+ return signature;
+ } catch (CMSException e) {
+ log.error("Error creating CMSSignature", e);
+ throw new SLCommandException(4000);
+ } catch (CMSSignatureException e) {
+ log.error("Error creating CMSSignature", e);
+ throw new SLCommandException(4000);
+ }
+ }
+
+ private X509Certificate requestSigningCertificate(String keyboxIdentifier, SLCommandContext commandContext)
+ throws SLCommandException {
+
+ InfoboxReadRequest stalRequest = new InfoboxReadRequest();
+ stalRequest.setInfoboxIdentifier(keyboxIdentifier);
+
+ STALHelper stalHelper = new STALHelper(commandContext.getSTAL());
+
+ stalHelper.transmitSTALRequest(Collections.singletonList((STALRequest) stalRequest));
+ List<X509Certificate> certificates = stalHelper.getCertificatesFromResponses();
+ if (certificates == null || certificates.size() != 1) {
+ log.info("Got an unexpected number of certificates from STAL.");
+ throw new SLCommandException(4000);
+ }
+ return signingCertificate = certificates.get(0);
+
+ }
+
+ private static BulkSignRequest getSTALSignRequest(List<BulkSignatureInfo> bulkSignatureInfo) {
+ BulkSignRequest bulkSignRequest = new BulkSignRequest();
+
+ for (int i = 0; i< bulkSignatureInfo.size(); i++) {
+
+ BulkSignatureInfo signatureInfo = bulkSignatureInfo.get(i);
+ SignRequest signRequest = new SignRequest();
+ signRequest.setKeyIdentifier(signatureInfo.getKeyboxIdentifier());
+ log.debug("SignedAttributes: " + Util.toBase64String(signatureInfo.getSignedAttributes()));
+ SignedInfo signedInfo = new SignedInfo();
+ signedInfo.setValue(signatureInfo.getSignedAttributes());
+ signedInfo.setIsCMSSignedAttributes(true);
+ signRequest.setSignedInfo(signedInfo);
+ log.info("set displayName for Request {}", signatureInfo.getHashDataInput().get(0).getFilename());
+ signRequest.setDisplayName(signatureInfo.getHashDataInput().get(0).getFilename());
+ signRequest.setMimeType(signatureInfo.getHashDataInput().get(0).getMimeType());
+
+ signRequest.setSignatureMethod(signatureInfo.getSignatureMethod());
+ signRequest.setDigestMethod(signatureInfo.getDigestMethod());
+ signRequest.setHashDataInput(signatureInfo.getHashDataInput());
+
+ ExcludedByteRangeType excludedByteRange = signatureInfo.getExcludedByteRange();
+ if (excludedByteRange != null) {
+ SignRequest.ExcludedByteRange ebr = new SignRequest.ExcludedByteRange();
+ ebr.setFrom(excludedByteRange.getFrom());
+ ebr.setTo(excludedByteRange.getTo());
+ signRequest.setExcludedByteRange(ebr);
+ }
+
+ bulkSignRequest.getSignRequests().add(signRequest);
+ }
+ return bulkSignRequest;
+ }
+
+ private static byte[] wrapSignatureValue(byte[] sig, AlgorithmID sigAlgorithmID) {
+ String id = sigAlgorithmID.getAlgorithm().getID();
+ if (id.startsWith(ID_ECSIGTYPE)) // X9.62 Format ECDSA signatures
+ {
+ // Wrap r and s in ASN.1 SEQUENCE
+ byte[] r = Arrays.copyOfRange(sig, 0, sig.length / 2);
+ byte[] s = Arrays.copyOfRange(sig, sig.length / 2, sig.length);
+ SEQUENCE sigS = new SEQUENCE();
+ sigS.addComponent(new INTEGER(new BigInteger(1, r)));
+ sigS.addComponent(new INTEGER(new BigInteger(1, s)));
+ return DerCoder.encode(sigS);
+ } else
+ return sig;
+ }
+
+} \ No newline at end of file
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkSignatureResultImpl.java
new file mode 100644
index 00000000..2a88b6be
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BulkSignatureResultImpl.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2015 Datentechnik Innovation and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.transform.Result;
+import javax.xml.transform.Templates;
+import javax.xml.transform.dom.DOMResult;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.BulkResponseType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.BulkResponseType.CreateSignatureResponse;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CreateCMSSignatureResponseType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ObjectFactory;
+import at.gv.egiz.bku.slcommands.BulkSignatureResult;
+import at.gv.egiz.bku.slcommands.SLMarshallerFactory;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+
+/**
+ * This implements the result of the security layer command
+ * <code>BulkRequest</code>.
+ *
+ * @author szoescher
+ */
+public class BulkSignatureResultImpl extends SLResultImpl implements BulkSignatureResult {
+
+ /**
+ * Logging facility.
+ */
+ private final Logger log = LoggerFactory.getLogger(BulkSignatureResultImpl.class);
+
+ /**
+ * The CMSSignatures data.
+ */
+ protected List<byte[]> signatures;
+
+
+ protected List<String> requestIds;
+
+
+ /**
+ * The BulkResponse.
+ */
+ private Element content;
+
+ /**
+ * Creates a new instance of this BulkSignatureResultImpl with the given
+ * signatures <code>signatures</code>.
+ */
+ public BulkSignatureResultImpl(List<byte[]> signatures, List<String> requestIds) {
+ super();
+
+ if (signatures == null || signatures.size() == 0)
+ throw new NullPointerException("Argument 'signature' must not be null.");
+ this.signatures = signatures;
+
+ this.requestIds = requestIds;
+
+ marshallBulkSignatureResponse();
+ }
+
+ /**
+ * Marshalls the <code>BulkResponseType</code>.
+ */
+ private void marshallBulkSignatureResponse() {
+
+ ObjectFactory factory = new ObjectFactory();
+
+ BulkResponseType bulkResponseType = factory.createBulkResponseType();
+
+ for (int i=0; i< signatures.size(); i++) {
+
+ byte[] signature = signatures.get(i);
+ CreateSignatureResponse createSignatureResponse = factory.createBulkResponseTypeCreateSignatureResponse();
+
+ if (requestIds.get(i) != null) {
+ createSignatureResponse.setId(requestIds.get(i));
+ }
+ CreateCMSSignatureResponseType createCreateCMSSignatureResponseType = factory
+ .createCreateCMSSignatureResponseType();
+ createCreateCMSSignatureResponseType.setCMSSignature(signature);
+ createSignatureResponse.setCreateCMSSignatureResponse(createCreateCMSSignatureResponseType);
+ bulkResponseType.getCreateSignatureResponse().add(createSignatureResponse);
+
+
+ }
+
+ JAXBElement<BulkResponseType> createBulkResponse = factory.createBulkResponse(bulkResponseType);
+ DOMResult res = new DOMResult();
+
+ Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false);
+
+ try {
+ marshaller.marshal(createBulkResponse, res);
+ } catch (JAXBException e) {
+ log.error("Failed to marshall 'createBulkResponse'.", e);
+ throw new SLRuntimeException(e);
+ }
+ content = ((Document) res.getNode()).getDocumentElement();
+ }
+
+ @Override
+ public void writeTo(Result result, Templates templates, boolean fragment) {
+ writeTo(content, result, templates, fragment);
+ }
+
+ @Override
+ public Element getContent() {
+ return content;
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImpl.java
index eaf3e70a..93e0eee8 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImpl.java
@@ -123,8 +123,9 @@ public class CreateCMSSignatureCommandImpl extends
// DataObject, SigningCertificate, SigningTime
Date signingTime = request.isPAdESCompatibility() ? null : new Date();
- signature = new Signature(request.getDataObject(), request.getStructure(),
- signingCertificate, signingTime, commandContext.getURLDereferencer(),
+ signature = new Signature(request.getDataObject() != null ? request.getDataObject()
+ : request.getReferenceObject(), request.getStructure(), signingCertificate, signingTime,
+ commandContext.getURLDereferencer(),
configurationFacade.getUseStrongHash());
}
} catch (SLCommandException e) {
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java
index d0451138..74a0b4da 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java
@@ -76,4 +76,8 @@ public class DataObjectHashDataInput implements HashDataInput {
return dataObject.getFilename();
}
+ @Override
+ public byte[] getDigest() {
+ return dataObject.getReference().getDigestValue();
+ }
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkCollectionSecurityProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkCollectionSecurityProvider.java
new file mode 100644
index 00000000..6bbdc682
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkCollectionSecurityProvider.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import iaik.asn1.structures.AlgorithmID;
+import iaik.cms.IaikProvider;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.SignatureException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.stal.HashDataInput;
+
+
+/**
+ * This security Provider is used to collect multiple sign Requests to create one Stal BulkRequest.
+ * The related signature parameters are stored as a List of <code>BulkSignatureInfo</code>.
+ * @author szoescher
+ *
+ */
+public class BulkCollectionSecurityProvider extends IaikProvider {
+
+ private final static Logger log = LoggerFactory.getLogger(BulkCollectionSecurityProvider.class);
+
+ private String keyboxIdentifier;
+ private List<HashDataInput> hashDataInput;
+ private ExcludedByteRangeType excludedByteRange;
+
+ private List<BulkSignatureInfo> bulkSignatureInfo;
+
+
+ public BulkCollectionSecurityProvider() {
+ bulkSignatureInfo = new LinkedList<BulkSignatureInfo>();
+ }
+
+ public BulkCollectionSecurityProvider(String keyboxIdentifier, HashDataInput hashDataInput,
+ ExcludedByteRangeType excludedByteRange) {
+
+ bulkSignatureInfo = new LinkedList<BulkSignatureInfo>();
+ updateBulkCollectionSecurityProvider(keyboxIdentifier, hashDataInput, excludedByteRange);
+
+ }
+
+ public void updateBulkCollectionSecurityProvider(String keyboxIdentifier, HashDataInput hashDataInput,
+ ExcludedByteRangeType excludedByteRange) {
+
+ this.keyboxIdentifier = keyboxIdentifier;
+ this.hashDataInput = new ArrayList<HashDataInput>();
+ this.hashDataInput.add(hashDataInput);
+ this.excludedByteRange = excludedByteRange;
+
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.cms.IaikProvider#calculateSignatureFromSignedAttributes(iaik.asn1.structures.AlgorithmID, iaik.asn1.structures.AlgorithmID, java.security.PrivateKey, byte[])
+ */
+ @Override
+ public byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm,
+ AlgorithmID digestAlgorithm, PrivateKey privateKey,
+ byte[] signedAttributes)
+ throws SignatureException, InvalidKeyException, NoSuchAlgorithmException {
+ log.debug("calculateSignatureFromSignedAttributes: " + signatureAlgorithm + ", " + digestAlgorithm);
+
+
+ STALPrivateKey spk = (STALPrivateKey) privateKey;
+
+ //Store signature information that is required to create a StalBulkSignatureRequest.
+ bulkSignatureInfo.add(new BulkSignatureInfo(privateKey, signatureAlgorithm, keyboxIdentifier, signedAttributes,
+ spk.getAlgorithm(), spk.getDigestAlgorithm(), hashDataInput, excludedByteRange));
+
+ //Size of placeholder doesn't matter
+ byte[] signaturePlaceholder = new byte[1];
+ return signaturePlaceholder;
+ }
+
+public List<BulkSignatureInfo> getBulkSignatureInfo() {
+ return bulkSignatureInfo;
+}
+
+
+
+
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignature.java
new file mode 100644
index 00000000..bf220034
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignature.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import iaik.asn1.CodingException;
+import iaik.cms.CMSException;
+import iaik.cms.CMSSignatureException;
+import iaik.cms.ContentInfo;
+import iaik.cms.SecurityProvider;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.x509.X509ExtensionException;
+
+import java.io.IOException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectOptionalMetaType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.stal.STAL;
+
+/**
+ * This class represents a CMS-Signature as to be created by the
+ * security layer command <code>BulkSignatureRequest</code>.
+ *
+ * @author szoescher
+ */
+public class BulkSignature extends Signature {
+
+ public final static String ID_AA_ETS_MIMETYPE = "0.4.0.1733.2.1";
+
+ public BulkSignature(CMSDataObjectOptionalMetaType dataObject, String structure,
+ X509Certificate signingCertificate, Date signingTime, URLDereferencer urlDereferencer,
+ boolean useStrongHash)
+ throws NoSuchAlgorithmException, CertificateEncodingException,
+ CertificateException, X509ExtensionException, InvalidParameterException,
+ CodingException, SLCommandException, IOException, CMSException {
+ super(dataObject, structure, signingCertificate, signingTime, urlDereferencer, useStrongHash);
+ }
+
+ /**
+ * Additionally to the <code>sign()<code> method from the supertype,
+ * contains a additional parameter to set a custom securityProvider.
+ * @param securityProvider The Security Provider that handles the sign request.
+ */
+ public byte[] sign(SecurityProvider securityProvider, STAL stal, String keyboxIdentifier) throws CMSException, CMSSignatureException, SLCommandException {
+ signedData.setSecurityProvider(securityProvider);
+ try {
+ signedData.addSignerInfo(signerInfo);
+ } catch (NoSuchAlgorithmException e) {
+ throw new CMSSignatureException(e);
+ }
+ if (digestValue != null) {
+ try {
+ signedData.setMessageDigest(digestAlgorithm, digestValue);
+ } catch (NoSuchAlgorithmException e) {
+ throw new CMSSignatureException(e);
+ }
+ }
+ ContentInfo contentInfo = new ContentInfo(signedData);
+ return contentInfo.getEncoded();
+ }
+
+
+ public ExcludedByteRangeType getExcludedByteRange() {
+ return excludedByteRange;
+ }
+
+ public SignerInfo getSignerInfo() {
+ return signerInfo;
+ }
+
+ public void setSignerInfo(SignerInfo signerInfo) {
+ this.signerInfo = signerInfo;
+ }
+
+
+ public SignedData getSignedData() {
+ return signedData;
+ }
+
+ public byte[] getEncoded() throws CMSException{
+ ContentInfo contentInfo = new ContentInfo(signedData);
+ return contentInfo.getEncoded();
+ }
+
+
+}
+
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignatureInfo.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignatureInfo.java
new file mode 100644
index 00000000..1d918f9f
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/BulkSignatureInfo.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import iaik.asn1.structures.AlgorithmID;
+
+import java.security.PrivateKey;
+import java.util.List;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.stal.HashDataInput;
+
+
+/**
+ *
+ * @author szoescher
+ *
+ */
+public class BulkSignatureInfo {
+
+ AlgorithmID signatureAlgorithm;
+
+ String keyboxIdentifier;
+
+ byte[] signedAttributes;
+
+ String signatureMethod;
+
+ String digestMethod;
+
+ List<HashDataInput> hashDataInput;
+
+ ExcludedByteRangeType excludedByteRange;
+
+ PrivateKey privateKey;
+
+ public BulkSignatureInfo(PrivateKey privateKey, AlgorithmID signatureAlgorithm, String keyboxIdentifier,
+ byte[] signedAttributes, String signatureMethod, String digestMethod, List<HashDataInput> hashDataInput,
+ ExcludedByteRangeType excludedByteRange) {
+ this.privateKey = privateKey;
+ this.signatureAlgorithm = signatureAlgorithm;
+ this.keyboxIdentifier = keyboxIdentifier;
+ this.signedAttributes = signedAttributes;
+ this.signatureMethod = signatureMethod;
+ this.digestMethod = digestMethod;
+ this.hashDataInput = hashDataInput;
+ this.excludedByteRange = excludedByteRange;
+ }
+
+ public String getKeyboxIdentifier() {
+ return keyboxIdentifier;
+ }
+
+ public byte[] getSignedAttributes() {
+ return signedAttributes;
+ }
+
+ public String getSignatureMethod() {
+ return signatureMethod;
+ }
+
+ public String getDigestMethod() {
+ return digestMethod;
+ }
+
+ public List<HashDataInput> getHashDataInput() {
+ return hashDataInput;
+ }
+
+ public ExcludedByteRangeType getExcludedByteRange() {
+ return excludedByteRange;
+ }
+
+ public AlgorithmID getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ public PrivateKey getPrivateKey() {
+ return privateKey;
+ }
+
+
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java
index e51c5823..25162dc4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/CMSHashDataInput.java
@@ -25,6 +25,7 @@
package at.gv.egiz.bku.slcommands.impl.cms;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import at.gv.egiz.bku.gui.viewer.MimeTypes;
@@ -32,18 +33,33 @@ import at.gv.egiz.stal.HashDataInput;
public class CMSHashDataInput implements HashDataInput {
- private final static String DEFAULT_FILENAME = "SignatureData";
+ public final static String DEFAULT_FILENAME = "SignatureData";
private byte[] data;
- private String mimeType;
+ private byte[] digest;
+ protected String mimeType;
+ private String referenceId;
+ private String fileName;
public CMSHashDataInput(byte[] data, String mimeType) {
this.data = data;
this.mimeType = mimeType;
}
+ public CMSHashDataInput(byte[] data, String mimeType, byte[] digest) {
+ this.data = data;
+ this.mimeType = mimeType;
+ }
+
+ public CMSHashDataInput() {
+ }
+
@Override
public String getReferenceId() {
+
+ if (referenceId != null) {
+ return referenceId;
+ }
return CMS_DEF_REFERENCE_ID;
}
@@ -59,11 +75,38 @@ public class CMSHashDataInput implements HashDataInput {
@Override
public String getFilename() {
+ if (fileName != null) {
+ return fileName;
+ }
+
+ if (mimeType != null) {
return DEFAULT_FILENAME + MimeTypes.getExtension(mimeType);
}
+ return DEFAULT_FILENAME;
+ }
+
@Override
- public InputStream getHashDataInput() {
+ public InputStream getHashDataInput() throws IOException {
return new ByteArrayInputStream(data);
}
+
+ @Override
+ public byte[] getDigest() {
+ return digest;
+ }
+
+
+ public void setFilename(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public void setDigest(byte[] digest) {
+ this.digest = digest;
+ }
+
+ public void setReferenceId(String referenceId) {
+ this.referenceId = referenceId;
+ }
+
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/ReferencedHashDataInput.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/ReferencedHashDataInput.java
new file mode 100644
index 00000000..96e0e7de
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/ReferencedHashDataInput.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.ArrayUtils;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+
+public class ReferencedHashDataInput extends CMSHashDataInput {
+
+ private String urlReference;
+ private URLDereferencer urlDereferencer;
+ private ExcludedByteRangeType excludedByteRange;
+
+ public ReferencedHashDataInput(String mimeType, URLDereferencer urlDereferencer, String urlReference, ExcludedByteRangeType excludedByteRange) {
+ super(null, mimeType);
+ this.urlDereferencer = urlDereferencer;
+ this.urlReference = urlReference;
+ this.excludedByteRange = excludedByteRange;
+ }
+
+
+ public URLDereferencer getUrlDereferencer() {
+ return urlDereferencer;
+ }
+
+
+ public void setUrlDereferencer(URLDereferencer urlDereferencer) {
+ this.urlDereferencer = urlDereferencer;
+ }
+
+ public InputStream getHashDataInput() throws IOException {
+
+ InputStream hashDataInputStream = urlDereferencer.dereference(urlReference).getStream();
+
+ try {
+ byte[] content = IOUtils.toByteArray(hashDataInputStream);
+
+ if (excludedByteRange != null) {
+
+ int from = excludedByteRange.getFrom().intValue();
+ int to = excludedByteRange.getTo().intValue();
+
+ byte[] signedContent = ArrayUtils.addAll(ArrayUtils.subarray(content, 0, from), ArrayUtils.subarray(content, to, content.length));
+
+ return new ByteArrayInputStream(signedContent);
+
+ } else {
+ return new ByteArrayInputStream(content);
+ }
+
+ } finally {
+ hashDataInputStream.close();
+ }
+ }
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
index 87c00644..1dd6cc9e 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/STALSecurityProvider.java
@@ -69,8 +69,8 @@ public class STALSecurityProvider extends IaikProvider {
private ExcludedByteRangeType excludedByteRange;
private STALSignatureException stalSignatureException;
- public STALSecurityProvider(STAL stal, String keyboxIdentifier,
- HashDataInput hashDataInput, ExcludedByteRangeType excludedByteRange) {
+ public STALSecurityProvider(STAL stal, String keyboxIdentifier, HashDataInput hashDataInput,
+ ExcludedByteRangeType excludedByteRange) {
this.keyboxIdentifier = keyboxIdentifier;
this.stal = stal;
this.hashDataInput = new ArrayList<HashDataInput>();
@@ -78,23 +78,27 @@ public class STALSecurityProvider extends IaikProvider {
this.excludedByteRange = excludedByteRange;
}
- /* (non-Javadoc)
- * @see iaik.cms.IaikProvider#calculateSignatureFromSignedAttributes(iaik.asn1.structures.AlgorithmID, iaik.asn1.structures.AlgorithmID, java.security.PrivateKey, byte[])
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * iaik.cms.IaikProvider#calculateSignatureFromSignedAttributes(iaik.asn1.
+ * structures.AlgorithmID, iaik.asn1.structures.AlgorithmID,
+ * java.security.PrivateKey, byte[])
*/
@Override
- public byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm,
- AlgorithmID digestAlgorithm, PrivateKey privateKey,
- byte[] signedAttributes)
- throws SignatureException, InvalidKeyException, NoSuchAlgorithmException {
+ public byte[] calculateSignatureFromSignedAttributes(AlgorithmID signatureAlgorithm, AlgorithmID digestAlgorithm,
+ PrivateKey privateKey, byte[] signedAttributes) throws SignatureException, InvalidKeyException,
+ NoSuchAlgorithmException {
+ stalSignatureException = null;
log.debug("calculateSignatureFromSignedAttributes: " + signatureAlgorithm + ", " + digestAlgorithm);
STALPrivateKey spk = (STALPrivateKey) privateKey;
- SignRequest signRequest = getSTALSignRequest(keyboxIdentifier, signedAttributes,
- spk.getAlgorithm(), spk.getDigestAlgorithm(), hashDataInput, excludedByteRange);
+ SignRequest signRequest = getSTALSignRequest(keyboxIdentifier, signedAttributes, spk.getAlgorithm(),
+ spk.getDigestAlgorithm(), hashDataInput, excludedByteRange);
log.debug("Sending STAL request ({})", privateKey.getAlgorithm());
- List<STALResponse> responses =
- stal.handleRequest(Collections.singletonList((STALRequest) signRequest));
+ List<STALResponse> responses = stal.handleRequest(Collections.singletonList((STALRequest) signRequest));
if (responses == null || responses.size() != 1) {
throw new SignatureException("Failed to access STAL.");
@@ -114,9 +118,9 @@ public class STALSecurityProvider extends IaikProvider {
}
}
- private static SignRequest getSTALSignRequest(String keyboxIdentifier,
- byte[] signedAttributes, String signatureMethod, String digestMethod,
- List<HashDataInput> hashDataInput, ExcludedByteRangeType excludedByteRange) {
+ private static SignRequest getSTALSignRequest(String keyboxIdentifier, byte[] signedAttributes,
+ String signatureMethod, String digestMethod, List<HashDataInput> hashDataInput,
+ ExcludedByteRangeType excludedByteRange) {
SignRequest signRequest = new SignRequest();
signRequest.setKeyIdentifier(keyboxIdentifier);
log.debug("SignedAttributes: " + Util.toBase64String(signedAttributes));
@@ -147,8 +151,7 @@ public class STALSecurityProvider extends IaikProvider {
sigS.addComponent(new INTEGER(new BigInteger(1, r)));
sigS.addComponent(new INTEGER(new BigInteger(1, s)));
return DerCoder.encode(sigS);
- }
- else
+ } else
return sig;
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java
index 7be546de..4a94ca7f 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/cms/Signature.java
@@ -24,48 +24,32 @@
package at.gv.egiz.bku.slcommands.impl.cms;
-import iaik.asn1.ASN1Object;
-import iaik.asn1.CodingException;
-import iaik.asn1.ObjectID;
-import iaik.asn1.SEQUENCE;
-import iaik.asn1.UTF8String;
-import iaik.asn1.structures.AlgorithmID;
-import iaik.asn1.structures.Attribute;
-import iaik.asn1.structures.ChoiceOfTime;
-import iaik.cms.CMSException;
-import iaik.cms.CMSSignatureException;
-import iaik.cms.CertificateIdentifier;
-import iaik.cms.ContentInfo;
-import iaik.cms.IssuerAndSerialNumber;
-import iaik.cms.SignedData;
-import iaik.cms.SignerInfo;
-import iaik.smime.ess.ESSCertID;
-import iaik.smime.ess.ESSCertIDv2;
-import iaik.x509.X509ExtensionException;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
-import java.security.PublicKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECParameterSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+import javax.xml.crypto.dsig.DigestMethod;
+
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3._2000._09.xmldsig_.DigestMethodType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectOptionalMetaType;
import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectRequiredMetaType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.DigestAndRefType;
import at.buergerkarte.namespaces.securitylayer._1_2_3.ExcludedByteRangeType;
import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactory;
import at.gv.egiz.bku.slcommands.impl.xsect.AlgorithmMethodFactoryImpl;
@@ -74,6 +58,24 @@ import at.gv.egiz.bku.slexceptions.SLCommandException;
import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
import at.gv.egiz.stal.HashDataInput;
import at.gv.egiz.stal.STAL;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.CodingException;
+import iaik.asn1.ObjectID;
+import iaik.asn1.SEQUENCE;
+import iaik.asn1.UTF8String;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.asn1.structures.Attribute;
+import iaik.asn1.structures.ChoiceOfTime;
+import iaik.cms.CMSException;
+import iaik.cms.CMSSignatureException;
+import iaik.cms.CertificateIdentifier;
+import iaik.cms.ContentInfo;
+import iaik.cms.IssuerAndSerialNumber;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.smime.ess.ESSCertID;
+import iaik.smime.ess.ESSCertIDv2;
+import iaik.x509.X509ExtensionException;
/**
* This class represents a CMS-Signature as to be created by the
@@ -90,25 +92,51 @@ public class Signature {
*/
private final Logger log = LoggerFactory.getLogger(Signature.class);
- private SignedData signedData;
- private SignerInfo signerInfo;
- private byte[] signedDocument;
- private String mimeType;
- private AlgorithmID signatureAlgorithm;
- private AlgorithmID digestAlgorithm;
- private String signatureAlgorithmURI;
- private String digestAlgorithmURI;
- private ExcludedByteRangeType excludedByteRange;
+ protected SignedData signedData;
+ protected SignerInfo signerInfo;
+ protected byte[] signedDocument;
+ protected String mimeType;
+ protected AlgorithmID signatureAlgorithm;
+ protected AlgorithmID digestAlgorithm;
+ protected byte[] digestValue;
+ protected String signatureAlgorithmURI;
+ protected String digestAlgorithmURI;
+ protected ExcludedByteRangeType excludedByteRange;
+ private HashDataInput hashDataInput;
+
- public Signature(CMSDataObjectRequiredMetaType dataObject, String structure,
+public Signature(CMSDataObjectOptionalMetaType dataObject, String structure,
X509Certificate signingCertificate, Date signingTime, URLDereferencer urlDereferencer,
boolean useStrongHash)
throws NoSuchAlgorithmException, CertificateEncodingException,
CertificateException, X509ExtensionException, InvalidParameterException,
- CodingException, SLCommandException, IOException {
- byte[] dataToBeSigned = getContent(dataObject, urlDereferencer);
+ CodingException, SLCommandException, IOException, CMSException {
int mode = structure.equalsIgnoreCase("enveloping") ? SignedData.IMPLICIT : SignedData.EXPLICIT;
+ if (dataObject.getContent() != null) {
+ byte[] dataToBeSigned = getContent(dataObject, urlDereferencer);
this.signedData = new SignedData(dataToBeSigned, mode);
+ if (dataObject.getMetaInfo() != null) {
+ this.mimeType = dataObject.getMetaInfo().getMimeType();
+ }
+
+ hashDataInput = new CMSHashDataInput(signedDocument, mimeType);
+
+ } else {
+ DigestAndRefType digestAndRef = dataObject.getDigestAndRef();
+ DigestMethodType digestMethod = digestAndRef.getDigestMethod();
+
+ hashDataInput = new ReferencedHashDataInput(dataObject.getMetaInfo().getMimeType(), urlDereferencer,
+ digestAndRef.getReference(), dataObject.getExcludedByteRange());
+
+ try {
+ digestAlgorithm = getAlgorithmID(digestMethod.getAlgorithm());
+ } catch (URISyntaxException e) {
+ //TODO: choose proper execption
+ throw new NoSuchAlgorithmException(e);
+ }
+ digestValue = digestAndRef.getDigestValue();
+ this.signedData = new SignedData(ObjectID.pkcs7_data);
+ }
setAlgorithmIDs(signingCertificate, useStrongHash);
createSignerInfo(signingCertificate);
setSignerCertificate(signingCertificate);
@@ -208,7 +236,7 @@ public class Signature {
attributes.add(signingTime);
}
- private byte[] getContent(CMSDataObjectRequiredMetaType dataObject, URLDereferencer urlDereferencer)
+ private byte[] getContent(CMSDataObjectOptionalMetaType dataObject, URLDereferencer urlDereferencer)
throws InvalidParameterException, SLCommandException, IOException {
byte[] data = dataObject.getContent().getBase64Content();
if (data == null) {
@@ -252,63 +280,36 @@ public class Signature {
}
private void setAlgorithmIDs(X509Certificate signingCertificate, boolean useStrongHash) throws NoSuchAlgorithmException {
- PublicKey publicKey = signingCertificate.getPublicKey();
- String algorithm = publicKey.getAlgorithm();
AlgorithmMethodFactory amf = new AlgorithmMethodFactoryImpl(signingCertificate, useStrongHash);
signatureAlgorithmURI = amf.getSignatureAlgorithmURI();
+ signatureAlgorithm = amf.getSignatureAlgorithmID();
+ if (digestAlgorithm != null) {
+ if (AlgorithmID.sha1.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA1;
+ } else if (AlgorithmID.sha256.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA256;
+ } else if (AlgorithmID.sha512.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.SHA512;
+ } else if (AlgorithmID.ripeMd160.equals(digestAlgorithm)) {
+ digestAlgorithmURI = DigestMethod.RIPEMD160;
+ } else {
+ throw new NoSuchAlgorithmException("Algorithm '" + digestAlgorithm + "' not supported.");
+ }
+ } else {
digestAlgorithmURI = amf.getDigestAlgorithmURI();
-
- if ("DSA".equals(algorithm)) {
- signatureAlgorithm = AlgorithmID.dsaWithSHA1;
- } else if ("RSA".equals(algorithm)) {
-
- int keyLength = 0;
- if (publicKey instanceof RSAPublicKey) {
- keyLength = ((RSAPublicKey) publicKey).getModulus().bitLength();
+ digestAlgorithm = amf.getDigestAlgorithmID();
}
-
- if (useStrongHash && keyLength >= 2048) {
- signatureAlgorithm = AlgorithmID.sha256WithRSAEncryption;
- digestAlgorithm = AlgorithmID.sha256;
-// } else if (useStrongHash) { // Cannot be used if not enabled in AlgorithmMethodFactoryImpl
-// signatureAlgorithm = AlgorithmID.rsaSignatureWithRipemd160;
-// digestAlgorithm = AlgorithmID.ripeMd160;
- } else {
- signatureAlgorithm = AlgorithmID.sha1WithRSAEncryption;
- digestAlgorithm = AlgorithmID.sha1;
}
- } else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) {
- int fieldSize = 0;
- if (publicKey instanceof ECPublicKey) {
- ECParameterSpec params = ((ECPublicKey) publicKey).getParams();
- fieldSize = params.getCurve().getField().getFieldSize();
- } else {
- throw new NoSuchAlgorithmException("Public key type not supported.");
- }
+ public HashDataInput getHashDataInput() {
- if (useStrongHash && fieldSize >= 512) {
- signatureAlgorithm = AlgorithmID.ecdsa_With_SHA512;
- digestAlgorithm = AlgorithmID.sha512;
- } else if (useStrongHash && fieldSize >= 256) {
- signatureAlgorithm = AlgorithmID.ecdsa_With_SHA256;
- digestAlgorithm = AlgorithmID.sha256;
- } else if (useStrongHash) {
- signatureAlgorithm = AlgorithmID.ecdsa_plain_With_RIPEMD160;
- digestAlgorithm = AlgorithmID.ripeMd160;
+ if (hashDataInput != null) {
+ return hashDataInput;
} else {
- signatureAlgorithm = AlgorithmID.ecdsa_With_SHA1;
- digestAlgorithm = AlgorithmID.sha1;
- }
- } else {
- throw new NoSuchAlgorithmException("Public key algorithm '" + algorithm
- + "' not supported.");
+ return new CMSHashDataInput(signedDocument, mimeType);
}
}
- private HashDataInput getHashDataInput() {
- return new CMSHashDataInput(signedDocument, mimeType);
- }
public byte[] sign(STAL stal, String keyboxIdentifier) throws CMSException, CMSSignatureException, SLCommandException {
STALSecurityProvider securityProvider = new STALSecurityProvider(stal, keyboxIdentifier, getHashDataInput(), this.excludedByteRange);
@@ -322,7 +323,29 @@ public class Signature {
}
throw new CMSSignatureException(e);
}
+ if (digestValue != null) {
+ try {
+ signedData.setMessageDigest(digestAlgorithm, digestValue);
+ } catch (NoSuchAlgorithmException e) {
+ throw new CMSSignatureException(e);
+ }
+ }
ContentInfo contentInfo = new ContentInfo(signedData);
return contentInfo.getEncoded();
}
+
+ protected AlgorithmID getAlgorithmID(String uri) throws URISyntaxException {
+ String oid = null;
+ URI urn = new URI(uri);
+ String scheme = urn.getScheme();
+ if ("URN".equalsIgnoreCase(scheme)) {
+ String schemeSpecificPart = urn.getSchemeSpecificPart().toLowerCase();
+ if (schemeSpecificPart.startsWith("oid:")) {
+ oid = schemeSpecificPart.substring(4, schemeSpecificPart.length());
+}
+ }
+ return new AlgorithmID(new ObjectID(oid));
+ }
}
+
+
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java
index d2484b56..1b801ec5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactory.java
@@ -32,6 +32,8 @@ import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.SignatureMethod;
+import iaik.asn1.structures.AlgorithmID;
+
/**
* A factory for creating {@link AlgorithmMethod}s.
*
@@ -87,4 +89,8 @@ public interface AlgorithmMethodFactory {
public String getSignatureAlgorithmURI();
public String getDigestAlgorithmURI();
+
+ AlgorithmID getSignatureAlgorithmID();
+
+ AlgorithmID getDigestAlgorithmID();
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
index 896552d8..c3fcd146 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
@@ -24,6 +24,7 @@
package at.gv.egiz.bku.slcommands.impl.xsect;
+import iaik.asn1.structures.AlgorithmID;
import iaik.xml.crypto.XmldsigMore;
import java.security.InvalidAlgorithmParameterException;
@@ -55,11 +56,21 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
private String signatureAlgorithmURI;
/**
+ * The signature algorithm ID.
+ */
+ private AlgorithmID signatureAlgorithmID;
+
+ /**
* the digest algorithm URI.
*/
private String digestAlgorithmURI = DigestMethod.SHA1;
/**
+ * The digest algorithm ID.
+ */
+ private AlgorithmID digestAlgorithmID = AlgorithmID.sha1;
+
+ /**
* The algorithm parameters for the signature algorithm.
*/
private SignatureMethodParameterSpec signatureMethodParameterSpec;
@@ -82,6 +93,7 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
if ("DSA".equals(algorithm)) {
signatureAlgorithmURI = SignatureMethod.DSA_SHA1;
+ signatureAlgorithmID = AlgorithmID.dsaWithSHA1;
} else if ("RSA".equals(algorithm)) {
int keyLength = 0;
@@ -91,12 +103,12 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
if (useStrongHash && keyLength >= 2048) {
signatureAlgorithmURI = XmldsigMore.SIGNATURE_RSA_SHA256;
+ signatureAlgorithmID = AlgorithmID.sha256WithRSAEncryption;
digestAlgorithmURI = DigestMethod.SHA256;
-// } else if (useStrongHash) {
-// signatureAlgorithmURI = XmldsigMore.SIGNATURE_RSA_RIPEMD160_ERRATA;
-// digestAlgorithmURI = DigestMethod.RIPEMD160;
+ digestAlgorithmID = AlgorithmID.sha256;
} else {
signatureAlgorithmURI = SignatureMethod.RSA_SHA1;
+ signatureAlgorithmID = AlgorithmID.sha1WithRSAEncryption;
}
} else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) {
@@ -111,15 +123,22 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
if (useStrongHash && fieldSize >= 512) {
signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA512;
+ signatureAlgorithmID = AlgorithmID.ecdsa_With_SHA512;
digestAlgorithmURI = DigestMethod.SHA512;
+ digestAlgorithmID = AlgorithmID.sha512;
} else if (useStrongHash && fieldSize >= 256) {
signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA256;
+ signatureAlgorithmID = AlgorithmID.ecdsa_With_SHA256;
digestAlgorithmURI = DigestMethod.SHA256;
+ digestAlgorithmID = AlgorithmID.sha256;
} else if (useStrongHash) {
signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_RIPEMD160;
+ signatureAlgorithmID = AlgorithmID.ecdsa_plain_With_RIPEMD160;
digestAlgorithmURI = DigestMethod.RIPEMD160;
+ digestAlgorithmID = AlgorithmID.ripeMd160;
} else {
signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA1;
+ signatureAlgorithmID = AlgorithmID.ecdsa_With_SHA1;
}
} else {
@@ -185,4 +204,14 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
return digestAlgorithmURI;
}
+ @Override
+ public AlgorithmID getSignatureAlgorithmID() {
+ return signatureAlgorithmID;
+ }
+
+ @Override
+ public AlgorithmID getDigestAlgorithmID() {
+ return digestAlgorithmID;
+ }
+
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/URLDereferencerFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/URLDereferencerFactoryBean.java
new file mode 100644
index 00000000..1a95a146
--- /dev/null
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/URLDereferencerFactoryBean.java
@@ -0,0 +1,75 @@
+package at.gv.egiz.bku.spring;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.commons.configuration.Configuration;
+import org.springframework.beans.factory.FactoryBean;
+
+import at.gv.egiz.bku.conf.MoccaConfigurationFacade;
+import at.gv.egiz.bku.utils.urldereferencer.FileURLProtocolHandlerImpl;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerImpl;
+
+public class URLDereferencerFactoryBean implements FactoryBean {
+
+ private HostnameVerifier hostnameVerifier;
+ private SSLSocketFactory sslSocketFactory;
+
+ protected final ConfigurationFacade configurationFacade = new ConfigurationFacade();
+
+ public class ConfigurationFacade implements MoccaConfigurationFacade {
+
+ private Configuration configuration;
+ public static final String ENABLE_FILEURIS = "enableFileURIs";
+
+ public boolean isEnableFileURIs() {
+ return configuration.getBoolean(ENABLE_FILEURIS, false);
+ }
+
+ }
+
+ public void setConfiguration(Configuration configuration) {
+ configurationFacade.configuration = configuration;
+ }
+
+ @Override
+ public Object getObject() throws Exception {
+
+ URLDereferencerImpl urlDereferencer = URLDereferencerImpl.getInstance();
+ urlDereferencer.setHostnameVerifier(hostnameVerifier);
+ urlDereferencer.setSSLSocketFactory(sslSocketFactory);
+
+ if(!configurationFacade.isEnableFileURIs()) {
+ urlDereferencer.registerHandler(FileURLProtocolHandlerImpl.FILE, new FileURLProtocolHandlerImpl());
+ }
+
+ return urlDereferencer;
+ }
+
+ @Override
+ public Class<URLDereferencerImpl> getObjectType() {
+ return URLDereferencerImpl.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public HostnameVerifier getHostnameVerifier() {
+ return hostnameVerifier;
+ }
+
+ public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+ this.hostnameVerifier = hostnameVerifier;
+ }
+
+ public SSLSocketFactory getSslSocketFactory() {
+ return sslSocketFactory;
+ }
+
+ public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
+ this.sslSocketFactory = sslSocketFactory;
+ }
+
+}
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
index de54e9b2..92955fc9 100644
--- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
@@ -108,3 +108,6 @@ ec4011.notimplemented=Befehl {0} ist nicht implementiert.
lec2901.notimplemented=Die in der Anfrage verwendete Version des Security-Layer Protokolls ({0}) wird nicht mehr unterstützt.
+# custom error messages for bulk signature
+ec4124= XML Signatur Requests werden aktuell in der Stapelsignatur nicht unterstützt.
+
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
index 471f4a13..4d90f71c 100644
--- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
@@ -106,3 +106,5 @@ ec4011.notimplemented=Command {0} not implemented.
# Legacy error codes
#
lec2901.notimplemented=The version ({0}) of the security-layer protocol used in the request is not supported.
+# custom error messages for bulk signature
+ec4124= XML signature requests are currently not supported in bulk signature requests.
diff --git a/bkucommon/src/site/apt/configuration.apt b/bkucommon/src/site/apt/configuration.apt
index ec6b7cd0..2aca5dc7 100644
--- a/bkucommon/src/site/apt/configuration.apt
+++ b/bkucommon/src/site/apt/configuration.apt
@@ -54,6 +54,10 @@ MOCCA Configuration
Default: <<<true>>>
+ [<<<enableFileURIs>>>] Whether to allow dereferencing of "file" URIs.
+
+ Default: <<<false>>>
+
[<<<SSL>>>]
The following two configuration elements must provide an URL which resolves to a directory in the file system. It may either be an absolute URL or a relative URL, which is resolved using the URL of the configuration file.
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImplTest.java
new file mode 100644
index 00000000..b91bec98
--- /dev/null
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/BulkCommandImplTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2015 Datentechnik Innovation and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.slcommands.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import iaik.asn1.ObjectID;
+import iaik.cms.SignedData;
+import iaik.xml.crypto.XSecProvider;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.BulkResponseType;
+import at.gv.egiz.bku.slcommands.BulkCommand;
+import at.gv.egiz.bku.slcommands.BulkSignatureResult;
+import at.gv.egiz.bku.slcommands.SLCommand;
+import at.gv.egiz.bku.slcommands.SLCommandContext;
+import at.gv.egiz.bku.slcommands.SLCommandFactory;
+import at.gv.egiz.bku.slcommands.SLResult;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.stal.STAL;
+import at.gv.egiz.stal.STALFactory;
+
+public class BulkCommandImplTest {
+
+ protected static ApplicationContext appCtx;
+ private SLCommandFactory factory;
+
+ private STAL stal;
+
+ private URLDereferencer urlDereferencer;
+
+ @BeforeClass
+ public static void setUpClass() {
+ appCtx = new ClassPathXmlApplicationContext("at/gv/egiz/bku/slcommands/testApplicationContext.xml");
+ XSecProvider.addAsProvider(true);
+ }
+
+ @Before
+ public void setUp() throws JAXBException {
+
+ Object bean = appCtx.getBean("slCommandFactory");
+ assertTrue(bean instanceof SLCommandFactory);
+
+ factory = (SLCommandFactory) bean;
+
+ bean = appCtx.getBean("stalFactory");
+ assertTrue(bean instanceof STALFactory);
+
+ stal = ((STALFactory) bean).createSTAL();
+
+ bean = appCtx.getBean("urlDereferencer");
+ assertTrue(bean instanceof URLDereferencer);
+
+ urlDereferencer = (URLDereferencer) bean;
+
+ }
+
+ @Test
+ public void testCreateCMSSignatureRequest() throws Exception {
+ InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
+ "at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequest.xml");
+ assertNotNull(inputStream);
+
+ SLCommand command = factory.createSLCommand(new StreamSource(new InputStreamReader(inputStream)));
+ assertTrue(command instanceof BulkCommand);
+
+ SLCommandContext context = new SLCommandContext(stal, urlDereferencer, null);
+ SLResult result = command.execute(context);
+
+ assertTrue(result instanceof BulkSignatureResult);
+
+ BulkSignatureResult bulkResult = (BulkSignatureResult) result;
+ System.out.println(bulkResult.getContent());
+
+ bulkResult.getContent();
+
+ // unmarshall response
+ Unmarshaller unmarshaller = factory.getJaxbContext().createUnmarshaller();
+
+ BulkResponseType response = unmarshaller.unmarshal(bulkResult.getContent(), BulkResponseType.class).getValue();
+
+ // verify ContentType of singature
+ byte[] cmsSignature = response.getCreateSignatureResponse().get(0).getCreateCMSSignatureResponse()
+ .getCMSSignature();
+ SignedData signedData = new SignedData(new ByteArrayInputStream(cmsSignature));
+
+ assertNotNull(signedData);
+ assertEquals(ObjectID.pkcs7_signedData, signedData.getContentType());
+ assertNotNull(response.getCreateSignatureResponse());
+ assertEquals(2, response.getCreateSignatureResponse().size());
+
+ result.writeTo(new StreamResult(System.out), false);
+
+ }
+
+}
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImplTest.java
index b1ec7777..09b70f09 100644
--- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImplTest.java
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateCMSSignatureCommandImplTest.java
@@ -24,13 +24,21 @@
package at.gv.egiz.bku.slcommands.impl;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import iaik.asn1.ObjectID;
+import iaik.cms.CMSParsingException;
+import iaik.cms.SignedData;
import iaik.xml.crypto.XSecProvider;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
@@ -40,7 +48,9 @@ import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CreateCMSSignatureResponseType;
import at.gv.egiz.bku.slcommands.CreateCMSSignatureCommand;
+import at.gv.egiz.bku.slcommands.CreateCMSSignatureResult;
import at.gv.egiz.bku.slcommands.SLCommand;
import at.gv.egiz.bku.slcommands.SLCommandContext;
import at.gv.egiz.bku.slcommands.SLCommandFactory;
@@ -89,8 +99,11 @@ public class CreateCMSSignatureCommandImplTest {
}
@Test
- public void testCreateCMSSignatureRequest() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException {
- InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/createcmssignaturerequest/CreateCMSSignatureRequest.xml");
+ public void testCreateCMSSignatureRequest() throws SLCommandException, SLRuntimeException, SLRequestException,
+ SLVersionException, JAXBException, CMSParsingException, IOException {
+
+ InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
+ "at/gv/egiz/bku/slcommands/createcmssignaturerequest/CreateCMSSignatureRequest.xml");
assertNotNull(inputStream);
SLCommand command = factory.createSLCommand(new StreamSource(new InputStreamReader(inputStream)));
@@ -98,6 +111,22 @@ public class CreateCMSSignatureCommandImplTest {
SLCommandContext context = new SLCommandContext(stal, urlDereferencer, null);
SLResult result = command.execute(context);
+
+ assertTrue(result instanceof CreateCMSSignatureResult);
+ CreateCMSSignatureResult sigResult = (CreateCMSSignatureResult) result;
+
+ //unmarshall response
+ Unmarshaller unmarshaller = factory.getJaxbContext().createUnmarshaller();
+
+ CreateCMSSignatureResponseType response = unmarshaller.unmarshal(sigResult.getContent(), CreateCMSSignatureResponseType.class).getValue();
+
+ //verify ContentType of singature
+ byte[] cmsSignature = response.getCMSSignature();
+ SignedData signedData = new SignedData(new ByteArrayInputStream(cmsSignature));
+
+ assertNotNull(signedData);
+ assertEquals(ObjectID.pkcs7_signedData, signedData.getContentType());
+
result.writeTo(new StreamResult(System.out), false);
}
}
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/cms/SignatureTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/cms/SignatureTest.java
new file mode 100644
index 00000000..56229b83
--- /dev/null
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/cms/SignatureTest.java
@@ -0,0 +1,130 @@
+package at.gv.egiz.bku.slcommands.impl.cms;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.util.Date;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3._2000._09.xmldsig_.DigestMethodType;
+
+import at.buergerkarte.namespaces.securitylayer._1_2_3.Base64OptRefContentType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.CMSDataObjectRequiredMetaType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.DigestAndRefType;
+import at.buergerkarte.namespaces.securitylayer._1_2_3.MetaInfoType;
+import at.gv.egiz.stal.dummy.DummySTAL;
+import iaik.asn1.ObjectID;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.cms.InvalidSignatureValueException;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.security.ecc.provider.ECCProvider;
+import iaik.security.provider.IAIK;
+import iaik.x509.X509Certificate;
+
+public class SignatureTest {
+
+ private DummySTAL stal = new DummySTAL();
+
+ @BeforeClass
+ public static void setUpClass() {
+ IAIK.addAsProvider();
+ ECCProvider.addAsProvider();
+ }
+
+ @Test
+ public void testSignCMSDataObject() throws Exception {
+
+ byte[] plaintext = "Plaintext".getBytes(Charset.forName("UTF-8"));
+
+ CMSDataObjectRequiredMetaType dataObject = new CMSDataObjectRequiredMetaType();
+ Base64OptRefContentType base64OptRefContentType = new Base64OptRefContentType();
+ base64OptRefContentType.setBase64Content(plaintext);
+ dataObject.setContent(base64OptRefContentType);
+ MetaInfoType metaInfoType = new MetaInfoType();
+ metaInfoType.setMimeType("text/plain");
+ dataObject.setMetaInfo(metaInfoType);
+
+ Signature signature = new Signature(dataObject, "detached", stal.getCert(), new Date(), null, true);
+ byte[] cmsSignature = signature.sign(stal, "SecureSignatureKeypair");
+
+ SignedData signedData = new SignedData(new ByteArrayInputStream(cmsSignature));
+ signedData.setContent(plaintext);
+ assertEquals(ObjectID.pkcs7_data, signedData.getEncapsulatedContentType());
+ SignerInfo[] signerInfos = signedData.getSignerInfos();
+ assertEquals(1, signerInfos.length);
+ SignerInfo signerInfo = signerInfos[0];
+ signedData.verify((X509Certificate) stal.getCert());
+ assertEquals(AlgorithmID.sha1, signerInfo.getDigestAlgorithm());
+ assertEquals(AlgorithmID.sha1WithRSAEncryption, signerInfo.getSignatureAlgorithm());
+
+ System.out.println(AlgorithmID.sha1);
+
+ }
+
+ @Test
+ public void testSignCMSReferenceSha1() throws Exception {
+ testSignCMSReference(AlgorithmID.sha1);
+ }
+
+ //TODO Why doesn't it work this way??
+ @Test(expected = InvalidSignatureValueException.class)
+ public void testSignCMSReferenceSha256() throws Exception {
+ testSignCMSReference(AlgorithmID.sha256);
+ }
+
+ private void testSignCMSReference(AlgorithmID digestAlgorithmID) throws Exception {
+
+ byte[] plaintext = "Plaintext".getBytes(Charset.forName("UTF-8"));
+
+ MessageDigest messageDigest = MessageDigest.getInstance(digestAlgorithmID.getImplementationName());
+ byte[] digestValue = messageDigest.digest(plaintext);
+
+ CMSDataObjectRequiredMetaType dataObject = new CMSDataObjectRequiredMetaType();
+ DigestAndRefType digestAndRefType = new DigestAndRefType();
+ DigestMethodType digestMethodType = new DigestMethodType();
+ digestMethodType.setAlgorithm("URN:OID:" + digestAlgorithmID.getAlgorithm().getID());
+ digestAndRefType.setDigestMethod(digestMethodType);
+ digestAndRefType.setDigestValue(digestValue);
+ dataObject.setDigestAndRef(digestAndRefType);
+ MetaInfoType metaInfoType = new MetaInfoType();
+ metaInfoType.setMimeType("text/plain");
+ dataObject.setMetaInfo(metaInfoType);
+
+ Signature signature = new Signature(dataObject, "detached", stal.getCert(), new Date(), null, true);
+ byte[] cmsSignature = signature.sign(stal, "SecureSignatureKeypair");
+
+ SignedData signedData = new SignedData(new ByteArrayInputStream(cmsSignature));
+ signedData.setContent(plaintext);
+ assertEquals(ObjectID.pkcs7_data, signedData.getEncapsulatedContentType());
+ SignerInfo[] signerInfos = signedData.getSignerInfos();
+ assertEquals(1, signerInfos.length);
+ SignerInfo signerInfo = signerInfos[0];
+ signedData.verify((X509Certificate) stal.getCert());
+ assertEquals(digestAlgorithmID, signerInfo.getDigestAlgorithm());
+ assertEquals(AlgorithmID.sha1WithRSAEncryption, signerInfo.getSignatureAlgorithm());
+
+ }
+
+ @Test
+ public void test() throws URISyntaxException {
+
+ String oid = null;
+ URI uri = new URI("URN:OID:1.3.14.3.2.26");
+ String scheme = uri.getScheme();
+ if ("URN".equalsIgnoreCase(scheme)) {
+ String schemeSpecificPart = uri.getSchemeSpecificPart().toLowerCase();
+ if (schemeSpecificPart.startsWith("oid:")) {
+ oid = schemeSpecificPart.substring(4, schemeSpecificPart.length());
+ }
+ }
+ assertEquals("1.3.14.3.2.26", oid);
+
+ }
+
+}
diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java
index 6e5612f6..04cf3552 100644
--- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java
+++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java
@@ -27,7 +27,7 @@ package at.gv.egiz.bku.slcommands.impl.xsect;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-
+import iaik.asn1.structures.AlgorithmID;
import iaik.xml.crypto.XSecProvider;
import java.io.IOException;
@@ -140,6 +140,16 @@ public class SignatureTest {
return DigestMethod.SHA1;
}
+ @Override
+ public AlgorithmID getSignatureAlgorithmID() {
+ return null;
+ }
+
+ @Override
+ public AlgorithmID getDigestAlgorithmID() {
+ return null;
+ }
+
}
private static final String RESOURCE_PREFIX = "at/gv/egiz/bku/slcommands/impl/";
diff --git a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java
index 61d0d480..0f054cf0 100644
--- a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java
+++ b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java
@@ -36,9 +36,13 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import javax.xml.crypto.dsig.SignatureMethod;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.stal.BulkSignRequest;
+import at.gv.egiz.stal.BulkSignResponse;
import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.InfoboxReadRequest;
import at.gv.egiz.stal.InfoboxReadResponse;
@@ -47,6 +51,7 @@ 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 iaik.xml.crypto.XmldsigMore;
public class DummySTAL implements STAL {
@@ -58,11 +63,9 @@ public class DummySTAL implements STAL {
public DummySTAL() {
try {
KeyStore ks = KeyStore.getInstance("pkcs12");
- InputStream ksStream = getClass().getClassLoader().getResourceAsStream(
- "at/gv/egiz/bku/slcommands/impl/Cert.p12");
+ InputStream ksStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/impl/Cert.p12");
ks.load(ksStream, "1622".toCharArray());
- for (Enumeration<String> aliases = ks.aliases(); aliases
- .hasMoreElements();) {
+ for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) {
String alias = aliases.nextElement();
log.debug("Found alias " + alias + " in keystore");
if (ks.isKeyEntry(alias)) {
@@ -78,25 +81,28 @@ public class DummySTAL implements STAL {
}
+ public X509Certificate getCert() {
+ return cert;
+ }
+
@Override
public List<STALResponse> handleRequest(List<? extends STALRequest> requestList) {
List<STALResponse> responses = new ArrayList<STALResponse>();
for (STALRequest request : requestList) {
- log.debug("Got STALRequest " + request + ".");
+ log.info("Got STALRequest " + request + ".");
if (request instanceof InfoboxReadRequest) {
- String infoboxIdentifier = ((InfoboxReadRequest) request)
- .getInfoboxIdentifier();
+ String infoboxIdentifier = ((InfoboxReadRequest) request).getInfoboxIdentifier();
InputStream stream = getClass().getClassLoader().getResourceAsStream(
"at/gv/egiz/stal/dummy/infoboxes4/" + infoboxIdentifier + ".bin");
STALResponse response;
if (stream != null) {
- log.debug("Infobox " + infoboxIdentifier + " found.");
+ log.info("Infobox " + infoboxIdentifier + " found.");
byte[] infobox;
try {
@@ -114,7 +120,8 @@ public class DummySTAL implements STAL {
infoboxReadResponse.setInfoboxValue(infobox);
response = infoboxReadResponse;
- } else if ((infoboxIdentifier.equals("SecureSignatureKeypair")) ||(infoboxIdentifier.equals("CertifiedKeypair"))) {
+ } else if ((infoboxIdentifier.equals("SecureSignatureKeypair"))
+ || (infoboxIdentifier.equals("CertifiedKeypair"))) {
try {
InfoboxReadResponse infoboxReadResponse = new InfoboxReadResponse();
infoboxReadResponse.setInfoboxValue(cert.getEncoded());
@@ -135,7 +142,13 @@ public class DummySTAL implements STAL {
try {
SignRequest signReq = (SignRequest) request;
- Signature s = Signature.getInstance("SHA1withRSA");
+ String signatureMethod = ((SignRequest) request).getSignatureMethod();
+ Signature s = null;
+ if (SignatureMethod.RSA_SHA1.equals(signatureMethod)) {
+ s = Signature.getInstance("SHA1withRSA");
+ } else if (XmldsigMore.SIGNATURE_RSA_SHA256.equals(signatureMethod)) {
+ s = Signature.getInstance("SHA256withRSA");
+ }
s.initSign(privateKey);
s.update(signReq.getSignedInfo().getValue());
byte[] sigVal = s.sign();
@@ -147,7 +160,37 @@ public class DummySTAL implements STAL {
responses.add(new ErrorResponse());
}
- } else {
+ }
+
+ //dummy handler for BulkSignRequest
+ else if (request instanceof BulkSignRequest) {
+
+ try {
+ BulkSignRequest bulkSignReq = (BulkSignRequest) request;
+
+ BulkSignResponse bulkSignResp = new BulkSignResponse();
+
+ for (int i = 0; i < bulkSignReq.getSignRequests().size(); i++) {
+
+ Signature s = Signature.getInstance("SHA1withRSA");
+ s.initSign(privateKey);
+ s.update(bulkSignReq.getSignRequests().get(i).getSignedInfo().getValue());
+ byte[] sigVal = s.sign();
+ SignResponse resp = new SignResponse();
+ resp.setSignatureValue(sigVal);
+ bulkSignResp.getSignResponse().add(resp);
+ }
+
+ responses.add(bulkSignResp);
+
+ } catch (Exception e) {
+ log.error("Failed to create signature.", e);
+ responses.add(new ErrorResponse());
+ }
+
+ }
+
+ else {
log.debug("Request not implemented.");
diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequest.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequest.xml
new file mode 100644
index 00000000..7fa39f57
--- /dev/null
+++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:BulkRequest
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" >
+ <sl:CreateSignatureRequest displayName="Urlaubsantrag &quot;Rössler&quot;">
+ <sl:CreateCMSSignatureRequest Structure="detached">
+ <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
+ <sl:DataObject>
+ <sl:MetaInfo>
+ <sl:MimeType>text/plain</sl:MimeType>
+ </sl:MetaInfo>
+ <sl:Content Reference="">
+ <sl:Base64Content>QW5kIG5vdyB0byBzb21ldGhpbmcgY29tcGxldGx5IGRpZmZlcmVudA==
+ </sl:Base64Content>
+ </sl:Content>
+ </sl:DataObject>
+ </sl:CreateCMSSignatureRequest>
+ </sl:CreateSignatureRequest>
+ <sl:CreateSignatureRequest displayName="Krankmeldung &quot;Meyer&quot;">
+ <sl:CreateCMSSignatureRequest
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#"
+ Structure="detached">
+ <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
+ <sl:DataObject>
+ <sl:MetaInfo>
+ <sl:MimeType>text/plain</sl:MimeType>
+ </sl:MetaInfo>
+ <sl:Content Reference="">
+ <sl:Base64Content>Vm9uIGRlciBTaWduYXR1ciB1bXNjaGxvc3NlbmUgRGF0ZW4u
+ </sl:Base64Content>
+ </sl:Content>
+ </sl:DataObject>
+ </sl:CreateCMSSignatureRequest>
+ </sl:CreateSignatureRequest>
+</sl:BulkRequest> \ No newline at end of file
diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequestWithReference.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequestWithReference.xml
new file mode 100644
index 00000000..a506d50c
--- /dev/null
+++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/bulksignaturerequest/BulkSignatureRequestWithReference.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sl:BulkRequest
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#"
+ xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" >
+ <sl:CreateSignatureRequest displayName="Urlaubsantrag &quot;Rössler&quot;">
+ <sl:CreateCMSSignatureRequest
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#"
+ Structure="detached">
+ <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
+ <sl:ReferenceObject>
+ <sl:MetaInfo>
+ <sl:MimeType>text/plain</sl:MimeType>
+ </sl:MetaInfo>
+ <sl:DigestAndRef>
+ <dsig:DigestMethod Algorithm="urn:oid:1.3.14.3.2.26"/>
+ <dsig:DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</dsig:DigestValue>
+ </sl:DigestAndRef>
+ </sl:ReferenceObject>
+ </sl:CreateCMSSignatureRequest>
+ </sl:CreateSignatureRequest>
+ <sl:CreateSignatureRequest displayName="Krankmeldung &quot;Meyer&quot;">
+ <sl:CreateCMSSignatureRequest
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#"
+ Structure="detached">
+ <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
+ <sl:ReferenceObject>
+ <sl:MetaInfo>
+ <sl:MimeType>text/plain</sl:MimeType>heis
+ </sl:MetaInfo>
+ <sl:DigestAndRef>
+ <dsig:DigestMethod Algorithm="urn:oid:1.3.14.3.2.26"/>
+ <dsig:DigestValue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</dsig:DigestValue>
+ </sl:DigestAndRef>
+ </sl:ReferenceObject>
+ </sl:CreateCMSSignatureRequest>
+ </sl:CreateSignatureRequest>
+</sl:BulkRequest> \ No newline at end of file
diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/testApplicationContext.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/testApplicationContext.xml
index fffabb47..9a76291c 100644
--- a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/testApplicationContext.xml
+++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/testApplicationContext.xml
@@ -119,6 +119,14 @@
value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
<constructor-arg value="CreateCMSSignatureRequest" />
</bean>
+ <bean id="bulkCommandFactory"
+ class="at.gv.egiz.bku.slcommands.impl.BulkCommandFactory"
+ parent="abstractCommandFactory" />
+ <bean id="bulkRequest" class="javax.xml.namespace.QName">
+ <constructor-arg
+ value="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" />
+ <constructor-arg value="BulkRequest"/>
+ </bean>
<bean id="getStatusCommandFactory" class="at.gv.egiz.bku.slcommands.impl.GetStatusCommandFactory"
parent="abstractCommandFactory" />
<bean id="getStatusRequest" class="javax.xml.namespace.QName">
@@ -136,6 +144,7 @@
<entry key-ref="infoboxUpdateRequest" value-ref="infoboxUpdateCommandFactory" />
<entry key-ref="createXMLSignatureRequest" value-ref="createXMLSignatureCommandFactory" />
<entry key-ref="createCMSSignatureRequest" value-ref="createCMSSignatureCommandFactory" />
+ <entry key-ref="bulkRequest" value-ref="bulkCommandFactory" />
<entry key-ref="getStatusRequest" value-ref="getStatusCommandFactory" />
</map>
</property>
diff --git a/pom.xml b/pom.xml
index 06653e87..325493ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -481,12 +481,6 @@
<version>2.3.1</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>javax.activation</groupId>
- <artifactId>activation</artifactId>
- <version>${activation.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
@@ -499,12 +493,6 @@
<version>${jaxb.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>${jaxb.version}</version>
- <scope>test</scope>
- </dependency>
</dependencies>
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/BulkSignException.java b/smcc/src/main/java/at/gv/egiz/smcc/BulkSignException.java
new file mode 100644
index 00000000..6acfd6c9
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/BulkSignException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+/**
+ * @author szoescher szoescher
+ */
+package at.gv.egiz.smcc;
+
+public class BulkSignException extends SignatureCardException {
+
+ private static final long serialVersionUID = 1L;
+
+ public BulkSignException() {
+ super();
+ }
+
+ public BulkSignException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BulkSignException(String message) {
+ super(message);
+ }
+
+ public BulkSignException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/OverrulePinpadPINGUI.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/OverrulePinpadPINGUI.java
new file mode 100644
index 00000000..3cfc7d98
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/OverrulePinpadPINGUI.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.smcc.pin.gui;
+
+public interface OverrulePinpadPINGUI extends PINGUI {
+
+ boolean allowOverrulePinpad() throws InterruptedException;
+
+}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java
index b740c0ad..4e7d72f2 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/pin/gui/PINProvider.java
@@ -24,6 +24,7 @@
package at.gv.egiz.smcc.pin.gui;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
@@ -52,8 +53,9 @@ public interface PINProvider {
* @return pin != null
* @throws at.gv.egiz.smcc.CancelledException
* @throws java.lang.InterruptedException
+ * @throws BulkSignException
*/
char[] providePIN(PinInfo pinSpec, int retries)
- throws CancelledException, InterruptedException;
+ throws CancelledException, InterruptedException, BulkSignException;
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
index 48331278..45b70ca6 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java
@@ -49,6 +49,7 @@ import at.gv.egiz.smcc.SignatureCardException;
import at.gv.egiz.smcc.TimeoutException;
import at.gv.egiz.smcc.VerifyAPDUSpec;
import at.gv.egiz.smcc.pin.gui.ModifyPINGUI;
+import at.gv.egiz.smcc.pin.gui.OverrulePinpadPINGUI;
import at.gv.egiz.smcc.pin.gui.PINGUI;
import at.gv.egiz.smcc.util.SMCCHelper;
@@ -597,6 +598,15 @@ public class PinpadCardReader extends DefaultCardReader {
byte[] s = createPINVerifyStructure(apduSpec, pinSpec);
Card icc = channel.getCard();
+ if (pinGUI instanceof OverrulePinpadPINGUI && (VERIFY || VERIFY_DIRECT)) {
+ if (((OverrulePinpadPINGUI) pinGUI).allowOverrulePinpad()) {
+ return super.verify(channel, apduSpec, pinGUI, pinSpec, retries);
+ } else {
+ log.debug("The User prohibited deactivation of the pinPad.");
+ throw new CancelledException();
+ }
+ }
+
if (VERIFY) {
boolean regain = dropExclusive(icc);
try {
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/card/CreateSignature.java b/smcc/src/test/java/at/gv/egiz/smcc/card/CreateSignature.java
index 5acc7e10..a2204bb7 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/card/CreateSignature.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/card/CreateSignature.java
@@ -35,6 +35,7 @@ import java.nio.charset.Charset;
import java.util.Formatter;
import java.util.Locale;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
import at.gv.egiz.smcc.SignatureCard;
@@ -96,7 +97,7 @@ public class CreateSignature {
@Override
public char[] providePIN(PinInfo pinSpec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
System.out.print("Enter " + pinSpec.getLocalizedName() + ": ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String pin;
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java
index 281ef7b2..35dbafa8 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/CancelPINProvider.java
@@ -24,6 +24,7 @@
package at.gv.egiz.smcc.pin.gui;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
@@ -31,7 +32,7 @@ public class CancelPINProvider extends DummyPINGUI implements PINGUI {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
throw new CancelledException("cancelled by cancelPINProvider");
}
} \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java
index 184cabc5..9eaa2945 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InterruptPINProvider.java
@@ -24,6 +24,7 @@
package at.gv.egiz.smcc.pin.gui;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
@@ -34,7 +35,7 @@ public class InterruptPINProvider extends DummyPINGUI implements PINGUI {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
throw new InterruptedException("interrupted by cancelPINProvider");
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java
index 22f155de..ab2f646b 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/InvalidPINProvider.java
@@ -24,6 +24,7 @@
package at.gv.egiz.smcc.pin.gui;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
@@ -41,7 +42,7 @@ public class InvalidPINProvider extends DummyPINGUI implements PINGUI {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
if (provided >= numWrongTries) {
throw new CancelledException("Number of wrong tries reached: " + provided);
} else {
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java
index 05bbc9df..05e18d90 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/pin/gui/SMCCTestPINProvider.java
@@ -24,6 +24,7 @@
package at.gv.egiz.smcc.pin.gui;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
@@ -38,7 +39,7 @@ public class SMCCTestPINProvider extends DummyPINGUI implements PINGUI {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
provided++;
return pin;
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/test/AbstractCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/test/AbstractCardTest.java
index f6faafe6..5012f34d 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/test/AbstractCardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/test/AbstractCardTest.java
@@ -36,6 +36,7 @@ import java.security.NoSuchAlgorithmException;
import org.junit.Test;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.CardNotSupportedException;
import at.gv.egiz.smcc.LockedException;
@@ -176,7 +177,7 @@ public abstract class AbstractCardTest extends AbstractCardTestBase {
PINGUI pinProvider = new DummyPINGUI() {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
try {
signatureCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR, null);
@@ -201,7 +202,7 @@ public abstract class AbstractCardTest extends AbstractCardTestBase {
PINGUI pinProvider = new DummyPINGUI() {
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
try {
signatureCard.getCertificate(KeyboxName.CERTIFIED_KEYPAIR, null);
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/test/ecard/ECardG3InfoboxContainerTest.java b/smcc/src/test/java/at/gv/egiz/smcc/test/ecard/ECardG3InfoboxContainerTest.java
index 9351fa21..a625168e 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/test/ecard/ECardG3InfoboxContainerTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/test/ecard/ECardG3InfoboxContainerTest.java
@@ -29,6 +29,7 @@ import static org.junit.Assert.*;
import org.junit.Test;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
import at.gv.egiz.smcc.SignatureCardException;
@@ -44,7 +45,7 @@ public class ECardG3InfoboxContainerTest extends AbstractCardTestBase {
PINGUI pinProvider = new DummyPINGUI() {
@Override
public char[] providePIN(PinInfo pinSpec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
// must not require a PIN!
fail();
return null;
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/BulkSignPINGUI.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/BulkSignPINGUI.java
new file mode 100644
index 00000000..b792fed2
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/BulkSignPINGUI.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.pin.gui;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
+import at.gv.egiz.smcc.BulkSignException;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.PinInfo;
+import at.gv.egiz.smcc.pin.gui.OverrulePinpadPINGUI;
+import at.gv.egiz.stal.SignatureInfo;
+
+import java.security.DigestException;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This PinProvider is used for BulkSignatureRequests.
+ * The pin input field is called once and the pin is stored for further sign requests.
+ *
+ *
+ * @author szoescher
+ */
+public class BulkSignPINGUI extends SignPINGUI implements OverrulePinpadPINGUI {
+
+ private final Logger log = LoggerFactory.getLogger(BulkSignPINGUI.class);
+
+ private boolean retry = false;
+
+ private char[] pin;
+
+ private boolean showSignaturePINDialog;
+
+ private int maxSignatures;
+
+ private int signatureCount;
+
+ List<SignatureInfo> signedInfo;
+
+
+
+ public BulkSignPINGUI(BKUGUIFacade gui, SecureViewer viewer, List<SignatureInfo> signedInfo, int maxSignatures) {
+ super(gui, viewer, null);
+
+ this.signedInfo = signedInfo;
+ this.maxSignatures = maxSignatures;
+
+ showSignaturePINDialog = true;
+ signatureCount = 0;
+ }
+
+ public int getSignatureCount() {
+ return signatureCount;
+ }
+
+ public boolean isShowSignaturePINDialog() {
+ return showSignaturePINDialog;
+ }
+
+ public void setShowSignaturePINDialog(boolean showSignaturePINDialog) {
+ this.showSignaturePINDialog = showSignaturePINDialog;
+ }
+
+
+
+ @Override
+ public char[] providePIN(PinInfo spec, int retries) throws CancelledException, InterruptedException, BulkSignException {
+
+ if (showSignaturePINDialog) {
+
+ signatureCount = 1;
+ gui.showSignaturePINDialog(spec, (retry) ? retries : -1, maxSignatures, this, "sign", this, "cancel", this, "secureViewer");
+
+ do {
+ log.trace("[{}] wait for action.", Thread.currentThread().getName());
+ waitForAction();
+ log.trace("[{}] received action {}.", Thread.currentThread().getName(), action);
+
+ if ("secureViewer".equals(action)) {
+ try {
+
+ viewer.displayDataToBeSigned(signedInfo, this, "pinEntry");
+
+ } catch (DigestException ex) {
+ log.error("Bad digest value: {}", ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH, new Object[] { ex.getMessage() }, this, "error");
+ } catch (Exception ex) {
+ log.error("Could not display hashdata inputs: {}", ex.getMessage());
+ gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA, new Object[] { ex.getMessage() }, this, "error");
+ }
+ } else if ("sign".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_BULKSIGNATURE, BKUGUIFacade.MESSAGE_BULKSIGN, new Object[]{signatureCount,maxSignatures}, BKUGUIFacade.BUTTON_CANCEL, this, "cancel");
+ retry = true;
+ pin = gui.getPin();
+ return pin;
+ } else if ("pinEntry".equals(action)) {
+ gui.showSignaturePINDialog(spec, (retry) ? retries : -1, this, "sign", this, "cancel", this, "secureViewer");
+ } else if ("cancel".equals(action) || "error".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ throw new CancelledException(spec.getLocalizedName() + " entry cancelled");
+ } else {
+ log.error("Unknown action command {}.", action);
+ }
+ } while (true);
+ } else {
+
+ signatureCount ++;
+
+ if(signatureCount > maxSignatures) {
+ throw new BulkSignException("Limit of "+ signatureCount + "Signatures exceeded.");
+ }
+
+ gui.updateMessageDialog(BKUGUIFacade.TITLE_BULKSIGNATURE, BKUGUIFacade.MESSAGE_BULKSIGN, new Object[]{signatureCount,maxSignatures}, BKUGUIFacade.BUTTON_CANCEL, this, "cancel");
+
+ if ("cancel".equals(action) || "error".equals(action)) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ throw new CancelledException(spec.getLocalizedName() + " entry cancelled");
+ }
+
+ return pin;
+ }
+ }
+
+ @Override
+ public boolean allowOverrulePinpad() throws InterruptedException {
+
+ if (showSignaturePINDialog) {
+ gui.showPinPadDeactivationDialog(this, "cancel", this, "ok");
+
+ do {
+ log.trace("[{}] wait for action.", Thread.currentThread().getName());
+ waitForAction();
+ log.trace("[{}] received action {}.", Thread.currentThread().getName(), action);
+
+ if ("cancel".equals(action)) {
+
+ return false;
+
+ } else if ("ok".equals(action)) {
+
+ return true;
+
+ } else {
+ log.error("Unknown action command {}.", action);
+ }
+ } while (true);
+ }
+
+ return true;
+ }
+}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java
index bc49b85e..da6c39b0 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINGUI.java
@@ -25,12 +25,14 @@
package at.gv.egiz.bku.pin.gui;
import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.bku.smccstal.SecureViewer;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
import at.gv.egiz.smcc.pin.gui.PINGUI;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import at.gv.egiz.stal.SignatureInfo;
+
import java.security.DigestException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +53,7 @@ public class SignPINGUI extends SignPINProvider implements PINGUI {
private boolean retry = false;
- public SignPINGUI(BKUGUIFacade gui, SecureViewer viewer, SignedInfoType signedInfo) {
+ public SignPINGUI(BKUGUIFacade gui, SecureViewer viewer, SignatureInfo signedInfo) {
super(gui, viewer, signedInfo);
}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java
index f9dfe068..efda713c 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/SignPINProvider.java
@@ -25,12 +25,15 @@
package at.gv.egiz.bku.pin.gui;
import at.gv.egiz.bku.gui.BKUGUIFacade;
-import at.gv.egiz.bku.smccstal.SecureViewer;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
import at.gv.egiz.smcc.pin.gui.PINProvider;
-import at.gv.egiz.stal.signedinfo.SignedInfoType;
+import at.gv.egiz.stal.SignatureInfo;
+
import java.security.DigestException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,10 +54,10 @@ public class SignPINProvider extends AbstractPINProvider implements PINProvider
protected BKUGUIFacade gui;
protected SecureViewer viewer;
- protected SignedInfoType signedInfo;
+ protected SignatureInfo signedInfo;
private boolean retry = false;
- public SignPINProvider(BKUGUIFacade gui, SecureViewer viewer, SignedInfoType signedInfo) {
+ public SignPINProvider(BKUGUIFacade gui, SecureViewer viewer, SignatureInfo signedInfo) {
this.gui = gui;
this.viewer = viewer;
this.signedInfo = signedInfo;
@@ -62,7 +65,7 @@ public class SignPINProvider extends AbstractPINProvider implements PINProvider
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
gui.showSignaturePINDialog(spec, (retry) ? retries : -1,
this, "sign",
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java
index 59ee0593..77528ecb 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/pin/gui/VerifyPINProvider.java
@@ -25,9 +25,11 @@
package at.gv.egiz.bku.pin.gui;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.smcc.BulkSignException;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.PinInfo;
import at.gv.egiz.smcc.pin.gui.PINProvider;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,7 +57,7 @@ public class VerifyPINProvider extends AbstractPINProvider implements PINProvide
@Override
public char[] providePIN(PinInfo spec, int retries)
- throws CancelledException, InterruptedException {
+ throws CancelledException, InterruptedException, BulkSignException {
gui.showVerifyPINDialog(spec, (retry) ? retries : -1,
this, "verify",
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/BulkSignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/BulkSignRequestHandler.java
new file mode 100644
index 00000000..6d0403f7
--- /dev/null
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/BulkSignRequestHandler.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egiz.bku.smccstal;
+
+import iaik.me.asn1.ASN1;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.SignatureException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
+import at.gv.egiz.bku.pin.gui.BulkSignPINGUI;
+import at.gv.egiz.smcc.BulkSignException;
+import at.gv.egiz.smcc.CancelledException;
+import at.gv.egiz.smcc.LockedException;
+import at.gv.egiz.smcc.NotActivatedException;
+import at.gv.egiz.smcc.SignatureCard;
+import at.gv.egiz.smcc.SignatureCard.KeyboxName;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.TimeoutException;
+import at.gv.egiz.stal.BulkSignRequest;
+import at.gv.egiz.stal.BulkSignResponse;
+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.SignatureInfo;
+import at.gv.egiz.stal.signedinfo.CanonicalizationMethodType;
+import at.gv.egiz.stal.signedinfo.DigestMethodType;
+import at.gv.egiz.stal.signedinfo.ObjectFactory;
+import at.gv.egiz.stal.signedinfo.ReferenceType;
+import at.gv.egiz.stal.signedinfo.SignatureMethodType;
+import at.gv.egiz.stal.signedinfo.SignedInfoType;
+
+/**
+ * @author szoescher
+ */
+public class BulkSignRequestHandler extends AbstractRequestHandler {
+
+ private final static Logger log = LoggerFactory.getLogger(BulkSignRequestHandler.class);
+
+ private final static String CMS_DEF_SIGNEDINFO_ID = "SignedInfo-1";
+ private final static String OID_MESSAGEDIGEST = "1.2.840.113549.1.9.4";
+
+ private static JAXBContext jaxbContext;
+
+ static {
+ try {
+ jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
+ } catch (JAXBException e) {
+ Logger log = LoggerFactory.getLogger(BulkSignRequestHandler.class);
+ log.error("Cannot init jaxbContext", e);
+ }
+ }
+
+ protected SecureViewer secureViewer;
+
+ public BulkSignRequestHandler(SecureViewer secureViewer) {
+ this.secureViewer = secureViewer;
+ }
+
+ private static ErrorResponse errorResponse(int errorCode, String errorMessage, Exception e) {
+ log.error(errorMessage, e);
+ ErrorResponse err = new ErrorResponse(errorCode);
+ err.setErrorMessage(errorMessage + (e == null ? "" : " " + e));
+ return err;
+ }
+
+ @Override
+ public STALResponse handleRequest(STALRequest request) throws InterruptedException {
+ if (request instanceof BulkSignRequest) {
+ BulkSignRequest bulkSignRequest = (BulkSignRequest) request;
+ BulkSignResponse stalResp = new BulkSignResponse();
+
+
+ LinkedList<SignatureInfo> signatureInfoList = new LinkedList<SignatureInfo>();
+ try {
+
+ for(SignRequest signRequest : bulkSignRequest.getSignRequests()){
+
+ byte[] signedInfoData = signRequest.getSignedInfo().getValue();
+
+ SignatureInfo signatureInfo;
+ if (signRequest.getSignedInfo().isIsCMSSignedAttributes()) {
+ signatureInfo = createCMSSignedInfo(signRequest);
+ } else {
+
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ InputStream is = new ByteArrayInputStream(signedInfoData);
+ @SuppressWarnings("unchecked")
+ JAXBElement<SignedInfoType> si = (JAXBElement<SignedInfoType>) unmarshaller.unmarshal(is);
+
+ signatureInfo = new SignatureInfo(si.getValue(), signRequest.getDisplayName(), signRequest.getMimeType());
+ }
+ signatureInfoList.add(signatureInfo);
+ }
+
+ BulkSignPINGUI pinGUI = new BulkSignPINGUI(gui, secureViewer, signatureInfoList, bulkSignRequest.getSignRequests().size());
+
+
+ for (int i = 0; i < bulkSignRequest.getSignRequests().size(); i++) {
+ SignRequest signRequest = bulkSignRequest.getSignRequests().get(i);
+ STALResponse response = handleSignRequest(signRequest, pinGUI, signatureInfoList.get(i));
+ pinGUI.setShowSignaturePINDialog(false);
+
+ if (response instanceof SignResponse) {
+ stalResp.getSignResponse().add((SignResponse) response);
+ }
+
+ if (response instanceof ErrorResponse) {
+ return response;
+ }
+
+ }
+ } catch (SignatureException e) {
+ return errorResponse(4000, "Error while parsing CMS signature.", e);
+ } catch (JAXBException e) {
+ return errorResponse(1000, "Cannot unmarshal signed info.", e);
+ }
+
+ return stalResp;
+ } else {
+ return errorResponse(1000, "Got unexpected STAL request: " + request + ".", null);
+ }
+ }
+
+ @Override
+ public boolean requireCard() {
+ return true;
+ }
+
+ private STALResponse handleSignRequest(SignRequest request, BulkSignPINGUI pinGUI, SignatureInfo signatureInfo) throws InterruptedException {
+ if (request instanceof SignRequest) {
+
+ SignRequest signReq = (SignRequest) request;
+ byte[] signedInfoData = signReq.getSignedInfo().getValue();
+ try {
+
+ String signatureMethod = signatureInfo.getSignatureMethod().getAlgorithm();
+ log.debug("Found signature method: {}.", signatureMethod);
+ KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
+
+ byte[] resp = card.createSignature(new ByteArrayInputStream(signedInfoData), kb, pinGUI, signatureMethod);
+
+ if (resp == null) {
+ return errorResponse(6001, "Response is null", null);
+ }
+
+ SignResponse stalResp = new SignResponse();
+ stalResp.setSignatureValue(resp);
+ return stalResp;
+ } catch (NotActivatedException e) {
+ gui.showErrorDialog(BKUGUIFacade.ERR_CARD_NOTACTIVATED, null, this, null);
+ waitForAction();
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ return errorResponse(6001, "Citizen card not activated.", e);
+ } catch (LockedException e) {
+ gui.showErrorDialog(BKUGUIFacade.ERR_CARD_LOCKED, null, this, null);
+ waitForAction();
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ return errorResponse(6001, "Citizen card locked.", e);
+ } catch (CancelledException cx) {
+ return errorResponse(6001, "User cancelled request.", null);
+ }catch (BulkSignException cx) {
+ return errorResponse(6001, "Limit of Signatures exceeded.", null);
+ } catch (TimeoutException ex) {
+ gui.showMessageDialog(BKUGUIFacade.TITLE_ENTRY_TIMEOUT, BKUGUIFacade.ERR_PIN_TIMEOUT, null,
+ BKUGUIFacade.BUTTON_CANCEL, this, null);
+ waitForAction();
+ gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, BKUGUIFacade.MESSAGE_WAIT);
+ return errorResponse(6001, "Timeout during pin entry.", null);
+ } catch (SignatureCardException e) {
+ return errorResponse(4000, "Error while creating signature.", e);
+ } catch (IOException e) {
+ return errorResponse(4000, "Error while creating signature.", e);
+ }
+ } else {
+ return errorResponse(1000, "Got unexpected STAL request: " + request + ".", null);
+ }
+ }
+
+ private static SignatureInfo createCMSSignedInfo(SignRequest signReq) throws SignatureException {
+ SignedInfoType signedInfo = new SignedInfoType();
+
+ log.trace("createCMSSignedInfo from SignRequest");
+ byte[] signedInfoData = signReq.getSignedInfo().getValue();
+
+ CanonicalizationMethodType canonicalizationMethod = new CanonicalizationMethodType();
+ canonicalizationMethod.setAlgorithm("");
+ signedInfo.setCanonicalizationMethod(canonicalizationMethod);
+
+ SignatureMethodType signatureMethod = new SignatureMethodType();
+ signatureMethod.setAlgorithm(signReq.getSignatureMethod());
+ signedInfo.setSignatureMethod(signatureMethod);
+
+ signedInfo.setId(CMS_DEF_SIGNEDINFO_ID);
+
+ List<ReferenceType> references = signedInfo.getReference();
+ ReferenceType reference = new ReferenceType();
+ reference.setId(HashDataInput.CMS_DEF_REFERENCE_ID);
+ DigestMethodType digestMethod = new DigestMethodType();
+ digestMethod.setAlgorithm(signReq.getDigestMethod());
+ reference.setDigestMethod(digestMethod);
+ byte[] messageDigest = null;
+ try {
+ ASN1 signedAttributes = new ASN1(signedInfoData);
+ if (!signedAttributes.isConstructed())
+ throw new SignatureException("Error while parsing CMS signature");
+ for (int i = 0; i < signedAttributes.getSize(); ++i) {
+ ASN1 signedAttribute = signedAttributes.getElementAt(i);
+ if (!signedAttribute.isConstructed())
+ throw new SignatureException("Error while parsing CMS signature");
+ ASN1 oid = signedAttribute.getElementAt(0);
+ if (oid.gvObjectId().equals(OID_MESSAGEDIGEST)) {
+ ASN1 value = signedAttribute.getElementAt(1);
+ if (!value.isConstructed())
+ throw new SignatureException("Error while parsing CMS signature");
+ messageDigest = value.getElementAt(0).gvByteArray();
+ break;
+ }
+ }
+ } catch (IOException e) {
+ throw new SignatureException(e);
+ }
+ reference.setDigestValue(messageDigest);
+ if (signReq.getExcludedByteRange() != null) {
+ // Abuse URI to store ExcludedByteRange
+ String range = "CMSExcludedByteRange:" + signReq.getExcludedByteRange().getFrom() + "-"
+ + signReq.getExcludedByteRange().getTo();
+ reference.setURI(range);
+ }
+
+ references.add(reference);
+
+ log.trace("Added SignatureInfo {} with name {} of type{}", new Object[] { signedInfo.getId(), signReq.getDisplayName(), signReq.getMimeType() });
+ return new SignatureInfo(signedInfo, signReq.getDisplayName(), signReq.getMimeType());
+ }
+
+}
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 3026d27a..31c63379 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
@@ -41,6 +41,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.viewer.SecureViewer;
import at.gv.egiz.bku.pin.gui.SignPINGUI;
import at.gv.egiz.smcc.CancelledException;
import at.gv.egiz.smcc.LockedException;
@@ -55,6 +56,7 @@ 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.SignatureInfo;
import at.gv.egiz.stal.signedinfo.CanonicalizationMethodType;
import at.gv.egiz.stal.signedinfo.DigestMethodType;
import at.gv.egiz.stal.signedinfo.ObjectFactory;
@@ -97,10 +99,12 @@ public class SignRequestHandler extends AbstractRequestHandler {
@Override
public STALResponse handleRequest(STALRequest request) throws InterruptedException {
if (request instanceof SignRequest) {
+
SignRequest signReq = (SignRequest) request;
+
byte[] signedInfoData = signReq.getSignedInfo().getValue();
try {
- SignedInfoType signedInfo;
+ SignatureInfo signedInfo;
if (signReq.getSignedInfo().isIsCMSSignedAttributes()) {
signedInfo = createCMSSignedInfo(signReq);
} else {
@@ -109,7 +113,8 @@ public class SignRequestHandler extends AbstractRequestHandler {
@SuppressWarnings("unchecked")
JAXBElement<SignedInfoType> si =
(JAXBElement<SignedInfoType>) unmarshaller.unmarshal(is);
- signedInfo = si.getValue();
+
+ signedInfo = new SignatureInfo(si.getValue(), signReq.getDisplayName(), signReq.getMimeType());
}
String signatureMethod = signedInfo.getSignatureMethod().getAlgorithm();
log.debug("Found signature method: {}.", signatureMethod);
@@ -159,7 +164,7 @@ public class SignRequestHandler extends AbstractRequestHandler {
}
}
- private static SignedInfoType createCMSSignedInfo(SignRequest signReq) throws SignatureException {
+ private static SignatureInfo createCMSSignedInfo(SignRequest signReq) throws SignatureException {
SignedInfoType signedInfo = new SignedInfoType();
byte[] signedInfoData = signReq.getSignedInfo().getValue();
@@ -210,7 +215,7 @@ public class SignRequestHandler extends AbstractRequestHandler {
reference.setURI(range);
}
references.add(reference);
- return signedInfo;
+ return new SignatureInfo(signedInfo, signReq.getDisplayName(), signReq.getMimeType());
}
@Override
diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSDataObjectOptionalMetaType.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSDataObjectOptionalMetaType.java
index 325d8dbf..8e00e85d 100644
--- a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSDataObjectOptionalMetaType.java
+++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSDataObjectOptionalMetaType.java
@@ -26,7 +26,10 @@ import javax.xml.bind.annotation.XmlType;
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
* &lt;sequence&gt;
* &lt;element name="MetaInfo" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}MetaInfoType" minOccurs="0"/&gt;
- * &lt;element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/&gt;
+ * &lt;choice&gt;
+ * &lt;element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/&gt;
+ * &lt;element name="DigestAndRef" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}DigestAndRefType"/&gt;
+ * &lt;/choice&gt;
* &lt;element name="ExcludedByteRange" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}ExcludedByteRangeType" minOccurs="0"/&gt;
* &lt;/sequence&gt;
* &lt;/restriction&gt;
@@ -40,10 +43,12 @@ import javax.xml.bind.annotation.XmlType;
@XmlType(name = "CMSDataObjectOptionalMetaType", propOrder = {
"metaInfo",
"content",
+ "digestAndRef",
"excludedByteRange"
})
@XmlSeeAlso({
- CMSDataObjectRequiredMetaType.class
+ CMSReferenceObject.class,
+ CMSDataObjectRequiredMetaType.class
})
public class CMSDataObjectOptionalMetaType {
@@ -51,6 +56,8 @@ public class CMSDataObjectOptionalMetaType {
protected MetaInfoType metaInfo;
@XmlElement(name = "Content", required = true)
protected Base64OptRefContentType content;
+ @XmlElement(name = "DigestAndRef")
+ protected DigestAndRefType digestAndRef;
@XmlElement(name = "ExcludedByteRange")
protected ExcludedByteRangeType excludedByteRange;
@@ -101,6 +108,30 @@ public class CMSDataObjectOptionalMetaType {
public void setContent(Base64OptRefContentType value) {
this.content = value;
}
+
+ /**
+ * Ruft den Wert der digestAndRef-Eigenschaft ab.
+ *
+ * @return
+ * possible object is
+ * {@link DigestAndRefType }
+ *
+ */
+ public DigestAndRefType getDigestAndRef() {
+ return digestAndRef;
+ }
+
+ /**
+ * Legt den Wert der digestAndRef-Eigenschaft fest.
+ *
+ * @param value
+ * allowed object is
+ * {@link DigestAndRefType }
+ *
+ */
+ public void setDigestAndRef(DigestAndRefType value) {
+ this.digestAndRef = value;
+ }
/**
* Gets the value of the excludedByteRange property.
diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSReferenceObject.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSReferenceObject.java
new file mode 100644
index 00000000..b7c18e6b
--- /dev/null
+++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CMSReferenceObject.java
@@ -0,0 +1,46 @@
+//
+// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.5 generiert
+// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren.
+// Generiert: 2015.09.28 um 04:08:24 PM CEST
+//
+
+package at.buergerkarte.namespaces.securitylayer._1_2_3;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java-Klasse für CMSReferenceObject complex type.
+ *
+ * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
+ *
+ * <pre>
+ * &lt;complexType name="CMSReferenceObject">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectOptionalMetaType">
+ * &lt;sequence>
+ * &lt;element name="MetaInfo" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}MetaInfoType"/>
+ * &lt;choice>
+ * &lt;element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/>
+ * &lt;element name="DigestAndRef" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}DigestAndRefType"/>
+ * &lt;/choice>
+ * &lt;element name="ExcludedByteRange" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}ExcludedByteRangeType" minOccurs="0"/>
+ * &lt;/sequence>
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "CMSReferenceObject")
+public class CMSReferenceObject
+ extends CMSDataObjectOptionalMetaType
+{
+
+
+}
diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CreateCMSSignatureRequestType.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CreateCMSSignatureRequestType.java
index 5c0d0a4b..9f1befe0 100644
--- a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CreateCMSSignatureRequestType.java
+++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/CreateCMSSignatureRequestType.java
@@ -28,7 +28,10 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
* &lt;sequence&gt;
* &lt;element name="KeyboxIdentifier" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}BoxIdentifierType"/&gt;
- * &lt;element name="DataObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectRequiredMetaType"/&gt;
+ * &lt;choice&gt;
+ * &lt;element name="DataObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectRequiredMetaType"/&gt;
+ * &lt;element name="ReferenceObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSReferenceObject"/&gt;
+ * &lt;/choice&gt;
* &lt;/sequence&gt;
* &lt;attribute name="Structure" use="required"&gt;
* &lt;simpleType&gt;
@@ -49,15 +52,18 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CreateCMSSignatureRequestType", propOrder = {
"keyboxIdentifier",
- "dataObject"
+ "dataObject",
+ "referenceObject"
})
public class CreateCMSSignatureRequestType {
@XmlElement(name = "KeyboxIdentifier", required = true)
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String keyboxIdentifier;
- @XmlElement(name = "DataObject", required = true)
+ @XmlElement(name = "DataObject")
protected CMSDataObjectRequiredMetaType dataObject;
+ @XmlElement(name = "ReferenceObject")
+ protected CMSReferenceObject referenceObject;
@XmlAttribute(name = "Structure", required = true)
protected String structure;
@XmlAttribute(name = "PAdESCompatibility")
@@ -110,6 +116,30 @@ public class CreateCMSSignatureRequestType {
public void setDataObject(CMSDataObjectRequiredMetaType value) {
this.dataObject = value;
}
+
+ /**
+ * Ruft den Wert der referenceObject-Eigenschaft ab.
+ *
+ * @return
+ * possible object is
+ * {@link CMSReferenceObject }
+ *
+ */
+ public CMSReferenceObject getReferenceObject() {
+ return referenceObject;
+ }
+
+ /**
+ * Legt den Wert der referenceObject-Eigenschaft fest.
+ *
+ * @param value
+ * allowed object is
+ * {@link CMSReferenceObject }
+ *
+ */
+ public void setReferenceObject(CMSReferenceObject value) {
+ this.referenceObject = value;
+ }
/**
* Gets the value of the structure property.
diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/DigestAndRefType.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/DigestAndRefType.java
new file mode 100644
index 00000000..477925ca
--- /dev/null
+++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/DigestAndRefType.java
@@ -0,0 +1,128 @@
+//
+// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.5 generiert
+// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
+// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren.
+// Generiert: 2015.09.29 um 11:17:38 AM CEST
+//
+
+
+package at.buergerkarte.namespaces.securitylayer._1_2_3;
+
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+import org.w3._2000._09.xmldsig_.DigestMethodType;
+
+
+/**
+ * <p>Java-Klasse für DigestAndRefType complex type.
+ *
+ * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
+ *
+ * <pre>
+ * &lt;complexType name="DigestAndRefType">
+ * &lt;complexContent>
+ * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ * &lt;sequence>
+ * &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}DigestMethod"/>
+ * &lt;element ref="{http://www.w3.org/2000/09/xmldsig#}DigestValue"/>
+ * &lt;/sequence>
+ * &lt;attribute name="Reference" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
+ * &lt;/restriction>
+ * &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ *
+ *
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "DigestAndRefType", propOrder = {
+ "digestMethod",
+ "digestValue"
+})
+public class DigestAndRefType {
+
+ @XmlElement(name = "DigestMethod", namespace = "http://www.w3.org/2000/09/xmldsig#", required = true)
+ protected DigestMethodType digestMethod;
+ @XmlElement(name = "DigestValue", namespace = "http://www.w3.org/2000/09/xmldsig#", required = true)
+ protected byte[] digestValue;
+ @XmlAttribute(name = "Reference")
+ @XmlSchemaType(name = "anyURI")
+ protected String reference;
+
+ /**
+ * Ruft den Wert der digestMethod-Eigenschaft ab.
+ *
+ * @return
+ * possible object is
+ * {@link DigestMethodType }
+ *
+ */
+ public DigestMethodType getDigestMethod() {
+ return digestMethod;
+ }
+
+ /**
+ * Legt den Wert der digestMethod-Eigenschaft fest.
+ *
+ * @param value
+ * allowed object is
+ * {@link DigestMethodType }
+ *
+ */
+ public void setDigestMethod(DigestMethodType value) {
+ this.digestMethod = value;
+ }
+
+ /**
+ * Ruft den Wert der digestValue-Eigenschaft ab.
+ *
+ * @return
+ * possible object is
+ * byte[]
+ */
+ public byte[] getDigestValue() {
+ return digestValue;
+ }
+
+ /**
+ * Legt den Wert der digestValue-Eigenschaft fest.
+ *
+ * @param value
+ * allowed object is
+ * byte[]
+ */
+ public void setDigestValue(byte[] value) {
+ this.digestValue = value;
+ }
+
+ /**
+ * Ruft den Wert der reference-Eigenschaft ab.
+ *
+ * @return
+ * possible object is
+ * {@link String }
+ *
+ */
+ public String getReference() {
+ return reference;
+ }
+
+ /**
+ * Legt den Wert der reference-Eigenschaft fest.
+ *
+ * @param value
+ * allowed object is
+ * {@link String }
+ *
+ */
+ public void setReference(String value) {
+ this.reference = value;
+ }
+
+}
diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/ObjectFactory.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/ObjectFactory.java
index 20d5b15d..b3be3b76 100644
--- a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/ObjectFactory.java
+++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1_2_3/ObjectFactory.java
@@ -660,6 +660,14 @@ public class ObjectFactory {
public CMSDataObjectRequiredMetaType createCMSDataObjectRequiredMetaType() {
return new CMSDataObjectRequiredMetaType();
}
+
+ /**
+ * Create an instance of {@link CMSReferenceObject }
+ *
+ */
+ public CMSReferenceObject createCMSReferenceObject() {
+ return new CMSReferenceObject();
+ }
/**
* Create an instance of {@link at.buergerkarte.namespaces.securitylayer._1_2_3.XMLContentType }
diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FileURLProtocolHandlerImpl.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FileURLProtocolHandlerImpl.java
new file mode 100644
index 00000000..1580eb48
--- /dev/null
+++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FileURLProtocolHandlerImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Datentechnik Innovation GmbH and Prime Sign GmbH, Austria
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.gv.egiz.bku.utils.urldereferencer;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileURLProtocolHandlerImpl implements URLProtocolHandler {
+
+ private final Logger log = LoggerFactory.getLogger(FileURLProtocolHandlerImpl.class);
+
+ public final static String FILE = "file";
+
+
+ @Override
+ public StreamData dereference(String url)
+ throws IOException {
+
+ URL u = new URL(url);
+ URLConnection connection = u.openConnection();
+
+ log.trace("Successfully opened connection.");
+ return new StreamData(url.toString(), connection.getContentType(), connection.getInputStream());
+
+ }
+
+ @Override
+ public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+ log.warn("not implemented for {}", this.getClass().getName());
+ }
+
+ @Override
+ public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
+ log.warn("not implemented for {}", this.getClass().getName());
+ }
+
+}
diff --git a/utils/src/main/resources/at/gv/egiz/bku/slschema/Core-1.2.xsd b/utils/src/main/resources/at/gv/egiz/bku/slschema/Core-1.2.xsd
index a97a98a5..75b999c7 100644
--- a/utils/src/main/resources/at/gv/egiz/bku/slschema/Core-1.2.xsd
+++ b/utils/src/main/resources/at/gv/egiz/bku/slschema/Core-1.2.xsd
@@ -1,1120 +1,1147 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Securitylayer, Schnittstellenspezifikation -->
-<!-- XML-Schema fuer Schnittstellenspezifikation Version 1.2.3 -->
-<!-- 01. 03. 2005, Bundeskanzleramt, Stabsstelle IKT-Strategie, Technik und Standards -->
-<!-- 24. 09. 2013, EGIZ -->
-<xsd:schema targetNamespace="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.2.1" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
- <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
- <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
- <!--###################################################################### -->
- <!--# Create CMS Signature # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Create CMS Signature Request = -->
- <!--====================================================================== -->
- <xsd:element name="CreateCMSSignatureRequest" type="CreateCMSSignatureRequestType"/>
- <xsd:complexType name="CreateCMSSignatureRequestType">
- <xsd:sequence>
- <xsd:element name="KeyboxIdentifier" type="BoxIdentifierType"/>
- <xsd:element name="DataObject" type="CMSDataObjectRequiredMetaType"/>
- </xsd:sequence>
- <xsd:attribute name="Structure" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="detached"/>
- <xsd:enumeration value="enveloping"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- <xsd:attribute name="PAdESCompatibility" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- <xsd:complexType name="CMSDataObjectRequiredMetaType">
- <xsd:complexContent>
- <xsd:restriction base="CMSDataObjectOptionalMetaType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType"/>
- <xsd:element name="Content" type="Base64OptRefContentType"/>
- <xsd:element name="ExcludedByteRange" type="ExcludedByteRangeType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:restriction>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="CMSDataObjectOptionalMetaType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
- <xsd:element name="Content" type="Base64OptRefContentType"/>
- <xsd:element name="ExcludedByteRange" type="ExcludedByteRangeType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ExcludedByteRangeType">
- <xsd:sequence>
- <xsd:element name="From" type="xsd:unsignedLong"/>
- <xsd:element name="To" type="xsd:unsignedLong"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Create CMS Signature Response = -->
- <!--====================================================================== -->
- <xsd:element name="CreateCMSSignatureResponse" type="CreateCMSSignatureResponseType"/>
- <xsd:complexType name="CreateCMSSignatureResponseType">
- <xsd:sequence>
- <xsd:element name="CMSSignature" type="xsd:base64Binary"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Create XML Signature # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Create XML Signature Request = -->
- <!--====================================================================== -->
- <xsd:element name="CreateXMLSignatureRequest" type="CreateXMLSignatureRequestType"/>
- <xsd:complexType name="CreateXMLSignatureRequestType">
- <xsd:sequence>
- <xsd:element name="KeyboxIdentifier" type="BoxIdentifierType"/>
- <xsd:element name="DataObjectInfo" type="DataObjectInfoType" maxOccurs="unbounded"/>
- <xsd:element name="SignatureInfo" type="SignatureInfoCreationType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="SignatureInfoCreationType">
- <xsd:sequence>
- <xsd:element name="SignatureEnvironment" type="Base64XMLOptRefContentType"/>
- <xsd:element name="SignatureLocation">
- <xsd:complexType>
- <xsd:simpleContent>
- <xsd:extension base="xsd:token">
- <xsd:attribute name="Index" type="xsd:nonNegativeInteger" use="required"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="MetaInfoType">
- <xsd:sequence>
- <xsd:element name="MimeType" type="MimeTypeType"/>
- <xsd:element name="Description" type="xsd:string" minOccurs="0"/>
- <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="DataObjectInfoType">
- <xsd:sequence>
- <xsd:element name="DataObject" type="Base64XMLLocRefOptRefContentType"/>
- <xsd:element name="TransformsInfo" type="TransformsInfoType" maxOccurs="unbounded"/>
- <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="Structure" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="detached"/>
- <xsd:enumeration value="enveloping"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- </xsd:complexType>
- <xsd:complexType name="TransformsInfoType">
- <xsd:sequence>
- <xsd:element ref="dsig:Transforms" minOccurs="0"/>
- <xsd:element name="FinalDataMetaInfo" type="MetaInfoType"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Create XML Signature Response = -->
- <!--====================================================================== -->
- <xsd:element name="CreateXMLSignatureResponse" type="CreateXMLSignatureResponseType"/>
- <xsd:complexType name="CreateXMLSignatureResponseType">
- <xsd:sequence>
- <xsd:any namespace="##any" processContents="lax" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Verify CMS Signature # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Verify CMS Signature Request = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyCMSSignatureRequest" type="VerifyCMSSignatureRequestType"/>
- <xsd:complexType name="VerifyCMSSignatureRequestType">
- <xsd:sequence>
- <xsd:element name="DateTime" type="xsd:dateTime" minOccurs="0"/>
- <xsd:element name="CMSSignature" type="xsd:base64Binary"/>
- <xsd:element name="DataObject" type="CMSDataObjectOptionalMetaType" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute name="Signatories" type="SignatoriesType" use="optional" default="1"/>
- </xsd:complexType>
- <xsd:simpleType name="SignatoriesType">
- <xsd:union memberTypes="AllSignatoriesType">
- <xsd:simpleType>
- <xsd:list itemType="xsd:positiveInteger"/>
- </xsd:simpleType>
- </xsd:union>
- </xsd:simpleType>
- <xsd:simpleType name="AllSignatoriesType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="all"/>
- </xsd:restriction>
- </xsd:simpleType>
- <!--====================================================================== -->
- <!--= Verify CMS Signature Response = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyCMSSignatureResponse" type="VerifyCMSSignatureResponseType"/>
- <xsd:complexType name="VerifyCMSSignatureResponseType">
- <xsd:sequence maxOccurs="unbounded">
- <xsd:element name="SignerInfo" type="dsig:KeyInfoType"/>
- <xsd:element name="SignatureCheck" type="CheckResultType"/>
- <xsd:element name="CertificateCheck" type="CheckResultType"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:element name="QualifiedCertificate"/>
- <!--###################################################################### -->
- <!--# Verify XML Signature # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Verify XML Signature Request = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyXMLSignatureRequest" type="VerifyXMLSignatureRequestType"/>
- <xsd:complexType name="VerifyXMLSignatureRequestType">
- <xsd:sequence>
- <xsd:element name="DateTime" type="xsd:dateTime" minOccurs="0"/>
- <xsd:element name="SignatureInfo" type="SignatureInfoVerificationType"/>
- <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="SignatureInfoVerificationType">
- <xsd:sequence>
- <xsd:element name="SignatureEnvironment" type="Base64XMLOptRefContentType"/>
- <xsd:element name="SignatureLocation" type="xsd:token"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Verify XML Signature Response = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyXMLSignatureResponse" type="VerifyXMLSignatureResponseType"/>
- <xsd:complexType name="VerifyXMLSignatureResponseType">
- <xsd:sequence>
- <xsd:element name="SignerInfo" type="dsig:KeyInfoType"/>
- <xsd:element name="SignatureCheck" type="ReferencesCheckResultType"/>
- <xsd:element name="SignatureManifestCheck" type="ReferencesCheckResultType"/>
- <xsd:element name="XMLDSIGManifestCheck" type="ManifestRefsCheckResultType" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="CertificateCheck" type="CheckResultType"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ReferencesCheckResultType">
- <xsd:sequence>
- <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
- <xsd:element name="Info" type="ReferencesCheckResultInfoType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ReferencesCheckResultInfoType" mixed="true">
- <xsd:sequence>
- <xsd:element name="FailedReference" type="xsd:positiveInteger" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ManifestRefsCheckResultType">
- <xsd:sequence>
- <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
- <xsd:element name="Info" type="ManifestRefsCheckResultInfoType"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ManifestRefsCheckResultInfoType" mixed="true">
- <xsd:sequence>
- <xsd:element name="ReferringSigReference" type="xsd:positiveInteger"/>
- <xsd:element name="FailedReference" type="xsd:positiveInteger" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="CheckResultType">
- <xsd:sequence>
- <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
- <xsd:element name="Info" type="AnyMixedChildrenType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Encrypt a CMS message # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Encrypt a CMS message: Request = -->
- <!--====================================================================== -->
- <xsd:element name="EncryptCMSRequest" type="EncryptCMSRequestType"/>
- <xsd:complexType name="EncryptCMSRequestType">
- <xsd:sequence>
- <xsd:element name="RecipientPublicKey" type="CMSRecipientPublicKeyType" maxOccurs="unbounded"/>
- <xsd:element name="ToBeEncrypted" type="CMSToBeEncryptedType"/>
- </xsd:sequence>
- <xsd:attribute name="ReturnBinaryResult" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- <xsd:complexType name="CMSToBeEncryptedType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType"/>
- <xsd:element name="Content" type="Base64OptRefContentType"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="CMSRecipientPublicKeyType">
- <xsd:choice>
- <xsd:element name="X509Certificate" type="xsd:base64Binary"/>
- </xsd:choice>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Encrypt a CMS message: Response = -->
- <!--====================================================================== -->
- <xsd:element name="EncryptCMSResponse" type="EncryptCMSResponseType"/>
- <xsd:complexType name="EncryptCMSResponseType">
- <xsd:sequence>
- <xsd:element name="CMSMessage" type="xsd:base64Binary"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Decrypt a CMS message # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Decrypt a CMS message: Request = -->
- <!--====================================================================== -->
- <xsd:element name="DecryptCMSRequest" type="DecryptCMSRequestType"/>
- <xsd:complexType name="DecryptCMSRequestType">
- <xsd:sequence>
- <xsd:element name="CMSMessage" type="xsd:base64Binary"/>
- <xsd:element name="EncryptedContent" type="CMSEncryptedContentType" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute name="ReturnResult" type="ReturnResultType" use="optional" default="xml"/>
- </xsd:complexType>
- <xsd:complexType name="CMSEncryptedContentType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
- <xsd:element name="Content" type="Base64OptRefContentType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:simpleType name="ReturnResultType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="binary"/>
- <xsd:enumeration value="xml"/>
- <xsd:enumeration value="none"/>
- </xsd:restriction>
- </xsd:simpleType>
- <!--====================================================================== -->
- <!--= Decrypt a CMS message: Response = -->
- <!--====================================================================== -->
- <xsd:element name="DecryptCMSResponse" type="DecryptCMSResponseType"/>
- <xsd:complexType name="DecryptCMSResponseType">
- <xsd:sequence>
- <xsd:element name="DecryptedData" type="xsd:base64Binary"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Encrypt an XML document # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Encrypt an XML document: Request = -->
- <!--====================================================================== -->
- <xsd:element name="EncryptXMLRequest">
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="EncryptXMLRequestType"/>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="EncryptXMLRequestType">
- <xsd:sequence>
- <xsd:element name="RecipientPublicKey" type="XMLRecipientPublicKeyType" maxOccurs="unbounded"/>
- <xsd:element name="ToBeEncrypted" type="ToBeEncryptedType" maxOccurs="unbounded"/>
- <xsd:element name="EncryptionInfo" type="EncryptionInfoType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ToBeEncryptedType">
- <xsd:choice>
- <xsd:element name="Element">
- <xsd:complexType>
- <xsd:attribute name="Selector" type="xsd:token" use="required"/>
- <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="ElementContent">
- <xsd:complexType>
- <xsd:attribute name="Selector" type="xsd:token" use="required"/>
- <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="New" type="XMLToBeEncryptedNewType"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="XMLToBeEncryptedNewType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType"/>
- <xsd:element name="Content" type="XMLToBeEncryptedNewContentType"/>
- </xsd:sequence>
- <xsd:attribute name="ParentSelector" type="xsd:token" use="required"/>
- <xsd:attribute name="NodeCount" type="xsd:nonNegativeInteger" use="required"/>
- </xsd:complexType>
- <xsd:complexType name="XMLToBeEncryptedNewContentType">
- <xsd:complexContent>
- <xsd:extension base="Base64XMLLocRefContentType">
- <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="XMLRecipientPublicKeyType">
- <xsd:choice>
- <xsd:element ref="dsig:KeyValue"/>
- <xsd:element name="X509Certificate" type="xsd:base64Binary"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="EncryptionInfoType">
- <xsd:sequence>
- <xsd:element name="EncryptionEnvironment" type="Base64XMLOptRefContentType"/>
- <xsd:element name="EncryptedKeyLocation" minOccurs="0">
- <xsd:complexType>
- <xsd:attribute name="ParentSelector" type="xsd:token" use="required"/>
- <xsd:attribute name="NodeCount" type="xsd:nonNegativeInteger" use="required"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Encrypt an XML document: Response = -->
- <!--====================================================================== -->
- <xsd:element name="EncryptXMLResponse" type="EncryptXMLResponseType"/>
- <xsd:complexType name="EncryptXMLResponseType">
- <xsd:sequence>
- <xsd:element name="EncryptionEnvironment">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:any namespace="##any" processContents="lax"/>
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="EncryptedData" type="EncryptedDataType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="EncryptedDataType">
- <xsd:simpleContent>
- <xsd:extension base="xsd:base64Binary">
- <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="required"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Decrypt an XML document # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Decrypt an XML document: Request = -->
- <!--====================================================================== -->
- <xsd:element name="DecryptXMLRequest" type="DecryptXMLRequestType"/>
- <xsd:complexType name="DecryptXMLRequestType">
- <xsd:sequence>
- <xsd:element name="EncryptedContent" type="Base64XMLOptRefContentType"/>
- <xsd:element name="EncrElemsSelector" type="xsd:string"/>
- <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="ReturnResult" type="ReturnResultType" use="optional" default="xml"/>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Decrypt an XML document: Response = -->
- <!--====================================================================== -->
- <xsd:element name="DecryptXMLResponse" type="DecryptXMLResponseType"/>
- <xsd:complexType name="DecryptXMLResponseType">
- <xsd:sequence minOccurs="0">
- <xsd:element name="CandidateDocument" type="XMLContentType"/>
- <xsd:element name="DecryptedBinaryData" minOccurs="0" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:simpleContent>
- <xsd:extension base="xsd:base64Binary">
- <xsd:attribute name="EncrElemSelector" type="xsd:string" use="required"/>
- <xsd:attribute name="MimeType" type="xsd:string" use="optional"/>
- <xsd:attribute name="Encoding" type="xsd:anyURI" use="optional"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- </xsd:element>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Hashing # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Hash Computation Request = -->
- <!--====================================================================== -->
- <xsd:element name="CreateHashRequest" type="CreateHashRequestType"/>
- <xsd:complexType name="CreateHashRequestType">
- <xsd:sequence>
- <xsd:element name="HashInfo" type="CreateHashInfoRequestType" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="CreateHashInfoRequestType">
- <xsd:sequence>
- <xsd:element name="HashData" type="HashDataType"/>
- <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
- <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute name="RespondHashData" type="xsd:boolean" use="required"/>
- </xsd:complexType>
- <xsd:complexType name="HashDataType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType"/>
- <xsd:element name="Content" type="Base64XMLOptRefContentType"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Hash Computation Response = -->
- <!--====================================================================== -->
- <xsd:element name="CreateHashResponse" type="CreateHashResponseType"/>
- <xsd:complexType name="CreateHashResponseType">
- <xsd:sequence>
- <xsd:element name="HashInfo" type="CreateHashInfoResponseType" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="CreateHashInfoResponseType">
- <xsd:sequence>
- <xsd:element name="HashData" type="HashDataType" minOccurs="0"/>
- <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
- <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
- <xsd:element name="HashValue" type="xsd:base64Binary"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Hash Verification Request = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyHashRequest" type="VerifyHashRequestType"/>
- <xsd:complexType name="VerifyHashRequestType">
- <xsd:sequence>
- <xsd:element name="HashInfo" type="VerifyHashInfoRequestType" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="VerifyHashInfoRequestType">
- <xsd:sequence>
- <xsd:element name="HashData" type="HashDataType"/>
- <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
- <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
- <xsd:element name="HashValue" type="xsd:base64Binary"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Hash Verification Response = -->
- <!--====================================================================== -->
- <xsd:element name="VerifyHashResponse" type="VerifyHashResponseType"/>
- <xsd:complexType name="VerifyHashResponseType">
- <xsd:sequence>
- <xsd:element name="VerificationResult" type="VerificationResultType" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="VerificationResultType">
- <xsd:sequence>
- <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
- <xsd:element name="Result" type="xsd:boolean"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Infobox Commands # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Check Available Infoboxes Request = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxAvailableRequest" type="InfoboxAvailableRequestType"/>
- <xsd:complexType name="InfoboxAvailableRequestType"/>
- <!--====================================================================== -->
- <!--= Check Available Infoboxes Response = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxAvailableResponse" type="InfoboxAvailableResponseType"/>
- <xsd:complexType name="InfoboxAvailableResponseType">
- <xsd:sequence minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Create Infobox Request = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxCreateRequest" type="InfoboxCreateRequestType"/>
- <xsd:complexType name="InfoboxCreateRequestType">
- <xsd:sequence>
- <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
- <xsd:element name="InfoboxType" type="InfoboxTypeType"/>
- <xsd:element name="Creator" type="xsd:string"/>
- <xsd:element name="Purpose" type="xsd:string"/>
- <xsd:element name="ReadAccessAuthorization" type="AccessAuthorizationType" minOccurs="0"/>
- <xsd:element name="UpdateAccessAuthorization" type="AccessAuthorizationType" minOccurs="0"/>
- <xsd:element name="ReadUserConfirmation" type="UserConfirmationType" minOccurs="0"/>
- <xsd:element name="UpdateUserConfirmation" type="UserConfirmationType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:simpleType name="InfoboxTypeType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="BinaryFile"/>
- <xsd:enumeration value="AssocArray"/>
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:complexType name="AccessAuthorizationType">
- <xsd:sequence>
- <xsd:element name="RequesterID" type="RequesterIDType" maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="UserMayChange" type="xsd:boolean" use="required"/>
- </xsd:complexType>
- <xsd:simpleType name="RequesterIDSimpleType">
- <xsd:restriction base="xsd:string"/>
- </xsd:simpleType>
- <xsd:complexType name="RequesterIDType">
- <xsd:simpleContent>
- <xsd:extension base="RequesterIDSimpleType">
- <xsd:attribute name="AuthenticationClass" type="AuthenticationClassType" use="required"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <xsd:complexType name="UserConfirmationType">
- <xsd:simpleContent>
- <xsd:extension base="UserConfirmationSimpleType">
- <xsd:attribute name="UserMayChange" type="xsd:boolean" use="required"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <xsd:simpleType name="UserConfirmationSimpleType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="none"/>
- <xsd:enumeration value="info"/>
- <xsd:enumeration value="confirm"/>
- <xsd:enumeration value="confirmWithSecret"/>
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:simpleType name="AuthenticationClassType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="anonym"/>
- <xsd:enumeration value="pseudoanonym"/>
- <xsd:enumeration value="certified"/>
- <xsd:enumeration value="certifiedGovAgency"/>
- </xsd:restriction>
- </xsd:simpleType>
- <!--====================================================================== -->
- <!--= Create Infobox Response = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxCreateResponse" type="InfoboxCreateResponseType"/>
- <xsd:complexType name="InfoboxCreateResponseType"/>
- <!--====================================================================== -->
- <!--= Delete Infobox Request = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxDeleteRequest" type="InfoboxDeleteRequestType"/>
- <xsd:complexType name="InfoboxDeleteRequestType">
- <xsd:sequence>
- <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Delete Infobox Response = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxDeleteResponse" type="InfoboxDeleteResponseType"/>
- <xsd:complexType name="InfoboxDeleteResponseType"/>
- <!--====================================================================== -->
- <!--= Read Infobox Request = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxReadRequest" type="InfoboxReadRequestType"/>
- <xsd:complexType name="InfoboxReadRequestType">
- <xsd:sequence>
- <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
- <xsd:choice>
- <xsd:element name="BinaryFileParameters" type="InfoboxReadParamsBinaryFileType"/>
- <xsd:element name="AssocArrayParameters" type="InfoboxReadParamsAssocArrayType"/>
- </xsd:choice>
- <xsd:element name="BoxSpecificParameters" type="AnyChildrenType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="InfoboxReadParamsBinaryFileType">
- <xsd:attribute name="ContentIsXMLEntity" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- <xsd:complexType name="InfoboxReadParamsAssocArrayType">
- <xsd:choice>
- <xsd:element name="ReadKeys">
- <xsd:complexType>
- <xsd:attribute name="SearchString" type="WildCardSearchStringType" use="required"/>
- <xsd:attribute name="UserMakesUnique" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="ReadPairs">
- <xsd:complexType>
- <xsd:attribute name="SearchString" type="WildCardSearchStringType" use="required"/>
- <xsd:attribute name="UserMakesUnique" type="xsd:boolean" use="optional" default="false"/>
- <xsd:attribute name="ValuesAreXMLEntities" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="ReadValue">
- <xsd:complexType>
- <xsd:attribute name="Key" type="BoxIdentifierType" use="required"/>
- <xsd:attribute name="ValueIsXMLEntity" type="xsd:boolean" use="optional" default="false"/>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- <xsd:element name="IdentityLinkDomainIdentifier" type="xsd:anyURI"/>
- <!--====================================================================== -->
- <!--= Read Infobox Response = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxReadResponse" type="InfoboxReadResponseType"/>
- <xsd:complexType name="InfoboxReadResponseType">
- <xsd:choice>
- <xsd:element name="BinaryFileData" type="Base64XMLContentType"/>
- <xsd:element name="AssocArrayData" type="InfoboxReadDataAssocArrayType"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="InfoboxReadDataAssocArrayType">
- <xsd:choice>
- <xsd:sequence minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="Key" type="BoxIdentifierType"/>
- </xsd:sequence>
- <xsd:sequence minOccurs="0" maxOccurs="unbounded">
- <xsd:element name="Pair" type="InfoboxAssocArrayPairType"/>
- </xsd:sequence>
- </xsd:choice>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Update Infobox Request = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxUpdateRequest" type="InfoboxUpdateRequestType"/>
- <xsd:complexType name="InfoboxUpdateRequestType">
- <xsd:sequence>
- <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
- <xsd:choice>
- <xsd:element name="BinaryFileParameters" type="Base64XMLContentType"/>
- <xsd:element name="AssocArrayParameters" type="InfoboxUpdateParamsAssocArrayType"/>
- </xsd:choice>
- <xsd:element name="BoxSpecificParameters" type="AnyChildrenType" minOccurs="0"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="InfoboxUpdateParamsAssocArrayType">
- <xsd:choice>
- <xsd:element name="UpdateKey">
- <xsd:complexType>
- <xsd:attribute name="Key" type="xsd:token" use="required"/>
- <xsd:attribute name="NewKey" type="xsd:token" use="required"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="UpdateValue" type="InfoboxAssocArrayPairType"/>
- <xsd:element name="DeletePair">
- <xsd:complexType>
- <xsd:attribute name="Key" type="xsd:token" use="required"/>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Update Infobox Response = -->
- <!--====================================================================== -->
- <xsd:element name="InfoboxUpdateResponse" type="InfoboxUpdateResponseType"/>
- <xsd:complexType name="InfoboxUpdateResponseType"/>
- <!--###################################################################### -->
- <!--# Null-Operation # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Null-Operation ReQuest = -->
- <!--====================================================================== -->
- <xsd:element name="NullOperationRequest" type="NullOperationRequestType"/>
- <xsd:complexType name="NullOperationRequestType"/>
- <!--====================================================================== -->
- <!--= Null-Operation Response = -->
- <!--====================================================================== -->
- <xsd:element name="NullOperationResponse" type="NullOperationResponseType"/>
- <xsd:complexType name="NullOperationResponseType"/>
- <!--###################################################################### -->
- <!--# Get Properties # -->
- <!--###################################################################### -->
- <xsd:element name="GetPropertiesRequest">
- <xsd:complexType>
- <xsd:complexContent>
- <xsd:extension base="GetPropertiesRequestType"/>
- </xsd:complexContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="GetPropertiesRequestType"/>
- <!--====================================================================== -->
- <!--= Get Properties Response = -->
- <!--====================================================================== -->
- <xsd:element name="GetPropertiesResponse" type="GetPropertiesResponseType"/>
- <xsd:complexType name="GetPropertiesResponseType">
- <xsd:sequence>
- <xsd:element name="ViewerMediaType" type="MimeTypeType" maxOccurs="unbounded"/>
- <xsd:element name="XMLSignatureTransform" type="xsd:anyURI" maxOccurs="unbounded"/>
- <xsd:element name="KeyboxIdentifier" type="QualifiedBoxIdentifierType" minOccurs="0" maxOccurs="unbounded"/>
- <xsd:element name="Binding" type="BindingType" maxOccurs="unbounded"/>
- <xsd:element name="ProtocolVersion" type="xsd:token" maxOccurs="unbounded"/>
- <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="BindingType">
- <xsd:complexContent>
- <xsd:extension base="AnyChildrenType">
- <xsd:attribute name="Identifier" type="xsd:token" use="required"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="QualifiedBoxIdentifierType">
- <xsd:simpleContent>
- <xsd:extension base="BoxIdentifierType">
- <xsd:attribute name="Signature" type="xsd:boolean" use="required"/>
- <xsd:attribute name="Encryption" type="xsd:boolean" use="required"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Get Token Status # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= Get Token Status Request = -->
- <!--====================================================================== -->
- <xsd:element name="GetStatusRequest" type="GetStatusRequestType"/>
- <xsd:complexType name="GetStatusRequestType">
- <xsd:sequence minOccurs="0">
- <xsd:element name="TokenStatus" type="TokenStatusType"/>
- <xsd:element name="MaxDelay" type="xsd:nonNegativeInteger"/>
- </xsd:sequence>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= Get Token Status Response = -->
- <!--====================================================================== -->
- <xsd:element name="GetStatusResponse" type="GetStatusResponseType"/>
- <xsd:complexType name="GetStatusResponseType">
- <xsd:sequence>
- <xsd:element name="TokenStatus" type="TokenStatusType"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:simpleType name="TokenStatusType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="ready"/>
- <xsd:enumeration value="removed"/>
- </xsd:restriction>
- </xsd:simpleType>
- <!--###################################################################### -->
- <!--# CardManagement # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= CardManagement Request = -->
- <!--====================================================================== -->
- <xsd:element name="CardManagementRequest">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="CardAction" type="CardActionElement" minOccurs="0" maxOccurs="unbounded" />
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="CardActionElement">
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute name="Action" type="CardActionType" use="required" />
- <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
- <xsd:attribute name="Name" type="xsd:string" use="optional" />
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= CardManagement Response = -->
- <!--====================================================================== -->
- <xsd:element name="CardManagementResponse">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="Result" type="ResultElement" minOccurs="0" maxOccurs="unbounded" />
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="ResultApplElement">
- <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
- <xsd:attribute name="Name" type="xsd:string" use="required" />
- <xsd:attribute name="Status" type="CardActionResponseType" use="required" />
- <xsd:attribute name="RetryCount" type="xsd:integer" use="optional" />
- </xsd:complexType>
- <xsd:complexType name="ResultElement">
- <xsd:attribute name="CardAction" type="CardActionType" use="required" />
- <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
- <xsd:attribute name="Result" type="CardActionResponseType" use="required" />
- <xsd:attribute name="RetryCount" type="xsd:integer" use="optional" />
- </xsd:complexType>
- <xsd:simpleType name="CardActionType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="ActivatePIN" />
- <xsd:enumeration value="ChangePIN" />
- <xsd:enumeration value="ReadPINStatus" />
- <xsd:enumeration value="UnblockPIN" />
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:simpleType name="ApplicationIdentifierType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="SecureSignatureApplication" />
- <xsd:enumeration value="CertifiedApplication" />
- <xsd:enumeration value="InfoboxApplication" />
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:simpleType name="CardActionResponseType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="OK" />
- <xsd:enumeration value="Error" />
- <xsd:enumeration value="Blocked" />
- <xsd:enumeration value="Activ" />
- <xsd:enumeration value="Inactive" />
- </xsd:restriction>
- </xsd:simpleType>
- <!--###################################################################### -->
- <!--# CardChannel # -->
- <!--###################################################################### -->
- <!--====================================================================== -->
- <!--= CardChannel Request = -->
- <!--====================================================================== -->
- <xsd:element name="CardChannelRequest">
- <xsd:complexType>
- <xsd:sequence minOccurs="1" maxOccurs="1">
- <xsd:element name="Script" type="ScriptElement" minOccurs="1" maxOccurs="1" />
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="ScriptElement">
- <xsd:sequence minOccurs="1" maxOccurs="unbounded">
- <xsd:element name="Reset" type="ResetType" minOccurs="0" maxOccurs="unbounded" />
- <xsd:element name="CommandAPDU" type="CommandAPDUType" minOccurs="0" maxOccurs="unbounded" />
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="ResetType">
- <xsd:attribute name="cold" type="ResetColdType" use="optional" />
- </xsd:complexType>
- <xsd:simpleType name="ResetColdType">
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="true" />
- <xsd:enumeration value="false" />
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:complexType name="CommandAPDUType">
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute name="sequence" type="xsd:integer" use="required" />
- <xsd:attribute name="of" type="xsd:integer" use="required" />
- <xsd:attribute name="expectedSW" type="xsd:string" use="optional" />
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <!--====================================================================== -->
- <!--= CardChannel Response = -->
- <!--====================================================================== -->
- <xsd:element name="CardChannelResponse">
- <xsd:complexType>
- <xsd:sequence minOccurs="1" maxOccurs="1">
- <xsd:element name="Response" type="APDUResponseElement" minOccurs="1" maxOccurs="1" />
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- <xsd:complexType name="APDUResponseElement">
- <xsd:sequence minOccurs="1" maxOccurs="unbounded">
- <xsd:element name="ATR" type="APDUATRType" minOccurs="0" maxOccurs="unbounded" />
- <xsd:element name="ResponseAPDU" type="ResponseAPDUType" minOccurs="0" maxOccurs="unbounded" />
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="APDUATRType">
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute name="rc" type="xsd:integer" use="required" />
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <xsd:complexType name="ResponseAPDUType">
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute name="sequence" type="xsd:integer" use="required" />
- <xsd:attribute name="rc" type="xsd:integer" use="required" />
- <xsd:attribute name="SW" type="xsd:string" use="required" />
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Bulk Request # -->
- <!--###################################################################### -->
- <xsd:element name="BulkRequest" type="BulkRequestType"/>
- <xsd:complexType name="BulkRequestType">
- <xsd:choice>
- <xsd:element name="CreateSignatureRequest" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="CreateCMSSignatureRequest"/>
- <xsd:element ref="CreateXMLSignatureRequest"/>
- </xsd:choice>
- <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="VerifySignatureRequest" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="VerifyCMSSignatureRequest"/>
- <xsd:element ref="VerifyXMLSignatureRequest"/>
- </xsd:choice>
- <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="EncryptRequest" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="EncryptCMSRequest"/>
- <xsd:element ref="EncryptXMLRequest"/>
- </xsd:choice>
- <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="DecryptRequest" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="DecryptCMSRequest"/>
- <xsd:element ref="DecryptXMLRequest"/>
- </xsd:choice>
- <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Bulk Response # -->
- <!--###################################################################### -->
- <xsd:element name="BulkResponse" type="BulkResponseType"/>
- <xsd:complexType name="BulkResponseType">
- <xsd:choice>
- <xsd:element name="CreateSignatureResponse" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="CreateCMSSignatureResponse"/>
- <xsd:element ref="CreateXMLSignatureResponse"/>
- <xsd:element ref="ErrorResponse"/>
- </xsd:choice>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="VerifySignatureResponse" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="VerifyCMSSignatureResponse"/>
- <xsd:element ref="VerifyXMLSignatureResponse"/>
- <xsd:element ref="ErrorResponse"/>
- </xsd:choice>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="EncryptResponse" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="EncryptCMSResponse"/>
- <xsd:element ref="EncryptXMLResponse"/>
- <xsd:element ref="ErrorResponse"/>
- </xsd:choice>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="DecryptResponse" maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="DecryptCMSResponse"/>
- <xsd:element ref="DecryptXMLResponse"/>
- <xsd:element ref="ErrorResponse"/>
- </xsd:choice>
- <xsd:attribute name="id" type="xsd:ID" use="optional"/>
- </xsd:complexType>
- </xsd:element>
- </xsd:choice>
- </xsd:complexType>
- <!--###################################################################### -->
- <!--# Error Response # -->
- <!--###################################################################### -->
- <xsd:element name="ErrorResponse" type="ErrorResponseType"/>
- <xsd:complexType name="ErrorResponseType">
- <xsd:sequence>
- <xsd:element name="ErrorCode" type="ErrorCodeType"/>
- <xsd:element name="Info" type="xsd:string"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:simpleType name="ErrorCodeType">
- <xsd:restriction base="xsd:integer">
- <xsd:minInclusive value="1000"/>
- <xsd:maxInclusive value="99999"/>
- </xsd:restriction>
- </xsd:simpleType>
- <!--###################################################################### -->
- <!--# Auxiliary Types # -->
- <!--###################################################################### -->
- <xsd:simpleType name="BoxIdentifierType">
- <xsd:restriction base="xsd:token"/>
- </xsd:simpleType>
- <xsd:simpleType name="MimeTypeType">
- <xsd:restriction base="xsd:token"/>
- </xsd:simpleType>
- <xsd:simpleType name="WildCardSearchStringType">
- <xsd:restriction base="xsd:string">
- <xsd:pattern value="[^\*/]*(\*[^\*/]*)?(/[^\*/]*(\*[^\*/]*)?)*"/>
- <xsd:pattern value="\*\*"/>
- </xsd:restriction>
- </xsd:simpleType>
- <xsd:complexType name="InfoboxAssocArrayPairType">
- <xsd:complexContent>
- <xsd:extension base="Base64XMLContentType">
- <xsd:attribute name="Key" type="xsd:string" use="required"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="AnyChildrenType" mixed="false">
- <xsd:sequence minOccurs="0" maxOccurs="unbounded">
- <xsd:any namespace="##any" processContents="lax"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="AnyMixedChildrenType" mixed="true">
- <xsd:sequence minOccurs="0" maxOccurs="unbounded">
- <xsd:any namespace="##any" processContents="lax"/>
- </xsd:sequence>
- </xsd:complexType>
- <xsd:complexType name="XMLContentType" mixed="true">
- <xsd:complexContent mixed="true">
- <xsd:extension base="AnyMixedChildrenType">
- <xsd:attribute ref="xml:space" use="optional"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="Base64XMLLocRefOptRefContentType">
- <xsd:complexContent>
- <xsd:extension base="Base64XMLLocRefContentType">
- <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="Base64XMLLocRefReqRefContentType">
- <xsd:complexContent>
- <xsd:extension base="Base64XMLLocRefContentType">
- <xsd:attribute name="Reference" type="xsd:anyURI" use="required"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="Base64XMLOptRefContentType">
- <xsd:complexContent>
- <xsd:extension base="Base64XMLContentType">
- <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="Base64OptRefContentType">
- <xsd:complexContent>
- <xsd:extension base="Base64ContentType">
- <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
- </xsd:extension>
- </xsd:complexContent>
- </xsd:complexType>
- <xsd:complexType name="Base64ContentType">
- <xsd:choice minOccurs="0">
- <xsd:element name="Base64Content" type="xsd:base64Binary"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="Base64XMLContentType">
- <xsd:choice minOccurs="0">
- <xsd:element name="Base64Content" type="xsd:base64Binary"/>
- <xsd:element name="XMLContent" type="XMLContentType"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="Base64XMLLocRefContentType">
- <xsd:choice minOccurs="0">
- <xsd:element name="Base64Content" type="xsd:base64Binary"/>
- <xsd:element name="XMLContent" type="XMLContentType"/>
- <xsd:element name="LocRefContent" type="xsd:anyURI"/>
- </xsd:choice>
- </xsd:complexType>
- <xsd:complexType name="DataObjectAssociationType">
- <xsd:sequence>
- <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
- <xsd:element name="Content" type="Base64XMLLocRefReqRefContentType"/>
- </xsd:sequence>
- </xsd:complexType>
-</xsd:schema>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Securitylayer, Schnittstellenspezifikation -->
+<!-- XML-Schema fuer Schnittstellenspezifikation Version 1.2.3 -->
+<!-- 01. 03. 2005, Bundeskanzleramt, Stabsstelle IKT-Strategie, Technik und Standards -->
+<!-- 24. 09. 2013, EGIZ -->
+<xsd:schema targetNamespace="http://www.buergerkarte.at/namespaces/securitylayer/1.2#" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.2.1" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
+ <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
+ <!--###################################################################### -->
+ <!--# Create CMS Signature # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Create CMS Signature Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateCMSSignatureRequest" type="CreateCMSSignatureRequestType"/>
+ <xsd:complexType name="CreateCMSSignatureRequestType">
+ <xsd:sequence>
+ <xsd:element name="KeyboxIdentifier" type="BoxIdentifierType"/>
+ <xsd:choice>
+ <xsd:element name="DataObject" type="CMSDataObjectRequiredMetaType"/>
+ <xsd:element name="ReferenceObject" type="CMSReferenceObject"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute name="Structure" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="detached"/>
+ <xsd:enumeration value="enveloping"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="PAdESCompatibility" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ <xsd:complexType name="CMSDataObjectRequiredMetaType">
+ <xsd:complexContent>
+ <xsd:restriction base="CMSDataObjectOptionalMetaType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType"/>
+ <xsd:element name="Content" type="Base64OptRefContentType"/>
+ <xsd:element name="ExcludedByteRange" type="ExcludedByteRangeType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="CMSReferenceObject">
+ <xsd:complexContent>
+ <xsd:restriction base="CMSDataObjectOptionalMetaType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType"/>
+ <xsd:choice>
+ <xsd:element name="Content" type="Base64OptRefContentType"/>
+ <xsd:element name="DigestAndRef" type="DigestAndRefType" />
+ </xsd:choice>
+ <xsd:element name="ExcludedByteRange" type="ExcludedByteRangeType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="CMSDataObjectOptionalMetaType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="Content" type="Base64OptRefContentType"/>
+ <xsd:element name="DigestAndRef" type="DigestAndRefType" />
+ </xsd:choice>
+ <xsd:element name="ExcludedByteRange" type="ExcludedByteRangeType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ExcludedByteRangeType">
+ <xsd:sequence>
+ <xsd:element name="From" type="xsd:unsignedLong"/>
+ <xsd:element name="To" type="xsd:unsignedLong"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Create CMS Signature Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateCMSSignatureResponse" type="CreateCMSSignatureResponseType"/>
+ <xsd:complexType name="CreateCMSSignatureResponseType">
+ <xsd:sequence>
+ <xsd:element name="CMSSignature" type="xsd:base64Binary"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Create XML Signature # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Create XML Signature Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateXMLSignatureRequest" type="CreateXMLSignatureRequestType"/>
+ <xsd:complexType name="CreateXMLSignatureRequestType">
+ <xsd:sequence>
+ <xsd:element name="KeyboxIdentifier" type="BoxIdentifierType"/>
+ <xsd:element name="DataObjectInfo" type="DataObjectInfoType" maxOccurs="unbounded"/>
+ <xsd:element name="SignatureInfo" type="SignatureInfoCreationType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="SignatureInfoCreationType">
+ <xsd:sequence>
+ <xsd:element name="SignatureEnvironment" type="Base64XMLOptRefContentType"/>
+ <xsd:element name="SignatureLocation">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:token">
+ <xsd:attribute name="Index" type="xsd:nonNegativeInteger" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="MetaInfoType">
+ <xsd:sequence>
+ <xsd:element name="MimeType" type="MimeTypeType"/>
+ <xsd:element name="Description" type="xsd:string" minOccurs="0"/>
+ <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="DataObjectInfoType">
+ <xsd:sequence>
+ <xsd:element name="DataObject" type="Base64XMLLocRefOptRefContentType"/>
+ <xsd:element name="TransformsInfo" type="TransformsInfoType" maxOccurs="unbounded"/>
+ <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="Structure" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="detached"/>
+ <xsd:enumeration value="enveloping"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+ <xsd:complexType name="TransformsInfoType">
+ <xsd:sequence>
+ <xsd:element ref="dsig:Transforms" minOccurs="0"/>
+ <xsd:element name="FinalDataMetaInfo" type="MetaInfoType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Create XML Signature Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateXMLSignatureResponse" type="CreateXMLSignatureResponseType"/>
+ <xsd:complexType name="CreateXMLSignatureResponseType">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Verify CMS Signature # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Verify CMS Signature Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyCMSSignatureRequest" type="VerifyCMSSignatureRequestType"/>
+ <xsd:complexType name="VerifyCMSSignatureRequestType">
+ <xsd:sequence>
+ <xsd:element name="DateTime" type="xsd:dateTime" minOccurs="0"/>
+ <xsd:element name="CMSSignature" type="xsd:base64Binary"/>
+ <xsd:element name="DataObject" type="CMSDataObjectOptionalMetaType" minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="Signatories" type="SignatoriesType" use="optional" default="1"/>
+ </xsd:complexType>
+ <xsd:simpleType name="SignatoriesType">
+ <xsd:union memberTypes="AllSignatoriesType">
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:positiveInteger"/>
+ </xsd:simpleType>
+ </xsd:union>
+ </xsd:simpleType>
+ <xsd:simpleType name="AllSignatoriesType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="all"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--====================================================================== -->
+ <!--= Verify CMS Signature Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyCMSSignatureResponse" type="VerifyCMSSignatureResponseType"/>
+ <xsd:complexType name="VerifyCMSSignatureResponseType">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="SignerInfo" type="dsig:KeyInfoType"/>
+ <xsd:element name="SignatureCheck" type="CheckResultType"/>
+ <xsd:element name="CertificateCheck" type="CheckResultType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="QualifiedCertificate"/>
+ <!--###################################################################### -->
+ <!--# Verify XML Signature # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Verify XML Signature Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyXMLSignatureRequest" type="VerifyXMLSignatureRequestType"/>
+ <xsd:complexType name="VerifyXMLSignatureRequestType">
+ <xsd:sequence>
+ <xsd:element name="DateTime" type="xsd:dateTime" minOccurs="0"/>
+ <xsd:element name="SignatureInfo" type="SignatureInfoVerificationType"/>
+ <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="SignatureInfoVerificationType">
+ <xsd:sequence>
+ <xsd:element name="SignatureEnvironment" type="Base64XMLOptRefContentType"/>
+ <xsd:element name="SignatureLocation" type="xsd:token"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Verify XML Signature Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyXMLSignatureResponse" type="VerifyXMLSignatureResponseType"/>
+ <xsd:complexType name="VerifyXMLSignatureResponseType">
+ <xsd:sequence>
+ <xsd:element name="SignerInfo" type="dsig:KeyInfoType"/>
+ <xsd:element name="SignatureCheck" type="ReferencesCheckResultType"/>
+ <xsd:element name="SignatureManifestCheck" type="ReferencesCheckResultType"/>
+ <xsd:element name="XMLDSIGManifestCheck" type="ManifestRefsCheckResultType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="CertificateCheck" type="CheckResultType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ReferencesCheckResultType">
+ <xsd:sequence>
+ <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
+ <xsd:element name="Info" type="ReferencesCheckResultInfoType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ReferencesCheckResultInfoType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="FailedReference" type="xsd:positiveInteger" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ManifestRefsCheckResultType">
+ <xsd:sequence>
+ <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
+ <xsd:element name="Info" type="ManifestRefsCheckResultInfoType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ManifestRefsCheckResultInfoType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="ReferringSigReference" type="xsd:positiveInteger"/>
+ <xsd:element name="FailedReference" type="xsd:positiveInteger" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="CheckResultType">
+ <xsd:sequence>
+ <xsd:element name="Code" type="xsd:nonNegativeInteger"/>
+ <xsd:element name="Info" type="AnyMixedChildrenType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Encrypt a CMS message # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Encrypt a CMS message: Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="EncryptCMSRequest" type="EncryptCMSRequestType"/>
+ <xsd:complexType name="EncryptCMSRequestType">
+ <xsd:sequence>
+ <xsd:element name="RecipientPublicKey" type="CMSRecipientPublicKeyType" maxOccurs="unbounded"/>
+ <xsd:element name="ToBeEncrypted" type="CMSToBeEncryptedType"/>
+ </xsd:sequence>
+ <xsd:attribute name="ReturnBinaryResult" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ <xsd:complexType name="CMSToBeEncryptedType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType"/>
+ <xsd:element name="Content" type="Base64OptRefContentType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="CMSRecipientPublicKeyType">
+ <xsd:choice>
+ <xsd:element name="X509Certificate" type="xsd:base64Binary"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Encrypt a CMS message: Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="EncryptCMSResponse" type="EncryptCMSResponseType"/>
+ <xsd:complexType name="EncryptCMSResponseType">
+ <xsd:sequence>
+ <xsd:element name="CMSMessage" type="xsd:base64Binary"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Decrypt a CMS message # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Decrypt a CMS message: Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="DecryptCMSRequest" type="DecryptCMSRequestType"/>
+ <xsd:complexType name="DecryptCMSRequestType">
+ <xsd:sequence>
+ <xsd:element name="CMSMessage" type="xsd:base64Binary"/>
+ <xsd:element name="EncryptedContent" type="CMSEncryptedContentType" minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="ReturnResult" type="ReturnResultType" use="optional" default="xml"/>
+ </xsd:complexType>
+ <xsd:complexType name="CMSEncryptedContentType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
+ <xsd:element name="Content" type="Base64OptRefContentType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:simpleType name="ReturnResultType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="binary"/>
+ <xsd:enumeration value="xml"/>
+ <xsd:enumeration value="none"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--====================================================================== -->
+ <!--= Decrypt a CMS message: Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="DecryptCMSResponse" type="DecryptCMSResponseType"/>
+ <xsd:complexType name="DecryptCMSResponseType">
+ <xsd:sequence>
+ <xsd:element name="DecryptedData" type="xsd:base64Binary"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Encrypt an XML document # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Encrypt an XML document: Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="EncryptXMLRequest">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="EncryptXMLRequestType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="EncryptXMLRequestType">
+ <xsd:sequence>
+ <xsd:element name="RecipientPublicKey" type="XMLRecipientPublicKeyType" maxOccurs="unbounded"/>
+ <xsd:element name="ToBeEncrypted" type="ToBeEncryptedType" maxOccurs="unbounded"/>
+ <xsd:element name="EncryptionInfo" type="EncryptionInfoType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ToBeEncryptedType">
+ <xsd:choice>
+ <xsd:element name="Element">
+ <xsd:complexType>
+ <xsd:attribute name="Selector" type="xsd:token" use="required"/>
+ <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ElementContent">
+ <xsd:complexType>
+ <xsd:attribute name="Selector" type="xsd:token" use="required"/>
+ <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="New" type="XMLToBeEncryptedNewType"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="XMLToBeEncryptedNewType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType"/>
+ <xsd:element name="Content" type="XMLToBeEncryptedNewContentType"/>
+ </xsd:sequence>
+ <xsd:attribute name="ParentSelector" type="xsd:token" use="required"/>
+ <xsd:attribute name="NodeCount" type="xsd:nonNegativeInteger" use="required"/>
+ </xsd:complexType>
+ <xsd:complexType name="XMLToBeEncryptedNewContentType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64XMLLocRefContentType">
+ <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="XMLRecipientPublicKeyType">
+ <xsd:choice>
+ <xsd:element ref="dsig:KeyValue"/>
+ <xsd:element name="X509Certificate" type="xsd:base64Binary"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="EncryptionInfoType">
+ <xsd:sequence>
+ <xsd:element name="EncryptionEnvironment" type="Base64XMLOptRefContentType"/>
+ <xsd:element name="EncryptedKeyLocation" minOccurs="0">
+ <xsd:complexType>
+ <xsd:attribute name="ParentSelector" type="xsd:token" use="required"/>
+ <xsd:attribute name="NodeCount" type="xsd:nonNegativeInteger" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Encrypt an XML document: Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="EncryptXMLResponse" type="EncryptXMLResponseType"/>
+ <xsd:complexType name="EncryptXMLResponseType">
+ <xsd:sequence>
+ <xsd:element name="EncryptionEnvironment">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EncryptedData" type="EncryptedDataType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="EncryptedDataType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:base64Binary">
+ <xsd:attribute name="EncDataReference" type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Decrypt an XML document # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Decrypt an XML document: Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="DecryptXMLRequest" type="DecryptXMLRequestType"/>
+ <xsd:complexType name="DecryptXMLRequestType">
+ <xsd:sequence>
+ <xsd:element name="EncryptedContent" type="Base64XMLOptRefContentType"/>
+ <xsd:element name="EncrElemsSelector" type="xsd:string"/>
+ <xsd:element name="Supplement" type="DataObjectAssociationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="ReturnResult" type="ReturnResultType" use="optional" default="xml"/>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Decrypt an XML document: Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="DecryptXMLResponse" type="DecryptXMLResponseType"/>
+ <xsd:complexType name="DecryptXMLResponseType">
+ <xsd:sequence minOccurs="0">
+ <xsd:element name="CandidateDocument" type="XMLContentType"/>
+ <xsd:element name="DecryptedBinaryData" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:base64Binary">
+ <xsd:attribute name="EncrElemSelector" type="xsd:string" use="required"/>
+ <xsd:attribute name="MimeType" type="xsd:string" use="optional"/>
+ <xsd:attribute name="Encoding" type="xsd:anyURI" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Hashing # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Hash Computation Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateHashRequest" type="CreateHashRequestType"/>
+ <xsd:complexType name="CreateHashRequestType">
+ <xsd:sequence>
+ <xsd:element name="HashInfo" type="CreateHashInfoRequestType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="CreateHashInfoRequestType">
+ <xsd:sequence>
+ <xsd:element name="HashData" type="HashDataType"/>
+ <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
+ <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="RespondHashData" type="xsd:boolean" use="required"/>
+ </xsd:complexType>
+ <xsd:complexType name="HashDataType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType"/>
+ <xsd:element name="Content" type="Base64XMLOptRefContentType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Hash Computation Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="CreateHashResponse" type="CreateHashResponseType"/>
+ <xsd:complexType name="CreateHashResponseType">
+ <xsd:sequence>
+ <xsd:element name="HashInfo" type="CreateHashInfoResponseType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="CreateHashInfoResponseType">
+ <xsd:sequence>
+ <xsd:element name="HashData" type="HashDataType" minOccurs="0"/>
+ <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
+ <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="HashValue" type="xsd:base64Binary"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Hash Verification Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyHashRequest" type="VerifyHashRequestType"/>
+ <xsd:complexType name="VerifyHashRequestType">
+ <xsd:sequence>
+ <xsd:element name="HashInfo" type="VerifyHashInfoRequestType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="VerifyHashInfoRequestType">
+ <xsd:sequence>
+ <xsd:element name="HashData" type="HashDataType"/>
+ <xsd:element name="HashAlgorithm" type="xsd:anyURI"/>
+ <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="HashValue" type="xsd:base64Binary"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Hash Verification Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="VerifyHashResponse" type="VerifyHashResponseType"/>
+ <xsd:complexType name="VerifyHashResponseType">
+ <xsd:sequence>
+ <xsd:element name="VerificationResult" type="VerificationResultType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="VerificationResultType">
+ <xsd:sequence>
+ <xsd:element name="FriendlyName" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="Result" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Infobox Commands # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Check Available Infoboxes Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxAvailableRequest" type="InfoboxAvailableRequestType"/>
+ <xsd:complexType name="InfoboxAvailableRequestType"/>
+ <!--====================================================================== -->
+ <!--= Check Available Infoboxes Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxAvailableResponse" type="InfoboxAvailableResponseType"/>
+ <xsd:complexType name="InfoboxAvailableResponseType">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Create Infobox Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxCreateRequest" type="InfoboxCreateRequestType"/>
+ <xsd:complexType name="InfoboxCreateRequestType">
+ <xsd:sequence>
+ <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
+ <xsd:element name="InfoboxType" type="InfoboxTypeType"/>
+ <xsd:element name="Creator" type="xsd:string"/>
+ <xsd:element name="Purpose" type="xsd:string"/>
+ <xsd:element name="ReadAccessAuthorization" type="AccessAuthorizationType" minOccurs="0"/>
+ <xsd:element name="UpdateAccessAuthorization" type="AccessAuthorizationType" minOccurs="0"/>
+ <xsd:element name="ReadUserConfirmation" type="UserConfirmationType" minOccurs="0"/>
+ <xsd:element name="UpdateUserConfirmation" type="UserConfirmationType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:simpleType name="InfoboxTypeType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="BinaryFile"/>
+ <xsd:enumeration value="AssocArray"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType name="AccessAuthorizationType">
+ <xsd:sequence>
+ <xsd:element name="RequesterID" type="RequesterIDType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="UserMayChange" type="xsd:boolean" use="required"/>
+ </xsd:complexType>
+ <xsd:simpleType name="RequesterIDSimpleType">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ <xsd:complexType name="RequesterIDType">
+ <xsd:simpleContent>
+ <xsd:extension base="RequesterIDSimpleType">
+ <xsd:attribute name="AuthenticationClass" type="AuthenticationClassType" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="UserConfirmationType">
+ <xsd:simpleContent>
+ <xsd:extension base="UserConfirmationSimpleType">
+ <xsd:attribute name="UserMayChange" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:simpleType name="UserConfirmationSimpleType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="none"/>
+ <xsd:enumeration value="info"/>
+ <xsd:enumeration value="confirm"/>
+ <xsd:enumeration value="confirmWithSecret"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="AuthenticationClassType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="anonym"/>
+ <xsd:enumeration value="pseudoanonym"/>
+ <xsd:enumeration value="certified"/>
+ <xsd:enumeration value="certifiedGovAgency"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--====================================================================== -->
+ <!--= Create Infobox Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxCreateResponse" type="InfoboxCreateResponseType"/>
+ <xsd:complexType name="InfoboxCreateResponseType"/>
+ <!--====================================================================== -->
+ <!--= Delete Infobox Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxDeleteRequest" type="InfoboxDeleteRequestType"/>
+ <xsd:complexType name="InfoboxDeleteRequestType">
+ <xsd:sequence>
+ <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Delete Infobox Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxDeleteResponse" type="InfoboxDeleteResponseType"/>
+ <xsd:complexType name="InfoboxDeleteResponseType"/>
+ <!--====================================================================== -->
+ <!--= Read Infobox Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxReadRequest" type="InfoboxReadRequestType"/>
+ <xsd:complexType name="InfoboxReadRequestType">
+ <xsd:sequence>
+ <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
+ <xsd:choice>
+ <xsd:element name="BinaryFileParameters" type="InfoboxReadParamsBinaryFileType"/>
+ <xsd:element name="AssocArrayParameters" type="InfoboxReadParamsAssocArrayType"/>
+ </xsd:choice>
+ <xsd:element name="BoxSpecificParameters" type="AnyChildrenType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="InfoboxReadParamsBinaryFileType">
+ <xsd:attribute name="ContentIsXMLEntity" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ <xsd:complexType name="InfoboxReadParamsAssocArrayType">
+ <xsd:choice>
+ <xsd:element name="ReadKeys">
+ <xsd:complexType>
+ <xsd:attribute name="SearchString" type="WildCardSearchStringType" use="required"/>
+ <xsd:attribute name="UserMakesUnique" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ReadPairs">
+ <xsd:complexType>
+ <xsd:attribute name="SearchString" type="WildCardSearchStringType" use="required"/>
+ <xsd:attribute name="UserMakesUnique" type="xsd:boolean" use="optional" default="false"/>
+ <xsd:attribute name="ValuesAreXMLEntities" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ReadValue">
+ <xsd:complexType>
+ <xsd:attribute name="Key" type="BoxIdentifierType" use="required"/>
+ <xsd:attribute name="ValueIsXMLEntity" type="xsd:boolean" use="optional" default="false"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:element name="IdentityLinkDomainIdentifier" type="xsd:anyURI"/>
+ <!--====================================================================== -->
+ <!--= Read Infobox Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxReadResponse" type="InfoboxReadResponseType"/>
+ <xsd:complexType name="InfoboxReadResponseType">
+ <xsd:choice>
+ <xsd:element name="BinaryFileData" type="Base64XMLContentType"/>
+ <xsd:element name="AssocArrayData" type="InfoboxReadDataAssocArrayType"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="InfoboxReadDataAssocArrayType">
+ <xsd:choice>
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="Key" type="BoxIdentifierType"/>
+ </xsd:sequence>
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="Pair" type="InfoboxAssocArrayPairType"/>
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Update Infobox Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxUpdateRequest" type="InfoboxUpdateRequestType"/>
+ <xsd:complexType name="InfoboxUpdateRequestType">
+ <xsd:sequence>
+ <xsd:element name="InfoboxIdentifier" type="BoxIdentifierType"/>
+ <xsd:choice>
+ <xsd:element name="BinaryFileParameters" type="Base64XMLContentType"/>
+ <xsd:element name="AssocArrayParameters" type="InfoboxUpdateParamsAssocArrayType"/>
+ </xsd:choice>
+ <xsd:element name="BoxSpecificParameters" type="AnyChildrenType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="InfoboxUpdateParamsAssocArrayType">
+ <xsd:choice>
+ <xsd:element name="UpdateKey">
+ <xsd:complexType>
+ <xsd:attribute name="Key" type="xsd:token" use="required"/>
+ <xsd:attribute name="NewKey" type="xsd:token" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="UpdateValue" type="InfoboxAssocArrayPairType"/>
+ <xsd:element name="DeletePair">
+ <xsd:complexType>
+ <xsd:attribute name="Key" type="xsd:token" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Update Infobox Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="InfoboxUpdateResponse" type="InfoboxUpdateResponseType"/>
+ <xsd:complexType name="InfoboxUpdateResponseType"/>
+ <!--###################################################################### -->
+ <!--# Null-Operation # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Null-Operation ReQuest = -->
+ <!--====================================================================== -->
+ <xsd:element name="NullOperationRequest" type="NullOperationRequestType"/>
+ <xsd:complexType name="NullOperationRequestType"/>
+ <!--====================================================================== -->
+ <!--= Null-Operation Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="NullOperationResponse" type="NullOperationResponseType"/>
+ <xsd:complexType name="NullOperationResponseType"/>
+ <!--###################################################################### -->
+ <!--# Get Properties # -->
+ <!--###################################################################### -->
+ <xsd:element name="GetPropertiesRequest">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="GetPropertiesRequestType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="GetPropertiesRequestType"/>
+ <!--====================================================================== -->
+ <!--= Get Properties Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="GetPropertiesResponse" type="GetPropertiesResponseType"/>
+ <xsd:complexType name="GetPropertiesResponseType">
+ <xsd:sequence>
+ <xsd:element name="ViewerMediaType" type="MimeTypeType" maxOccurs="unbounded"/>
+ <xsd:element name="XMLSignatureTransform" type="xsd:anyURI" maxOccurs="unbounded"/>
+ <xsd:element name="KeyboxIdentifier" type="QualifiedBoxIdentifierType" minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="Binding" type="BindingType" maxOccurs="unbounded"/>
+ <xsd:element name="ProtocolVersion" type="xsd:token" maxOccurs="unbounded"/>
+ <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="BindingType">
+ <xsd:complexContent>
+ <xsd:extension base="AnyChildrenType">
+ <xsd:attribute name="Identifier" type="xsd:token" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="QualifiedBoxIdentifierType">
+ <xsd:simpleContent>
+ <xsd:extension base="BoxIdentifierType">
+ <xsd:attribute name="Signature" type="xsd:boolean" use="required"/>
+ <xsd:attribute name="Encryption" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Get Token Status # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= Get Token Status Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="GetStatusRequest" type="GetStatusRequestType"/>
+ <xsd:complexType name="GetStatusRequestType">
+ <xsd:sequence minOccurs="0">
+ <xsd:element name="TokenStatus" type="TokenStatusType"/>
+ <xsd:element name="MaxDelay" type="xsd:nonNegativeInteger"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= Get Token Status Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="GetStatusResponse" type="GetStatusResponseType"/>
+ <xsd:complexType name="GetStatusResponseType">
+ <xsd:sequence>
+ <xsd:element name="TokenStatus" type="TokenStatusType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:simpleType name="TokenStatusType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="ready"/>
+ <xsd:enumeration value="removed"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--###################################################################### -->
+ <!--# CardManagement # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= CardManagement Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="CardManagementRequest">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="CardAction" type="CardActionElement" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="CardActionElement">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="Action" type="CardActionType" use="required" />
+ <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
+ <xsd:attribute name="Name" type="xsd:string" use="optional" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= CardManagement Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="CardManagementResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="Result" type="ResultElement" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ResultApplElement">
+ <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ <xsd:attribute name="Status" type="CardActionResponseType" use="required" />
+ <xsd:attribute name="RetryCount" type="xsd:integer" use="optional" />
+ </xsd:complexType>
+ <xsd:complexType name="ResultElement">
+ <xsd:attribute name="CardAction" type="CardActionType" use="required" />
+ <xsd:attribute name="ApplicationIdentifier" type="ApplicationIdentifierType" use="required" />
+ <xsd:attribute name="Result" type="CardActionResponseType" use="required" />
+ <xsd:attribute name="RetryCount" type="xsd:integer" use="optional" />
+ </xsd:complexType>
+ <xsd:simpleType name="CardActionType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="ActivatePIN" />
+ <xsd:enumeration value="ChangePIN" />
+ <xsd:enumeration value="ReadPINStatus" />
+ <xsd:enumeration value="UnblockPIN" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="ApplicationIdentifierType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="SecureSignatureApplication" />
+ <xsd:enumeration value="CertifiedApplication" />
+ <xsd:enumeration value="InfoboxApplication" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="CardActionResponseType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="OK" />
+ <xsd:enumeration value="Error" />
+ <xsd:enumeration value="Blocked" />
+ <xsd:enumeration value="Activ" />
+ <xsd:enumeration value="Inactive" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--###################################################################### -->
+ <!--# CardChannel # -->
+ <!--###################################################################### -->
+ <!--====================================================================== -->
+ <!--= CardChannel Request = -->
+ <!--====================================================================== -->
+ <xsd:element name="CardChannelRequest">
+ <xsd:complexType>
+ <xsd:sequence minOccurs="1" maxOccurs="1">
+ <xsd:element name="Script" type="ScriptElement" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ScriptElement">
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <xsd:element name="Reset" type="ResetType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="CommandAPDU" type="CommandAPDUType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="ResetType">
+ <xsd:attribute name="cold" type="ResetColdType" use="optional" />
+ </xsd:complexType>
+ <xsd:simpleType name="ResetColdType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="true" />
+ <xsd:enumeration value="false" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType name="CommandAPDUType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="sequence" type="xsd:integer" use="required" />
+ <xsd:attribute name="of" type="xsd:integer" use="required" />
+ <xsd:attribute name="expectedSW" type="xsd:string" use="optional" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!--====================================================================== -->
+ <!--= CardChannel Response = -->
+ <!--====================================================================== -->
+ <xsd:element name="CardChannelResponse">
+ <xsd:complexType>
+ <xsd:sequence minOccurs="1" maxOccurs="1">
+ <xsd:element name="Response" type="APDUResponseElement" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="APDUResponseElement">
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <xsd:element name="ATR" type="APDUATRType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="ResponseAPDU" type="ResponseAPDUType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="APDUATRType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="rc" type="xsd:integer" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <xsd:complexType name="ResponseAPDUType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="sequence" type="xsd:integer" use="required" />
+ <xsd:attribute name="rc" type="xsd:integer" use="required" />
+ <xsd:attribute name="SW" type="xsd:string" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Bulk Request # -->
+ <!--###################################################################### -->
+ <xsd:element name="BulkRequest" type="BulkRequestType"/>
+ <xsd:complexType name="BulkRequestType">
+ <xsd:choice>
+ <xsd:element name="CreateSignatureRequest" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="CreateCMSSignatureRequest"/>
+ <xsd:element ref="CreateXMLSignatureRequest"/>
+ </xsd:choice>
+ <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="VerifySignatureRequest" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="VerifyCMSSignatureRequest"/>
+ <xsd:element ref="VerifyXMLSignatureRequest"/>
+ </xsd:choice>
+ <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EncryptRequest" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="EncryptCMSRequest"/>
+ <xsd:element ref="EncryptXMLRequest"/>
+ </xsd:choice>
+ <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DecryptRequest" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="DecryptCMSRequest"/>
+ <xsd:element ref="DecryptXMLRequest"/>
+ </xsd:choice>
+ <xsd:attribute name="displayName" type="xsd:string" use="optional"/>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Bulk Response # -->
+ <!--###################################################################### -->
+ <xsd:element name="BulkResponse" type="BulkResponseType"/>
+ <xsd:complexType name="BulkResponseType">
+ <xsd:choice>
+ <xsd:element name="CreateSignatureResponse" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="CreateCMSSignatureResponse"/>
+ <xsd:element ref="CreateXMLSignatureResponse"/>
+ <xsd:element ref="ErrorResponse"/>
+ </xsd:choice>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="VerifySignatureResponse" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="VerifyCMSSignatureResponse"/>
+ <xsd:element ref="VerifyXMLSignatureResponse"/>
+ <xsd:element ref="ErrorResponse"/>
+ </xsd:choice>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EncryptResponse" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="EncryptCMSResponse"/>
+ <xsd:element ref="EncryptXMLResponse"/>
+ <xsd:element ref="ErrorResponse"/>
+ </xsd:choice>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DecryptResponse" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="DecryptCMSResponse"/>
+ <xsd:element ref="DecryptXMLResponse"/>
+ <xsd:element ref="ErrorResponse"/>
+ </xsd:choice>
+ <xsd:attribute name="id" type="xsd:ID" use="optional"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ <!--###################################################################### -->
+ <!--# Error Response # -->
+ <!--###################################################################### -->
+ <xsd:element name="ErrorResponse" type="ErrorResponseType"/>
+ <xsd:complexType name="ErrorResponseType">
+ <xsd:sequence>
+ <xsd:element name="ErrorCode" type="ErrorCodeType"/>
+ <xsd:element name="Info" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:simpleType name="ErrorCodeType">
+ <xsd:restriction base="xsd:integer">
+ <xsd:minInclusive value="1000"/>
+ <xsd:maxInclusive value="99999"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!--###################################################################### -->
+ <!--# Auxiliary Types # -->
+ <!--###################################################################### -->
+ <xsd:simpleType name="BoxIdentifierType">
+ <xsd:restriction base="xsd:token"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="MimeTypeType">
+ <xsd:restriction base="xsd:token"/>
+ </xsd:simpleType>
+ <xsd:simpleType name="WildCardSearchStringType">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="[^\*/]*(\*[^\*/]*)?(/[^\*/]*(\*[^\*/]*)?)*"/>
+ <xsd:pattern value="\*\*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType name="InfoboxAssocArrayPairType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64XMLContentType">
+ <xsd:attribute name="Key" type="xsd:string" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="AnyChildrenType" mixed="false">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:any namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="AnyMixedChildrenType" mixed="true">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:any namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="XMLContentType" mixed="true">
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="AnyMixedChildrenType">
+ <xsd:attribute ref="xml:space" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="Base64XMLLocRefOptRefContentType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64XMLLocRefContentType">
+ <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="Base64XMLLocRefReqRefContentType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64XMLLocRefContentType">
+ <xsd:attribute name="Reference" type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="Base64XMLOptRefContentType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64XMLContentType">
+ <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="DigestAndRefType">
+ <xsd:sequence>
+ <xsd:element ref="dsig:DigestMethod" />
+ <xsd:element ref="dsig:DigestValue" />
+ </xsd:sequence>
+ <xsd:attribute name="Reference" type="xsd:anyURI" />
+ </xsd:complexType>
+ <xsd:complexType name="Base64OptRefContentType">
+ <xsd:complexContent>
+ <xsd:extension base="Base64ContentType">
+ <xsd:attribute name="Reference" type="xsd:anyURI" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="Base64ContentType">
+ <xsd:choice minOccurs="0">
+ <xsd:element name="Base64Content" type="xsd:base64Binary"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="Base64XMLContentType">
+ <xsd:choice minOccurs="0">
+ <xsd:element name="Base64Content" type="xsd:base64Binary"/>
+ <xsd:element name="XMLContent" type="XMLContentType"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="Base64XMLLocRefContentType">
+ <xsd:choice minOccurs="0">
+ <xsd:element name="Base64Content" type="xsd:base64Binary"/>
+ <xsd:element name="XMLContent" type="XMLContentType"/>
+ <xsd:element name="LocRefContent" type="xsd:anyURI"/>
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="DataObjectAssociationType">
+ <xsd:sequence>
+ <xsd:element name="MetaInfo" type="MetaInfoType" minOccurs="0"/>
+ <xsd:element name="Content" type="Base64XMLLocRefReqRefContentType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+</xsd:schema>