summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java9
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java519
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java47
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINSpecRenderer.java (renamed from STALExt/src/main/java/at/gv/egiz/stal/ext/ChangePINRequest.java)17
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusRenderer.java63
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java60
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementApplet.java3
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementBKUWorker.java82
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java331
-rw-r--r--BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINMgmtRequestHandler.java93
-rw-r--r--BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties28
-rw-r--r--BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties30
-rw-r--r--BKUAppletExt/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java4
-rw-r--r--BKUAppletExt/src/test/resources/appletTest.html2
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/BKUGUIImpl.java8
-rw-r--r--BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java28
-rw-r--r--BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties4
-rw-r--r--BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java2
-rw-r--r--STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementRequest.java (renamed from STALExt/src/main/java/at/gv/egiz/stal/ext/ActivatePINRequest.java)5
-rw-r--r--STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementResponse.java (renamed from STALExt/src/main/java/at/gv/egiz/stal/ext/UnblockPINRequest.java)4
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java2078
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java5
-rw-r--r--bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java1505
-rw-r--r--bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/TransformsInfo_2.xml397
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java25
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java10
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java30
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java25
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java14
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java5
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractBKUWorker.java3
-rw-r--r--smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java9
-rw-r--r--utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java (renamed from BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusProvider.java)18
-rw-r--r--utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java16
-rw-r--r--utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java389
-rw-r--r--utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java1
-rw-r--r--utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java2
-rw-r--r--utils/src/main/java/org/w3/_2000/_09/xmldsig_/ObjectFactory.java1
-rw-r--r--utils/src/main/java/org/w3/_2000/_09/xmldsig_/TransformsType.java2
-rw-r--r--utils/src/test/java/at/gv/egiz/slbinding/RedirectTest.java29
-rw-r--r--utils/src/test/requests/CreateXMLSignatureRequest02.xml_redirect.txt5
41 files changed, 3711 insertions, 2197 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 5a57ef18..8c1bd2bd 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
@@ -195,11 +195,16 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable {
}
}
+ /**
+ *
+ * @param err_code
+ * @param ex if not null, the message will be appended as parameter to the error message
+ */
protected void showErrorDialog(String err_code, Exception ex) {
actionCommandList.clear();
actionCommandList.add("ok");
- gui.showErrorDialog(err_code,
- new Object[]{ex.getMessage()}, this, "ok");
+ Object[] params = (ex != null) ? new Object[] { ex.getMessage() } : null;
+ gui.showErrorDialog(err_code, params, this, "ok");
try {
waitForAction();
} catch (InterruptedException e) {
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
index 8acf051e..8eef8aea 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUI.java
@@ -17,15 +17,28 @@
package at.gv.egiz.bku.gui;
+import at.gv.egiz.smcc.PINSpec;
import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
import java.net.URL;
+import java.text.MessageFormat;
import java.util.Locale;
+import java.util.Map;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
+import javax.swing.JPasswordField;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
import javax.swing.LayoutStyle;
+import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
/**
* TODO pull out ResourceBundle to common superclass for activationGUI and pinMgmtGUI
@@ -33,9 +46,10 @@ import javax.swing.SwingUtilities;
*/
public class PINManagementGUI extends ActivationGUI implements PINManagementGUIFacade {
- public static final String BUTTON_ACTIVATE = "button.activate";
- public static final String BUTTON_UNBLOCK = "button.unblock";
- public static final String BUTTON_CHANGE = "button.change";
+ /** remember the pinfield to return to worker */
+ protected JPasswordField oldPinField;
+ /** remember the pinSpec to return to worker */
+ protected PINSpec pinSpec;
public PINManagementGUI(Container contentPane,
Locale locale,
@@ -46,12 +60,31 @@ public class PINManagementGUI extends ActivationGUI implements PINManagementGUIF
}
@Override
- public void showPINManagementDialog(final PINStatusProvider pinStatusProvider,
- final ActionListener activateListener, final String activateCmd,
- final ActionListener changeListener, final String changeCmd,
- final ActionListener unblockListener, final String unblockCmd,
- final ActionListener cancelListener, final String cancelCmd) {
-// try {
+ public char[] getOldPin() {
+ if (oldPinField != null) {
+ char[] pin = oldPinField.getPassword();
+ oldPinField = null;
+ return pin;
+ }
+ return null;
+ }
+
+ @Override
+ public PINSpec getSelectedPIN() {
+ return pinSpec;
+ }
+
+ @Override
+ public void showPINManagementDialog(final Map<PINSpec, STATUS> pins,
+ final ActionListener activateListener,
+ final String activateCmd,
+ final String changeCmd,
+ final String unblockCmd,
+ final ActionListener cancelListener,
+ final String cancelCmd) {
+
+ log.debug("scheduling PIN managment dialog");
+
SwingUtilities.invokeLater(new Runnable() {
@Override
@@ -68,13 +101,76 @@ public class PINManagementGUI extends ActivationGUI implements PINManagementGUIF
if (renderHeaderPanel) {
titleLabel.setText(cardmgmtMessages.getString(TITLE_PINMGMT));
- mgmtLabel.setText(cardmgmtMessages.getString(MESSAGE_PINMGMT));
+ String infoPattern = cardmgmtMessages.getString(MESSAGE_PINMGMT);
+ mgmtLabel.setText(MessageFormat.format(infoPattern, pins.size()));
} else {
mgmtLabel.setText(cardmgmtMessages.getString(TITLE_PINMGMT));
}
+ final PINStatusTableModel tableModel = new PINStatusTableModel(pins);
+ final JTable pinStatusTable = new JTable(tableModel);
+ pinStatusTable.setDefaultRenderer(PINSpec.class, new PINSpecRenderer());
+ pinStatusTable.setDefaultRenderer(STATUS.class, new PINStatusRenderer(cardmgmtMessages));
+ pinStatusTable.setTableHeader(null);
-
+ pinStatusTable.addMouseMotionListener(new MouseMotionAdapter() {
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if (pinStatusTable.columnAtPoint(e.getPoint()) == 0) {
+ pinStatusTable.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ } else {
+ pinStatusTable.setCursor(Cursor.getDefaultCursor());
+ }
+ }
+ });
+
+ final JButton activateButton = new JButton();
+ activateButton.setFont(activateButton.getFont().deriveFont(activateButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ activateButton.addActionListener(activateListener);
+
+ pinStatusTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ pinStatusTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ //invoke later to allow thread to paint selection background
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+ int selectionIdx = lsm.getMinSelectionIndex();
+ if (selectionIdx >= 0) {
+ pinSpec = (PINSpec) tableModel.getValueAt(selectionIdx, 0);
+ STATUS status = (STATUS) tableModel.getValueAt(selectionIdx, 1);
+
+ if (status == STATUS.NOT_ACTIV) {
+ activateButton.setText(cardmgmtMessages.getString(BUTTON_ACTIVATE));
+ activateButton.setEnabled(true);
+ activateButton.setActionCommand(activateCmd);
+ } else if (status == STATUS.BLOCKED) {
+ activateButton.setText(cardmgmtMessages.getString(BUTTON_UNBLOCK));
+ activateButton.setEnabled(true);
+ activateButton.setActionCommand(unblockCmd);
+ } else if (status == STATUS.ACTIV) {
+ activateButton.setText(cardmgmtMessages.getString(BUTTON_CHANGE));
+ activateButton.setEnabled(true);
+ activateButton.setActionCommand(changeCmd);
+ } else {
+ activateButton.setText(cardmgmtMessages.getString(BUTTON_ACTIVATE));
+ activateButton.setEnabled(false);
+ }
+ }
+ }
+ });
+ }
+ });
+
+ //select first entry
+ pinStatusTable.getSelectionModel().setSelectionInterval(0, 0);
+
+ JScrollPane pinStatusScrollPane = new JScrollPane(pinStatusTable);
GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
mainPanel.setLayout(mainPanelLayout);
@@ -91,30 +187,16 @@ public class PINManagementGUI extends ActivationGUI implements PINManagementGUIF
.addComponent(helpLabel);
}
- mainPanelLayout.setHorizontalGroup(messageHorizontal);
- mainPanelLayout.setVerticalGroup(messageVertical);
+ mainPanelLayout.setHorizontalGroup(
+ mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(messageHorizontal)
+ .addComponent(pinStatusScrollPane, 0, 0, Short.MAX_VALUE));
-
- JButton activateButton = new JButton();
- activateButton.setFont(activateButton.getFont().deriveFont(activateButton.getFont().getStyle() & ~java.awt.Font.BOLD));
- activateButton.setText(cardmgmtMessages.getString(BUTTON_ACTIVATE));
- activateButton.setEnabled(true);//false);
- activateButton.setActionCommand(activateCmd);
- activateButton.addActionListener(activateListener);
-
- JButton changeButton = new JButton();
- changeButton.setFont(activateButton.getFont().deriveFont(activateButton.getFont().getStyle() & ~java.awt.Font.BOLD));
- changeButton.setText(cardmgmtMessages.getString(BUTTON_CHANGE));
- changeButton.setEnabled(false);
- changeButton.setActionCommand(changeCmd);
- changeButton.addActionListener(changeListener);
-
- JButton unblockButton = new JButton();
- unblockButton.setFont(activateButton.getFont().deriveFont(activateButton.getFont().getStyle() & ~java.awt.Font.BOLD));
- unblockButton.setText(cardmgmtMessages.getString(BUTTON_UNBLOCK));
- unblockButton.setEnabled(false);
- unblockButton.setActionCommand(unblockCmd);
- unblockButton.addActionListener(unblockListener);
+ mainPanelLayout.setVerticalGroup(
+ mainPanelLayout.createSequentialGroup()
+ .addGroup(messageVertical)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinStatusScrollPane, 0, 0, pinStatusTable.getPreferredSize().height+3));
JButton cancelButton = new JButton();
cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
@@ -129,30 +211,377 @@ public class PINManagementGUI extends ActivationGUI implements PINManagementGUIF
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(activateButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(changeButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(unblockButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE);
GroupLayout.Group buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(activateButton)
- .addComponent(changeButton)
- .addComponent(unblockButton)
.addComponent(cancelButton);
buttonPanelLayout.setHorizontalGroup(buttonHorizontal);
buttonPanelLayout.setVerticalGroup(buttonVertical);
contentPanel.validate();
-
}
});
+ }
+
+ @Override
+ public void showActivatePINDialog(final PINSpec pin,
+ final ActionListener okListener, final String okCommand,
+ final ActionListener cancelListener, final String cancelCommand) {
+ log.debug("scheduling activate pin dialog");
+ showPINDialog(false, pin, okListener, okCommand, cancelListener, cancelCommand);
+ }
+
+
+ private void showPINDialog(final boolean changePin, final PINSpec pinSpec,
+ final ActionListener okListener, final String okCommand,
+ final ActionListener cancelListener, final String cancelCommand) {
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ String HELP_TOPIC, TITLE, MESSAGE_MGMT;
+ if (changePin) {
+ log.debug("show change pin dialog");
+ HELP_TOPIC = HELP_PINMGMT;
+ TITLE = TITLE_CHANGE_PIN;
+ MESSAGE_MGMT = MESSAGE_CHANGE_PIN;
+ } else {
+ log.debug("show activate pin dialog");
+ HELP_TOPIC = HELP_PINMGMT;
+ TITLE = TITLE_ACTIVATE_PIN;
+ MESSAGE_MGMT = MESSAGE_ACTIVATE_PIN;
+ oldPinField = null;
+ }
+
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
+
+ helpListener.setHelpTopic(HELP_TOPIC);
+
+ JLabel mgmtLabel = new JLabel();
+ mgmtLabel.setFont(mgmtLabel.getFont().deriveFont(mgmtLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(cardmgmtMessages.getString(TITLE));
+ String mgmtPattern = cardmgmtMessages.getString(MESSAGE_MGMT);
+ if (shortText) {
+ mgmtLabel.setText(MessageFormat.format(mgmtPattern, "PIN"));
+ } else {
+ mgmtLabel.setText(MessageFormat.format(mgmtPattern, pinSpec.getLocalizedName()));
+ }
+ } else {
+ mgmtLabel.setText(cardmgmtMessages.getString(TITLE));
+ }
+
+ JButton okButton = new JButton();
+ okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ okButton.setText(messages.getString(BUTTON_OK));
+ okButton.setEnabled(false);
+ okButton.setActionCommand(okCommand);
+ okButton.addActionListener(okListener);
+
+ JLabel pinLabel = new JLabel();
+ pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ String pinLabelPattern = (changePin) ? cardmgmtMessages.getString(LABEL_NEW_PIN) : messages.getString(LABEL_PIN);
+ pinLabel.setText(MessageFormat.format(pinLabelPattern, new Object[]{pinSpec.getLocalizedName()}));
+
+ final JPasswordField repeatPinField = new JPasswordField();
+ pinField = new JPasswordField();
+ pinField.setText("");
+ pinField.setDocument(new PINDocument(pinSpec, null));
+ pinField.setActionCommand(okCommand);
+ pinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (pinField.getPassword().length >= pinSpec.getMinLength()) {
+ repeatPinField.requestFocusInWindow();
+ }
+ }
+ });
+ JLabel repeatPinLabel = new JLabel();
+ repeatPinLabel.setFont(pinLabel.getFont());
+ String repeatPinLabelPattern = cardmgmtMessages.getString(LABEL_REPEAT_PIN);
+ repeatPinLabel.setText(MessageFormat.format(repeatPinLabelPattern, new Object[]{pinSpec.getLocalizedName()}));
+
+ repeatPinField.setText("");
+ repeatPinField.setDocument(new PINDocument(pinSpec, okButton, pinField.getDocument()));
+ repeatPinField.setActionCommand(okCommand);
+ repeatPinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (pinField.getPassword().length >= pinSpec.getMinLength()) {
+ okListener.actionPerformed(e);
+ }
+ }
+ });
+
+ JLabel oldPinLabel = null;
+ if (changePin) {
+ oldPinLabel = new JLabel();
+ oldPinLabel.setFont(oldPinLabel.getFont().deriveFont(oldPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ String oldPinLabelPattern = cardmgmtMessages.getString(LABEL_OLD_PIN);
+ oldPinLabel.setText(MessageFormat.format(oldPinLabelPattern, new Object[]{pinSpec.getLocalizedName()}));
+
+ oldPinField = new JPasswordField();
+ oldPinField.setText("");
+ oldPinField.setDocument(new PINDocument(pinSpec, null));
+ oldPinField.setActionCommand(okCommand);
+ oldPinField.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (oldPinField.getPassword().length >= pinSpec.getMinLength()) {
+ pinField.requestFocusInWindow();
+ }
+ }
+ });
+ }
+
+ JLabel pinsizeLabel = new JLabel();
+ pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(pinsizeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, pinsizeLabel.getFont().getSize()-2));
+ String pinsizePattern = messages.getString(LABEL_PINSIZE);
+ String pinSize = String.valueOf(pinSpec.getMinLength());
+ if (pinSpec.getMinLength() != pinSpec.getMaxLength()) {
+ pinSize += "-" + pinSpec.getMaxLength();
+ }
+ pinsizeLabel.setText(MessageFormat.format(pinsizePattern, new Object[]{pinSize}));
+
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.SequentialGroup infoHorizontal = mainPanelLayout.createSequentialGroup()
+ .addComponent(mgmtLabel);
+ GroupLayout.ParallelGroup infoVertical = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(mgmtLabel);
+
+ if (!renderHeaderPanel) {
+ infoHorizontal
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(helpLabel);
+ infoVertical
+ .addComponent(helpLabel);
+ }
-// } catch (Exception ex) {
-// log.error(ex.getMessage(), ex);
-// showErrorDialog(ERR_UNKNOWN_WITH_PARAM, new Object[] {ex.getMessage()});
-// }
+ GroupLayout.ParallelGroup pinHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING);
+ GroupLayout.SequentialGroup pinVertical = mainPanelLayout.createSequentialGroup();
+
+ if (pinLabelPos == PinLabelPosition.ABOVE) {
+ if (changePin) {
+ pinHorizontal
+ .addComponent(oldPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(oldPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
+ pinVertical
+ .addComponent(oldPinLabel)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(oldPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
+ }
+ pinHorizontal
+ .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(repeatPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(repeatPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE));
+ pinVertical
+ .addComponent(pinLabel)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(repeatPinLabel)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(repeatPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinsizeLabel);
+ } else {
+ if (changePin) {
+ pinHorizontal
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(oldPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(repeatPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(oldPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(repeatPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+
+ pinVertical
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(oldPinLabel)
+ .addComponent(oldPinField))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
+ } else {
+ pinHorizontal
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(repeatPinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(repeatPinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+
+ }
+ pinHorizontal
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE));
+ pinVertical
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(pinLabel)
+ .addComponent(pinField))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(repeatPinLabel)
+ .addComponent(repeatPinField))
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(pinsizeLabel);
+ }
+
+ mainPanelLayout.setHorizontalGroup(
+ mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(infoHorizontal)
+ .addGroup(pinHorizontal));
+
+ mainPanelLayout.setVerticalGroup(
+ mainPanelLayout.createSequentialGroup()
+ .addGroup(infoVertical)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(pinVertical));
+
+ GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
+ buttonPanel.setLayout(buttonPanelLayout);
+
+ GroupLayout.SequentialGroup buttonHorizontal = buttonPanelLayout.createSequentialGroup()
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(okButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE);
+ GroupLayout.Group buttonVertical;
+
+ JButton cancelButton = new JButton();
+ cancelButton.setFont(cancelButton.getFont().deriveFont(cancelButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ cancelButton.setText(messages.getString(BUTTON_CANCEL));
+ cancelButton.setActionCommand(cancelCommand);
+ cancelButton.addActionListener(cancelListener);
+
+ buttonHorizontal
+ .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cancelButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE);
+ buttonVertical = buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+ .addComponent(okButton)
+ .addComponent(cancelButton);
+
+ buttonPanelLayout.setHorizontalGroup(buttonHorizontal);
+ buttonPanelLayout.setVerticalGroup(buttonVertical);
+
+ if (oldPinField != null) {
+ oldPinField.requestFocusInWindow();
+ } else {
+ pinField.requestFocusInWindow();
+ }
+ contentPanel.validate();
+
+ }
+ });
+ }
+
+ @Override
+ public void showChangePINDialog(final PINSpec pin,
+ final ActionListener okListener, final String okCommand,
+ final ActionListener cancelListener, final String cancelCommand) {
+
+ log.debug("scheduling change pin dialog");
+ showPINDialog(true, pin, okListener, okCommand, cancelListener, cancelCommand);
+ }
+
+ @Override
+ public void showUnblockPINDialog(final PINSpec pin,
+ final ActionListener okListener, final String okCommand,
+ final ActionListener cancelListener, final String cancelCommand) {
+
+ log.debug("scheduling unblock PIN dialog");
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+
+ log.debug("show unblock PIN dialog");
+
+ log.error("unblock pin not supported");
+
+ mainPanel.removeAll();
+ buttonPanel.removeAll();
+
+ if (renderHeaderPanel) {
+ titleLabel.setText(messages.getString(TITLE_ERROR));
+ }
+
+ helpListener.setHelpTopic(HELP_PINMGMT);
+
+ String errorMsgPattern = cardmgmtMessages.getString(ERR_UNBLOCK);
+ String errorMsg = MessageFormat.format(errorMsgPattern, pin.getLocalizedName());
+
+ JLabel errorMsgLabel = new JLabel();
+ errorMsgLabel.setFont(errorMsgLabel.getFont().deriveFont(errorMsgLabel.getFont().getStyle() & ~java.awt.Font.BOLD));
+ errorMsgLabel.setText(errorMsg);
+
+ GroupLayout mainPanelLayout = new GroupLayout(mainPanel);
+ mainPanel.setLayout(mainPanelLayout);
+
+ GroupLayout.ParallelGroup mainHorizontal = mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING);
+ GroupLayout.SequentialGroup mainVertical = mainPanelLayout.createSequentialGroup();
+
+ if (!renderHeaderPanel) {
+ JLabel errorTitleLabel = new JLabel();
+ errorTitleLabel.setFont(errorTitleLabel.getFont().deriveFont(errorTitleLabel.getFont().getStyle() | java.awt.Font.BOLD));
+ errorTitleLabel.setText(messages.getString(TITLE_ERROR));
+ errorTitleLabel.setForeground(ERROR_COLOR);
+
+ mainHorizontal
+ .addGroup(mainPanelLayout.createSequentialGroup()
+ .addComponent(errorTitleLabel)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE)
+ .addComponent(helpLabel));
+ mainVertical
+ .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(errorTitleLabel)
+ .addComponent(helpLabel));
+ }
+
+ mainPanelLayout.setHorizontalGroup(mainHorizontal
+ .addComponent(errorMsgLabel));
+ mainPanelLayout.setVerticalGroup(mainVertical
+ .addComponent(errorMsgLabel));
+
+ JButton okButton = new JButton();
+ okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD));
+ okButton.setText(messages.getString(BUTTON_OK));
+ okButton.setActionCommand(cancelCommand);
+ okButton.addActionListener(cancelListener);
+
+ GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel);
+ buttonPanel.setLayout(buttonPanelLayout);
+
+ buttonPanelLayout.setHorizontalGroup(
+ buttonPanelLayout.createSequentialGroup()
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(okButton, GroupLayout.PREFERRED_SIZE, buttonSize, GroupLayout.PREFERRED_SIZE));
+ buttonPanelLayout.setVerticalGroup(
+ buttonPanelLayout.createSequentialGroup()
+ .addComponent(okButton));
+
+ contentPanel.validate();
+ }
+ });
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
index 3d653fab..2a8f28d2 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINManagementGUIFacade.java
@@ -17,7 +17,9 @@
package at.gv.egiz.bku.gui;
+import at.gv.egiz.smcc.PINSpec;
import java.awt.event.ActionListener;
+import java.util.Map;
/**
*
@@ -27,8 +29,49 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {
public static final String HELP_PINMGMT = "help.pin.mgmt";
public static final String TITLE_PINMGMT = "title.pin.mgmt";
+ public static final String TITLE_ACTIVATE_PIN = "title.activate.pin";
+ public static final String TITLE_CHANGE_PIN = "title.change.pin";
+ public static final String TITLE_UNBLOCK_PIN = "title.unblock.pin";
public static final String MESSAGE_PINMGMT = "message.pin.mgmt";
-
- public void showPINManagementDialog(PINStatusProvider pinStatusProvider, ActionListener activateListener, String activateCmd, ActionListener changeListener, String changeCmd, ActionListener unblockListener, String unblockCmd, ActionListener cancelListener, String cancelCmd);
+ public static final String MESSAGE_ACTIVATE_PIN = "message.activate.pin";
+ public static final String MESSAGE_CHANGE_PIN = "message.change.pin";
+ public static final String MESSAGE_UNBLOCK_PIN = "message.unblock.pin";
+ public static final String LABEL_OLD_PIN = "label.old.pin";
+ public static final String LABEL_NEW_PIN = "label.new.pin";
+ public static final String LABEL_REPEAT_PIN = "label.repeat.pin";
+ public static final String ERR_ACTIVATE = "err.activate";
+ public static final String ERR_CHANGE = "err.change";
+ public static final String ERR_UNBLOCK = "err.unblock";
+
+ public static final String BUTTON_ACTIVATE = "button.activate";
+ public static final String BUTTON_UNBLOCK = "button.unblock";
+ public static final String BUTTON_CHANGE = "button.change";
+
+ public static final String STATUS_ACTIVE = "status.active";
+ public static final String STATUS_BLOCKED = "status.blocked";
+ public static final String STATUS_NOT_ACTIVE = "status.not.active";
+ public static final String STATUS_UNKNOWN = "status.unknown";
+
+ public enum STATUS { ACTIV, NOT_ACTIV, BLOCKED, UNKNOWN };
+
+ public void showPINManagementDialog(Map<PINSpec, STATUS> pins,
+ ActionListener activateListener, String activateCmd, String changeCmd, String unblockCmd,
+ ActionListener cancelListener, String cancelCmd);
+
+ public void showActivatePINDialog(PINSpec pin,
+ ActionListener okListener, String okCmd,
+ ActionListener cancelListener, String cancelCmd);
+
+ public void showChangePINDialog(PINSpec pin,
+ ActionListener okListener, String okCmd,
+ ActionListener cancelListener, String cancelCmd);
+
+ public void showUnblockPINDialog(PINSpec pin,
+ ActionListener okListener, String okCmd,
+ ActionListener cancelListener, String cancelCmd);
+
+ public char[] getOldPin();
+
+ public PINSpec getSelectedPIN();
}
diff --git a/STALExt/src/main/java/at/gv/egiz/stal/ext/ChangePINRequest.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINSpecRenderer.java
index ea508146..e3d73e1f 100644
--- a/STALExt/src/main/java/at/gv/egiz/stal/ext/ChangePINRequest.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINSpecRenderer.java
@@ -15,14 +15,25 @@
* limitations under the License.
*/
-package at.gv.egiz.stal.ext;
+package at.gv.egiz.bku.gui;
-import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.smcc.PINSpec;
+import javax.swing.table.DefaultTableCellRenderer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public class ChangePINRequest extends STALRequest {
+public class PINSpecRenderer extends DefaultTableCellRenderer {
+
+ private static final Log log = LogFactory.getLog(PINSpecRenderer.class);
+
+ @Override
+ protected void setValue(Object value) {
+ PINSpec pinSpec = (PINSpec) value;
+ super.setText(pinSpec.getLocalizedName());
+ }
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusRenderer.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusRenderer.java
new file mode 100644
index 00000000..2f8852ff
--- /dev/null
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusRenderer.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package at.gv.egiz.bku.gui;
+
+import at.gv.egiz.bku.gui.PINManagementGUIFacade.STATUS;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.ResourceBundle;
+import javax.swing.table.DefaultTableCellRenderer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINStatusRenderer extends DefaultTableCellRenderer {
+
+ private static final Log log = LogFactory.getLog(PINStatusRenderer.class);
+
+ public static final Color RED = new Color(0.9f, 0.0f, 0.0f);
+ public static final Color GREEN = new Color(0.0f, 0.8f, 0.0f);
+ protected ResourceBundle messages;
+
+ public PINStatusRenderer(ResourceBundle messages) {
+ this.messages = messages;
+ }
+
+ @Override
+ protected void setValue(Object value) {
+ STATUS pinStatus = (STATUS) value;
+ super.setFont(super.getFont().deriveFont(super.getFont().getStyle() | Font.BOLD));
+
+ if (pinStatus == STATUS.NOT_ACTIV) {
+ super.setForeground(RED);
+ super.setText("<html>" + messages.getString(PINManagementGUIFacade.STATUS_NOT_ACTIVE) + "</html>");
+ } else if (pinStatus == STATUS.ACTIV) {
+ super.setForeground(GREEN);
+ super.setText("<html>" + messages.getString(PINManagementGUIFacade.STATUS_ACTIVE) + "</html>");
+ } else if (pinStatus == STATUS.BLOCKED) {
+ super.setForeground(RED);
+ super.setText("<html>" + messages.getString(PINManagementGUIFacade.STATUS_BLOCKED) + "</html>");
+ } else {
+ super.setForeground(Color.BLACK);
+ super.setText("<html>" + messages.getString(PINManagementGUIFacade.STATUS_UNKNOWN) + "</html>");
+ }
+ }
+}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java
new file mode 100644
index 00000000..feaa5072
--- /dev/null
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.bku.gui;
+
+import at.gv.egiz.bku.gui.PINManagementGUIFacade.STATUS;
+import at.gv.egiz.smcc.PINSpec;
+import java.util.Map;
+import javax.swing.table.DefaultTableModel;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINStatusTableModel extends DefaultTableModel {
+
+ protected static final Log log = LogFactory.getLog(PINStatusTableModel.class);
+ protected Class[] types;
+
+ public PINStatusTableModel(Map<PINSpec, STATUS> pinStatuses) {
+ super(0, 2);
+ if (pinStatuses == null) {
+ throw new RuntimeException("pinStatuses must not be null");
+ }
+ log.trace(pinStatuses.size() + " PINs");
+ types = new Class[] { PINSpec.class, STATUS.class };
+ for (PINSpec pinSpec : pinStatuses.keySet()) {
+ addRow(new Object[] { pinSpec, pinStatuses.get(pinSpec) });
+ }
+// PINSpec activePIN = new PINSpec(0, 1, null, "active-PIN", (byte) 0x01);
+// PINSpec blockedPIN = new PINSpec(0, 1, null, "blocked-PIN", (byte) 0x01);
+// addRow(new Object[] { activePIN, PINStatusProvider.STATUS.ACTIV });
+// addRow(new Object[] { blockedPIN, PINStatusProvider.STATUS.BLOCKED });
+ }
+
+ @Override
+ public Class getColumnClass(int columnIndex) {
+ return types[columnIndex];
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return false;
+ }
+}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementApplet.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementApplet.java
index 72d06618..d948ac03 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementApplet.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementApplet.java
@@ -19,6 +19,7 @@ package at.gv.egiz.bku.online.applet;
import at.gv.egiz.bku.gui.AbstractHelpListener;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.gui.PINManagementGUI;
+import at.gv.egiz.bku.gui.PINManagementGUIFacade;
import java.awt.Container;
import java.net.URL;
import java.util.Locale;
@@ -45,6 +46,6 @@ public class PINManagementApplet extends BKUApplet {
@Override
protected AppletBKUWorker createBKUWorker(BKUApplet applet, BKUGUIFacade gui) {
- return new PINManagementBKUWorker(applet, gui);
+ return new PINManagementBKUWorker(applet, (PINManagementGUIFacade) gui);
}
}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementBKUWorker.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementBKUWorker.java
index e65d98ca..ffd83e42 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementBKUWorker.java
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/online/applet/PINManagementBKUWorker.java
@@ -18,35 +18,28 @@ package at.gv.egiz.bku.online.applet;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import at.gv.egiz.bku.gui.PINManagementGUIFacade;
-import at.gv.egiz.bku.smccstal.ext.PINMgmtRequestHandler;
+import at.gv.egiz.bku.smccstal.ext.PINManagementRequestHandler;
+import at.gv.egiz.stal.ErrorResponse;
import at.gv.egiz.stal.STALResponse;
-import at.gv.egiz.stal.ext.ActivatePINRequest;
-import at.gv.egiz.stal.ext.ChangePINRequest;
-import at.gv.egiz.stal.ext.UnblockPINRequest;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Collection;
+import at.gv.egiz.stal.ext.PINManagementRequest;
+import at.gv.egiz.stal.ext.PINManagementResponse;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
- *
+ * This BKU Worker does not connect to STAL webservice
+ * (no Internet connection permitted while activating PINs).
+ *
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
public class PINManagementBKUWorker extends AppletBKUWorker {
- protected PINMgmtRequestHandler handler = new PINMgmtRequestHandler();
- protected PINManagementActionListener listener = new PINManagementActionListener();
-
- public PINManagementBKUWorker(BKUApplet applet, BKUGUIFacade gui) {
+ public PINManagementBKUWorker(BKUApplet applet, PINManagementGUIFacade gui) {
super(applet, gui);
handlerMap.clear();
-// PINMgmtRequestHandler handler = new PINMgmtRequestHandler();
-// addRequestHandler(ActivatePINRequest.class, handler);
-// addRequestHandler(ChangePINRequest.class, handler);
-// addRequestHandler(UnblockPINRequest.class, handler);
+ addRequestHandler(PINManagementRequest.class, new PINManagementRequestHandler());
}
@Override
@@ -54,22 +47,24 @@ public class PINManagementBKUWorker extends AppletBKUWorker {
gui.showWelcomeDialog();
try {
-
- if (waitForCard()) {
- gui.showErrorDialog("no card, canceled PIN mgmt dialog", null);
+ List<STALResponse> responses = handleRequest(Collections.singletonList(new PINManagementRequest()));
+
+ if (responses.size() == 1) {
+ STALResponse response = responses.get(0);
+ if (response instanceof PINManagementResponse) {
+ log.debug("PIN management dialog finished");
+ } else if (response instanceof ErrorResponse) {
+ showErrorDialog(BKUGUIFacade.ERR_UNKNOWN, null);
+ } else {
+ throw new RuntimeException("Invalid STAL response: " + response.getClass().getName());
+ }
+ } else {
+ throw new RuntimeException("invalid number of STAL responses: " + responses.size());
}
- actionCommandList.clear();
- actionCommandList.add("cancel");
-
- ((PINManagementGUIFacade) gui).showPINManagementDialog(handler,
- listener, "activate",
- listener, "change",
- listener, "unblock",
- this, "cancel");
-
- waitForAction();
-
+ } catch (RuntimeException ex) {
+ log.error("unexpected error: " + ex.getMessage(), ex);
+ showErrorDialog(BKUGUIFacade.ERR_UNKNOWN, null);
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
showErrorDialog(BKUGUIFacade.ERR_UNKNOWN_WITH_PARAM, ex);
@@ -82,31 +77,4 @@ public class PINManagementBKUWorker extends AppletBKUWorker {
applet.sendRedirect(sessionId);
}
- protected class PINManagementActionListener implements ActionListener {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- String cmd = e.getActionCommand();
- if ("activate".equals(cmd)) {
- //create STAL request, call handle(req)
- ActivatePINRequest stalReq = new ActivatePINRequest();
- STALResponse stalResp = handler.handleRequest(stalReq);
- gui.showErrorDialog(BKUGUIFacade.ERR_UNKNOWN_WITH_PARAM, new Object[]{"debug"}, this, "back");
- } else if ("change".equals(cmd)) {
- } else if ("unblock".equals(cmd)) {
- } else if ("back".equals(cmd)) {
-
- ((PINManagementGUIFacade) gui).showPINManagementDialog(handler,
- this, "activate",
- this, "change",
- this, "unblock",
- PINManagementBKUWorker.this, "cancel");
-
- }
- } catch (InterruptedException ex) {
- log.fatal(ex);
- }
- }
}
-}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java
new file mode 100644
index 00000000..fcef3191
--- /dev/null
+++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINManagementRequestHandler.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package at.gv.egiz.bku.smccstal.ext;
+
+import at.gv.egiz.bku.gui.BKUGUIFacade;
+import at.gv.egiz.bku.gui.PINManagementGUIFacade;
+import at.gv.egiz.bku.gui.PINManagementGUIFacade.STATUS;
+import at.gv.egiz.bku.smccstal.AbstractRequestHandler;
+import at.gv.egiz.smcc.PINSpec;
+import at.gv.egiz.smcc.SignatureCardException;
+import at.gv.egiz.smcc.util.SMCCHelper;
+import at.gv.egiz.stal.ErrorResponse;
+import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
+import at.gv.egiz.stal.ext.PINManagementRequest;
+import at.gv.egiz.stal.ext.PINManagementResponse;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.smartcardio.Card;
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
+ */
+public class PINManagementRequestHandler extends AbstractRequestHandler {
+
+ public static final String ERR_NOPIN_SELECTED = "err.no.pin.selected";
+ protected static final Log log = LogFactory.getLog(PINManagementRequestHandler.class);
+
+// protected ResourceBundle messages;
+
+// public PINManagementRequestHandler(ResourceBundle messages) {
+// this.messages = messages;
+// }
+ @Override
+ public STALResponse handleRequest(STALRequest request) throws InterruptedException {
+ if (request instanceof PINManagementRequest) {
+
+ PINManagementGUIFacade gui = (PINManagementGUIFacade) this.gui;
+
+ showPINManagementDialog(gui);
+
+ while (true) {
+
+ waitForAction();
+
+ if ("cancel".equals(actionCommand)) {
+ return new PINManagementResponse();
+ } else if ("back".equals(actionCommand)) {
+ showPINManagementDialog(gui);
+ } else {
+ PINSpec selectedPIN = gui.getSelectedPIN();
+
+ if (selectedPIN == null) {
+ throw new RuntimeException("no PIN selected for activation/change");
+ }
+
+ if ("activate_enterpin".equals(actionCommand)) {
+ gui.showActivatePINDialog(selectedPIN, this, "activate", this, "back");
+ } else if ("change_enterpin".equals(actionCommand)) {
+ gui.showChangePINDialog(selectedPIN, this, "change", this, "back");
+ } else if ("unblock_enterpuk".equals(actionCommand)) {
+ gui.showUnblockPINDialog(selectedPIN, this, "unblock", this, "back");
+ } else if ("activate".equals(actionCommand)) {
+ try {
+ byte[] pin = encodePIN(gui.getPin());
+ activatePIN(selectedPIN.getKID(), selectedPIN.getContextAID(), pin);
+ showPINManagementDialog(gui);
+ } catch (SignatureCardException ex) {
+ log.error("failed to activate " + selectedPIN.getLocalizedName() + ": " + ex.getMessage());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_ACTIVATE,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, "cancel");
+ }
+ } else if ("change".equals(actionCommand)) {
+ try {
+ byte[] oldPin = encodePIN(gui.getOldPin()); //new byte[]{(byte) 0x25, (byte) 0x40, (byte) 0x01};
+ byte[] pin = encodePIN(gui.getPin()); //new byte[]{(byte) 0x25, (byte) 0x40};
+ changePIN(selectedPIN.getKID(), selectedPIN.getContextAID(), oldPin, pin);
+ showPINManagementDialog(gui);
+ } catch (SignatureCardException ex) {
+ log.error("failed to change " + selectedPIN.getLocalizedName() + ": " + ex.getMessage());
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_CHANGE,
+ new Object[] {selectedPIN.getLocalizedName()},
+ this, "cancel");
+ }
+ } else if ("unblock".equals(actionCommand)) {
+ log.error("unblock PIN not implemented");
+ gui.showErrorDialog(PINManagementGUIFacade.ERR_UNBLOCK, null, this, "cancel");
+ } else {
+ throw new RuntimeException("unsupported action " + actionCommand);
+ }
+ }
+ }
+ } else {
+ log.error("Got unexpected STAL request: " + request);
+ return new ErrorResponse(1000);
+ }
+ }
+
+ @Override
+ public boolean requireCard() {
+ return true;
+ }
+
+ /**
+ * pin.length &lt; 4bit
+ * @param kid
+ * @param contextAID
+ * @param pin
+ * @throws at.gv.egiz.smcc.SignatureCardException
+ */
+ private void activatePIN(byte kid, byte[] contextAID, byte[] pin) throws SignatureCardException {
+ try {
+ Card icc = card.getCard();
+ icc.beginExclusive();
+ CardChannel channel = icc.getBasicChannel();
+
+ if (contextAID != null) {
+ CommandAPDU selectAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID);
+ ResponseAPDU responseAPDU = channel.transmit(selectAPDU);
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) +
+ ": Failed to select AID " + SMCCHelper.toString(contextAID) +
+ ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ if (pin.length > 7) {
+ log.error("Invalid PIN");
+ throw new SignatureCardException("Invalid PIN");
+ }
+ byte length = (byte) (0x20 | pin.length * 2);
+
+ byte[] apdu = new byte[]{
+ (byte) 0x00, (byte) 0x24, (byte) 0x01, kid, (byte) 0x08,
+ (byte) length, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+ for (int i = 0; i < pin.length; i++) {
+ apdu[i + 6] = pin[i];
+ }
+
+ CommandAPDU verifyAPDU = new CommandAPDU(apdu);
+ ResponseAPDU responseAPDU = channel.transmit(verifyAPDU);
+
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) + ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+
+
+ icc.endExclusive();
+
+
+ } catch (CardException ex) {
+ log.error("Failed to get PIN status: " + ex.getMessage());
+ throw new SignatureCardException("Failed to get PIN status", ex);
+ }
+ }
+
+ private void changePIN(byte kid, byte[] contextAID, byte[] oldPIN, byte[] newPIN) throws SignatureCardException {
+ try {
+ Card icc = card.getCard();
+ icc.beginExclusive();
+ CardChannel channel = icc.getBasicChannel();
+
+ if (contextAID != null) {
+ CommandAPDU selectAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID);
+ ResponseAPDU responseAPDU = channel.transmit(selectAPDU);
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to change PIN " + SMCCHelper.toString(new byte[]{kid}) +
+ ": Failed to select AID " + SMCCHelper.toString(contextAID) +
+ ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ if (oldPIN.length > 7 || newPIN.length > 7) {
+ log.error("Invalid PIN");
+ throw new SignatureCardException("Invalid PIN");
+ }
+ byte oldLength = (byte) (0x20 | oldPIN.length * 2);
+ byte newLength = (byte) (0x20 | newPIN.length * 2);
+
+ byte[] apdu = new byte[]{
+ (byte) 0x00, (byte) 0x24, (byte) 0x00, kid, (byte) 0x10,
+ oldLength, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ newLength, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+ for (int i = 0; i < oldPIN.length; i++) {
+ apdu[i + 6] = oldPIN[i];
+ }
+ for (int i = 0; i < newPIN.length; i++) {
+ apdu[i + 14] = newPIN[i];
+ }
+
+ CommandAPDU verifyAPDU = new CommandAPDU(apdu);
+ ResponseAPDU responseAPDU = channel.transmit(verifyAPDU);
+
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to change PIN " + SMCCHelper.toString(new byte[]{kid}) + ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+
+
+ icc.endExclusive();
+
+
+ } catch (CardException ex) {
+ log.error("Failed to get PIN status: " + ex.getMessage());
+ throw new SignatureCardException("Failed to get PIN status", ex);
+ }
+ }
+
+ public Map<PINSpec, STATUS> getPINStatuses() throws SignatureCardException {
+ try {
+ Card icc = card.getCard();
+ icc.beginExclusive();
+ CardChannel channel = icc.getBasicChannel();
+
+ HashMap<PINSpec, STATUS> pinStatuses = new HashMap<PINSpec, STATUS>();
+ List<PINSpec> pins = card.getPINSpecs();
+
+ //select DF_SichereSignatur 00 A4 04 0C 08 D0 40 00 00 17 00 12 01
+// CommandAPDU selectAPDU = new CommandAPDU(new byte[]{(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x0c, (byte) 0x08,
+// (byte) 0xd0, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x12, (byte) 0x01});
+// ResponseAPDU rAPDU = channel.transmit(selectAPDU);
+// log.debug("SELECT FILE DF_SichereSignatur: " + SMCCHelper.toString(rAPDU.getBytes()));
+
+ //select DF_SIG DF 70
+// CommandAPDU selectAPDU = new CommandAPDU(new byte[]{(byte) 0x00, (byte) 0xa4, (byte) 0x00, (byte) 0x0c, (byte) 0x02,
+// (byte) 0xdf, (byte) 0x70 });
+// ResponseAPDU rAPDU = channel.transmit(selectAPDU);
+// log.debug("SELECT FILE DF_SIG: " + SMCCHelper.toString(rAPDU.getBytes()));
+
+ //select DF_DEC DF 71
+// CommandAPDU selectAPDU = new CommandAPDU(new byte[]{(byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x0c, (byte) 0x08,
+// (byte) 0xd0, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x12, (byte) 0x01});
+// ResponseAPDU rAPDU = channel.transmit(selectAPDU);
+// log.debug("SELECT FILE DF_SichereSignatur: " + SMCCHelper.toString(rAPDU.getBytes()));
+
+ for (PINSpec pinSpec : pins) {
+ byte kid = pinSpec.getKID();
+ byte[] contextAID = pinSpec.getContextAID();
+
+ if (contextAID != null) {
+ CommandAPDU selectAPDU = new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID);
+ ResponseAPDU responseAPDU = channel.transmit(selectAPDU);
+ if (responseAPDU.getSW() != 0x9000) {
+ String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) +
+ ": Failed to select AID " + SMCCHelper.toString(contextAID) +
+ ": " + SMCCHelper.toString(responseAPDU.getBytes());
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ }
+ }
+
+ CommandAPDU verifyAPDU = new CommandAPDU(new byte[]{(byte) 0x00, (byte) 0x20, (byte) 00, kid});
+ ResponseAPDU responseAPDU = channel.transmit(verifyAPDU);
+
+ STATUS status = STATUS.UNKNOWN;
+ if (responseAPDU.getSW() == 0x6984) {
+ status = STATUS.NOT_ACTIV;
+ } else if (responseAPDU.getSW() == 0x63c0) {
+ status = STATUS.BLOCKED;
+ } else if (responseAPDU.getSW1() == 0x63) {
+ status = STATUS.ACTIV;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("PIN " + pinSpec.getLocalizedName() + " status: " + SMCCHelper.toString(responseAPDU.getBytes()));
+ }
+
+ pinStatuses.put(pinSpec, status);
+ }
+ icc.endExclusive();
+
+ return pinStatuses;
+
+ } catch (CardException ex) {
+ log.error("Failed to get PIN status: " + ex.getMessage());
+ throw new SignatureCardException("Failed to get PIN status", ex);
+ }
+ }
+
+ private byte[] encodePIN(char[] pinChars) {
+ int length = (int) Math.ceil(pinChars.length/2);
+ byte[] pin = new byte[length];
+ for (int i = 0; i < length; i++) {
+ pin[i] = (byte) (16*Character.digit(pinChars[i*2], 16) + Character.digit(pinChars[i*2+1], 16));
+ }
+ log.trace("***** " + SMCCHelper.toString(pin) + " ******");
+ return pin;
+ }
+
+ private void showPINManagementDialog(PINManagementGUIFacade gui) {
+ try {
+ Map<PINSpec, STATUS> pins = getPINStatuses();
+ gui.showPINManagementDialog(pins,
+ this, "activate_enterpin", "change_enterpin", "unblock_enterpuk",
+ this, "cancel");
+ } catch (SignatureCardException ex) {
+ gui.showErrorDialog(BKUGUIFacade.ERR_UNKNOWN_WITH_PARAM,
+ new Object[]{"FAILED TO GET PIN STATUSES: " + ex.getMessage()},
+ this, "cancel");
+ }
+ }
+}
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINMgmtRequestHandler.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINMgmtRequestHandler.java
deleted file mode 100644
index b2d34ff2..00000000
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PINMgmtRequestHandler.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2008 Federal Chancellery Austria and
- * Graz University of Technology
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package at.gv.egiz.bku.smccstal.ext;
-
-import at.gv.egiz.bku.gui.PINStatusProvider;
-import at.gv.egiz.bku.smccstal.AbstractRequestHandler;
-import at.gv.egiz.smcc.SignatureCardException;
-import at.gv.egiz.stal.ErrorResponse;
-import at.gv.egiz.stal.STALRequest;
-import at.gv.egiz.stal.STALResponse;
-import at.gv.egiz.stal.ext.ActivatePINRequest;
-import at.gv.egiz.stal.ext.ChangePINRequest;
-import at.gv.egiz.stal.ext.UnblockPINRequest;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.smartcardio.Card;
-import javax.smartcardio.CardChannel;
-import javax.smartcardio.CardException;
-import javax.smartcardio.CommandAPDU;
-import javax.smartcardio.ResponseAPDU;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- *
- * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
- */
-public class PINMgmtRequestHandler extends AbstractRequestHandler implements PINStatusProvider {
-
- protected static final Log log = LogFactory.getLog(PINMgmtRequestHandler.class);
-
- @Override
- public STALResponse handleRequest(STALRequest request) throws InterruptedException {
- if (request instanceof ActivatePINRequest) {
- log.error("not implemented yet");
- return new ErrorResponse(1000);
-
- } else if (request instanceof ChangePINRequest) {
- log.error("not implemented yet");
- return new ErrorResponse(1000);
-
- } else if (request instanceof UnblockPINRequest) {
- log.error("not implemented yet");
- return new ErrorResponse(1000);
-
- } else {
- log.error("Got unexpected STAL request: " + request);
- return new ErrorResponse(1000);
- }
- }
-
- @Override
- public boolean requireCard() {
- return true;
- }
-
- @Override
- public STATUS getPINStatus(int pin) throws SignatureCardException {
- try {
- Card icc = card.getCard();
- icc.beginExclusive();
- CardChannel channel = icc.getBasicChannel();
- CommandAPDU verifyAPDU = new CommandAPDU(new byte[] {(byte) 0x00} );
- ResponseAPDU responseAPDU = channel.transmit(verifyAPDU);
- byte sw1 = (byte) responseAPDU.getSW1();
- byte[] sw = new byte[] {
- (byte) (0xFF & responseAPDU.getSW1()),
- (byte) (0xFF & responseAPDU.getSW2()) };
-
- icc.endExclusive();
- return STATUS.ACTIV;
- } catch (CardException ex) {
- log.error("Failed to get PIN status: " + ex.getMessage());
- throw new SignatureCardException("Failed to get PIN status", ex);
- }
- }
-
-}
diff --git a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
index 469af15f..e51044af 100644
--- a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
+++ b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages.properties
@@ -15,10 +15,34 @@
title.activation=<html>Aktivierung</html>
title.pin.mgmt=<html>PIN Verwaltung</html>
-message.pin.mgmt=<html>under construction</html>
+title.activate.pin=<html>PIN Aktivieren</html>
+title.change.pin=<html>PIN \u00C4ndern</html>
+title.unblock.pin=<html>PIN Entsperren</html>
+
+message.pin.mgmt=<html>Die Karte verf\u00FCgt \u00FCber {0} PINs</html>
+message.activate.pin=<html>{0} eingeben und best\u00E4tigen</html>
+message.change.pin=<html>{0} eingeben und best\u00E4tigen</html>
+message.unblock.pin=<html>PUK zu {0} eingeben</html>
+
label.activation=<html>e-card Aktivierungsprozess</html>
label.activation.step=<html>Schritt {0}</html>
label.activation.idle=<html>Warte auf Server...</html>
+label.old.pin=<html>Alte {0}:</html>
+label.new.pin=<html>Neue {0}:</html>
+label.repeat.pin=<html>Best\u00E4tigung:</html>
+
button.activate=Aktivieren
button.change=\u00C4ndern
-button.unblock=Entsperren \ No newline at end of file
+button.unblock=Entsperren
+
+help.activation=help.activation
+help.pin.mgmt=help.pin.mgmt
+
+err.activate=<html>Beim Aktivieren der {0} trat ein Fehler auf.</html>
+err.change=<html>Beim \u00C4ndern der {0} trat ein Fehler auf.</html>
+err.unblock=<html>Das Entsperren der {0} wird nicht unterst\u00FCtzt.</html>
+
+status.not.active=NICHT AKTIV
+status.active=AKTIV
+status.blocked=GESPERRT
+status.unknown=UNBEKANNT
diff --git a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
index 16ac7d0b..1cf4a102 100644
--- a/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
+++ b/BKUAppletExt/src/main/resources/at/gv/egiz/bku/gui/ActivationMessages_en.properties
@@ -13,12 +13,36 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-title.activation=<html>Aktivation</html>
+title.activation=<html>Activation</html>
title.pin.mgmt=<html>PIN Management</html>
-message.pin.mgmt=<html>under construction</html>
+title.activate.pin=<html>Activate PIN</html>
+title.change.pin=<html>Change PIN</html>
+title.unblock.pin=<html>Unblock PIN</html>
+
+message.pin.mgmt=<html>The smartcard has {0} PINs</html>
+message.activate.pin=<html>Enter and confirm {0}</html>
+message.change.pin=<html>Enter and confirm {0}</html>
+message.unblock.pin=<html>Enter PUK for {0}</html>
+
label.activation=<html>e-card activation process</html>
label.activation.step=<html>Step {0}</html>
label.activation.idle=<html>Wait for server...</html>
+label.old.pin=<html>Old {0}:</html>
+label.new.pin=<html>New {0}:</html>
+label.repeat.pin=<html>Confirmation:</html>
+
button.activate=Activate
button.change=Change
-button.unblock=Unblock \ No newline at end of file
+button.unblock=Unblock
+
+help.activation=help.activation
+help.pin.mgmt=help.pin.mgmt
+
+err.activate=<html>An error occured during activation of {0}.</html>
+err.change=<html>An error occured during changing of {0}.</html>
+err.unblock=<html>Unblocking of {0} is not supported.</html>
+
+status.not.active=Not active
+status.active=Active
+status.blocked=Blocked
+status.unknown=Unknown
diff --git a/BKUAppletExt/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java b/BKUAppletExt/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
index 669a63fc..ef8c87e4 100644
--- a/BKUAppletExt/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
+++ b/BKUAppletExt/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java
@@ -25,8 +25,6 @@ import at.gv.egiz.stal.HashDataInput;
import at.gv.egiz.stal.impl.ByteArrayHashDataInput;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@@ -46,7 +44,7 @@ public class BKUGUIWorker implements Runnable {
public void run() {
try {
- final PINSpec signPinSpec = new PINSpec(6, 10, "[0-9]", "Signatur-PIN");
+ final PINSpec signPinSpec = new PINSpec(6, 10, "[0-9]", "Signatur-PIN", (byte)0x00, null);
final ActionListener cancelListener = new ActionListener() {
diff --git a/BKUAppletExt/src/test/resources/appletTest.html b/BKUAppletExt/src/test/resources/appletTest.html
index 9add4309..813ee1f0 100644
--- a/BKUAppletExt/src/test/resources/appletTest.html
+++ b/BKUAppletExt/src/test/resources/appletTest.html
@@ -19,7 +19,7 @@
<center>
<applet code="at.gv.egiz.bku.online.applet.PINManagementApplet.class"
archive="../BKUAppletExt-1.0.2-SNAPSHOT.jar, commons-logging.jar , iaik_jce_me4se.jar"
- width=152 height=145>
+ width=270 height=180>
<param name="GuiStyle" value="simple"/>
<param name="Locale" value="ja_JA"/>
<!--param name="Background" value="jar:file:/home/clemens/workspace/mocca/BKUApplet/target/BKUApplet-1.0-SNAPSHOT.jar!/images/help.png"/-->
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 f564c07a..1d5a2cf4 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
@@ -38,9 +38,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.CellRendererPane;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
@@ -51,7 +48,6 @@ import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
-import javax.swing.JTextField;
import javax.swing.LayoutStyle;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
@@ -1064,7 +1060,9 @@ public class BKUGUIImpl implements BKUGUIFacade {
@Override
public char[] getPin() {
if (pinField != null) {
- return pinField.getPassword();
+ char[] pin = pinField.getPassword();
+ pinField = null;
+ return pin;
}
return null;
}
diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
index 2054ae86..87b636f0 100644
--- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
+++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/PinDocument.java
@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import javax.swing.JButton;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
@@ -30,9 +31,10 @@ import javax.swing.text.PlainDocument;
*/
class PINDocument extends PlainDocument {
- private PINSpec pinSpec;
- private Pattern pinPattern;
- private JButton enterButton;
+ protected PINSpec pinSpec;
+ protected Pattern pinPattern;
+ protected JButton enterButton;
+ protected Document compareTo;
public PINDocument(PINSpec pinSpec, JButton enterButton) {
this.pinSpec = pinSpec;
@@ -44,6 +46,11 @@ class PINDocument extends PlainDocument {
this.enterButton = enterButton;
}
+ public PINDocument(PINSpec pinSpec, JButton enterButton, Document compareTo) {
+ this(pinSpec, enterButton);
+ this.compareTo = compareTo;
+ }
+
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (pinSpec.getMaxLength() < 0 || pinSpec.getMaxLength() >= (getLength() + str.length())) {
@@ -58,12 +65,23 @@ class PINDocument extends PlainDocument {
super.insertString(offs, str, a);
}
}
- enterButton.setEnabled(getLength() >= pinSpec.getMinLength());
+ if (enterButton != null) {
+ enterButton.setEnabled(getLength() >= pinSpec.getMinLength() && compare());
+ }
}
@Override
public void remove(int offs, int len) throws BadLocationException {
super.remove(offs, len);
- enterButton.setEnabled(getLength() >= pinSpec.getMinLength());
+ if (enterButton != null) {
+ enterButton.setEnabled(getLength() >= pinSpec.getMinLength() && compare());
+ }
+ }
+
+ private boolean compare() throws BadLocationException {
+ if (compareTo == null) {
+ return true;
+ }
+ return compareTo.getText(0, compareTo.getLength()).equals(getText(0, getLength()));
}
} \ No newline at end of file
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 8436a730..1e0bc9f5 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
@@ -20,7 +20,7 @@ title.cardnotsupported=<html>Die Karte wird nicht unterst\u00FCtzt</html>
title.cardpin=<html>Karte wird gelesen</html>
title.sign=<html>Signatur erstellen</html>
title.error=<html>Fehler</html>
-title.retry=<html>Falscher PIN</html>
+title.retry=<html>Falsche PIN</html>
title.wait=<html>Bitte warten</html>
title.hashdata=<html>Signaturdaten</html>
windowtitle.save=Signaturdaten speichern
@@ -84,7 +84,7 @@ help.cardnotsupported=Nicht unterst\u00FCtzte B\u00FCrgerkarte
help.insertcard=Keine B\u00FCrgerkarte im Kartenleser
help.cardpin=Pineingabe
help.signpin=Signatur-Pineingabe
-help.retry=Falscher Pin
+help.retry=Falsche Pin
help.hashdata=Signierte Inhalte
help.hashdatalist=Signierte Inhalte
help.hashdataviewer=Anzeige signierter Inhalte \ No newline at end of file
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 73aaab46..08ecaa7f 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
@@ -46,7 +46,7 @@ public class BKUGUIWorker implements Runnable {
public void run() {
// try {
- final PINSpec signPinSpec = new PINSpec(6, 10, "[0-9]", "Signatur-PIN");
+ final PINSpec signPinSpec = new PINSpec(6, 10, "[0-9]", "Signatur-PIN", (byte) 0x81, null);
final ActionListener cancelListener = new ActionListener() {
diff --git a/STALExt/src/main/java/at/gv/egiz/stal/ext/ActivatePINRequest.java b/STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementRequest.java
index f2039388..87c53e24 100644
--- a/STALExt/src/main/java/at/gv/egiz/stal/ext/ActivatePINRequest.java
+++ b/STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementRequest.java
@@ -20,9 +20,12 @@ package at.gv.egiz.stal.ext;
import at.gv.egiz.stal.STALRequest;
/**
+ * Dummy STAL request to trigger PIN Management. (no proper STAL requests
+ * for PIN activation, unblocking)
+ *
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public class ActivatePINRequest extends STALRequest {
+public class PINManagementRequest extends STALRequest {
}
diff --git a/STALExt/src/main/java/at/gv/egiz/stal/ext/UnblockPINRequest.java b/STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementResponse.java
index 543de31c..b8b90604 100644
--- a/STALExt/src/main/java/at/gv/egiz/stal/ext/UnblockPINRequest.java
+++ b/STALExt/src/main/java/at/gv/egiz/stal/ext/PINManagementResponse.java
@@ -17,12 +17,12 @@
package at.gv.egiz.stal.ext;
-import at.gv.egiz.stal.STALRequest;
+import at.gv.egiz.stal.STALResponse;
/**
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public class UnblockPINRequest extends STALRequest {
+public class PINManagementResponse extends STALResponse {
}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
index ae4918ce..b64306aa 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java
@@ -14,98 +14,105 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package at.gv.egiz.bku.slcommands.impl.xsect;
-
-import iaik.xml.crypto.dom.DOMCryptoContext;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.SequenceInputStream;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
+package at.gv.egiz.bku.slcommands.impl.xsect;
+
+import iaik.xml.crypto.dom.DOMCryptoContext;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.dom.DOMStructure;
-import javax.xml.crypto.dsig.CanonicalizationMethod;
-import javax.xml.crypto.dsig.DigestMethod;
-import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.Transform;
-import javax.xml.crypto.dsig.XMLObject;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
-import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
-import javax.xml.crypto.dsig.spec.XPathType;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.DOMConfiguration;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentFragment;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSException;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSOutput;
-import org.w3c.dom.ls.LSParser;
-import org.w3c.dom.ls.LSSerializer;
-
-import at.buergerkarte.namespaces.securitylayer._1.Base64XMLLocRefOptRefContentType;
-import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
-import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType;
-import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType;
-import at.gv.egiz.bku.binding.HttpUtil;
-import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.bku.slexceptions.SLRequestException;
-import at.gv.egiz.bku.slexceptions.SLRuntimeException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathType;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3._2000._09.xmldsig_.TransformType;
+import org.w3._2000._09.xmldsig_.TransformsType;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSParser;
+import org.w3c.dom.ls.LSSerializer;
+
+import at.buergerkarte.namespaces.securitylayer._1.Base64XMLLocRefOptRefContentType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
+import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType;
+import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType;
+import at.gv.egiz.bku.binding.HttpUtil;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
+import at.gv.egiz.bku.slexceptions.SLRuntimeException;
import at.gv.egiz.bku.slexceptions.SLViewerException;
-import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
import at.gv.egiz.bku.viewer.ValidationException;
import at.gv.egiz.bku.viewer.Validator;
import at.gv.egiz.bku.viewer.ValidatorFactory;
-import at.gv.egiz.dom.DOMUtils;
-import at.gv.egiz.slbinding.impl.XMLContentType;
-
-/**
- * This class represents a <code>DataObject</code> of an XML-Signature
- * created by the security layer command <code>CreateXMLSignature</code>.
- *
- * @author mcentner
- */
-public class DataObject {
-
- /**
- * Logging facility.
- */
- private static Log log = LogFactory.getLog(DataObject.class);
-
- /**
- * DOM Implementation.
- */
- private static final String DOM_LS_3_0 = "LS 3.0";
-
- /**
- * The array of the default preferred MIME type order.
- */
- private static final String[] DEFAULT_PREFFERED_MIME_TYPES =
- new String[] {
+import at.gv.egiz.dom.DOMUtils;
+import at.gv.egiz.marshal.NamespacePrefix;
+import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
+import at.gv.egiz.slbinding.impl.XMLContentType;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/**
+ * This class represents a <code>DataObject</code> of an XML-Signature
+ * created by the security layer command <code>CreateXMLSignature</code>.
+ *
+ * @author mcentner
+ */
+public class DataObject {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(DataObject.class);
+
+ /**
+ * DOM Implementation.
+ */
+ private static final String DOM_LS_3_0 = "LS 3.0";
+
+ /**
+ * The array of the default preferred MIME type order.
+ */
+ private static final String[] DEFAULT_PREFFERED_MIME_TYPES =
+ new String[] {
"text/plain",
- "application/xhtml+xml"
+ "application/xhtml+xml"
};
/**
@@ -149,87 +156,87 @@ public class DataObject {
validMimeTypes = mediaTypes;
}
- /**
- * The DOM implementation used.
- */
- private DOMImplementationLS domImplLS;
-
- /**
- * The signature context.
- */
- private SignatureContext ctx;
-
- /**
- * The Reference for this DataObject.
- */
- private XSECTReference reference;
-
- /**
- * The XMLObject for this DataObject.
- */
- private XMLObject xmlObject;
-
- /**
- * The MIME-Type of the digest input.
- */
- private String mimeType;
-
- /**
- * An optional description of the digest input.
- */
- private String description;
-
- /**
- * Creates a new instance.
- *
- * @param document the document of the target signature
- */
- public DataObject(SignatureContext signatureContext) {
- this.ctx = signatureContext;
-
- DOMImplementationRegistry registry;
- try {
- registry = DOMImplementationRegistry.newInstance();
- } catch (Exception e) {
- log.error("Failed to get DOMImplementationRegistry.", e);
- throw new SLRuntimeException("Failed to get DOMImplementationRegistry.");
- }
-
- domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0);
- if (domImplLS == null) {
- log.error("Failed to get DOMImplementation " + DOM_LS_3_0);
- throw new SLRuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0);
- }
-
- }
-
- /**
- * @return the reference
- */
- public Reference getReference() {
- return reference;
- }
-
- /**
- * @return the xmlObject
- */
- public XMLObject getXmlObject() {
- return xmlObject;
- }
-
- /**
- * @return the mimeType
- */
- public String getMimeType() {
- return mimeType;
- }
-
- /**
- * @return the description
- */
- public String getDescription() {
- return description;
- }
+ /**
+ * The DOM implementation used.
+ */
+ private DOMImplementationLS domImplLS;
+
+ /**
+ * The signature context.
+ */
+ private SignatureContext ctx;
+
+ /**
+ * The Reference for this DataObject.
+ */
+ private XSECTReference reference;
+
+ /**
+ * The XMLObject for this DataObject.
+ */
+ private XMLObject xmlObject;
+
+ /**
+ * The MIME-Type of the digest input.
+ */
+ private String mimeType;
+
+ /**
+ * An optional description of the digest input.
+ */
+ private String description;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param document the document of the target signature
+ */
+ public DataObject(SignatureContext signatureContext) {
+ this.ctx = signatureContext;
+
+ DOMImplementationRegistry registry;
+ try {
+ registry = DOMImplementationRegistry.newInstance();
+ } catch (Exception e) {
+ log.error("Failed to get DOMImplementationRegistry.", e);
+ throw new SLRuntimeException("Failed to get DOMImplementationRegistry.");
+ }
+
+ domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0);
+ if (domImplLS == null) {
+ log.error("Failed to get DOMImplementation " + DOM_LS_3_0);
+ throw new SLRuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0);
+ }
+
+ }
+
+ /**
+ * @return the reference
+ */
+ public Reference getReference() {
+ return reference;
+ }
+
+ /**
+ * @return the xmlObject
+ */
+ public XMLObject getXmlObject() {
+ return xmlObject;
+ }
+
+ /**
+ * @return the mimeType
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
public void validateHashDataInput() throws SLViewerException {
@@ -293,823 +300,920 @@ public class DataObject {
}
}
-
- /**
- * Configures this DataObject with the information provided within the given
- * <code>sl:DataObjectInfo</code>.
- *
- * @param dataObjectInfo
- * the <code>sl:DataObjectInfo</code>
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObjectInfo</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObjectInfo</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObjectInfo</code> is <code>null</code>
- */
- public void setDataObjectInfo(DataObjectInfoType dataObjectInfo) throws SLCommandException, SLRequestException {
-
- Base64XMLLocRefOptRefContentType dataObject = dataObjectInfo.getDataObject();
- String structure = dataObjectInfo.getStructure();
-
- // select and unmarshal an appropriate transformation path if provided
- // and set the final data meta information
- XSECTTransforms transforms = createTransformsAndSetFinalDataMetaInfo(dataObjectInfo.getTransformsInfo());
-
- if ("enveloping".equals(structure)) {
-
- // configure this DataObject as an enveloped DataObject
- setEnvelopedDataObject(dataObject, transforms);
-
- } else if ("detached".equals(structure)) {
-
- // configure this DataObject as an detached DataObject
- setDetachedDataObject(dataObject, transforms);
-
- }
- // other values are not allowed by the schema and are therefore ignored
-
- }
-
- /**
- * Configures this DataObject as an enveloped DataObject with the information
- * provided within the given <code>sl:DataObject</code>.
- *
- * @param dataObject
- * the <code>sl:DataObject</code>
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObject</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObject</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObject</code> is <code>null</code>
- */
- private void setEnvelopedDataObject(
- Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
- throws SLCommandException, SLRequestException {
-
- String reference = dataObject.getReference();
- if (reference == null) {
- //
- // case A
- //
- // The Reference attribute is not used; the content of sl:DataObject represents the data object.
- // If the data object is XML-coded (the sl:XMLContent element is used in sl:DataObject), then it
- // must be incorporated in the signature structure as parsed XML.
- //
-
- if (dataObject.getBase64Content() != null) {
-
- log.debug("Adding DataObject (Base64Content) without a reference URI.");
-
- // create XMLObject
- XMLObject xmlObject = createXMLObject(new ByteArrayInputStream(dataObject.getBase64Content()));
-
- setXMLObjectAndReferenceBase64(xmlObject, transforms);
-
- } else if (dataObject.getXMLContent() != null) {
-
- log.debug("Adding DataObject (XMLContent) without a reference URI.");
-
- // create XMLObject
- DocumentFragment content = parseDataObject((XMLContentType) dataObject.getXMLContent());
- XMLObject xmlObject = createXMLObject(content);
-
- setXMLObjectAndReferenceXML(xmlObject, transforms);
-
- } else if (dataObject.getLocRefContent() != null) {
-
- log.debug("Adding DataObject (LocRefContent) without a reference URI.");
-
- setEnvelopedDataObject(dataObject.getLocRefContent(), transforms);
-
- } else {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='enveloped' without a reference must contain content.");
- throw new SLRequestException(3003);
-
- }
-
- } else {
-
- if (dataObject.getBase64Content() == null &&
- dataObject.getXMLContent() == null &&
- dataObject.getLocRefContent() == null) {
-
- //
- // case B
- //
- // The Reference attribute contains a URI that must be resolved by the
- // Citizen Card Environment to obtain the data object.
- // The content of sl:DataObject remains empty
- //
-
- log.debug("Adding DataObject from reference URI '" + reference + "'.");
-
- setEnvelopedDataObject(reference, transforms);
-
- } else {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='enveloped' with reference must not contain content.");
- throw new SLRequestException(3003);
-
- }
-
-
- }
-
- }
-
- /**
- * Configures this DataObject as an enveloped DataObject with the content to
- * be dereferenced from the given <code>reference</code>.
- *
- * @param reference
- * the <code>reference</code> URI
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if dereferencing the given <code>reference</code> fails, or if
- * configuring this DataObject with the data dereferenced from the
- * given <code>reference</code> fails.
- * @throws NullPointerException
- * if <code>reference</code> is <code>null</code>
- */
- private void setEnvelopedDataObject(String reference, XSECTTransforms transforms) throws SLCommandException {
-
- if (reference == null) {
- throw new NullPointerException("Argument 'reference' must not be null.");
- }
-
- // dereference URL
- URLDereferencer dereferencer = URLDereferencer.getInstance();
-
- StreamData streamData;
- try {
- streamData = dereferencer.dereference(reference, ctx.getDereferencerContext());
- } catch (IOException e) {
- log.info("Failed to dereference XMLObject from '" + reference + "'.", e);
- throw new SLCommandException(4110);
- }
-
- Node childNode;
-
- String contentType = streamData.getContentType();
- if (contentType.startsWith("text/xml")) {
-
- // If content type is text/xml parse content.
- String charset = HttpUtil.getCharset(contentType, true);
-
- Document doc = parseDataObject(streamData.getStream(), charset);
-
- childNode = doc.getDocumentElement();
-
- if (childNode == null) {
- log.info("Failed to parse XMLObject from '" + reference + "'.");
- throw new SLCommandException(4111);
- }
-
- XMLObject xmlObject = createXMLObject(childNode);
-
- setXMLObjectAndReferenceXML(xmlObject, transforms);
-
- } else {
-
- // Include content Base64 encoded.
- XMLObject xmlObject = createXMLObject(streamData.getStream());
-
- setXMLObjectAndReferenceBase64(xmlObject, transforms);
-
- }
-
- }
-
- /**
- * Configures this DataObject as an detached DataObject with the information
- * provided in the given <code>sl:DataObject</code> and optionally
- * <code>transforms</code>.
- *
- * @param dataObject
- * the <code>sl:DataObject</code>
- * @param transforms
- * an optional Transforms object, may be <code>null</code>
- *
- * @throws SLCommandException
- * if configuring this DataObject with the information provided in
- * the <code>sl:DataObject</code> fails.
- * @throws SLRequestException
- * if the information provided in the <code>sl:DataObject</code>
- * does not conform to the security layer specification.
- * @throws NullPointerException
- * if <code>dataObject</code> is <code>null</code>
- */
- private void setDetachedDataObject(
- Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
- throws SLCommandException, SLRequestException {
-
- String referenceURI = dataObject.getReference();
-
- if (referenceURI == null) {
-
- // not allowed
- log.info("XML structure of the command request contains an " +
- "invalid combination of optional elements or attributes. " +
- "DataObject of structure='detached' must contain a reference.");
- throw new SLRequestException(3003);
-
- } else {
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
-
- String idValue = ctx.getIdValueFactory().createIdValue("Reference");
-
- reference = new XSECTReference(referenceURI, dm, transforms, null, idValue);
-
- // case D:
- //
- // The Reference attribute contains a URI that is used by the Citizen Card
- // Environment to code the reference to the data object as part of the XML
- // signature (attribute URI in the dsig:Reference) element. The content of
- // sl:DataObject represents the data object.
-
- if (dataObject.getLocRefContent() != null) {
- String locRef = dataObject.getLocRefContent();
- try {
- this.reference.setDereferencer(new LocRefDereferencer(ctx.getDereferencerContext(), locRef));
- } catch (URISyntaxException e) {
- log.info("Invalid URI '" + locRef + "' in DataObject.", e);
- throw new SLCommandException(4003);
- } catch (IllegalArgumentException e) {
- log.info("LocRef URI of '" + locRef + "' not supported in DataObject. ", e);
- throw new SLCommandException(4003);
- }
- } else if (dataObject.getBase64Content() != null) {
- byte[] base64Content = dataObject.getBase64Content();
- this.reference.setDereferencer(new ByteArrayDereferencer(base64Content));
- } else if (dataObject.getXMLContent() != null) {
- XMLContentType xmlContent = (XMLContentType) dataObject.getXMLContent();
- byte[] bytes = xmlContent.getRedirectedStream().toByteArray();
- this.reference.setDereferencer(new ByteArrayDereferencer(bytes));
- } else {
-
- // case C:
- //
- // The Reference attribute contains a URI that must be resolved by the
- // Citizen Card Environment to obtain the data object. The Reference
- // attribute contains a URI that is used by the Citizen Card Environment
- // to code the reference to the data object as part of the XML signature
- // (attribute URI in the dsig:Reference) element. The content of
- // sl:DataObject remains empty.
-
- }
-
- }
- }
-
- /**
- * Returns the preferred <code>sl:TransformInfo</code> from the given list of
- * <code>transformInfos</code>, or <code>null</code> if none of the given
- * <code>transformInfos</code> is preferred over the others.
- *
- * @param transformsInfos
- * a list of <code>sl:TransformInfo</code>s
- *
- * @return the selected <code>sl:TransformInfo</code> or <code>null</code>, if
- * none is preferred over the others
- */
- private TransformsInfoType selectPreferredTransformsInfo(List<TransformsInfoType> transformsInfos) {
-
- Map<String, TransformsInfoType> mimeTypes = new HashMap<String, TransformsInfoType>();
-
- StringBuilder debugString = null;
- if (log.isDebugEnabled()) {
- debugString = new StringBuilder();
- debugString.append("Got " + transformsInfos.size() + " TransformsInfo(s):");
- }
-
- for (TransformsInfoType transformsInfoType : transformsInfos) {
- MetaInfoType finalDataMetaInfo = transformsInfoType.getFinalDataMetaInfo();
- String mimeType = finalDataMetaInfo.getMimeType();
- String description = finalDataMetaInfo.getDescription();
- mimeTypes.put(mimeType, transformsInfoType);
- if (debugString != null) {
- debugString.append("\n FinalDataMetaInfo: MIME-Type=");
- debugString.append(mimeType);
- if (description != null) {
- debugString.append(" ");
- debugString.append(description);
- }
- }
- }
-
- if (debugString != null) {
- log.debug(debugString);
- }
-
- // look for preferred transform
- for (String mimeType : DEFAULT_PREFFERED_MIME_TYPES) {
- if (mimeTypes.containsKey(mimeType)) {
- return mimeTypes.get(mimeType);
- }
- }
-
- // no preferred transform
- return null;
-
- }
-
- /**
- * Create an instance of <code>ds:Transforms</code> from the given
- * <code>sl:TransformsInfo</code>.
- *
- * @param transformsInfo
- * the <code>sl:TransformsInfo</code>
- *
- * @return a corresponding unmarshalled <code>ds:Transforms</code>, or
- * <code>null</code> if the given <code>sl:TransformsInfo</code> does
- * not contain a <code>dsig:Transforms</code> element
- *
- * @throws SLRequestException
- * if the <code>ds:Transforms</code> in the given
- * <code>transformsInfo</code> are not valid or cannot be parsed.
- *
- * @throws MarshalException
- * if the <code>ds:Transforms</code> in the given
- * <code>transformsInfo</code> cannot be unmarshalled.
- */
- private XSECTTransforms createTransforms(TransformsInfoType transformsInfo) throws SLRequestException, MarshalException {
-
- ByteArrayOutputStream redirectedStream = ((at.gv.egiz.slbinding.impl.TransformsInfoType) transformsInfo).getRedirectedStream();
- byte[] transformBytes = (redirectedStream != null) ? redirectedStream.toByteArray() : null;
-
- if (transformBytes != null && transformBytes.length > 0) {
-
- // debug
- if (log.isTraceEnabled()) {
- StringBuilder sb = new StringBuilder();
- sb.append("Trying to parse transforms:\n");
- sb.append(new String(transformBytes, Charset.forName("UTF-8")));
- log.trace(sb);
- }
-
- DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
- LSInput input = domImplLS.createLSInput();
- input.setByteStream(new ByteArrayInputStream(transformBytes));
-
- LSParser parser = domImplLS.createLSParser(
- DOMImplementationLS.MODE_SYNCHRONOUS, null);
- DOMConfiguration domConfig = parser.getDomConfig();
- SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
- domConfig.setParameter("error-handler", errorHandler);
- domConfig.setParameter("validate", Boolean.FALSE);
-
- Document document;
- try {
- document = parser.parse(input);
- } catch (DOMException e) {
- log.info("Failed to parse dsig:Transforms.", e);
- throw new SLRequestException(3002);
- } catch (LSException e) {
- log.info("Failed to parse dsig:Transforms.", e);
- throw new SLRequestException(3002);
- }
-
- // adopt ds:Transforms
- Element documentElement = document.getDocumentElement();
- Node adoptedTransforms = ctx.getDocument().adoptNode(documentElement);
-
- DOMCryptoContext context = new DOMCryptoContext();
-
- // unmarshall ds:Transforms
- return new XSECTTransforms(context, adoptedTransforms);
-
- } else {
- return null;
- }
-
- }
-
- /**
- * Sets the <code>mimeType</code> and the <code>description</code> value
- * for this DataObject.
- *
- * @param metaInfoType the <code>sl:FinalMetaDataInfo</code>
- *
- * @throws NullPointerException if <code>metaInfoType</code> is <code>null</code>
- */
- private void setFinalDataMetaInfo(MetaInfoType metaInfoType) {
-
- this.mimeType = metaInfoType.getMimeType();
- this.description = metaInfoType.getDescription();
-
- }
-
- /**
- * Selects an appropriate transformation path (if present) from the given list
- * of <code>sl:TransformInfos</code>, sets the corresponding final data meta info and
- * returns the corresponding unmarshalled <code>ds:Transforms</code>.
- *
- * @param transformsInfos the <code>sl:TransformInfos</code>
- *
- * @return the unmarshalled <code>ds:Transforms</code>, or <code>null</code> if
- * no transformation path has been selected.
- *
- * @throws SLRequestException if the given list <code>ds:TransformsInfo</code> contains
- * an invalid <code>ds:Transforms</code> element, or no suitable transformation path
- * can be found.
- */
- private XSECTTransforms createTransformsAndSetFinalDataMetaInfo(
- List<TransformsInfoType> transformsInfos) throws SLRequestException {
-
- TransformsInfoType preferredTransformsInfo = selectPreferredTransformsInfo(transformsInfos);
- // try preferred transform
- if (preferredTransformsInfo != null) {
-
- try {
- XSECTTransforms transforms = createTransforms(preferredTransformsInfo);
- setFinalDataMetaInfo(preferredTransformsInfo.getFinalDataMetaInfo());
- return transforms;
- } catch (MarshalException e) {
-
- String mimeType = preferredTransformsInfo.getFinalDataMetaInfo().getMimeType();
- log.info("Failed to unmarshal preferred transformation path (MIME-Type="
- + mimeType + ").", e);
-
- }
-
- }
-
- // look for another suitable transformation path
- for (TransformsInfoType transformsInfoType : transformsInfos) {
-
- try {
- XSECTTransforms transforms = createTransforms(transformsInfoType);
- setFinalDataMetaInfo(transformsInfoType.getFinalDataMetaInfo());
- return transforms;
- } catch (MarshalException e) {
-
- String mimeType = transformsInfoType.getFinalDataMetaInfo().getMimeType();
- log.info("Failed to unmarshal transformation path (MIME-Type="
- + mimeType + ").", e);
- }
-
- }
-
- // no suitable transformation path found
- throw new SLRequestException(3003);
-
- }
-
- /**
- * Create an XMLObject with the Base64 encoding of the given
- * <code>content</code>.
- *
- * @param content
- * the to-be Base64 encoded content
- * @return an XMLObject with the Base64 encoded <code>content</code>
- */
- private XMLObject createXMLObject(InputStream content) {
-
- Text textNode;
- try {
- textNode = at.gv.egiz.dom.DOMUtils.createBase64Text(content, ctx.getDocument());
- } catch (IOException e) {
- log.error(e);
- throw new SLRuntimeException(e);
- }
-
- DOMStructure structure = new DOMStructure(textNode);
-
- String idValue = ctx.getIdValueFactory().createIdValue("Object");
-
- return ctx.getSignatureFactory().newXMLObject(Collections.singletonList(structure), idValue, null, null);
-
- }
-
- /**
- * Create an XMLObject with the given <code>content</code> node.
- *
- * @param content the content node
- *
- * @return an XMLObject with the given <code>content</code>
- */
- private XMLObject createXMLObject(Node content) {
-
- String idValue = ctx.getIdValueFactory().createIdValue("Object");
-
- List<DOMStructure> structures = Collections.singletonList(new DOMStructure(content));
-
- return ctx.getSignatureFactory().newXMLObject(structures, idValue, null, null);
-
- }
-
- /**
- * Sets the given <code>xmlObject</code> and creates and sets a corresponding
- * <code>Reference</code>.
- * <p>
- * A transform to Base64-decode the xmlObject's content is inserted at the top
- * of to the optional <code>transforms</code> if given, or to a newly created
- * <code>Transforms</code> element if <code>transforms</code> is
- * <code>null</code>.
- *
- * @param xmlObject
- * the XMLObject
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if creating the Reference fails
- * @throws NullPointerException
- * if <code>xmlObject</code> is <code>null</code>
- */
- private void setXMLObjectAndReferenceBase64(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
-
- // create reference URI
- //
- // NOTE: the ds:Object can be referenced directly, as the Base64 transform
- // operates on the text() of the input nodelist.
- //
- String referenceURI = "#" + xmlObject.getId();
-
- // create Base64 Transform
- Transform transform;
- try {
- transform = ctx.getSignatureFactory().newTransform(Transform.BASE64, (TransformParameterSpec) null);
- } catch (NoSuchAlgorithmException e) {
- // algorithm must be present
- throw new SLRuntimeException(e);
- } catch (InvalidAlgorithmParameterException e) {
- // algorithm does not take parameters
- throw new SLRuntimeException(e);
- }
-
- if (transforms == null) {
- transforms = new XSECTTransforms(Collections.singletonList(transform));
- } else {
- transforms.insertTransform(transform);
- }
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
- String id = ctx.getIdValueFactory().createIdValue("Reference");
-
- this.xmlObject = xmlObject;
- this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
-
- }
-
- /**
- * Sets the given <code>xmlObject</code> and creates and sets a corresponding
- * <code>Reference</code>.
- * <p>
- * A transform to select the xmlObject's content is inserted at the top of to
- * the optional <code>transforms</code> if given, or to a newly created
- * <code>Transforms</code> element if <code>transforms</code> is
- * <code>null</code>.
- * </p>
- *
- * @param xmlObject
- * the XMLObject
- * @param transforms
- * an optional <code>Transforms</code> element (may be
- * <code>null</code>)
- *
- * @throws SLCommandException
- * if creating the Reference fails
- * @throws NullPointerException
- * if <code>xmlObject</code> is <code>null</code>
- */
- private void setXMLObjectAndReferenceXML(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
-
- // create reference URI
- String referenceURI = "#" + xmlObject.getId();
-
- // create Transform to select ds:Object's children
- Transform xpathTransform;
- Transform c14nTransform;
- try {
-
- XPathType xpath = new XPathType("id(\"" + xmlObject.getId() + "\")/node()", XPathType.Filter.INTERSECT);
- List<XPathType> xpaths = Collections.singletonList(xpath);
- XPathFilter2ParameterSpec params = new XPathFilter2ParameterSpec(xpaths);
-
- xpathTransform = ctx.getSignatureFactory().newTransform(Transform.XPATH2, params);
-
- // add exclusive canonicalization to avoid signing the namespace context of the ds:Object
- c14nTransform = ctx.getSignatureFactory().newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
-
- } catch (NoSuchAlgorithmException e) {
- // algorithm must be present
- throw new SLRuntimeException(e);
- } catch (InvalidAlgorithmParameterException e) {
- // params must be appropriate
- throw new SLRuntimeException(e);
- }
-
- if (transforms == null) {
- List<Transform> newTransfroms = new ArrayList<Transform>();
- newTransfroms.add(xpathTransform);
- newTransfroms.add(c14nTransform);
- transforms = new XSECTTransforms(newTransfroms);
- } else {
- transforms.insertTransform(xpathTransform);
- }
-
- DigestMethod dm;
- try {
- dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
- } catch (NoSuchAlgorithmException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- } catch (InvalidAlgorithmParameterException e) {
- log.error("Failed to get DigestMethod.", e);
- throw new SLCommandException(4006);
- }
- String id = ctx.getIdValueFactory().createIdValue("Reference");
-
- this.xmlObject = xmlObject;
- this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
-
- }
-
- /**
- * Parses the given <code>xmlContent</code> and returns a corresponding
- * document fragment.
- *
- * <p>
- * The to-be parsed content is surrounded by <dummy> ... </dummy> elements to
- * allow for mixed (e.g. Text and Element) content in XMLContent.
- * </p>
- *
- * @param xmlContent
- * the XMLContent to-be parsed
- *
- * @return a document fragment containing the parsed nodes
- *
- * @throws SLCommandException
- * if parsing the given <code>xmlContent</code> fails
- *
- * @throws NullPointerException
- * if <code>xmlContent</code> is <code>null</code>
- */
- private DocumentFragment parseDataObject(XMLContentType xmlContent) throws SLCommandException {
-
- ByteArrayOutputStream redirectedStream = xmlContent.getRedirectedStream();
-
- // Note: We can assume a fixed character encoding of UTF-8 for the
- // content of the redirect stream as the content has already been parsed
- // and serialized again to the redirect stream.
-
- List<InputStream> inputStreams = new ArrayList<InputStream>();
- try {
- // dummy start element
- inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8")));
-
- // content
- inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray()));
-
- // dummy end element
- inputStreams.add(new ByteArrayInputStream("</dummy>".getBytes("UTF-8")));
- } catch (UnsupportedEncodingException e) {
- throw new SLRuntimeException(e);
- }
-
- SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams));
-
- // parse DataObject
- Document doc = parseDataObject(inputStream, "UTF-8");
-
- Element documentElement = doc.getDocumentElement();
-
- if (documentElement == null ||
- !"dummy".equals(documentElement.getLocalName())) {
- log.info("Failed to parse DataObject XMLContent.");
- throw new SLCommandException(4111);
- }
-
- DocumentFragment fragment = doc.createDocumentFragment();
- while (documentElement.getFirstChild() != null) {
- fragment.appendChild(documentElement.getFirstChild());
- }
-
- // log parsed document
- if (log.isTraceEnabled()) {
-
- StringWriter writer = new StringWriter();
-
- writer.write("DataObject:\n");
-
- LSOutput output = domImplLS.createLSOutput();
- output.setCharacterStream(writer);
- output.setEncoding("UTF-8");
- LSSerializer serializer = domImplLS.createLSSerializer();
- serializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE);
- serializer.write(fragment, output);
-
- log.trace(writer.toString());
- }
-
- return fragment;
-
- }
-
- /**
- * Parses the given <code>inputStream</code> using the given
- * <code>encoding</code> and returns the parsed document.
- *
- * @param inputStream
- * the to-be parsed input
- *
- * @param encoding
- * the encoding to be used for parsing the given
- * <code>inputStream</code>
- *
- * @return the parsed document
- *
- * @throws SLCommandException
- * if parsing the <code>inputStream</code> fails.
- *
- * @throws NullPointerException
- * if <code>inputStram</code> is <code>null</code>
- */
- private Document parseDataObject(InputStream inputStream, String encoding) throws SLCommandException {
-
- LSInput input = domImplLS.createLSInput();
- input.setByteStream(inputStream);
-
- if (encoding != null) {
- input.setEncoding(encoding);
- }
-
- LSParser parser = domImplLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
- DOMConfiguration domConfig = parser.getDomConfig();
- SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
- domConfig.setParameter("error-handler", errorHandler);
- domConfig.setParameter("validate", Boolean.FALSE);
-
- Document doc;
- try {
- doc = parser.parse(input);
- } catch (DOMException e) {
- log.info("Existing XML document cannot be parsed.", e);
- throw new SLCommandException(4111);
- } catch (LSException e) {
- log.info("Existing XML document cannot be parsed. ", e);
- throw new SLCommandException(4111);
- }
-
- if (errorHandler.hasErrors()) {
- // log errors
- if (log.isInfoEnabled()) {
- List<String> errorMessages = errorHandler.getErrorMessages();
- StringBuffer sb = new StringBuffer();
- for (String errorMessage : errorMessages) {
- sb.append(" ");
- sb.append(errorMessage);
- }
- log.info("Existing XML document cannot be parsed. " + sb.toString());
- }
- throw new SLCommandException(4111);
- }
-
- return doc;
-
- }
-
-
-}
+
+ /**
+ * Configures this DataObject with the information provided within the given
+ * <code>sl:DataObjectInfo</code>.
+ *
+ * @param dataObjectInfo
+ * the <code>sl:DataObjectInfo</code>
+ *
+ * @throws SLCommandException
+ * if configuring this DataObject with the information provided in
+ * the <code>sl:DataObjectInfo</code> fails.
+ * @throws SLRequestException
+ * if the information provided in the <code>sl:DataObjectInfo</code>
+ * does not conform to the security layer specification.
+ * @throws NullPointerException
+ * if <code>dataObjectInfo</code> is <code>null</code>
+ */
+ public void setDataObjectInfo(DataObjectInfoType dataObjectInfo) throws SLCommandException, SLRequestException {
+
+ Base64XMLLocRefOptRefContentType dataObject = dataObjectInfo.getDataObject();
+ String structure = dataObjectInfo.getStructure();
+
+ // select and unmarshal an appropriate transformation path if provided
+ // and set the final data meta information
+ XSECTTransforms transforms = createTransformsAndSetFinalDataMetaInfo(dataObjectInfo.getTransformsInfo());
+
+ if ("enveloping".equals(structure)) {
+
+ // configure this DataObject as an enveloped DataObject
+ setEnvelopedDataObject(dataObject, transforms);
+
+ } else if ("detached".equals(structure)) {
+
+ // configure this DataObject as an detached DataObject
+ setDetachedDataObject(dataObject, transforms);
+
+ }
+ // other values are not allowed by the schema and are therefore ignored
+
+ }
+
+ private byte[] getTransformsBytes(at.gv.egiz.slbinding.impl.TransformsInfoType ti) {
+ return ti.getRedirectedStream().toByteArray();
+// byte[] transformsBytes = ti.getRedirectedStream().toByteArray();
+//
+// if (transformsBytes == null || transformsBytes.length == 0) {
+// return null;
+// }
+//
+// String dsigPrefix = ti.getNamespaceContext().getNamespaceURI("http://www.w3.org/2000/09/xmldsig#");
+// byte[] pre, post;
+// if (dsigPrefix == null) {
+// log.trace("XMLDSig not declared in outside dsig:Transforms");
+// pre = "<AssureDSigNS>".getBytes();
+// post = "</AssureDSigNS>".getBytes();
+// } else {
+// log.trace("XMLDSig bound to prefix " + dsigPrefix);
+// pre = ("<AssureDSigNS xmlns:" + dsigPrefix + "=\"http://www.w3.org/2000/09/xmldsig#\">").getBytes();
+// post = "</AssureDSigNS>".getBytes();
+// }
+//
+// byte[] workaround = new byte[pre.length + transformsBytes.length + post.length];
+// System.arraycopy(pre, 0, workaround, 0, pre.length);
+// System.arraycopy(transformsBytes, 0, workaround, pre.length, transformsBytes.length);
+// System.arraycopy(post, 0, workaround, pre.length + transformsBytes.length, post.length);
+// return workaround;
+ }
+
+ /**
+ * Configures this DataObject as an enveloped DataObject with the information
+ * provided within the given <code>sl:DataObject</code>.
+ *
+ * @param dataObject
+ * the <code>sl:DataObject</code>
+ * @param transforms
+ * an optional <code>Transforms</code> element (may be
+ * <code>null</code>)
+ *
+ * @throws SLCommandException
+ * if configuring this DataObject with the information provided in
+ * the <code>sl:DataObject</code> fails.
+ * @throws SLRequestException
+ * if the information provided in the <code>sl:DataObject</code>
+ * does not conform to the security layer specification.
+ * @throws NullPointerException
+ * if <code>dataObject</code> is <code>null</code>
+ */
+ private void setEnvelopedDataObject(
+ Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
+ throws SLCommandException, SLRequestException {
+
+ String reference = dataObject.getReference();
+ if (reference == null) {
+ //
+ // case A
+ //
+ // The Reference attribute is not used; the content of sl:DataObject represents the data object.
+ // If the data object is XML-coded (the sl:XMLContent element is used in sl:DataObject), then it
+ // must be incorporated in the signature structure as parsed XML.
+ //
+
+ if (dataObject.getBase64Content() != null) {
+
+ log.debug("Adding DataObject (Base64Content) without a reference URI.");
+
+ // create XMLObject
+ XMLObject xmlObject = createXMLObject(new ByteArrayInputStream(dataObject.getBase64Content()));
+
+ setXMLObjectAndReferenceBase64(xmlObject, transforms);
+
+ } else if (dataObject.getXMLContent() != null) {
+
+ log.debug("Adding DataObject (XMLContent) without a reference URI.");
+
+ // create XMLObject
+ DocumentFragment content = parseDataObject((XMLContentType) dataObject.getXMLContent());
+ XMLObject xmlObject = createXMLObject(content);
+
+ setXMLObjectAndReferenceXML(xmlObject, transforms);
+
+ } else if (dataObject.getLocRefContent() != null) {
+
+ log.debug("Adding DataObject (LocRefContent) without a reference URI.");
+
+ setEnvelopedDataObject(dataObject.getLocRefContent(), transforms);
+
+ } else {
+
+ // not allowed
+ log.info("XML structure of the command request contains an " +
+ "invalid combination of optional elements or attributes. " +
+ "DataObject of structure='enveloped' without a reference must contain content.");
+ throw new SLRequestException(3003);
+
+ }
+
+ } else {
+
+ if (dataObject.getBase64Content() == null &&
+ dataObject.getXMLContent() == null &&
+ dataObject.getLocRefContent() == null) {
+
+ //
+ // case B
+ //
+ // The Reference attribute contains a URI that must be resolved by the
+ // Citizen Card Environment to obtain the data object.
+ // The content of sl:DataObject remains empty
+ //
+
+ log.debug("Adding DataObject from reference URI '" + reference + "'.");
+
+ setEnvelopedDataObject(reference, transforms);
+
+ } else {
+
+ // not allowed
+ log.info("XML structure of the command request contains an " +
+ "invalid combination of optional elements or attributes. " +
+ "DataObject of structure='enveloped' with reference must not contain content.");
+ throw new SLRequestException(3003);
+
+ }
+
+
+ }
+
+ }
+
+ /**
+ * Configures this DataObject as an enveloped DataObject with the content to
+ * be dereferenced from the given <code>reference</code>.
+ *
+ * @param reference
+ * the <code>reference</code> URI
+ * @param transforms
+ * an optional <code>Transforms</code> element (may be
+ * <code>null</code>)
+ *
+ * @throws SLCommandException
+ * if dereferencing the given <code>reference</code> fails, or if
+ * configuring this DataObject with the data dereferenced from the
+ * given <code>reference</code> fails.
+ * @throws NullPointerException
+ * if <code>reference</code> is <code>null</code>
+ */
+ private void setEnvelopedDataObject(String reference, XSECTTransforms transforms) throws SLCommandException {
+
+ if (reference == null) {
+ throw new NullPointerException("Argument 'reference' must not be null.");
+ }
+
+ // dereference URL
+ URLDereferencer dereferencer = URLDereferencer.getInstance();
+
+ StreamData streamData;
+ try {
+ streamData = dereferencer.dereference(reference, ctx.getDereferencerContext());
+ } catch (IOException e) {
+ log.info("Failed to dereference XMLObject from '" + reference + "'.", e);
+ throw new SLCommandException(4110);
+ }
+
+ Node childNode;
+
+ String contentType = streamData.getContentType();
+ if (contentType.startsWith("text/xml")) {
+
+ // If content type is text/xml parse content.
+ String charset = HttpUtil.getCharset(contentType, true);
+
+ Document doc = parseDataObject(streamData.getStream(), charset);
+
+ childNode = doc.getDocumentElement();
+
+ if (childNode == null) {
+ log.info("Failed to parse XMLObject from '" + reference + "'.");
+ throw new SLCommandException(4111);
+ }
+
+ XMLObject xmlObject = createXMLObject(childNode);
+
+ setXMLObjectAndReferenceXML(xmlObject, transforms);
+
+ } else {
+
+ // Include content Base64 encoded.
+ XMLObject xmlObject = createXMLObject(streamData.getStream());
+
+ setXMLObjectAndReferenceBase64(xmlObject, transforms);
+
+ }
+
+ }
+
+ /**
+ * Configures this DataObject as an detached DataObject with the information
+ * provided in the given <code>sl:DataObject</code> and optionally
+ * <code>transforms</code>.
+ *
+ * @param dataObject
+ * the <code>sl:DataObject</code>
+ * @param transforms
+ * an optional Transforms object, may be <code>null</code>
+ *
+ * @throws SLCommandException
+ * if configuring this DataObject with the information provided in
+ * the <code>sl:DataObject</code> fails.
+ * @throws SLRequestException
+ * if the information provided in the <code>sl:DataObject</code>
+ * does not conform to the security layer specification.
+ * @throws NullPointerException
+ * if <code>dataObject</code> is <code>null</code>
+ */
+ private void setDetachedDataObject(
+ Base64XMLLocRefOptRefContentType dataObject, XSECTTransforms transforms)
+ throws SLCommandException, SLRequestException {
+
+ String referenceURI = dataObject.getReference();
+
+ if (referenceURI == null) {
+
+ // not allowed
+ log.info("XML structure of the command request contains an " +
+ "invalid combination of optional elements or attributes. " +
+ "DataObject of structure='detached' must contain a reference.");
+ throw new SLRequestException(3003);
+
+ } else {
+
+ DigestMethod dm;
+ try {
+ dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ }
+
+ String idValue = ctx.getIdValueFactory().createIdValue("Reference");
+
+ reference = new XSECTReference(referenceURI, dm, transforms, null, idValue);
+
+ // case D:
+ //
+ // The Reference attribute contains a URI that is used by the Citizen Card
+ // Environment to code the reference to the data object as part of the XML
+ // signature (attribute URI in the dsig:Reference) element. The content of
+ // sl:DataObject represents the data object.
+
+ if (dataObject.getLocRefContent() != null) {
+ String locRef = dataObject.getLocRefContent();
+ try {
+ this.reference.setDereferencer(new LocRefDereferencer(ctx.getDereferencerContext(), locRef));
+ } catch (URISyntaxException e) {
+ log.info("Invalid URI '" + locRef + "' in DataObject.", e);
+ throw new SLCommandException(4003);
+ } catch (IllegalArgumentException e) {
+ log.info("LocRef URI of '" + locRef + "' not supported in DataObject. ", e);
+ throw new SLCommandException(4003);
+ }
+ } else if (dataObject.getBase64Content() != null) {
+ byte[] base64Content = dataObject.getBase64Content();
+ this.reference.setDereferencer(new ByteArrayDereferencer(base64Content));
+ } else if (dataObject.getXMLContent() != null) {
+ XMLContentType xmlContent = (XMLContentType) dataObject.getXMLContent();
+ byte[] bytes = xmlContent.getRedirectedStream().toByteArray();
+ this.reference.setDereferencer(new ByteArrayDereferencer(bytes));
+ } else {
+
+ // case C:
+ //
+ // The Reference attribute contains a URI that must be resolved by the
+ // Citizen Card Environment to obtain the data object. The Reference
+ // attribute contains a URI that is used by the Citizen Card Environment
+ // to code the reference to the data object as part of the XML signature
+ // (attribute URI in the dsig:Reference) element. The content of
+ // sl:DataObject remains empty.
+
+ }
+
+ }
+ }
+
+ /**
+ * Returns the preferred <code>sl:TransformInfo</code> from the given list of
+ * <code>transformInfos</code>, or <code>null</code> if none of the given
+ * <code>transformInfos</code> is preferred over the others.
+ *
+ * @param transformsInfos
+ * a list of <code>sl:TransformInfo</code>s
+ *
+ * @return the selected <code>sl:TransformInfo</code> or <code>null</code>, if
+ * none is preferred over the others
+ */
+ private TransformsInfoType selectPreferredTransformsInfo(List<TransformsInfoType> transformsInfos) {
+
+ Map<String, TransformsInfoType> mimeTypes = new HashMap<String, TransformsInfoType>();
+
+ StringBuilder debugString = null;
+ if (log.isDebugEnabled()) {
+ debugString = new StringBuilder();
+ debugString.append("Got " + transformsInfos.size() + " TransformsInfo(s):");
+ }
+
+ for (TransformsInfoType transformsInfoType : transformsInfos) {
+ MetaInfoType finalDataMetaInfo = transformsInfoType.getFinalDataMetaInfo();
+ String mimeType = finalDataMetaInfo.getMimeType();
+ String description = finalDataMetaInfo.getDescription();
+ mimeTypes.put(mimeType, transformsInfoType);
+ if (debugString != null) {
+ debugString.append("\n FinalDataMetaInfo: MIME-Type=");
+ debugString.append(mimeType);
+ if (description != null) {
+ debugString.append(" ");
+ debugString.append(description);
+ }
+ }
+ }
+
+ if (debugString != null) {
+ log.debug(debugString);
+ }
+
+ // look for preferred transform
+ for (String mimeType : DEFAULT_PREFFERED_MIME_TYPES) {
+ if (mimeTypes.containsKey(mimeType)) {
+ return mimeTypes.get(mimeType);
+ }
+ }
+
+ // no preferred transform
+ return null;
+
+ }
+
+ /**
+ * Create an instance of <code>ds:Transforms</code> from the given
+ * <code>sl:TransformsInfo</code>.
+ *
+ * @param transformsInfo
+ * the <code>sl:TransformsInfo</code>
+ *
+ * @return a corresponding unmarshalled <code>ds:Transforms</code>, or
+ * <code>null</code> if the given <code>sl:TransformsInfo</code> does
+ * not contain a <code>dsig:Transforms</code> element
+ *
+ * @throws SLRequestException
+ * if the <code>ds:Transforms</code> in the given
+ * <code>transformsInfo</code> are not valid or cannot be parsed.
+ *
+ * @throws MarshalException
+ * if the <code>ds:Transforms</code> in the given
+ * <code>transformsInfo</code> cannot be unmarshalled.
+ */
+ private XSECTTransforms createTransforms(TransformsInfoType transformsInfo) throws SLRequestException, MarshalException {
+
+ byte[] transforms = getTransformsBytes((at.gv.egiz.slbinding.impl.TransformsInfoType) transformsInfo);
+
+ if (transforms != null && transforms.length > 0) {
+ // debug
+ if (log.isTraceEnabled()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Trying to parse transforms:\n");
+ sb.append(new String(transforms, Charset.forName("UTF-8")));
+ log.trace(sb);
+ }
+
+ DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
+ LSInput input = domImplLS.createLSInput();
+ input.setByteStream(new ByteArrayInputStream(transforms));
+
+ LSParser parser = domImplLS.createLSParser(
+ DOMImplementationLS.MODE_SYNCHRONOUS, null);
+ DOMConfiguration domConfig = parser.getDomConfig();
+ SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
+ domConfig.setParameter("error-handler", errorHandler);
+ domConfig.setParameter("validate", Boolean.FALSE);
+
+ Document document;
+ try {
+ document = parser.parse(input);
+ } catch (DOMException e) {
+ log.info("Failed to parse dsig:Transforms.", e);
+ throw new SLRequestException(3002);
+ } catch (LSException e) {
+ log.info("Failed to parse dsig:Transforms.", e);
+ throw new SLRequestException(3002);
+ }
+
+ // adopt ds:Transforms
+ Element transformsElt = document.getDocumentElement();
+ Node adoptedTransforms = ctx.getDocument().adoptNode(transformsElt);
+
+ DOMCryptoContext context = new DOMCryptoContext();
+
+ // unmarshall ds:Transforms
+ return new XSECTTransforms(context, adoptedTransforms);
+
+ } else {
+ return null;
+ }
+
+
+// TransformsType transformsType = transformsInfo.getTransforms();
+// if (transformsType == null) {
+// return null;
+// }
+// List<TransformType> transformList = transformsType.getTransform();
+//
+// DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
+//// Document transformsDoc = ((DOMImplementation) domImplLS).createDocument("http://www.w3.org/2000/09/xmldsig#", "Transforms", null);
+//// Element transforms = transformsDoc.getDocumentElement();
+// Document transformsDoc = DOMUtils.createDocument();
+// Element transforms = transformsDoc.createElementNS(
+// "http://www.w3.org/2000/09/xmldsig#",
+// Signature.XMLDSIG_PREFIX + ":Transforms");
+// transformsDoc.appendChild(transforms);
+//
+// for (TransformType transformType : transformList) {
+// log.trace("found " + transformType.getClass().getName());
+// Element transform = transformsDoc.createElementNS(
+// "http://www.w3.org/2000/09/xmldsig#",
+// Signature.XMLDSIG_PREFIX + ":Transform");
+// String algorithm = transformType.getAlgorithm();
+// if (algorithm != null) {
+// log.trace("found algorithm " + algorithm);
+// transform.setAttribute("Algorithm", algorithm);
+// }
+//
+// at.gv.egiz.slbinding.impl.TransformType t = (at.gv.egiz.slbinding.impl.TransformType) transformType;
+// byte[] redirectedBytes = t.getRedirectedStream().toByteArray();
+// if (redirectedBytes != null && redirectedBytes.length > 0) {
+// if (log.isTraceEnabled()) {
+// StringBuilder sb = new StringBuilder();
+// sb.append("Trying to parse dsig:Transform:\n");
+// sb.append(new String(redirectedBytes, Charset.forName("UTF-8")));
+// log.trace(sb);
+// }
+// LSInput input = domImplLS.createLSInput();
+// input.setByteStream(new ByteArrayInputStream(redirectedBytes));
+//
+// LSParser parser = domImplLS.createLSParser(
+// DOMImplementationLS.MODE_SYNCHRONOUS, null);
+// DOMConfiguration domConfig = parser.getDomConfig();
+// SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
+// domConfig.setParameter("error-handler", errorHandler);
+// domConfig.setParameter("validate", Boolean.FALSE);
+//
+// try {
+// Document redirectedDoc = parser.parse(input);
+// Node redirected = transformsDoc.adoptNode(redirectedDoc.getDocumentElement());
+// transform.appendChild(redirected);
+//
+// //not supported by Xerces2.9.1
+//// Node redirected = parser.parseWithContext(input, transform, LSParser.ACTION_APPEND_AS_CHILDREN);
+//
+// } catch (DOMException e) {
+// log.info("Failed to parse dsig:Transform.", e);
+// throw new SLRequestException(3002);
+// } catch (LSException e) {
+// log.info("Failed to parse dsig:Transform.", e);
+// throw new SLRequestException(3002);
+// }
+// }
+// transforms.appendChild(transform);
+// }
+//
+// //adopt ds:Transforms
+// Node adoptedTransforms = ctx.getDocument().adoptNode(transforms);
+// DOMCryptoContext context = new DOMCryptoContext();
+//
+// // unmarshall ds:Transforms
+// return new XSECTTransforms(context, adoptedTransforms);
+
+ }
+
+ /**
+ * Sets the <code>mimeType</code> and the <code>description</code> value
+ * for this DataObject.
+ *
+ * @param metaInfoType the <code>sl:FinalMetaDataInfo</code>
+ *
+ * @throws NullPointerException if <code>metaInfoType</code> is <code>null</code>
+ */
+ private void setFinalDataMetaInfo(MetaInfoType metaInfoType) {
+
+ this.mimeType = metaInfoType.getMimeType();
+ this.description = metaInfoType.getDescription();
+
+ }
+
+ /**
+ * Selects an appropriate transformation path (if present) from the given list
+ * of <code>sl:TransformInfos</code>, sets the corresponding final data meta info and
+ * returns the corresponding unmarshalled <code>ds:Transforms</code>.
+ *
+ * @param transformsInfos the <code>sl:TransformInfos</code>
+ *
+ * @return the unmarshalled <code>ds:Transforms</code>, or <code>null</code> if
+ * no transformation path has been selected.
+ *
+ * @throws SLRequestException if the given list <code>ds:TransformsInfo</code> contains
+ * an invalid <code>ds:Transforms</code> element, or no suitable transformation path
+ * can be found.
+ */
+ private XSECTTransforms createTransformsAndSetFinalDataMetaInfo(
+ List<TransformsInfoType> transformsInfos) throws SLRequestException {
+
+ TransformsInfoType preferredTransformsInfo = selectPreferredTransformsInfo(transformsInfos);
+ // try preferred transform
+ if (preferredTransformsInfo != null) {
+
+ try {
+ XSECTTransforms transforms = createTransforms(preferredTransformsInfo);
+ setFinalDataMetaInfo(preferredTransformsInfo.getFinalDataMetaInfo());
+ return transforms;
+ } catch (MarshalException e) {
+
+ String mimeType = preferredTransformsInfo.getFinalDataMetaInfo().getMimeType();
+ log.info("Failed to unmarshal preferred transformation path (MIME-Type="
+ + mimeType + ").", e);
+
+ }
+
+ }
+
+ // look for another suitable transformation path
+ for (TransformsInfoType transformsInfoType : transformsInfos) {
+
+ try {
+ XSECTTransforms transforms = createTransforms(transformsInfoType);
+ setFinalDataMetaInfo(transformsInfoType.getFinalDataMetaInfo());
+ return transforms;
+ } catch (MarshalException e) {
+
+ String mimeType = transformsInfoType.getFinalDataMetaInfo().getMimeType();
+ log.info("Failed to unmarshal transformation path (MIME-Type="
+ + mimeType + ").", e);
+ }
+
+ }
+
+ // no suitable transformation path found
+ throw new SLRequestException(3003);
+
+ }
+
+ /**
+ * Create an XMLObject with the Base64 encoding of the given
+ * <code>content</code>.
+ *
+ * @param content
+ * the to-be Base64 encoded content
+ * @return an XMLObject with the Base64 encoded <code>content</code>
+ */
+ private XMLObject createXMLObject(InputStream content) {
+
+ Text textNode;
+ try {
+ textNode = at.gv.egiz.dom.DOMUtils.createBase64Text(content, ctx.getDocument());
+ } catch (IOException e) {
+ log.error(e);
+ throw new SLRuntimeException(e);
+ }
+
+ DOMStructure structure = new DOMStructure(textNode);
+
+ String idValue = ctx.getIdValueFactory().createIdValue("Object");
+
+ return ctx.getSignatureFactory().newXMLObject(Collections.singletonList(structure), idValue, null, null);
+
+ }
+
+ /**
+ * Create an XMLObject with the given <code>content</code> node.
+ *
+ * @param content the content node
+ *
+ * @return an XMLObject with the given <code>content</code>
+ */
+ private XMLObject createXMLObject(Node content) {
+
+ String idValue = ctx.getIdValueFactory().createIdValue("Object");
+
+ List<DOMStructure> structures = Collections.singletonList(new DOMStructure(content));
+
+ return ctx.getSignatureFactory().newXMLObject(structures, idValue, null, null);
+
+ }
+
+ /**
+ * Sets the given <code>xmlObject</code> and creates and sets a corresponding
+ * <code>Reference</code>.
+ * <p>
+ * A transform to Base64-decode the xmlObject's content is inserted at the top
+ * of to the optional <code>transforms</code> if given, or to a newly created
+ * <code>Transforms</code> element if <code>transforms</code> is
+ * <code>null</code>.
+ *
+ * @param xmlObject
+ * the XMLObject
+ * @param transforms
+ * an optional <code>Transforms</code> element (may be
+ * <code>null</code>)
+ *
+ * @throws SLCommandException
+ * if creating the Reference fails
+ * @throws NullPointerException
+ * if <code>xmlObject</code> is <code>null</code>
+ */
+ private void setXMLObjectAndReferenceBase64(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
+
+ // create reference URI
+ //
+ // NOTE: the ds:Object can be referenced directly, as the Base64 transform
+ // operates on the text() of the input nodelist.
+ //
+ String referenceURI = "#" + xmlObject.getId();
+
+ // create Base64 Transform
+ Transform transform;
+ try {
+ transform = ctx.getSignatureFactory().newTransform(Transform.BASE64, (TransformParameterSpec) null);
+ } catch (NoSuchAlgorithmException e) {
+ // algorithm must be present
+ throw new SLRuntimeException(e);
+ } catch (InvalidAlgorithmParameterException e) {
+ // algorithm does not take parameters
+ throw new SLRuntimeException(e);
+ }
+
+ if (transforms == null) {
+ transforms = new XSECTTransforms(Collections.singletonList(transform));
+ } else {
+ transforms.insertTransform(transform);
+ }
+
+ DigestMethod dm;
+ try {
+ dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ }
+ String id = ctx.getIdValueFactory().createIdValue("Reference");
+
+ this.xmlObject = xmlObject;
+ this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
+
+ }
+
+ /**
+ * Sets the given <code>xmlObject</code> and creates and sets a corresponding
+ * <code>Reference</code>.
+ * <p>
+ * A transform to select the xmlObject's content is inserted at the top of to
+ * the optional <code>transforms</code> if given, or to a newly created
+ * <code>Transforms</code> element if <code>transforms</code> is
+ * <code>null</code>.
+ * </p>
+ *
+ * @param xmlObject
+ * the XMLObject
+ * @param transforms
+ * an optional <code>Transforms</code> element (may be
+ * <code>null</code>)
+ *
+ * @throws SLCommandException
+ * if creating the Reference fails
+ * @throws NullPointerException
+ * if <code>xmlObject</code> is <code>null</code>
+ */
+ private void setXMLObjectAndReferenceXML(XMLObject xmlObject, XSECTTransforms transforms) throws SLCommandException {
+
+ // create reference URI
+ String referenceURI = "#" + xmlObject.getId();
+
+ // create Transform to select ds:Object's children
+ Transform xpathTransform;
+ Transform c14nTransform;
+ try {
+
+ XPathType xpath = new XPathType("id(\"" + xmlObject.getId() + "\")/node()", XPathType.Filter.INTERSECT);
+ List<XPathType> xpaths = Collections.singletonList(xpath);
+ XPathFilter2ParameterSpec params = new XPathFilter2ParameterSpec(xpaths);
+
+ xpathTransform = ctx.getSignatureFactory().newTransform(Transform.XPATH2, params);
+
+ // add exclusive canonicalization to avoid signing the namespace context of the ds:Object
+ c14nTransform = ctx.getSignatureFactory().newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null);
+
+ } catch (NoSuchAlgorithmException e) {
+ // algorithm must be present
+ throw new SLRuntimeException(e);
+ } catch (InvalidAlgorithmParameterException e) {
+ // params must be appropriate
+ throw new SLRuntimeException(e);
+ }
+
+ if (transforms == null) {
+ List<Transform> newTransfroms = new ArrayList<Transform>();
+ newTransfroms.add(xpathTransform);
+ newTransfroms.add(c14nTransform);
+ transforms = new XSECTTransforms(newTransfroms);
+ } else {
+ transforms.insertTransform(xpathTransform);
+ }
+
+ DigestMethod dm;
+ try {
+ dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get DigestMethod.", e);
+ throw new SLCommandException(4006);
+ }
+ String id = ctx.getIdValueFactory().createIdValue("Reference");
+
+ this.xmlObject = xmlObject;
+ this.reference = new XSECTReference(referenceURI, dm, transforms, null, id);
+
+ }
+
+ /**
+ * Parses the given <code>xmlContent</code> and returns a corresponding
+ * document fragment.
+ *
+ * <p>
+ * The to-be parsed content is surrounded by <dummy> ... </dummy> elements to
+ * allow for mixed (e.g. Text and Element) content in XMLContent.
+ * </p>
+ *
+ * @param xmlContent
+ * the XMLContent to-be parsed
+ *
+ * @return a document fragment containing the parsed nodes
+ *
+ * @throws SLCommandException
+ * if parsing the given <code>xmlContent</code> fails
+ *
+ * @throws NullPointerException
+ * if <code>xmlContent</code> is <code>null</code>
+ */
+ private DocumentFragment parseDataObject(XMLContentType xmlContent) throws SLCommandException {
+
+ ByteArrayOutputStream redirectedStream = xmlContent.getRedirectedStream();
+
+ // Note: We can assume a fixed character encoding of UTF-8 for the
+ // content of the redirect stream as the content has already been parsed
+ // and serialized again to the redirect stream.
+
+ List<InputStream> inputStreams = new ArrayList<InputStream>();
+ try {
+ // dummy start element
+ inputStreams.add(new ByteArrayInputStream("<dummy>".getBytes("UTF-8")));
+
+ // content
+ inputStreams.add(new ByteArrayInputStream(redirectedStream.toByteArray()));
+
+ // dummy end element
+ inputStreams.add(new ByteArrayInputStream("</dummy>".getBytes("UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ throw new SLRuntimeException(e);
+ }
+
+ SequenceInputStream inputStream = new SequenceInputStream(Collections.enumeration(inputStreams));
+
+ // parse DataObject
+ Document doc = parseDataObject(inputStream, "UTF-8");
+
+ Element documentElement = doc.getDocumentElement();
+
+ if (documentElement == null ||
+ !"dummy".equals(documentElement.getLocalName())) {
+ log.info("Failed to parse DataObject XMLContent.");
+ throw new SLCommandException(4111);
+ }
+
+ DocumentFragment fragment = doc.createDocumentFragment();
+ while (documentElement.getFirstChild() != null) {
+ fragment.appendChild(documentElement.getFirstChild());
+ }
+
+ // log parsed document
+ if (log.isTraceEnabled()) {
+
+ StringWriter writer = new StringWriter();
+
+ writer.write("DataObject:\n");
+
+ LSOutput output = domImplLS.createLSOutput();
+ output.setCharacterStream(writer);
+ output.setEncoding("UTF-8");
+ LSSerializer serializer = domImplLS.createLSSerializer();
+ serializer.getDomConfig().setParameter("xml-declaration", Boolean.FALSE);
+ serializer.write(fragment, output);
+
+ log.trace(writer.toString());
+ }
+
+ return fragment;
+
+ }
+
+ /**
+ * Parses the given <code>inputStream</code> using the given
+ * <code>encoding</code> and returns the parsed document.
+ *
+ * @param inputStream
+ * the to-be parsed input
+ *
+ * @param encoding
+ * the encoding to be used for parsing the given
+ * <code>inputStream</code>
+ *
+ * @return the parsed document
+ *
+ * @throws SLCommandException
+ * if parsing the <code>inputStream</code> fails.
+ *
+ * @throws NullPointerException
+ * if <code>inputStram</code> is <code>null</code>
+ */
+ private Document parseDataObject(InputStream inputStream, String encoding) throws SLCommandException {
+
+ LSInput input = domImplLS.createLSInput();
+ input.setByteStream(inputStream);
+
+ if (encoding != null) {
+ input.setEncoding(encoding);
+ }
+
+ LSParser parser = domImplLS.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
+ DOMConfiguration domConfig = parser.getDomConfig();
+ SimpleDOMErrorHandler errorHandler = new SimpleDOMErrorHandler();
+ domConfig.setParameter("error-handler", errorHandler);
+ domConfig.setParameter("validate", Boolean.FALSE);
+
+ Document doc;
+ try {
+ doc = parser.parse(input);
+ } catch (DOMException e) {
+ log.info("Existing XML document cannot be parsed.", e);
+ throw new SLCommandException(4111);
+ } catch (LSException e) {
+ log.info("Existing XML document cannot be parsed. ", e);
+ throw new SLCommandException(4111);
+ }
+
+ if (errorHandler.hasErrors()) {
+ // log errors
+ if (log.isInfoEnabled()) {
+ List<String> errorMessages = errorHandler.getErrorMessages();
+ StringBuffer sb = new StringBuffer();
+ for (String errorMessage : errorMessages) {
+ sb.append(" ");
+ sb.append(errorMessage);
+ }
+ log.info("Existing XML document cannot be parsed. " + sb.toString());
+ }
+ throw new SLCommandException(4111);
+ }
+
+ return doc;
+
+ }
+
+
+}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
index 8baa0137..9182e824 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
@@ -87,6 +87,8 @@ import at.gv.egiz.bku.utils.urldereferencer.StreamData;
import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
import at.gv.egiz.dom.DOMUtils;
+import at.gv.egiz.marshal.NamespacePrefix;
+import at.gv.egiz.marshal.NamespacePrefixMapperImpl;
import at.gv.egiz.slbinding.impl.XMLContentType;
import at.gv.egiz.stal.STAL;
import at.gv.egiz.xades.QualifyingPropertiesException;
@@ -99,6 +101,7 @@ import at.gv.egiz.xades.QualifyingPropertiesFactory;
* @author mcentner
*/
public class Signature {
+ public static final String XMLDSIG_PREFIX = "dsig";
/**
* Logging facility.
@@ -407,7 +410,7 @@ public class Signature {
signContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
- signContext.putNamespacePrefix(XMLSignature.XMLNS, "dsig");
+ signContext.putNamespacePrefix(XMLSignature.XMLNS,XMLDSIG_PREFIX);
signContext.setURIDereferencer(new URIDereferncerAdapter(ctx.getDereferencerContext()));
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 78172dcb..7ce7b42d 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
@@ -14,185 +14,186 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-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.xml.crypto.XSecProvider;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.List;
-
+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.xml.crypto.XSecProvider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.crypto.MarshalException;
-import javax.xml.crypto.dsig.CanonicalizationMethod;
-import javax.xml.crypto.dsig.DigestMethod;
-import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.SignatureMethod;
-import javax.xml.crypto.dsig.Transform;
-import javax.xml.crypto.dsig.XMLObject;
-import javax.xml.crypto.dsig.XMLSignatureException;
-import javax.xml.crypto.dsig.XMLSignatureFactory;
-import javax.xml.crypto.dsig.dom.DOMSignContext;
-import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
-import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
-import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
-import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSOutput;
-import org.w3c.dom.ls.LSSerializer;
-
-import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureRequestType;
-import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
-import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
-import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
-import at.gv.egiz.bku.slexceptions.SLCommandException;
-import at.gv.egiz.bku.slexceptions.SLRequestException;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+
+import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureRequestType;
+import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType;
+import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory;
+import at.buergerkarte.namespaces.securitylayer._1.SignatureInfoCreationType;
+import at.gv.egiz.bku.slexceptions.SLCommandException;
+import at.gv.egiz.bku.slexceptions.SLRequestException;
import at.gv.egiz.bku.slexceptions.SLViewerException;
-import at.gv.egiz.bku.utils.urldereferencer.StreamData;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
-import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
-import at.gv.egiz.bku.utils.urldereferencer.URLProtocolHandler;
-import at.gv.egiz.dom.DOMUtils;
-import at.gv.egiz.slbinding.RedirectEventFilter;
-import at.gv.egiz.slbinding.RedirectUnmarshallerListener;
-
-public class SignatureTest {
-
- private class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
-
- @Override
- public CanonicalizationMethod createCanonicalizationMethod(
- SignatureContext signatureContext) {
-
- XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
-
- try {
- return signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public DigestMethod createDigestMethod(SignatureContext signatureContext) {
-
- XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
-
- try {
- return signatureFactory.newDigestMethod(DigestMethod.SHA1, (DigestMethodParameterSpec) null);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public SignatureMethod createSignatureMethod(
- SignatureContext signatureContext) {
-
- XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
-
- try {
- return signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, (SignatureMethodParameterSpec) null);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- }
-
- }
-
- private static final String RESOURCE_PREFIX = "at/gv/egiz/bku/slcommands/impl/";
-
- private static Unmarshaller unmarshaller;
-
- private static PrivateKey privateKey;
-
- private static X509Certificate certificate;
-
- @BeforeClass
- public static void setUpClass() throws JAXBException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
-
- XSecProvider.addAsProvider(true);
-
- String packageName = ObjectFactory.class.getPackage().getName();
- packageName += ":"
- + org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
- JAXBContext jaxbContext = JAXBContext.newInstance(packageName);
-
- unmarshaller = jaxbContext.createUnmarshaller();
-
- initURLDereferencer();
-
- ClassLoader classLoader = SignatureTest.class.getClassLoader();
- InputStream certStream = classLoader.getResourceAsStream(RESOURCE_PREFIX + "Cert.p12");
- assertNotNull("Certificate not found.", certStream);
-
- char[] passwd = "1622".toCharArray();
-
- KeyStore keystore = KeyStore.getInstance("PKCS12");
- keystore.load(certStream, passwd);
- String firstAlias = keystore.aliases().nextElement();
- certificate = (X509Certificate) keystore.getCertificate(firstAlias);
- privateKey = (PrivateKey) keystore.getKey(firstAlias, passwd);
-
- }
-
- private static void initURLDereferencer() {
-
- URLDereferencer.getInstance().registerHandler("testlocal", new URLProtocolHandler() {
-
- @Override
- public StreamData dereference(String url, URLDereferencerContext context)
- throws IOException {
-
- ClassLoader classLoader = SignatureTest.class.getClassLoader();
-
- String filename = url.split(":", 2)[1];
-
- InputStream stream = classLoader.getResourceAsStream(RESOURCE_PREFIX + filename);
-
- if (stream == null) {
-
- throw new IOException("Failed to resolve resource '" + url + "'.");
-
- } else {
-
- String contentType;
- if (filename.endsWith(".xml")) {
- contentType = "text/xml";
- } else if (filename.endsWith(".txt")) {
- contentType = "text/plain";
- } else {
- contentType = "";
- }
-
- return new StreamData(url, contentType, stream);
-
- }
-
+import at.gv.egiz.bku.utils.urldereferencer.StreamData;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer;
+import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext;
+import at.gv.egiz.bku.utils.urldereferencer.URLProtocolHandler;
+import at.gv.egiz.dom.DOMUtils;
+import at.gv.egiz.slbinding.RedirectEventFilter;
+import at.gv.egiz.slbinding.RedirectUnmarshallerListener;
+import org.junit.Ignore;
+
+public class SignatureTest {
+
+ private class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
+
+ @Override
+ public CanonicalizationMethod createCanonicalizationMethod(
+ SignatureContext signatureContext) {
+
+ XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
+
+ try {
+ return signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public DigestMethod createDigestMethod(SignatureContext signatureContext) {
+
+ XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
+
+ try {
+ return signatureFactory.newDigestMethod(DigestMethod.SHA1, (DigestMethodParameterSpec) null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public SignatureMethod createSignatureMethod(
+ SignatureContext signatureContext) {
+
+ XMLSignatureFactory signatureFactory = signatureContext.getSignatureFactory();
+
+ try {
+ return signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, (SignatureMethodParameterSpec) null);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ }
+
+ private static final String RESOURCE_PREFIX = "at/gv/egiz/bku/slcommands/impl/";
+
+ private static Unmarshaller unmarshaller;
+
+ private static PrivateKey privateKey;
+
+ private static X509Certificate certificate;
+
+ @BeforeClass
+ public static void setUpClass() throws JAXBException, NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
+
+ XSecProvider.addAsProvider(true);
+
+ String packageName = ObjectFactory.class.getPackage().getName();
+ packageName += ":"
+ + org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName();
+ JAXBContext jaxbContext = JAXBContext.newInstance(packageName);
+
+ unmarshaller = jaxbContext.createUnmarshaller();
+
+ initURLDereferencer();
+
+ ClassLoader classLoader = SignatureTest.class.getClassLoader();
+ InputStream certStream = classLoader.getResourceAsStream(RESOURCE_PREFIX + "Cert.p12");
+ assertNotNull("Certificate not found.", certStream);
+
+ char[] passwd = "1622".toCharArray();
+
+ KeyStore keystore = KeyStore.getInstance("PKCS12");
+ keystore.load(certStream, passwd);
+ String firstAlias = keystore.aliases().nextElement();
+ certificate = (X509Certificate) keystore.getCertificate(firstAlias);
+ privateKey = (PrivateKey) keystore.getKey(firstAlias, passwd);
+
+ }
+
+ private static void initURLDereferencer() {
+
+ URLDereferencer.getInstance().registerHandler("testlocal", new URLProtocolHandler() {
+
+ @Override
+ public StreamData dereference(String url, URLDereferencerContext context)
+ throws IOException {
+
+ ClassLoader classLoader = SignatureTest.class.getClassLoader();
+
+ String filename = url.split(":", 2)[1];
+
+ InputStream stream = classLoader.getResourceAsStream(RESOURCE_PREFIX + filename);
+
+ if (stream == null) {
+
+ throw new IOException("Failed to resolve resource '" + url + "'.");
+
+ } else {
+
+ String contentType;
+ if (filename.endsWith(".xml")) {
+ contentType = "text/xml";
+ } else if (filename.endsWith(".txt")) {
+ contentType = "text/plain";
+ } else {
+ contentType = "";
+ }
+
+ return new StreamData(url, contentType, stream);
+
+ }
+
}
@Override
@@ -205,558 +206,600 @@ public class SignatureTest {
public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
// TODO Auto-generated method stub
- }
-
- });
-
- }
-
- private Object unmarshal(String file) throws XMLStreamException, JAXBException {
-
- ClassLoader classLoader = SignatureTest.class.getClassLoader();
- InputStream resourceStream = classLoader.getResourceAsStream(RESOURCE_PREFIX + file);
- assertNotNull(resourceStream);
-
- XMLInputFactory inputFactory = XMLInputFactory.newInstance();
- XMLEventReader eventReader = inputFactory.createXMLEventReader(resourceStream);
- RedirectEventFilter redirectEventFilter = new RedirectEventFilter();
- XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter);
-
- unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter));
-
- return unmarshaller.unmarshal(filteredReader);
-
- }
-
- //
- //
- // SignatureInfo
- //
- //
-
- @SuppressWarnings("unchecked")
- private SignatureInfoCreationType unmarshalSignatureInfo(String file) throws JAXBException, XMLStreamException {
-
- Object object = unmarshal(file);
-
- Object requestType = ((JAXBElement) object).getValue();
-
- assertTrue(requestType instanceof CreateXMLSignatureRequestType);
-
- SignatureInfoCreationType signatureInfo = ((CreateXMLSignatureRequestType) requestType).getSignatureInfo();
-
- assertNotNull(signatureInfo);
-
- return signatureInfo;
-
- }
-
- @Test
- public void testSetSignatureInfo_Base64_1() throws JAXBException, SLCommandException, XMLStreamException {
-
- SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
-
- signature.setSignatureInfo(signatureInfo);
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- assertNotNull(parent);
- assertTrue("urn:document".equals(parent.getNamespaceURI()));
- assertTrue("XMLDocument".equals(parent.getLocalName()));
-
- assertNotNull(nextSibling);
- assertTrue("urn:document".equals(nextSibling.getNamespaceURI()));
- assertTrue("Paragraph".equals(nextSibling.getLocalName()));
-
- }
-
- @Test
- public void testSetSignature_Base64_2() throws JAXBException, SLCommandException, XMLStreamException {
-
- SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_2.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
-
- signature.setSignatureInfo(signatureInfo);
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- assertNotNull(parent);
- assertTrue("XMLDocument".equals(parent.getLocalName()));
-
- assertNotNull(nextSibling);
- assertTrue("Paragraph".equals(nextSibling.getLocalName()));
-
- }
-
- @Test
- public void testSetSignature_Base64_3() throws JAXBException, SLCommandException, XMLStreamException {
-
- SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_3.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
-
- signature.setSignatureInfo(signatureInfo);
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- assertNotNull(parent);
- assertTrue("XMLDocument".equals(parent.getLocalName()));
-
- assertNotNull(nextSibling);
- assertTrue("Paragraph".equals(nextSibling.getLocalName()));
-
- }
-
- @Test
- public void testSetSignatureInfo_XMLContent_1() throws JAXBException, SLCommandException, XMLStreamException {
-
- SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_XMLContent_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
-
- signature.setSignatureInfo(signatureInfo);
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- assertNotNull(parent);
- assertTrue("urn:document".equals(parent.getNamespaceURI()));
- assertTrue("Whole".equals(parent.getLocalName()));
-
- assertNull(nextSibling);
-
- }
-
- @Test
- public void testSetSignature_Reference_1() throws JAXBException, SLCommandException, XMLStreamException {
-
- SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Reference_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
-
- signature.setSignatureInfo(signatureInfo);
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- assertNotNull(parent);
- assertTrue("urn:document".equals(parent.getNamespaceURI()));
- assertTrue("Paragraph".equals(parent.getLocalName()));
-
- assertNull(nextSibling);
-
- }
-
- //
- //
- // DataObject
- //
- //
-
- @SuppressWarnings("unchecked")
- private List<DataObjectInfoType> unmarshalDataObjectInfo(String file) throws JAXBException, XMLStreamException {
-
- Object object = unmarshal(file);
-
- Object requestType = ((JAXBElement) object).getValue();
-
- assertTrue(requestType instanceof CreateXMLSignatureRequestType);
-
- List<DataObjectInfoType> dataObjectInfos = ((CreateXMLSignatureRequestType) requestType).getDataObjectInfo();
-
- assertNotNull(dataObjectInfos);
-
- return dataObjectInfos;
-
- }
-
- private void signAndMarshalSignature(Signature signature) throws MarshalException, XMLSignatureException, SLCommandException, SLViewerException {
-
- Node parent = signature.getParent();
- Node nextSibling = signature.getNextSibling();
-
- DOMSignContext signContext = (nextSibling == null)
- ? new DOMSignContext(privateKey, parent)
- : new DOMSignContext(privateKey, parent, nextSibling);
-
- signature.sign(signContext);
-
- Document document = signature.getDocument();
-
- DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
- LSOutput output = domImplLS.createLSOutput();
- output.setByteStream(System.out);
-
- LSSerializer serializer = domImplLS.createLSSerializer();
-// serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
- serializer.getDomConfig().setParameter("namespaces", Boolean.FALSE);
- serializer.write(document, output);
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_Base64Content_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Base64Content_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.setSignerCeritifcate(certificate);
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 1);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_XMLContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.setSignerCeritifcate(certificate);
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 2);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_XMLContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_2.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.setSignerCeritifcate(certificate);
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 2);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_LocRefContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 2);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_LocRefContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_2.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 1);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_Reference_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Reference_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 1);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
-
- XMLObject object = objects.get(0);
-
- assertTrue(("#" + object.getId()).equals(reference.getURI()));
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_Detached_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 0);
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue(objects.size() == 1);
-
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testDataObject_Detached_Base64Content() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_Base64Content.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue(transforms.size() == 0);
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue(objects.size() == 1);
-
- }
-
- //
- //
- // TransformsInfo
- //
- //
-
- @SuppressWarnings("unchecked")
- private CreateXMLSignatureRequestType unmarshalCreateXMLSignatureRequest(String file) throws JAXBException, XMLStreamException {
-
- Object object = unmarshal(file);
-
- Object requestType = ((JAXBElement) object).getValue();
-
- assertTrue(requestType instanceof CreateXMLSignatureRequestType);
-
- return (CreateXMLSignatureRequestType) requestType;
-
- }
-
-
- @SuppressWarnings("unchecked")
- @Test
- public void testTransformsInfo_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
-
- CreateXMLSignatureRequestType requestType = unmarshalCreateXMLSignatureRequest("TransformsInfo_1.xml");
-
- Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
-
-
- signature.setSignatureInfo(requestType.getSignatureInfo());
-
- List<DataObjectInfoType> dataObjectInfos = requestType.getDataObjectInfo();
-
- for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
- signature.addDataObject(dataObjectInfo);
- }
-
- signature.setSignerCeritifcate(certificate);
-
- signature.buildXMLSignature();
-
- signAndMarshalSignature(signature);
-
- List<Reference> references = signature.getReferences();
- assertTrue(references.size() == 2);
-
- Reference reference = references.get(0);
- assertNotNull(reference.getId());
-
- List<Transform> transforms = reference.getTransforms();
- assertTrue("Size " + transforms.size() + "", transforms.size() == 3);
-
- Transform transform = transforms.get(0);
- assertTrue(Transform.ENVELOPED.equals(transform.getAlgorithm()));
-
- List<XMLObject> objects = signature.getXMLObjects();
- assertNotNull(objects);
- assertTrue("Size " + objects.size() + " but should be 1.", objects.size() == 1);
-
- }
-
-
-}
+ }
+
+ });
+
+ }
+
+ private Object unmarshal(String file) throws XMLStreamException, JAXBException {
+
+ ClassLoader classLoader = SignatureTest.class.getClassLoader();
+ InputStream resourceStream = classLoader.getResourceAsStream(RESOURCE_PREFIX + file);
+ assertNotNull(resourceStream);
+
+ XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ XMLEventReader eventReader = inputFactory.createXMLEventReader(resourceStream);
+ RedirectEventFilter redirectEventFilter = new RedirectEventFilter();
+ XMLEventReader filteredReader = inputFactory.createFilteredReader(eventReader, redirectEventFilter);
+
+ unmarshaller.setListener(new RedirectUnmarshallerListener(redirectEventFilter));
+
+ return unmarshaller.unmarshal(filteredReader);
+
+ }
+
+ //
+ //
+ // SignatureInfo
+ //
+ //
+
+ @SuppressWarnings("unchecked")
+ private SignatureInfoCreationType unmarshalSignatureInfo(String file) throws JAXBException, XMLStreamException {
+
+ Object object = unmarshal(file);
+
+ Object requestType = ((JAXBElement) object).getValue();
+
+ assertTrue(requestType instanceof CreateXMLSignatureRequestType);
+
+ SignatureInfoCreationType signatureInfo = ((CreateXMLSignatureRequestType) requestType).getSignatureInfo();
+
+ assertNotNull(signatureInfo);
+
+ return signatureInfo;
+
+ }
+
+ @Test
+ public void testSetSignatureInfo_Base64_1() throws JAXBException, SLCommandException, XMLStreamException {
+
+ SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
+
+ signature.setSignatureInfo(signatureInfo);
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ assertNotNull(parent);
+ assertTrue("urn:document".equals(parent.getNamespaceURI()));
+ assertTrue("XMLDocument".equals(parent.getLocalName()));
+
+ assertNotNull(nextSibling);
+ assertTrue("urn:document".equals(nextSibling.getNamespaceURI()));
+ assertTrue("Paragraph".equals(nextSibling.getLocalName()));
+
+ }
+
+ @Test
+ public void testSetSignature_Base64_2() throws JAXBException, SLCommandException, XMLStreamException {
+
+ SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_2.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
+
+ signature.setSignatureInfo(signatureInfo);
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ assertNotNull(parent);
+ assertTrue("XMLDocument".equals(parent.getLocalName()));
+
+ assertNotNull(nextSibling);
+ assertTrue("Paragraph".equals(nextSibling.getLocalName()));
+
+ }
+
+ @Test
+ public void testSetSignature_Base64_3() throws JAXBException, SLCommandException, XMLStreamException {
+
+ SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Base64_3.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
+
+ signature.setSignatureInfo(signatureInfo);
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ assertNotNull(parent);
+ assertTrue("XMLDocument".equals(parent.getLocalName()));
+
+ assertNotNull(nextSibling);
+ assertTrue("Paragraph".equals(nextSibling.getLocalName()));
+
+ }
+
+ @Test
+ public void testSetSignatureInfo_XMLContent_1() throws JAXBException, SLCommandException, XMLStreamException {
+
+ SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_XMLContent_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
+
+ signature.setSignatureInfo(signatureInfo);
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ assertNotNull(parent);
+ assertTrue("urn:document".equals(parent.getNamespaceURI()));
+ assertTrue("Whole".equals(parent.getLocalName()));
+
+ assertNull(nextSibling);
+
+ }
+
+ @Test
+ public void testSetSignature_Reference_1() throws JAXBException, SLCommandException, XMLStreamException {
+
+ SignatureInfoCreationType signatureInfo = unmarshalSignatureInfo("SignatureInfo_Reference_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), null);
+
+ signature.setSignatureInfo(signatureInfo);
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ assertNotNull(parent);
+ assertTrue("urn:document".equals(parent.getNamespaceURI()));
+ assertTrue("Paragraph".equals(parent.getLocalName()));
+
+ assertNull(nextSibling);
+
+ }
+
+ //
+ //
+ // DataObject
+ //
+ //
+
+ @SuppressWarnings("unchecked")
+ private List<DataObjectInfoType> unmarshalDataObjectInfo(String file) throws JAXBException, XMLStreamException {
+
+ Object object = unmarshal(file);
+
+ Object requestType = ((JAXBElement) object).getValue();
+
+ assertTrue(requestType instanceof CreateXMLSignatureRequestType);
+
+ List<DataObjectInfoType> dataObjectInfos = ((CreateXMLSignatureRequestType) requestType).getDataObjectInfo();
+
+ assertNotNull(dataObjectInfos);
+
+ return dataObjectInfos;
+
+ }
+
+ private void signAndMarshalSignature(Signature signature) throws MarshalException, XMLSignatureException, SLCommandException, SLViewerException {
+
+ Node parent = signature.getParent();
+ Node nextSibling = signature.getNextSibling();
+
+ DOMSignContext signContext = (nextSibling == null)
+ ? new DOMSignContext(privateKey, parent)
+ : new DOMSignContext(privateKey, parent, nextSibling);
+
+ signature.sign(signContext);
+
+ Document document = signature.getDocument();
+
+ DOMImplementationLS domImplLS = DOMUtils.getDOMImplementationLS();
+ LSOutput output = domImplLS.createLSOutput();
+ output.setByteStream(System.out);
+
+ LSSerializer serializer = domImplLS.createLSSerializer();
+// serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
+ serializer.getDomConfig().setParameter("namespaces", Boolean.FALSE);
+ serializer.write(document, output);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_Base64Content_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Base64Content_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.setSignerCeritifcate(certificate);
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 1);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_XMLContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.setSignerCeritifcate(certificate);
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 2);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_XMLContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_2.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.setSignerCeritifcate(certificate);
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 2);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_LocRefContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 2);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.XPATH2.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_LocRefContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_2.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 1);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_Reference_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Reference_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 1);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.BASE64.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 2.", objects.size() == 2);
+
+ XMLObject object = objects.get(0);
+
+ assertTrue(("#" + object.getId()).equals(reference.getURI()));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_Detached_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 0);
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue(objects.size() == 1);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testDataObject_Detached_Base64Content() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ List<DataObjectInfoType> dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_Base64Content.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue(transforms.size() == 0);
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue(objects.size() == 1);
+
+ }
+
+ //
+ //
+ // TransformsInfo
+ //
+ //
+
+ @SuppressWarnings("unchecked")
+ private CreateXMLSignatureRequestType unmarshalCreateXMLSignatureRequest(String file) throws JAXBException, XMLStreamException {
+
+ Object object = unmarshal(file);
+
+ Object requestType = ((JAXBElement) object).getValue();
+
+ assertTrue(requestType instanceof CreateXMLSignatureRequestType);
+
+ return (CreateXMLSignatureRequestType) requestType;
+
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testTransformsInfo_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ CreateXMLSignatureRequestType requestType = unmarshalCreateXMLSignatureRequest("TransformsInfo_1.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+
+ signature.setSignatureInfo(requestType.getSignatureInfo());
+
+ List<DataObjectInfoType> dataObjectInfos = requestType.getDataObjectInfo();
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.setSignerCeritifcate(certificate);
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue("Size " + transforms.size() + "", transforms.size() == 3);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.ENVELOPED.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 1.", objects.size() == 1);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ @Ignore
+ public void testTransformsInfo_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException {
+
+ CreateXMLSignatureRequestType requestType = unmarshalCreateXMLSignatureRequest("TransformsInfo_2.xml");
+
+ Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl());
+
+
+ signature.setSignatureInfo(requestType.getSignatureInfo());
+
+ List<DataObjectInfoType> dataObjectInfos = requestType.getDataObjectInfo();
+
+ for (DataObjectInfoType dataObjectInfo : dataObjectInfos) {
+ signature.addDataObject(dataObjectInfo);
+ }
+
+ signature.setSignerCeritifcate(certificate);
+
+ signature.buildXMLSignature();
+
+ signAndMarshalSignature(signature);
+
+ List<Reference> references = signature.getReferences();
+ assertTrue(references.size() == 2);
+
+ Reference reference = references.get(0);
+ assertNotNull(reference.getId());
+
+ List<Transform> transforms = reference.getTransforms();
+ assertTrue("Size " + transforms.size() + "", transforms.size() == 2);
+
+ Transform transform = transforms.get(0);
+ assertTrue(Transform.XSLT.equals(transform.getAlgorithm()));
+
+ List<XMLObject> objects = signature.getXMLObjects();
+ assertNotNull(objects);
+ assertTrue("Size " + objects.size() + " but should be 1.", objects.size() == 1);
+
+ }
+
+
+}
diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/TransformsInfo_2.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/TransformsInfo_2.xml
new file mode 100644
index 00000000..f43dc61a
--- /dev/null
+++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/TransformsInfo_2.xml
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<sl:CreateXMLSignatureRequest xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
+ xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
+ <sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
+ <sl:DataObjectInfo Structure="detached">
+ <sl:DataObject Reference=""/>
+ <sl:TransformsInfo>
+ <dsig:Transforms xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+ xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#">
+ <xsl:template match="/" xmlns="http://www.w3.org/1999/xhtml">
+ <html>
+ <head>
+ <title>Signatur der Anmeldedaten</title>
+ <style type="text/css" media="screen">
+ .boldstyle { font-weight: bold; }
+ .italicstyle { font-style: italic; }
+ .annotationstyle { font-size: 0.8em; }
+ </style>
+ </head>
+ <body>
+ <h1>Signatur der Anmeldedaten</h1>
+ <p/>
+ <h4>Mit meiner elektronischen Signatur beantrage ich, <span
+ class="boldstyle">
+ <xsl:value-of select="//@Issuer"/>
+ </span>, geboren am <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,9,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,6,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,1,4)"
+ />, <xsl:if
+ test="//saml:Attribute[@AttributeName='OIDTextualDescription']"
+ > in der Rolle als <xsl:value-of
+ select="//saml:Attribute[@AttributeName='OIDTextualDescription']/saml:AttributeValue"
+ /> (OID***= <xsl:value-of
+ select="//saml:Attribute[@AttributeName='OID']/saml:AttributeValue"
+ />), </xsl:if> den Zugang zur gesicherten Anwendung. </h4>
+ <p/>
+ <h4>Datum und Uhrzeit: <xsl:value-of
+ select="substring(//@IssueInstant,9,2)"/>. <xsl:value-of
+ select="substring(//@IssueInstant,6,2)"/>. <xsl:value-of
+ select="substring(//@IssueInstant,1,4)"/>, <xsl:value-of
+ select="substring(//@IssueInstant,12,2)"/>:
+ <xsl:value-of select="substring(//@IssueInstant,15,2)"
+ />: <xsl:value-of select="substring(//@IssueInstant,18,2)"/>
+ </h4>
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <h4>HPI(**): <xsl:value-of
+ select="//saml:Attribute[@AttributeName='HPI']/saml:AttributeValue"
+ /></h4>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <h4>wbPK(*): <xsl:value-of
+ select="//saml:Attribute[@AttributeName='wbPK']/saml:AttributeValue/pr:Identification/pr:Value"
+ /></h4>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorName']">
+ <hr/>
+ <h4>Ich bin weiters ermächtigt als <xsl:value-of
+ select="//saml:Attribute[@AttributeName='RepresentationType']/saml:AttributeValue/text()"
+ /> von <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorName']/saml:AttributeValue/text()"/>
+ <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorDateOfBirth']"
+ >, geboren am <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,9,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,6,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,1,4)"
+ />
+ </xsl:if>
+ <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']"
+ >, <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']/saml:AttributeValue/text()"
+ />
+ </xsl:if>, in deren Auftrag zu handeln. <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorWbpk']">
+ <h4>wbPK(*) des Vollmachtgebers: <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorWbpk']/saml:AttributeValue/text()"
+ /></h4>
+ </xsl:if>
+ </h4>
+ <p/>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="//saml:Attribute[@AttributeName='OID']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ <xsl:when test="//saml:Attribute[@AttributeName='HPI']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ <xsl:when test="//saml:Attribute[@AttributeName='wbPK']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <div class="annotationstyle">(*) wbPK: Das <span
+ class="italicstyle">wirtschaftsbereichsspezifische
+ Personenkennzeichen</span> wird aus den jeweiligen
+ Stammzahlen des Bürgers und des Wirtschaftsunternehmens
+ berechnet und ermöglicht eine eindeutige Zuordnung des
+ Bürgers zum Wirtschaftsunternehmen.</div>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <div class="annotationstyle">(**) HPI: Der <span
+ class="italicstyle">eHealth Professional
+ Identifier</span> wird aus den jeweiligen Stammzahlen
+ der Gesundheitsdiensteanbieterinnen /
+ Gesundheitsdiensteanbieter berechnet und ermöglicht eine
+ eindeutige Zuordnung der Gesundheitsdiensteanbieterin /
+ des Gesundheitsdiensteanbieters im
+ Gesundheitsbereich.</div>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='OID']">
+ <div class="annotationstyle">(***) OID: <span
+ class="italicstyle">Object Identifier</span> sind
+ standardisierte Objekt-Bezeichner und beschreiben
+ eindeutig die Rollen des GDA-Token Inhabers.</div>
+ </xsl:if>
+ </body>
+ </html>
+ </xsl:template>
+ </xsl:stylesheet>
+ </dsig:Transform>
+ <dsig:Transform
+ Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
+ </dsig:Transforms>
+ <sl:FinalDataMetaInfo>
+ <sl:MimeType>application/xhtml+xml</sl:MimeType>
+ </sl:FinalDataMetaInfo>
+ </sl:TransformsInfo>
+ <sl:TransformsInfo>
+ <dsig:Transforms xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
+ <dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+ <dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+ xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#">
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
+ <xsl:template match="/" xmlns="http://www.w3.org/1999/xhtml">
+ <html>
+ <head>
+ <title>Signatur der Anmeldedaten</title>
+ </head>
+ <body>
+ <h1>Signatur der Anmeldedaten</h1>
+ <p/>
+ <h4>Mit meiner elektronischen Signatur beantrage ich, <b>
+ <xsl:value-of select="//@Issuer"/>
+ </b>, geboren am <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,9,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,6,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,1,4)"
+ />, <xsl:if
+ test="//saml:Attribute[@AttributeName='OIDTextualDescription']"
+ > in der Rolle als <xsl:value-of
+ select="//saml:Attribute[@AttributeName='OIDTextualDescription']/saml:AttributeValue"
+ /> (OID***= <xsl:value-of
+ select="//saml:Attribute[@AttributeName='OID']/saml:AttributeValue"
+ />), </xsl:if> den Zugang zur gesicherten Anwendung. </h4>
+ <p/>
+ <h4>Datum und Uhrzeit: <xsl:value-of
+ select="substring(//@IssueInstant,9,2)"/>. <xsl:value-of
+ select="substring(//@IssueInstant,6,2)"/>. <xsl:value-of
+ select="substring(//@IssueInstant,1,4)"/>, <xsl:value-of
+ select="substring(//@IssueInstant,12,2)"/>:
+ <xsl:value-of select="substring(//@IssueInstant,15,2)"
+ />: <xsl:value-of select="substring(//@IssueInstant,18,2)"/>
+ </h4>
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <h4>HPI(**): <xsl:value-of
+ select="//saml:Attribute[@AttributeName='HPI']/saml:AttributeValue"
+ /></h4>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <h4>wbPK(*): <xsl:value-of
+ select="//saml:Attribute[@AttributeName='wbPK']/saml:AttributeValue/pr:Identification/pr:Value"
+ /></h4>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorName']">
+ <hr/>
+ <h4>Ich bin weiters ermächtigt als <xsl:value-of
+ select="//saml:Attribute[@AttributeName='RepresentationType']/saml:AttributeValue/text()"
+ /> von <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorName']/saml:AttributeValue/text()"/>
+ <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorDateOfBirth']"
+ >, geboren am <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,9,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,6,2)"
+ />. <xsl:value-of
+ select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,1,4)"
+ />
+ </xsl:if>
+ <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']"
+ >, <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']/saml:AttributeValue/text()"
+ />
+ </xsl:if>, in deren Auftrag zu handeln. <xsl:if
+ test="//saml:Attribute[@AttributeName='MandatorWbpk']">
+ <h4>wbPK(*) des Vollmachtgebers: <xsl:value-of
+ select="//saml:Attribute[@AttributeName='MandatorWbpk']/saml:AttributeValue/text()"
+ /></h4>
+ </xsl:if>
+ </h4>
+ <p/>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="//saml:Attribute[@AttributeName='OID']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ <xsl:when test="//saml:Attribute[@AttributeName='HPI']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ <xsl:when test="//saml:Attribute[@AttributeName='wbPK']">
+ <p/>
+ <hr/>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <h6>(*) wbPK: Das <i>wirtschaftsbereichsspezifische
+ Personenkennzeichen</i> wird aus den jeweiligen
+ Stammzahlen des Bürgers und des Wirtschaftsunternehmens
+ berechnet und ermöglicht eine eindeutige Zuordnung des
+ Bürgers zum Wirtschaftsunternehmen.</h6>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <h6>(**) HPI: Der <i>eHealth Professional Identifier</i>
+ wird aus den jeweiligen Stammzahlen der
+ Gesundheitsdiensteanbieterinnen /
+ Gesundheitsdiensteanbieter berechnet und ermöglicht eine
+ eindeutige Zuordnung der Gesundheitsdiensteanbieterin /
+ des Gesundheitsdiensteanbieters im
+ Gesundheitsbereich.</h6>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='OID']">
+ <h6>(***) OID: <i>Object Identifier</i> sind standardisierte
+ Objekt-Bezeichner und beschreiben eindeutig die Rollen
+ des GDA-Token Inhabers.</h6>
+ </xsl:if>
+ </body>
+ </html>
+ </xsl:template>
+ </xsl:stylesheet>
+ </dsig:Transform>
+ <dsig:Transform
+ Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
+ </dsig:Transforms>
+ <sl:FinalDataMetaInfo>
+ <sl:MimeType>text/html</sl:MimeType>
+ </sl:FinalDataMetaInfo>
+ </sl:TransformsInfo>
+ <sl:TransformsInfo>
+ <dsig:Transforms> <!-- xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"-->
+ <dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#" exclude-result-prefixes="pr saml">
+ <xsl:output method="xml" xml:space="default"/>
+ <xsl:template match="/" xmlns="">
+ <text>
+ <xsl:text>Mit meiner elektronischen Signatur beantrage ich, </xsl:text>
+ <xsl:value-of select="//@Issuer"/>
+ <xsl:text>, geboren am </xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,9,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,6,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='Geburtsdatum']/saml:AttributeValue,1,4)"/>
+ <xsl:text>, </xsl:text>
+ <xsl:if test="//saml:Attribute[@AttributeName='OIDTextualDescription']">
+ <xsl:text>in der Rolle als </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='OIDTextualDescription']/saml:AttributeValue"/>
+ <xsl:text>(OID***= </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='OID']/saml:AttributeValue"/>)
+ <xsl:text>, </xsl:text>
+ </xsl:if>
+ <xsl:text>den Zugang zur gesicherten Anwendung.</xsl:text>
+ <xsl:text>&#xa;&#xa;Datum und Uhrzeit: </xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,9,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,6,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,1,4)"/>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,12,2)"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,15,2)"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="substring(//@IssueInstant,18,2)"/>
+
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <xsl:text>&#xa;&#xa;HPI(**): </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='HPI']/saml:AttributeValue"/>
+ </xsl:if>
+
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <xsl:text>&#xa;&#xa;wbPK(*): </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='wbPK']/saml:AttributeValue/pr:Identification/pr:Value"/>
+ </xsl:if>
+
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorName']">
+ <xsl:text>&#xa;&#xa;Ich bin weiters ermächtigt als </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='RepresentationType']/saml:AttributeValue/text()"/>
+ <xsl:text>von </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='MandatorName']/saml:AttributeValue/text()"/>
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorDateOfBirth']">
+ <xsl:text>, geboren am </xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,9,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,6,2)"/>
+ <xsl:text>.</xsl:text>
+ <xsl:value-of select="substring(//saml:Attribute[@AttributeName='MandatorDateOfBirth']/saml:AttributeValue,1,4)"/>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']">
+ <xsl:text>,</xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='MandatorDomainIdentifier']/saml:AttributeValue/text()"/>
+ </xsl:if>
+ <xsl:text>, in deren Auftrag zu handeln.</xsl:text>
+
+ <xsl:if test="//saml:Attribute[@AttributeName='MandatorWbpk']">
+ <xsl:text>&#xa;&#xa;wbPK(*) des Vollmachtgebers: </xsl:text>
+ <xsl:value-of select="//saml:Attribute[@AttributeName='MandatorWbpk']/saml:AttributeValue/text()"/>
+ </xsl:if>
+ </xsl:if>
+
+ <xsl:if test="//saml:Attribute[@AttributeName='wbPK']">
+ <xsl:text>&#xa;&#xa;(*) wbPK: Das wirtschaftsbereichsspezifische Personenkennzeichen wird aus den jeweiligen Stammzahlen des Bürgers und des Wirtschaftsunternehmens berechnet und ermöglicht eine eindeutige Zuordnung des Bürgers zum Wirtschaftsunternehmen.</xsl:text>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='HPI']">
+ <xsl:text>&#xa;&#xa;(**) HPI: Der eHealth Professional Identifier wird aus den jeweiligen Stammzahlen der Gesundheitsdiensteanbieterinnen / Gesundheitsdiensteanbieter berechnet und ermöglicht eine eindeutige Zuordnung der Gesundheitsdiensteanbieterin / des Gesundheitsdiensteanbieters im Gesundheitsbereich.</xsl:text>
+ </xsl:if>
+ <xsl:if test="//saml:Attribute[@AttributeName='OID']">
+ <xsl:text>&#xa;&#xa;(***) OID: Object Identifier sind standardisierte Objekt-Bezeichner und beschreiben eindeutig die Rollen des GDA-Token Inhabers.</xsl:text>
+ </xsl:if>
+ </text>
+ </xsl:template>
+ </xsl:stylesheet>
+ </dsig:Transform>
+ <dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
+ <dsig:XPath>not(text())</dsig:XPath>
+ </dsig:Transform>
+ </dsig:Transforms>
+ <sl:FinalDataMetaInfo>
+ <sl:MimeType>text/plain</sl:MimeType>
+ </sl:FinalDataMetaInfo>
+ </sl:TransformsInfo>
+ </sl:DataObjectInfo>
+ <sl:SignatureInfo>
+ <sl:SignatureEnvironment>
+ <sl:XMLContent>
+ <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+ xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#"
+ MajorVersion="1" MinorVersion="0" AssertionID="any" Issuer="Klämens Örthäçké"
+ IssueInstant="2008-06-05T11:26:10+02:00">
+ <saml:AttributeStatement>
+ <saml:Subject>
+ <saml:NameIdentifier>https://demo.egiz.gv.at/exchange-moa-id-auth/</saml:NameIdentifier>
+ </saml:Subject>
+ <saml:Attribute AttributeName="wbPK"
+ AttributeNamespace="http://reference.e-government.gv.at/namespace/moa/20020822#">
+ <saml:AttributeValue>
+ <pr:Identification>
+ <pr:Value>LTpz8VYzns2jrx0J8Gm/R/nAhxA=</pr:Value>
+ <pr:Type>urn:publicid:gv.at:wbpk+FN+TODO</pr:Type>
+ </pr:Identification>
+ </saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute AttributeName="OA"
+ AttributeNamespace="http://reference.e-government.gv.at/namespace/moa/20020822#">
+ <saml:AttributeValue>https://apps.egiz.gv.at/urlaubsschein-frontend/moaid-login</saml:AttributeValue>
+ </saml:Attribute>
+ <saml:Attribute AttributeName="Geburtsdatum"
+ AttributeNamespace="http://reference.e-government.gv.at/namespace/moa/20020822#">
+ <saml:AttributeValue>1971-11-10</saml:AttributeValue>
+ </saml:Attribute>
+ </saml:AttributeStatement>
+ </saml:Assertion>
+ </sl:XMLContent>
+ </sl:SignatureEnvironment>
+ <sl:SignatureLocation Index="2" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">/saml:Assertion</sl:SignatureLocation>
+ </sl:SignatureInfo>
+</sl:CreateXMLSignatureRequest>
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
index 13c57686..86223854 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -30,8 +30,6 @@ package at.gv.egiz.smcc;
import java.nio.charset.Charset;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
@@ -41,7 +39,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
-
+
private static Log log = LogFactory.getLog(ACOSCard.class);
public static final byte[] AID_DEC = new byte[] { (byte) 0xA0, (byte) 0x00,
@@ -100,8 +98,15 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
(byte) 0x01 // RSA // TODO: Not verified yet
};
+ private static final int PINSPEC_INF = 0;
+ private static final int PINSPEC_DEC = 1;
+ private static final int PINSPEC_SIG = 2;
+
public ACOSCard() {
super("at/gv/egiz/smcc/ACOSCard");
+ pinSpecs.add(PINSPEC_INF, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name"), KID_PIN_INF, null));
+ pinSpecs.add(PINSPEC_DEC, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name"), KID_PIN_DEC, null));
+ pinSpecs.add(PINSPEC_SIG, new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SIG, null));
}
/* (non-Javadoc)
@@ -165,7 +170,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
try {
if ("IdentityLink".equals(infobox)) {
- PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_INF);
+ //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name"));
int retries = -1;
String pin = null;
@@ -219,7 +225,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) {
- PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_SIG);
+ //new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"));
int retries = -1;
String pin = null;
@@ -260,7 +267,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
} else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) {
- PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_DEC);
+ //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name"));
int retries = -1;
String pin = null;
@@ -322,11 +330,6 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {
}
@Override
- public byte[] getKIDs() {
- return new byte[] { KID_PIN_DEC, KID_PIN_INF, KID_PIN_SIG };
- }
-
- @Override
public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
CardChannel channel = getCardChannel();
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
index 67f090a5..cb068725 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java
@@ -31,7 +31,11 @@ package at.gv.egiz.smcc;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
import javax.smartcardio.ATR;
@@ -49,6 +53,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
private static Log log = LogFactory.getLog(AbstractSignatureCard.class);
+ protected List<PINSpec> pinSpecs = new ArrayList<PINSpec>();
+
private ResourceBundle i18n;
private String resourceBundleName;
@@ -433,4 +439,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {
}
}
+ @Override
+ public List<PINSpec> getPINSpecs() {
+ return pinSpecs;
+ }
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java b/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
index 0852d664..d180ddf0 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/PINSpec.java
@@ -35,23 +35,40 @@ public class PINSpec {
String name_;
+ byte kid_;
+
+ byte[] context_aid_;
+
+ /**
+ *
+ * @param minLenght
+ * @param maxLength
+ * @param rexepPattern
+ * @param resourceBundle
+ * @param name
+ * @param kid the keyId for this pin
+ */
public PINSpec(int minLenght, int maxLength, String rexepPattern,
- ResourceBundle resourceBundle, String name) {
+ ResourceBundle resourceBundle, String name, byte kid, byte[] contextAID) {
minLength_ = minLenght;
maxLength_ = maxLength;
rexepPattern_ = rexepPattern;
resourceBundle_ = resourceBundle;
name_ = name;
+ kid_ = kid;
+ context_aid_ = contextAID;
}
public PINSpec(int minLenght, int maxLength, String rexepPattern,
- String name) {
+ String name, byte kid, byte[] contextAID) {
minLength_ = minLenght;
maxLength_ = maxLength;
rexepPattern_ = rexepPattern;
name_ = name;
+ kid_ = kid;
+ context_aid_ = contextAID;
}
@@ -75,7 +92,14 @@ public class PINSpec {
public String getRexepPattern() {
return rexepPattern_;
}
-
+
+ public byte getKID() {
+ return kid_;
+ }
+
+ public byte[] getContextAID() {
+ return context_aid_;
+ }
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
index e80c6683..ae43629e 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -29,10 +29,8 @@
package at.gv.egiz.smcc;
import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
@@ -42,7 +40,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class STARCOSCard extends AbstractSignatureCard implements SignatureCard {
-
+
/**
* Logging facility.
*/
@@ -155,12 +153,17 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
};
public static final byte KID_PIN_CARD = (byte) 0x01;
-
+
+ private static final int PINSPEC_CARD = 0;
+ private static final int PINSPEC_SS = 1;
+
/**
* Creates an new instance.
*/
public STARCOSCard() {
super("at/gv/egiz/smcc/STARCOSCard");
+ pinSpecs.add(PINSPEC_CARD, new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name"), KID_PIN_CARD, null));
+ pinSpecs.add(PINSPEC_SS, new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"), KID_PIN_SS, AID_DF_SS));
}
@Override
@@ -210,7 +213,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
try {
if ("IdentityLink".equals(infobox)) {
- PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_CARD);
+ //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name"));
int retries = -1;
String pin = null;
@@ -302,7 +306,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) {
- PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_SS);
+ //new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name"));
int retries = -1;
String pin = null;
@@ -334,7 +339,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
} else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) {
- PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name"));
+ PINSpec spec = pinSpecs.get(PINSPEC_CARD);
+ //new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name"));
int retries = -1;
String pin = null;
@@ -455,11 +461,6 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard
}
}
- @Override
- public byte[] getKIDs() {
- return new byte[] { KID_PIN_CARD, KID_PIN_SS };
- }
-
/**
* VERIFY PIN
* <p>
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
index bad7ccf6..8dc4ac2a 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -36,9 +36,13 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
@@ -311,7 +315,7 @@ public class SWCard implements SignatureCard {
if (password == null) {
- PINSpec pinSpec = new PINSpec(0, -1, ".", "KeyStore-Password");
+ PINSpec pinSpec = new PINSpec(0, -1, ".", "KeyStore-Password", (byte) 0x01, null);
password = provider.providePIN(pinSpec, -1);
@@ -390,13 +394,13 @@ public class SWCard implements SignatureCard {
}
@Override
- public byte[] getKIDs() {
- return null;
+ public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
+ return -1;
}
@Override
- public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
- return -1;
+ public List<PINSpec> getPINSpecs() {
+ return new ArrayList<PINSpec>();
}
}
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
index 1ec35b78..1e5e09c8 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -31,6 +31,7 @@ package at.gv.egiz.smcc;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import javax.smartcardio.Card;
import javax.smartcardio.CardTerminal;
@@ -118,10 +119,10 @@ public interface SignatureCard {
PINProvider provider) throws SignatureCardException, InterruptedException;
/**
- * get the KIDs for the availabel PINs
+ * Get the KIDs for all available PINs and the corresponding PINSpecs
* @return array of KIDs
*/
- public byte[] getKIDs();
+ public List<PINSpec> getPINSpecs();
/**
*
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractBKUWorker.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractBKUWorker.java
index e10ba8f9..b6c5a8ca 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractBKUWorker.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractBKUWorker.java
@@ -102,6 +102,9 @@ public abstract class AbstractBKUWorker extends AbstractSMCCSTAL implements Acti
@Override
protected boolean waitForCard() {
+ if (signatureCard != null) {
+ return false;
+ }
SMCCHelper smccHelper = new SMCCHelper();
actionCommandList.clear();
actionCommandList.add("cancel");
diff --git a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
index a5f8a771..a5d6df23 100644
--- a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
+++ b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
@@ -86,15 +86,16 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements
}
- @Override
- public byte[] getKIDs() {
- return null;
- }
@Override
public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException {
return 0;
}
+
+ @Override
+ public List<PINSpec> getPINSpecs() {
+ return new ArrayList<PINSpec>();
+ }
};
return false;
diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusProvider.java b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java
index 73fa0920..c03f17cd 100644
--- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusProvider.java
+++ b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java
@@ -15,18 +15,20 @@
* limitations under the License.
*/
-package at.gv.egiz.bku.gui;
-
-import at.gv.egiz.smcc.SignatureCardException;
+package at.gv.egiz.marshal;
/**
*
* @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>
*/
-public interface PINStatusProvider {
-
- public enum STATUS { ACTIV, NOT_ACTIV, BLOCKED };
-
- public STATUS getPINStatus(int pin) throws SignatureCardException;
+public interface NamespacePrefix {
+ String CARDCHANNEL_PREFIX = "cc";
+ String ECDSA_PREFIX = "ecdsa";
+ String PERSONDATA_PREFIX = "pr";
+ String SAML10_PREFIX = "saml";
+ String SL_PREFIX = "sl";
+ String XADES_PREFIX = "xades";
+ String XMLDSIG_PREFIX = "xmldsig";
+ String XSI_PREFIX = "xsi";
}
diff --git a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java
index a08c1188..519f6b1f 100644
--- a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java
+++ b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java
@@ -36,35 +36,35 @@ public class NamespacePrefixMapperImpl extends NamespacePrefixMapper {
log.trace("prefix for namespace " + namespaceUri + " requested");
}
if ("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceUri)) {
- return "xsi";
+ return NamespacePrefix.XSI_PREFIX;
}
if ("http://www.w3.org/2000/09/xmldsig#".equals(namespaceUri)) {
- return "dsig";
+ return NamespacePrefix.XMLDSIG_PREFIX;
}
if ("http://www.buergerkarte.at/namespaces/securitylayer/1.2#".equals(namespaceUri)) {
- return "sl";
+ return NamespacePrefix.SL_PREFIX;
}
if ("http://www.buergerkarte.at/cardchannel".equals(namespaceUri)) {
- return "cc";
+ return NamespacePrefix.CARDCHANNEL_PREFIX;
}
if ("http://www.w3.org/2001/04/xmldsig-more#".equals(namespaceUri)) {
- return "ecdsa";
+ return NamespacePrefix.ECDSA_PREFIX;
}
if ("http://reference.e-government.gv.at/namespace/persondata/20020228#".equals(namespaceUri)) {
- return "pr";
+ return NamespacePrefix.PERSONDATA_PREFIX;
}
if ("urn:oasis:names:tc:SAML:1.0:assertion".equals(namespaceUri)) {
- return "saml";
+ return NamespacePrefix.SAML10_PREFIX;
}
if ("http://uri.etsi.org/01903/v1.1.1#".equals(namespaceUri)) {
- return "xades";
+ return NamespacePrefix.XADES_PREFIX;
}
return suggestion;
diff --git a/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java
index d2a7fb30..14c5ba48 100644
--- a/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java
+++ b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java
@@ -1,19 +1,19 @@
/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
+ * Copyright 2008 Federal Chancellery Austria and
+ * Graz University of Technology
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
@@ -33,79 +33,84 @@ import javax.xml.stream.events.XMLEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+/*
+ * TODO: don't set redirect stream from caller (caller does not know whether redirection will be triggered)
+ * rather create on trigger and pass to caller
+ */
public class RedirectEventFilter implements EventFilter {
- public static final String DEFAULT_ENCODING = "UTF-8";
- private static Log log = LogFactory.getLog(RedirectEventFilter.class);
- protected XMLEventWriter redirectWriter = null;
- protected Set<QName> redirectTriggers = null;
- private int depth = -1;
- protected NamespaceContext currentNamespaceContext = null;
+ public static final String DEFAULT_ENCODING = "UTF-8";
+ private static Log log = LogFactory.getLog(RedirectEventFilter.class);
+ protected XMLEventWriter redirectWriter = null;
+ protected Set<QName> redirectTriggers = null;
+ private int depth = -1;
+ protected NamespaceContext currentNamespaceContext = null;
- /**
- * Event redirection is disabled, set a redirect stream to enable.
- */
- public RedirectEventFilter() {
- redirectWriter = null;
- // redirectTriggers = null;
- }
+ /**
+ * Event redirection is disabled, set a redirect stream to enable.
+ */
+ public RedirectEventFilter() {
+ redirectWriter = null;
+ // redirectTriggers = null;
+ }
- /**
- *
- * @param redirectStream
- * if null, no events are redirected
- * @param redirectTriggers
- * if null, all events are redirected
- */
- public RedirectEventFilter(OutputStream redirectStream, String encoding)
- throws XMLStreamException { // , List<QName> redirectTriggers
- if (redirectStream != null) {
- XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
- if (encoding == null) {
- encoding = DEFAULT_ENCODING;
- }
- this.redirectWriter = outputFactory.createXMLEventWriter(redirectStream,
+ /**
+ *
+ * @param redirectStream
+ * if null, no events are redirected
+ * @param redirectTriggers
+ * if null, all events are redirected
+ */
+ public RedirectEventFilter(OutputStream redirectStream, String encoding)
+ throws XMLStreamException { // , List<QName> redirectTriggers
+ if (redirectStream != null) {
+ XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+ if (encoding == null) {
+ encoding = DEFAULT_ENCODING;
+ }
+ this.redirectWriter = outputFactory.createXMLEventWriter(redirectStream,
encoding);
- }
- // this.redirectTriggers = redirectTriggers;
}
+ // this.redirectTriggers = redirectTriggers;
+ }
- /**
- * All startElement events occuring in the redirectTriggers list will trigger
- * redirection of the entire (sub-)fragment.
- *
- * @param event
- * @return false if an event is redirected
- */
- @Override
- public boolean accept(XMLEvent event) {
- int eventType = event.getEventType();
+ /**
+ * All startElement events occuring in the redirectTriggers list will trigger
+ * redirection of the entire (sub-)fragment.
+ *
+ * @param event
+ * @return false if an event is redirected
+ */
+ @Override
+ public boolean accept(XMLEvent event) {
+ int eventType = event.getEventType();
- if (eventType == XMLStreamConstants.START_ELEMENT) {
- currentNamespaceContext = event.asStartElement().getNamespaceContext();
- }
- if (redirectWriter == null) {
- return true;
- }
- if (eventType == XMLStreamConstants.START_ELEMENT) {
- if (depth >= 0 || triggersRedirect(event.asStartElement().getName())) {
- depth++;
- }
- } else if (eventType == XMLStreamConstants.END_ELEMENT) {
- if (depth >= 0 && --depth < 0) {
- // redirect the end element of the trigger,
- // but do not redirect the end element of the calling type
- if (redirectTriggers != null) {
- redirectEvent(event);
- return false;
- }
- }
- }
- if (depth >= 0) { //|| (depth == 0 && redirectTriggers == null)) {
- redirectEvent(event);
- return false;
+ if (eventType == XMLStreamConstants.START_ELEMENT) {
+ //hopefully, this is a copy
+ currentNamespaceContext = event.asStartElement().getNamespaceContext();
+ }
+ if (redirectWriter == null) {
+ return true;
+ }
+ if (eventType == XMLStreamConstants.START_ELEMENT) {
+ if (depth >= 0 || triggersRedirect(event.asStartElement().getName())) {
+ depth++;
+ }
+ } else if (eventType == XMLStreamConstants.END_ELEMENT) {
+ if (depth >= 0 && --depth < 0) {
+ // redirect the end element of the trigger,
+ // but do not redirect the end element of the calling type
+ if (redirectTriggers != null) {
+ redirectEvent(event);
+ return false;
}
- return true; // depth < 0;
+ }
+ }
+ if (depth >= 0) { //|| (depth == 0 && redirectTriggers == null)) {
+ redirectEvent(event);
+ return false;
+ }
+ return true; // depth < 0;
// switch (event.getEventType()) {
// case XMLStreamConstants.START_ELEMENT:
@@ -132,128 +137,130 @@ public class RedirectEventFilter implements EventFilter {
// return false;
// }
// return true; // depth < 0;
- }
+ }
- /**
- * @param startElt
- * @return true if the set of triggers contains startElement
- * (or no triggers are registered, i.e. everything is redirected)
- */
- private boolean triggersRedirect(QName startElement) {
- if (redirectTriggers != null) {
- return redirectTriggers.contains(startElement);
- }
- return true;
+ /**
+ * @param startElt
+ * @return true if the set of triggers contains startElement
+ * (or no triggers are registered, i.e. everything is redirected)
+ */
+ private boolean triggersRedirect(QName startElement) {
+ if (redirectTriggers != null) {
+ return redirectTriggers.contains(startElement);
}
+ return true;
+ }
- private void redirectEvent(XMLEvent event) {
- try {
- if (log.isTraceEnabled()) {
- log.trace("redirecting StAX event " + event);
- }
- redirectWriter.add(event);
- } catch (XMLStreamException ex) {
- ex.printStackTrace();
- }
+ private void redirectEvent(XMLEvent event) {
+ try {
+ if (log.isTraceEnabled()) {
+ log.trace("redirecting StAX event " + event);
+ }
+ redirectWriter.add(event);
+ } catch (XMLStreamException ex) {
+ ex.printStackTrace();
}
+ }
- /**
- * Enable/disable redirection of <em>all</em> events from now on.
- * The redirected events will be UTF-8 encoded and written to the stream.
- *
- * @param redirectstream
- * if null, redirection is disabled
- */
- public void setRedirectStream(OutputStream redirectStream) throws XMLStreamException {
- setRedirectStream(redirectStream, DEFAULT_ENCODING, null);
- }
+ /**
+ * Enable/disable redirection of <em>all</em> events from now on.
+ * The redirected events will be UTF-8 encoded and written to the stream.
+ *
+ * @param redirectstream
+ * if null, redirection is disabled
+ */
+ public void setRedirectStream(OutputStream redirectStream) throws XMLStreamException {
+ setRedirectStream(redirectStream, DEFAULT_ENCODING, null);
+ }
- /**
- * Enable/disable redirection of <em>all</em> events from now on.
- *
- * @param redirectStream if null, redirection is disabled
- * @param encoding The encoding for the redirect stream
- * @throws javax.xml.stream.XMLStreamException
- */
- public void setRedirectStream(OutputStream redirectStream, String encoding) throws XMLStreamException {
- setRedirectStream(redirectStream, encoding, null);
- }
+ /**
+ * Enable/disable redirection of <em>all</em> events from now on.
+ *
+ * @param redirectStream if null, redirection is disabled
+ * @param encoding The encoding for the redirect stream
+ * @throws javax.xml.stream.XMLStreamException
+ */
+ public void setRedirectStream(OutputStream redirectStream, String encoding) throws XMLStreamException {
+ setRedirectStream(redirectStream, encoding, null);
+ }
- /**
- * Enable/disable redirection of all (child) elements contained in redirect triggers.
- * The redirected events will be UTF-8 encoded and written to the stream.
- *
- * @param redirectstream
- * if null, redirection is disabled
- * @param redirectTriggers elements that trigger the redirection
- */
- public void setRedirectStream(OutputStream redirectStream, Set<QName> redirectTriggers) throws XMLStreamException {
- setRedirectStream(redirectStream, DEFAULT_ENCODING, redirectTriggers);
- }
+ /**
+ * Enable/disable redirection of all (child) elements contained in redirect triggers.
+ * The redirected events will be UTF-8 encoded and written to the stream.
+ *
+ * @param redirectstream
+ * if null, redirection is disabled
+ * @param redirectTriggers elements that trigger the redirection
+ */
+ public void setRedirectStream(OutputStream redirectStream, Set<QName> redirectTriggers) throws XMLStreamException {
+ setRedirectStream(redirectStream, DEFAULT_ENCODING, redirectTriggers);
+ }
- /**
- * Enable/disable redirection of all (child) elements contained in redirect triggers.
- *
- * @param redirectstream
- * if null, redirection is disabled
- * @param encoding The encoding for the redirect stream
- * @param redirectTriggers elements that trigger the redirection
- */
- public void setRedirectStream(OutputStream redirectStream, String encoding, Set<QName> redirectTriggers) throws XMLStreamException {
- if (redirectStream != null) {
- XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
- if (encoding == null) {
- encoding = DEFAULT_ENCODING;
- }
- redirectWriter = outputFactory.createXMLEventWriter(redirectStream,
+ /**
+ * Enable/disable redirection of all (child) elements contained in redirect triggers.
+ *
+ * TODO: don't set redirect stream from caller (caller does not know whether redirection will be triggered)
+ * rather create on trigger and pass to caller
+ * @param redirectstream
+ * if null, redirection is disabled
+ * @param encoding The encoding for the redirect stream
+ * @param redirectTriggers elements that trigger the redirection
+ */
+ public void setRedirectStream(OutputStream redirectStream, String encoding, Set<QName> redirectTriggers) throws XMLStreamException {
+ if (redirectStream != null) {
+ XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+ if (encoding == null) {
+ encoding = DEFAULT_ENCODING;
+ }
+ redirectWriter = outputFactory.createXMLEventWriter(redirectStream,
encoding);
- if (redirectTriggers == null) {
- // start redirecting
- depth = 0;
- }
- this.redirectTriggers = redirectTriggers;
- } else {
- redirectWriter = null;
- this.redirectTriggers = null;
- }
+ if (redirectTriggers == null) {
+ // start redirecting
+ depth = 0;
+ }
+ this.redirectTriggers = redirectTriggers;
+ } else {
+ redirectWriter = null;
+ this.redirectTriggers = null;
}
+ }
- /**
- * Enable/disable redirection of fragments (defined by elements in
- * redirectTriggers)
- *
- * @param redirectStream
- * if null, redirection is disabled
- * @param redirectTriggers
- * All startElement events occuring in this list will trigger
- * redirection of the entire fragment. If null, all events are
- * redirected
- */
- // public void setRedirectStream(OutputStream redirectStream, List<QName>
- // redirectTriggers) throws XMLStreamException {
- // if (redirectStream != null) {
- // XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
- // redirectWriter = outputFactory.createXMLEventWriter(redirectStream);
- // } else {
- // redirectWriter = null;
- // }
- // this.redirectTriggers = (redirectStream == null) ? null : redirectTriggers;
- // }
- /**
- * flushes the internal EventWriter
- *
- * @throws javax.xml.stream.XMLStreamException
- */
- public void flushRedirectStream() throws XMLStreamException {
- redirectWriter.flush();
- }
+ /**
+ * Enable/disable redirection of fragments (defined by elements in
+ * redirectTriggers)
+ *
+ * @param redirectStream
+ * if null, redirection is disabled
+ * @param redirectTriggers
+ * All startElement events occuring in this list will trigger
+ * redirection of the entire fragment. If null, all events are
+ * redirected
+ */
+ // public void setRedirectStream(OutputStream redirectStream, List<QName>
+ // redirectTriggers) throws XMLStreamException {
+ // if (redirectStream != null) {
+ // XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+ // redirectWriter = outputFactory.createXMLEventWriter(redirectStream);
+ // } else {
+ // redirectWriter = null;
+ // }
+ // this.redirectTriggers = (redirectStream == null) ? null : redirectTriggers;
+ // }
+ /**
+ * flushes the internal EventWriter
+ *
+ * @throws javax.xml.stream.XMLStreamException
+ */
+ public void flushRedirectStream() throws XMLStreamException {
+ redirectWriter.flush();
+ }
- /**
- * the namespaceContext of the last startelement event read
- *
- * @return
- */
- public NamespaceContext getCurrentNamespaceContext() {
- return currentNamespaceContext;
- }
+ /**
+ * the namespaceContext of the last startelement event read
+ *
+ * @return
+ */
+ public NamespaceContext getCurrentNamespaceContext() {
+ return currentNamespaceContext;
+ }
}
diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java
index b4e988f0..1180e9fa 100644
--- a/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java
+++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java
@@ -25,6 +25,7 @@ import java.io.ByteArrayOutputStream;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import org.apache.commons.logging.Log;
diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java
index c32542aa..eb147f88 100644
--- a/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java
+++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java
@@ -35,7 +35,7 @@ import org.apache.commons.logging.LogFactory;
public class XMLContentType extends at.buergerkarte.namespaces.securitylayer._1.XMLContentType implements RedirectCallback {
@XmlTransient
- private static Log log = LogFactory.getLog(TransformsInfoType.class);
+ private static Log log = LogFactory.getLog(XMLContentType.class);
@XmlTransient
protected ByteArrayOutputStream redirectOS = null;
diff --git a/utils/src/main/java/org/w3/_2000/_09/xmldsig_/ObjectFactory.java b/utils/src/main/java/org/w3/_2000/_09/xmldsig_/ObjectFactory.java
index 4ab376f1..fae77451 100644
--- a/utils/src/main/java/org/w3/_2000/_09/xmldsig_/ObjectFactory.java
+++ b/utils/src/main/java/org/w3/_2000/_09/xmldsig_/ObjectFactory.java
@@ -167,6 +167,7 @@ public class ObjectFactory {
*
*/
public TransformType createTransformType() {
+// return new at.gv.egiz.slbinding.impl.TransformType();
return new TransformType();
}
diff --git a/utils/src/main/java/org/w3/_2000/_09/xmldsig_/TransformsType.java b/utils/src/main/java/org/w3/_2000/_09/xmldsig_/TransformsType.java
index 584baf80..c7044c4c 100644
--- a/utils/src/main/java/org/w3/_2000/_09/xmldsig_/TransformsType.java
+++ b/utils/src/main/java/org/w3/_2000/_09/xmldsig_/TransformsType.java
@@ -57,7 +57,7 @@ import javax.xml.bind.annotation.XmlType;
})
public class TransformsType {
- @XmlElement(name = "Transform", required = true)
+ @XmlElement(name = "Transform", required = true) //, type=at.gv.egiz.slbinding.impl.TransformType.class)
protected List<TransformType> transform;
/**
diff --git a/utils/src/test/java/at/gv/egiz/slbinding/RedirectTest.java b/utils/src/test/java/at/gv/egiz/slbinding/RedirectTest.java
index 99d353ac..7c8c206a 100644
--- a/utils/src/test/java/at/gv/egiz/slbinding/RedirectTest.java
+++ b/utils/src/test/java/at/gv/egiz/slbinding/RedirectTest.java
@@ -52,6 +52,8 @@ import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import static org.junit.Assert.*;
+import org.w3._2000._09.xmldsig_.TransformType;
+import org.w3._2000._09.xmldsig_.TransformsType;
/**
*
@@ -131,11 +133,34 @@ public class RedirectTest {
Iterator<TransformsInfoType> tiIt = transformsInfos.iterator();
while (tiIt.hasNext()) {
at.gv.egiz.slbinding.impl.TransformsInfoType ti = (at.gv.egiz.slbinding.impl.TransformsInfoType) tiIt.next();
+// TransformsInfoType ti = tiIt.next();
assertNotNull(ti);
- System.out.println("found at.gv.egiz.slbinding.impl.TransformsInfoType TransformsInfo");
+ System.out.println("found sl:TransformsInfo: " + ti.getClass().getName()); //at.gv.egiz.slbinding.impl.TransformsInfoType TransformsInfo");
+// TransformsType ts = ti.getTransforms();
+// assertNotNull(ts);
+// System.out.println("found dsig:Transforms " + ts.getClass().getName()); //org.w3._2000._09.xmldsig_.TransformsType dsig:Transforms");
+// List<TransformType> tL = ts.getTransform();
+// assertNotNull(tL);
+// System.out.println("found " + tL.size() + " org.w3._2000._09.xmldsig_.TransformType dsig:Transform");
+// for (TransformType t : tL) {
+// if (t instanceof at.gv.egiz.slbinding.impl.TransformType) {
+// System.out.println("found at.gv.egiz.slbinding.impl.TransformType");
+// byte[] redirectedBytes = ((at.gv.egiz.slbinding.impl.TransformType) t).getRedirectedStream().toByteArray();
+// if (redirectedBytes != null && redirectedBytes.length > 0) {
+// System.out.println("reading redirected stream...");
+// os.write("--- redirected Transform ---".getBytes());
+// os.write(redirectedBytes);
+// os.write("\n".getBytes());
+// } else {
+// System.out.println("no redirected stream");
+// }
+// }
+// }
+
ByteArrayOutputStream dsigTransforms = ti.getRedirectedStream();
+ os.write("--- redirected TransformsInfo content ---".getBytes());
os.write(dsigTransforms.toByteArray());
- os.write("\n".getBytes());
+ os.write("\n---".getBytes());
MetaInfoType mi = ti.getFinalDataMetaInfo();
assertNotNull(mi);
diff --git a/utils/src/test/requests/CreateXMLSignatureRequest02.xml_redirect.txt b/utils/src/test/requests/CreateXMLSignatureRequest02.xml_redirect.txt
index 31be50b7..fc0e4f14 100644
--- a/utils/src/test/requests/CreateXMLSignatureRequest02.xml_redirect.txt
+++ b/utils/src/test/requests/CreateXMLSignatureRequest02.xml_redirect.txt
@@ -1,4 +1,4 @@
-<dsig:Transforms>
+--- redirected TransformsInfo content ---<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></dsig:Transform>
<dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#" version="1.0">
@@ -82,7 +82,7 @@
</dsig:Transform>
<dsig:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></dsig:Transform>
</dsig:Transforms>
-<dsig:Transforms>
+------ redirected TransformsInfo content ---<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></dsig:Transform>
<dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:pr="http://reference.e-government.gv.at/namespace/persondata/20020228#" version="1.0">
@@ -162,3 +162,4 @@
</dsig:Transform>
<dsig:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></dsig:Transform>
</dsig:Transforms>
+--- \ No newline at end of file