diff options
| author | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-03-06 14:53:37 +0000 | 
|---|---|---|
| committer | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-03-06 14:53:37 +0000 | 
| commit | e177419331b8849497d25d3eb1866c5dc715bc88 (patch) | |
| tree | 15d5d1c7dbaa9692eb03ebae9c91a8aff17d2aa7 /BKUAppletExt/src/main/java/at/gv/egiz/bku | |
| parent | a8690cc956924e1d83b0c45d21995ee2e10fbba2 (diff) | |
| download | mocca-e177419331b8849497d25d3eb1866c5dc715bc88.tar.gz mocca-e177419331b8849497d25d3eb1866c5dc715bc88.tar.bz2 mocca-e177419331b8849497d25d3eb1866c5dc715bc88.zip | |
1.1-rc4
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@312 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'BKUAppletExt/src/main/java/at/gv/egiz/bku')
5 files changed, 435 insertions, 166 deletions
| 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 1276f2d0..c904be0c 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 @@ -20,6 +20,7 @@ package at.gv.egiz.bku.gui;  import at.gv.egiz.smcc.PINSpec;  import java.awt.Container;  import java.awt.Cursor; +import java.awt.Font;  import java.awt.event.ActionEvent;  import java.awt.event.ActionListener;  import java.awt.event.MouseEvent; @@ -55,6 +56,8 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac    /** remember the pinSpec to return to worker */    protected PINSpec pinSpec; +  protected enum DIALOG { VERIFY, ACTIVATE, CHANGE, UNBLOCK }; +    public PINManagementGUI(Container contentPane,            Locale locale,            Style guiStyle, @@ -84,6 +87,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac            final String activateCmd,            final String changeCmd,            final String unblockCmd, +          final String verifyCmd,            final ActionListener cancelListener,            final String cancelCmd) { @@ -161,9 +165,10 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                              activateButton.setText(getMessage(BUTTON_CHANGE));                              activateButton.setEnabled(true);                              activateButton.setActionCommand(changeCmd); -                          } else { -                            activateButton.setText(getMessage(BUTTON_ACTIVATE)); -                            activateButton.setEnabled(false); +                          } else if (status == STATUS.UNKNOWN) { +                            activateButton.setText(getMessage(BUTTON_VERIFY)); +                            activateButton.setEnabled(true); +                            activateButton.setActionCommand(verifyCmd);                            }                          }                        } @@ -234,11 +239,11 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac            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); +    showPINDialog(DIALOG.ACTIVATE, pin, okListener, okCommand, cancelListener, cancelCommand);    } -  private void showPINDialog(final boolean changePin, final PINSpec pinSpec, +  private void showPINDialog(final DIALOG type, final PINSpec pinSpec,            final ActionListener okListener, final String okCommand,            final ActionListener cancelListener, final String cancelCommand) { @@ -248,17 +253,25 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac              public void run() {                String HELP_TOPIC, TITLE, MESSAGE_MGMT; -              if (changePin) { +              HELP_TOPIC = HELP_PINMGMT; + +              if (type == DIALOG.CHANGE) {                  log.debug("show change pin dialog"); -                HELP_TOPIC = HELP_PINMGMT;                  TITLE = TITLE_CHANGE_PIN;                  MESSAGE_MGMT = MESSAGE_CHANGE_PIN; -              } else { +              } else if (type == DIALOG.ACTIVATE) {                  log.debug("show activate pin dialog"); -                HELP_TOPIC = HELP_PINMGMT;                  TITLE = TITLE_ACTIVATE_PIN;                  MESSAGE_MGMT = MESSAGE_ACTIVATE_PIN;                  oldPinField = null; +              } else if (type == DIALOG.VERIFY) { +                log.debug("show verify pin dialog"); +                TITLE = TITLE_VERIFY_PIN; +                MESSAGE_MGMT = MESSAGE_VERIFY_PIN; +              } else { +                log.debug("show unblock pin dialog"); +                TITLE = TITLE_UNBLOCK_PIN; +                MESSAGE_MGMT = MESSAGE_UNBLOCK_PIN;                }                  mainPanel.removeAll(); @@ -267,7 +280,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                  helpListener.setHelpTopic(HELP_TOPIC);                  JLabel mgmtLabel = new JLabel(); -                mgmtLabel.setFont(mgmtLabel.getFont().deriveFont(mgmtLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); +                mgmtLabel.setFont(mgmtLabel.getFont().deriveFont(mgmtLabel.getFont().getStyle() & ~Font.BOLD));                  if (renderHeaderPanel) {                    titleLabel.setText(getMessage(TITLE)); @@ -282,73 +295,83 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                  }                  JButton okButton = new JButton(); -                okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~java.awt.Font.BOLD)); +                okButton.setFont(okButton.getFont().deriveFont(okButton.getFont().getStyle() & ~Font.BOLD));                  okButton.setText(getMessage(BUTTON_OK)); -                okButton.setEnabled(false); +                okButton.setEnabled(type == DIALOG.VERIFY && pinSpec.getMinLength() == 0);                  okButton.setActionCommand(okCommand);                  okButton.addActionListener(okListener); +                JLabel oldPinLabel = null; +                JLabel repeatPinLabel = null;                  JLabel pinLabel = new JLabel(); -                pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); -                String pinLabelPattern = (changePin) ? getMessage(LABEL_NEW_PIN) : getMessage(LABEL_PIN); +                pinLabel.setFont(pinLabel.getFont().deriveFont(pinLabel.getFont().getStyle() & ~Font.BOLD)); +                String pinLabelPattern = (type == DIALOG.CHANGE) ? getMessage(LABEL_NEW_PIN) : getMessage(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 = getMessage(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()) { +                          if (type == DIALOG.VERIFY) {                              okListener.actionPerformed(e); +                          } else { +                            repeatPinField.requestFocusInWindow(); +                          }                          }                      }                  }); -                JLabel oldPinLabel = null; -                if (changePin) { -                  oldPinLabel = new JLabel(); -                  oldPinLabel.setFont(oldPinLabel.getFont().deriveFont(oldPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); -                  String oldPinLabelPattern = getMessage(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() { +                if (type != DIALOG.VERIFY) { +                  pinField.setDocument(new PINDocument(pinSpec, null)); +                  repeatPinLabel = new JLabel(); +                  repeatPinLabel.setFont(pinLabel.getFont()); +                  String repeatPinLabelPattern = getMessage(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 (oldPinField.getPassword().length >= pinSpec.getMinLength()) { -                            pinField.requestFocusInWindow(); +                          if (pinField.getPassword().length >= pinSpec.getMinLength()) { +                              okListener.actionPerformed(e);                            }                        }                    }); + +                  if (type == DIALOG.CHANGE) { +                    oldPinLabel = new JLabel(); +                    oldPinLabel.setFont(oldPinLabel.getFont().deriveFont(oldPinLabel.getFont().getStyle() & ~java.awt.Font.BOLD)); +                    String oldPinLabelPattern = getMessage(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(); +                            } +                        } +                    }); +                  } // else -> ACTIVATE (not verify, not change) +                } else { +                  pinField.setDocument(new PINDocument(pinSpec, okButton));                  } -                 +                  JLabel pinsizeLabel = new JLabel(); -                pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(pinsizeLabel.getFont().getStyle() & ~java.awt.Font.BOLD, pinsizeLabel.getFont().getSize()-2)); +                pinsizeLabel.setFont(pinsizeLabel.getFont().deriveFont(pinsizeLabel.getFont().getStyle() & ~Font.BOLD, pinsizeLabel.getFont().getSize()-2));                  String pinsizePattern = getMessage(LABEL_PINSIZE);                  String pinSize = String.valueOf(pinSpec.getMinLength());                  if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { @@ -375,37 +398,39 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                  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) { +//                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 (type == DIALOG.CHANGE) {                      pinHorizontal                            .addGroup(mainPanelLayout.createSequentialGroup()                              .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) @@ -422,8 +447,16 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                            .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)                              .addComponent(oldPinLabel)                              .addComponent(oldPinField)) +                          .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) +                          .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); -                  } else { +                  } else if (type == DIALOG.ACTIVATE) {                      pinHorizontal                            .addGroup(mainPanelLayout.createSequentialGroup()                              .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) @@ -434,12 +467,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                                .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 +                    pinVertical                            .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)                              .addComponent(pinLabel)                              .addComponent(pinField)) @@ -447,9 +475,27 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac                            .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)                              .addComponent(repeatPinLabel)                              .addComponent(repeatPinField)) -                          .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) +                          .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); +                  } else { // VERIFY +                    pinHorizontal +                          .addGroup(mainPanelLayout.createSequentialGroup() +                            .addComponent(pinLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) +                            .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) +                            .addComponent(pinField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)); + +                    pinVertical +                          .addGroup(mainPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) +                            .addComponent(pinLabel) +                            .addComponent(pinField)) +                          .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED); +                  } +                  pinHorizontal +                          .addGroup(mainPanelLayout.createSequentialGroup() +                            .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, 0, Short.MAX_VALUE) +                            .addComponent(pinsizeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)); +                  pinVertical                            .addComponent(pinsizeLabel); -                } +//                }                  mainPanelLayout.setHorizontalGroup(                    mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) @@ -503,7 +549,7 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac            final ActionListener cancelListener, final String cancelCommand) {        log.debug("scheduling change pin dialog"); -      showPINDialog(true, pin, okListener, okCommand, cancelListener, cancelCommand); +      showPINDialog(DIALOG.CHANGE, pin, okListener, okCommand, cancelListener, cancelCommand);    }    @Override @@ -612,4 +658,9 @@ public class PINManagementGUI extends CardMgmtGUI implements PINManagementGUIFac      return bs;    } + +  @Override +  public void showVerifyPINDialog(PINSpec pin, ActionListener okListener, String okCmd, ActionListener cancelListener, String cancelCmd) { +    showPINDialog(DIALOG.VERIFY, pin, okListener, okCmd, cancelListener, cancelCmd); +  }  } 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 6b083e16..9c630431 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 @@ -31,6 +31,7 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {    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_VERIFY_PIN = "title.verify.pin";    public static final String TITLE_UNBLOCK_PIN = "title.unblock.pin";    public static final String TITLE_ACTIVATE_SUCCESS = "title.activate.success";    public static final String TITLE_CHANGE_SUCCESS = "title.change.success"; @@ -39,19 +40,25 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {    public static final String MESSAGE_PINMGMT = "message.pin.mgmt";    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_VERIFY_PIN = "message.verify.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_STATUS = "err.status";    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 ERR_VERIFY = "err.verify";    public static final String ERR_RETRIES = "err.retries"; +  public static final String ERR_LOCKED = "err.locked"; +  public static final String ERR_NOT_ACTIVE = "err.not.active";    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 BUTTON_VERIFY = "button.verify";    public static final String STATUS_ACTIVE = "status.active";    public static final String STATUS_BLOCKED = "status.blocked"; @@ -61,7 +68,7 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {    public enum STATUS { ACTIV, NOT_ACTIV, BLOCKED, UNKNOWN };    public void showPINManagementDialog(Map<PINSpec, STATUS> pins, -          ActionListener activateListener, String activateCmd, String changeCmd, String unblockCmd, +          ActionListener activateListener, String activateCmd, String changeCmd, String unblockCmd, String verifyCmd,            ActionListener cancelListener, String cancelCmd);    public void showActivatePINDialog(PINSpec pin, @@ -76,6 +83,10 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {            ActionListener okListener, String okCmd,            ActionListener cancelListener, String cancelCmd); +  public void showVerifyPINDialog(PINSpec pin, +          ActionListener okListener, String okCmd, +          ActionListener cancelListener, String cancelCmd); +    public char[] getOldPin();    public PINSpec getSelectedPINSpec(); 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 index feaa5072..052c13b2 100644 --- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java +++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/gui/PINStatusTableModel.java @@ -20,8 +20,6 @@ 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;  /**   * @@ -29,7 +27,7 @@ import org.apache.commons.logging.LogFactory;   */  public class PINStatusTableModel extends DefaultTableModel { -  protected static final Log log = LogFactory.getLog(PINStatusTableModel.class); +//  protected static final Log log = LogFactory.getLog(PINStatusTableModel.class);    protected Class[] types;    public PINStatusTableModel(Map<PINSpec, STATUS> pinStatuses) { @@ -37,7 +35,7 @@ public class PINStatusTableModel extends DefaultTableModel {      if (pinStatuses == null) {        throw new RuntimeException("pinStatuses must not be null");      } -    log.trace(pinStatuses.size() + " PINs"); +//    log.trace(pinStatuses.size() + " PINs");      types = new Class[] { PINSpec.class, STATUS.class };      for (PINSpec pinSpec : pinStatuses.keySet()) {        addRow(new Object[] { pinSpec, pinStatuses.get(pinSpec) }); diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/GetPINStatusException.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/GetPINStatusException.java new file mode 100644 index 00000000..abbe66a1 --- /dev/null +++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/GetPINStatusException.java @@ -0,0 +1,41 @@ +/* + * 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.smcc.SignatureCardException; + +/** + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class GetPINStatusException extends SignatureCardException { + +    /** +     * Creates a new instance of <code>GetStatusException</code> without detail message. +     */ +    public GetPINStatusException() { +    } + + +    /** +     * Constructs an instance of <code>GetStatusException</code> with the specified detail message. +     * @param msg the detail message. +     */ +    public GetPINStatusException(String msg) { +        super(msg); +    } +} 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 index c8472c97..66db0484 100644 --- 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 @@ -20,7 +20,10 @@ 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.LockedException; +import at.gv.egiz.smcc.NotActivatedException;  import at.gv.egiz.smcc.PINSpec; +import at.gv.egiz.smcc.STARCOSCard;  import at.gv.egiz.smcc.SignatureCardException;  import at.gv.egiz.smcc.VerificationFailedException;  import at.gv.egiz.smcc.util.SMCCHelper; @@ -32,6 +35,8 @@ import at.gv.egiz.stal.ext.PINManagementResponse;  import java.util.HashMap;  import java.util.List;  import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger;  import javax.smartcardio.Card;  import javax.smartcardio.CardChannel;  import javax.smartcardio.CardException; @@ -48,13 +53,20 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {    protected static final Log log = LogFactory.getLog(PINManagementRequestHandler.class); +  Map<PINSpec, STATUS> pinStatuses; +    @Override    public STALResponse handleRequest(STALRequest request) throws InterruptedException {      if (request instanceof PINManagementRequest) {        PINManagementGUIFacade gui = (PINManagementGUIFacade) this.gui; -      showPINManagementDialog(gui); +      try { +      pinStatuses = getPINStatuses(); + +      gui.showPINManagementDialog(pinStatuses, +              this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +              this, "cancel");        while (true) { @@ -63,7 +75,9 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {          if ("cancel".equals(actionCommand)) {            return new PINManagementResponse();          } else if ("back".equals(actionCommand)) { -          showPINManagementDialog(gui); +          gui.showPINManagementDialog(pinStatuses, +              this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +              this, "cancel");          } else {            PINSpec selectedPIN = gui.getSelectedPINSpec(); @@ -72,63 +86,163 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {            }            if ("activate_enterpin".equals(actionCommand)) { -            gui.showActivatePINDialog(selectedPIN, this, "activate", this, "back"); +            gui.showActivatePINDialog(selectedPIN, +                    this, "activate", this, "back");            } else if ("change_enterpin".equals(actionCommand)) { -            gui.showChangePINDialog(selectedPIN, this, "change", this, "back"); +            gui.showChangePINDialog(selectedPIN, +                    this, "change", this, "back");            } else if ("unblock_enterpuk".equals(actionCommand)) { -            gui.showUnblockPINDialog(selectedPIN, this, "unblock", this, "back"); +            gui.showUnblockPINDialog(selectedPIN, +                    this, "unblock", this, "back"); +          } else if ("verify_enterpin".equals(actionCommand)) { +            gui.showVerifyPINDialog(selectedPIN, +                    this, "verify", this, "back");            } else if ("activate".equals(actionCommand)) {              try { -              card.activatePIN(selectedPIN.getKID(), -                      selectedPIN.getContextAID(), +              log.debug("activate " + selectedPIN.getLocalizedName()); +              card.activatePIN(selectedPIN,                        String.valueOf(gui.getPin())); +              updatePINStatus(selectedPIN, STATUS.ACTIV);                gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS,                        PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS,                        new Object[] {selectedPIN.getLocalizedName()},                        this, "ok");                waitForAction(); -              showPINManagementDialog(gui); +              gui.showPINManagementDialog(pinStatuses, +                this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                this, "cancel"); +            } catch (GetPINStatusException ex) { +              log.error("failed to get " +  selectedPIN.getLocalizedName() + +                      " status: " + ex.getMessage()); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, null, +                      this, "cancel");              } catch (SignatureCardException ex) { -              log.error("failed to activate " + selectedPIN.getLocalizedName() + ": " + ex.getMessage()); +              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)) { +            log.info("change " + selectedPIN.getLocalizedName());              try { -              card.changePIN(selectedPIN.getKID(), -                      selectedPIN.getContextAID(), +              card.changePIN(selectedPIN,                        String.valueOf(gui.getOldPin()),                        String.valueOf(gui.getPin())); +              updatePINStatus(selectedPIN, STATUS.ACTIV);                gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS,                        PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS,                        new Object[] {selectedPIN.getLocalizedName()},                        this, "ok");                waitForAction(); -              showPINManagementDialog(gui); +              gui.showPINManagementDialog(pinStatuses, +                this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                this, "cancel"); +            } catch (GetPINStatusException ex) { +              log.error("failed to get " +  selectedPIN.getLocalizedName() + +                      " status: " + ex.getMessage()); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, null, +                      this, "cancel"); +            } catch (LockedException ex) { +              log.error("failed to change " + selectedPIN.getLocalizedName() + +                      ": PIN locked"); +              updatePINStatus(selectedPIN, STATUS.BLOCKED); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_LOCKED, +                      new Object[] {selectedPIN.getLocalizedName()}, +                      this, "ok"); +              waitForAction(); +              gui.showPINManagementDialog(pinStatuses, +                this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                this, "cancel");              } catch (VerificationFailedException ex) { -              log.error("failed to change " + selectedPIN.getLocalizedName() + ": " + ex.getMessage()); +              log.error("failed to change " + selectedPIN.getLocalizedName() + +                      ": " + ex.getMessage());                gui.showErrorDialog(PINManagementGUIFacade.ERR_RETRIES,                        new Object[] {selectedPIN.getLocalizedName(), ex.getRetries()}, -                      this, "back"); +                      this, "change_enterpin"); +            } catch (NotActivatedException ex) { +              log.error("failed to change " + selectedPIN.getLocalizedName() + +                      ": PIN not active"); +              updatePINStatus(selectedPIN, STATUS.NOT_ACTIV); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_NOT_ACTIVE, +                      new Object[] {selectedPIN.getLocalizedName()}, +                      this, "ok"); +              waitForAction(); +              gui.showPINManagementDialog(pinStatuses, +                this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                this, "cancel");              } catch (SignatureCardException ex) { -              log.error("failed to change " + selectedPIN.getLocalizedName() + ": " + ex.getMessage()); +              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.info("unblock " + selectedPIN.getLocalizedName());              log.error("unblock PIN not implemented");              gui.showErrorDialog(PINManagementGUIFacade.ERR_UNBLOCK, null, this, "cancel"); +          } else if ("verify".equals(actionCommand)) { +            try { +              log.info("verify " + selectedPIN.getLocalizedName()); +              int retries = card.verifyPIN(selectedPIN, String.valueOf(gui.getPin())); +              log.trace(retries + " retries"); +              if (retries < 0) { +                updatePINStatus(selectedPIN, STATUS.ACTIV); +                gui.showPINManagementDialog(pinStatuses, +                        this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                        this, "cancel"); +              } else { +                log.error("failed to verify " + selectedPIN.getLocalizedName() + +                      ": " + retries + " retries left"); +                gui.showErrorDialog(PINManagementGUIFacade.ERR_RETRIES, +                      new Object[] {selectedPIN.getLocalizedName(), retries}, +                      this, "verify_enterpin"); +              } +            } catch (GetPINStatusException ex) { +              log.error("failed to get " +  selectedPIN.getLocalizedName() + +                      " status: " + ex.getMessage()); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, null, +                      this, "cancel"); +            } catch (LockedException ex) { +              log.error("failed to verify " + selectedPIN.getLocalizedName() + +                      ": PIN locked"); +              updatePINStatus(selectedPIN, STATUS.BLOCKED); +              gui.showPINManagementDialog(pinStatuses, +                      this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                      this, "cancel"); +            } catch (NotActivatedException ex) { +              log.error("failed to verify " + selectedPIN.getLocalizedName() + +                      ": PIN not active"); +              updatePINStatus(selectedPIN, STATUS.NOT_ACTIV); +              gui.showPINManagementDialog(pinStatuses, +                      this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", +                      this, "cancel"); +            } catch (SignatureCardException ex) { +              log.error("failed to verify " + selectedPIN.getLocalizedName() + +                      ": " + ex.getMessage()); +              gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, +                      new Object[] {selectedPIN.getLocalizedName()}, +                      this, "cancel"); +            } +            } else {              throw new RuntimeException("unsupported action " + actionCommand);            }          }        } +      } catch (GetPINStatusException ex) { +        log.error("Failed to get PIN statuses: " + ex.getMessage()); +        gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, null, +                this, "ok"); +        waitForAction(); +        return new ErrorResponse(1000); +      }      } else {        log.error("Got unexpected STAL request: " + request);        return new ErrorResponse(1000);      } +    }    @Override @@ -136,75 +250,129 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {      return true;    } -  public Map<PINSpec, STATUS> getPINStatuses() throws SignatureCardException { -    Card icc = card.getCard(); -    try { -      icc.beginExclusive(); -      CardChannel channel = icc.getBasicChannel(); +  private Map<PINSpec, STATUS> getPINStatuses() throws GetPINStatusException { +    HashMap<PINSpec, STATUS> pinStatuses = new HashMap<PINSpec, STATUS>(); +    List<PINSpec> pins = card.getPINSpecs(); -      HashMap<PINSpec, STATUS> pinStatuses = new HashMap<PINSpec, STATUS>(); -      List<PINSpec> pins = card.getPINSpecs(); +    if (card instanceof STARCOSCard) { +      Card icc = card.getCard(); +      try { +        icc.beginExclusive(); +        CardChannel channel = icc.getBasicChannel(); -      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) { -            icc.endExclusive(); -            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); +        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) { +              icc.endExclusive(); +              String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) + +                  ": SW=" + Integer.toHexString(responseAPDU.getSW()); +              log.error(msg); +              throw new GetPINStatusException(msg); +            }            } -        } -        CommandAPDU verifyAPDU = new CommandAPDU(new byte[]{(byte) 0x00, (byte) 0x20, (byte) 00, kid}); -        ResponseAPDU responseAPDU = channel.transmit(verifyAPDU); +          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())); +          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);          } +        return pinStatuses; -        pinStatuses.put(pinSpec, status); -      } -//      icc.endExclusive(); - -      return pinStatuses; - -    } catch (CardException ex) { -      log.error("Failed to get PIN status: " + ex.getMessage()); -      throw new SignatureCardException(ex.getMessage(), ex); -    } finally { -      try { -        icc.endExclusive();        } catch (CardException ex) { -        log.trace("failed to end exclusive card access"); +        log.error("Failed to get PIN status: " + ex.getMessage(), ex); +        throw new GetPINStatusException(ex.getMessage()); +      } finally { +        try { +          icc.endExclusive(); +        } catch (CardException ex) { +          log.trace("failed to end exclusive card access: " + ex.getMessage()); +        } +      } +    } else { +      for (PINSpec pinSpec : pins) { +        pinStatuses.put(pinSpec, STATUS.UNKNOWN);        }      } +    return pinStatuses;    } -  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[]{ex.getMessage()}, -              this, "cancel"); +  /** +   * query status for STARCOS card, +   * assume provided status for ACOS card +   * @param pinSpec +   * @param status +   * @throws at.gv.egiz.smcc.SignatureCardException if query status fails +   */ +  private void updatePINStatus(PINSpec pinSpec, STATUS status) throws GetPINStatusException { +    if (card instanceof STARCOSCard) { +      Card icc = card.getCard(); +      try { +        icc.beginExclusive(); +        CardChannel channel = icc.getBasicChannel(); + +          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) { +              icc.endExclusive(); +              String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) + +                  ": SW=" + Integer.toHexString(responseAPDU.getSW()); +              log.error(msg); +              throw new GetPINStatusException(msg); +            } +          } + +          CommandAPDU verifyAPDU = new CommandAPDU(new byte[] { +            (byte) 0x00, (byte) 0x20, (byte) 00, kid }); +          ResponseAPDU responseAPDU = channel.transmit(verifyAPDU); + +          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(pinSpec.getLocalizedName() + +                    " status: " + SMCCHelper.toString(responseAPDU.getBytes())); +          } +          pinStatuses.put(pinSpec, status); + +      } catch (CardException ex) { +        log.error("Failed to get PIN status: " + ex.getMessage(), ex); +        throw new GetPINStatusException(ex.getMessage()); +      } finally { +        try { +          icc.endExclusive(); +        } catch (CardException ex) { +          log.warn("failed to end exclusive card access: " + ex.getMessage()); +        } +      } +    } else { +      pinStatuses.put(pinSpec, status);      }    }  } | 
