diff options
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 <clemens.orthacker@iaik.tugraz.at>   */ -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 <clemens.orthacker@iaik.tugraz.at> + * @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 <clemens.orthacker@iaik.tugraz.at>   */ -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> + * <complexType name="BulkSignRequestType"> + *   <complexContent> + *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + *       <sequence maxOccurs="unbounded"> + *         <element name="SignRequests" type="{http://www.egiz.gv.at/stal}SignRequestType"/> + *       </sequence> + *     </restriction> + *   </complexContent> + * </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> + * <complexType name="BulkSignResponseType"> + *   <complexContent> + *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + *       <sequence maxOccurs="unbounded"> + *         <element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/> + *       </sequence> + *     </restriction> + *   </complexContent> + * </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;   *         </element>   *         <element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>   *         <element name="DigestMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> + *         <element name="displayName" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"> + *         <element name="mimeType" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/>   *         <element name="ExcludedByteRange" minOccurs="0">   *           <complexType>   *             <complexContent> @@ -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> + * <complexType name="BulkSignRequestType"> + *   <complexContent> + *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + *       <sequence maxOccurs="unbounded"> + *         <element name="SignRequests" type="{http://www.egiz.gv.at/stal}SignRequestType"/> + *       </sequence> + *     </restriction> + *   </complexContent> + * </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> + * <complexType name="BulkSignResponseType"> + *   <complexContent> + *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + *       <sequence maxOccurs="unbounded"> + *         <element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/> + *       </sequence> + *     </restriction> + *   </complexContent> + * </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;   *             <complexContent>   *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">   *                 <attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /> + *                 <attribute name="digest" type="{http://www.w3.org/2001/XMLSchema}base64Binary" //>   *               </restriction>   *             </complexContent>   *           </complexType> @@ -133,13 +132,14 @@ public class GetHashDataInputType {       * <p>The following schema fragment specifies the expected content contained within this class.       *        * <pre> -     * <complexType> -     *   <complexContent> -     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> -     *       <attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /> -     *     </restriction> -     *   </complexContent> -     * </complexType> +     * <complexType> +     *   <complexContent> +     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> +     *       <attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /> +     *       <attribute name="digest" type="{http://www.w3.org/2001/XMLSchema}base64Binary" /> +     *     </restriction> +     *   </complexContent> +     * </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;   *       <choice maxOccurs="unbounded">   *         <element name="InfoboxReadRequest" type="{http://www.egiz.gv.at/stal}InfoboxReadRequestType"/>   *         <element name="SignRequest" type="{http://www.egiz.gv.at/stal}SignRequestType"/> + *         <element name="BulkSignRequest" type="{http://www.egiz.gv.at/stal}BulkSignRequestType"/>   *         <element name="QuitRequest" type="{http://www.egiz.gv.at/stal}QuitRequestType"/>   *         <element name="StatusRequest" type="{http://www.egiz.gv.at/stal}StatusRequestType"/>   *         <element ref="{http://www.egiz.gv.at/stal}OtherRequest"/> @@ -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;   *       <choice maxOccurs="unbounded">   *         <element name="InfoboxReadResponse" type="{http://www.egiz.gv.at/stal}InfoboxReadResponseType"/>   *         <element name="SignResponse" type="{http://www.egiz.gv.at/stal}SignResponseType"/> + *         <element name="BulkSignResponse" type="{http://www.egiz.gv.at/stal}BulkSignResponseType"/>   *         <element name="ErrorResponse" type="{http://www.egiz.gv.at/stal}ErrorResponseType"/>   *         <element name="StatusResponse" type="{http://www.egiz.gv.at/stal}StatusResponseType"/>   *         <element ref="{http://www.egiz.gv.at/stal}OtherResponse"/> @@ -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;   *         </element>   *         <element name="SignatureMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>   *         <element name="DigestMethod" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> + *         <element name="displayName" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/> + *         <element name="mimeType" type="{http://www.w3.org/2001/XMLSchema}string minOccurs="0"/>   *         <element name="ExcludedByteRange" minOccurs="0">   *           <complexType>   *             <complexContent> @@ -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> -     * <complexType> -     *   <complexContent> -     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> -     *       <attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /> -     *       <attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /> -     *     </restriction> -     *   </complexContent> -     * </complexType> +     * <complexType> +     *   <complexContent> +     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> +     *       <attribute name="from" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /> +     *       <attribute name="to" use="required" type="{http://www.w3.org/2001/XMLSchema}unsignedLong" /> +     *     </restriction> +     *   </complexContent> +     * </complexType>       * </pre>       *        *  @@ -313,13 +370,13 @@ public class SignRequestType       * <p>The following schema fragment specifies the expected content contained within this class.       *        * <pre> -     * <complexType> -     *   <simpleContent> -     *     <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> -     *       <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> -     *     </extension> -     *   </simpleContent> -     * </complexType> +     * <complexType> +     *   <simpleContent> +     *     <extension base="<http://www.w3.org/2001/XMLSchema>base64Binary"> +     *       <attribute name="IsCMSSignedAttributes" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /> +     *     </extension> +     *   </simpleContent> +     * </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 "Rössler""> +		<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 "Meyer""> +		<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 "Rössler""> +    <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 "Meyer""> +		<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> @@ -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;   *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">   *       <sequence>   *         <element name="MetaInfo" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}MetaInfoType" minOccurs="0"/> - *         <element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/> + *         <choice> + *           <element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/> + *           <element name="DigestAndRef" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}DigestAndRefType"/> + *         </choice>   *         <element name="ExcludedByteRange" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}ExcludedByteRangeType" minOccurs="0"/>   *       </sequence>   *     </restriction> @@ -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> + * <complexType name="CMSReferenceObject"> + *   <complexContent> + *     <restriction base="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectOptionalMetaType"> + *       <sequence> + *         <element name="MetaInfo" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}MetaInfoType"/> + *         <choice> + *           <element name="Content" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}Base64OptRefContentType"/> + *           <element name="DigestAndRef" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}DigestAndRefType"/> + *         </choice> + *         <element name="ExcludedByteRange" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}ExcludedByteRangeType" minOccurs="0"/> + *       </sequence> + *     </restriction> + *   </complexContent> + * </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;   *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">   *       <sequence>   *         <element name="KeyboxIdentifier" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}BoxIdentifierType"/> - *         <element name="DataObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectRequiredMetaType"/> + *         <choice> + *           <element name="DataObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSDataObjectRequiredMetaType"/> + *           <element name="ReferenceObject" type="{http://www.buergerkarte.at/namespaces/securitylayer/1.2#}CMSReferenceObject"/> + *         </choice>   *       </sequence>   *       <attribute name="Structure" use="required">   *         <simpleType> @@ -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> + * <complexType name="DigestAndRefType"> + *   <complexContent> + *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + *       <sequence> + *         <element ref="{http://www.w3.org/2000/09/xmldsig#}DigestMethod"/> + *         <element ref="{http://www.w3.org/2000/09/xmldsig#}DigestValue"/> + *       </sequence> + *       <attribute name="Reference" type="{http://www.w3.org/2001/XMLSchema}anyURI" /> + *     </restriction> + *   </complexContent> + * </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> | 
