diff options
| author | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-04-02 19:13:48 +0000 | 
|---|---|---|
| committer | clemenso <clemenso@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2009-04-02 19:13:48 +0000 | 
| commit | 2dbf2347bc78fd835c857ad438514fb6251f6f7a (patch) | |
| tree | ec8eb7876dfdca86eeeec1d08ebbeb31eb464892 | |
| parent | 1ad095128a98137e2b4c904814722be4ec43eebd (diff) | |
| download | mocca-2dbf2347bc78fd835c857ad438514fb6251f6f7a.tar.gz mocca-2dbf2347bc78fd835c857ad438514fb6251f6f7a.tar.bz2 mocca-2dbf2347bc78fd835c857ad438514fb6251f6f7a.zip | |
1.1-RC7 (pinpad revisited)
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@325 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
25 files changed, 1174 insertions, 750 deletions
| 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 f0cc0a27..848cd17f 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 @@ -62,6 +62,9 @@ public interface PINManagementGUIFacade extends BKUGUIFacade {    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 ERR_PIN_FORMAT = "err.pin.format"; +  public static final String ERR_PIN_CONFIRMATION = "err.pin.confirmation"; +  public static final String ERR_PIN_OPERATION_ABORTED = "err.pin.operation.aborted";    public static final String BUTTON_ACTIVATE = "button.activate";    public static final String BUTTON_UNBLOCK = "button.unblock"; diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java index d635b8df..090caf50 100644 --- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java +++ b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/ManagementPINProviderFactory.java @@ -17,38 +17,242 @@  package at.gv.egiz.bku.smccstal.ext; +import at.gv.egiz.bku.gui.BKUGUIFacade;  import at.gv.egiz.smcc.ChangePINProvider;  import at.gv.egiz.bku.gui.PINManagementGUIFacade; +import at.gv.egiz.bku.smccstal.AbstractPINProvider; +import at.gv.egiz.bku.smccstal.PINProviderFactory; +import at.gv.egiz.smcc.CancelledException;  import at.gv.egiz.smcc.ccid.CCID;  import at.gv.egiz.smcc.PINProvider; +import at.gv.egiz.smcc.PINSpec;  import at.gv.egiz.smcc.SignatureCard;  /**   *   * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>   */ -public abstract class ManagementPINProviderFactory { -//        extends at.gv.egiz.bku.smccstal.PINProviderFactory { +public class ManagementPINProviderFactory extends PINProviderFactory { -  PINManagementGUIFacade gui; +  public ManagementPINProviderFactory(CCID reader, PINManagementGUIFacade gui) { +    super(reader, gui); +  } -  public static ManagementPINProviderFactory getInstance(SignatureCard forCard, -          PINManagementGUIFacade gui) { -    if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { -//      forCard.ifdSupportsFeature(SignatureCard.FEATURE_MODIFY_PIN_DIRECT) -      return new PinpadPINProviderFactory(gui); +//  public static ManagementPINProviderFactory getInstance(SignatureCard forCard, +//          PINManagementGUIFacade gui) { +//    if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +//      return new PinpadPINProviderFactory(gui); +// +//    } else { +//      return new SoftwarePINProviderFactory(gui); +//    } +//  } + +  public PINProvider getVerifyPINProvider() { +    if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY); +    } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY); +    } else { +      return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.VERIFY); +    } +  } + +  public PINProvider getActivatePINProvider() { +    if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE); +    } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE); +    } else { +      return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.ACTIVATE); +    } +  } +  public ChangePINProvider getChangePINProvider() { +    if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.CHANGE); +    } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.CHANGE);      } else { -      return new SoftwarePINProviderFactory(gui); +      return new ChangePinProvider(); +    } +  } + +  public PINProvider getUnblockPINProvider() { +    if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK); +    } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +      return new PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK); +    } else { +      return new SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG.UNBLOCK); +    } +  } + +  class PinpadGenericPinProvider extends AbstractPINProvider +          implements ChangePINProvider { + +    protected PINManagementGUIFacade.DIALOG type; + +    private PinpadGenericPinProvider(PINManagementGUIFacade.DIALOG type) { +      this.type = type; +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      showPinpadPINDialog(retries, spec); +      retry = true; +      return null; +    } + +    /** +     * do not call this method without calling providePIN() +     * (no message is displayed) +     * @param spec +     * @param retries +     * @return +     */ +    @Override +    public char[] provideOldPIN(PINSpec spec, int retries) { +      return null; +    } + +    private void showPinpadPINDialog(int retries, PINSpec pinSpec) { +      String title, message; +      Object[] params; +      if (retry) { +        title = BKUGUIFacade.TITLE_RETRY; +        message = BKUGUIFacade.MESSAGE_RETRIES; +        params = new Object[]{String.valueOf(retries)}; +      } else if (type == PINManagementGUIFacade.DIALOG.VERIFY) { +        title = PINManagementGUIFacade.TITLE_VERIFY_PIN; +        message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD; +        String pinSize = String.valueOf(pinSpec.getMinLength()); +        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { +          pinSize += "-" + pinSpec.getMaxLength(); +        } +        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; +      } else if (type == PINManagementGUIFacade.DIALOG.ACTIVATE) { +        title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN; +        message = PINManagementGUIFacade.MESSAGE_ACTIVATEPIN_PINPAD; +        String pinSize = String.valueOf(pinSpec.getMinLength()); +        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { +          pinSize += "-" + pinSpec.getMaxLength(); +        } +        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; +      } else if (type == PINManagementGUIFacade.DIALOG.CHANGE) { +        title = PINManagementGUIFacade.TITLE_CHANGE_PIN; +        message = PINManagementGUIFacade.MESSAGE_CHANGEPIN_PINPAD; +        String pinSize = String.valueOf(pinSpec.getMinLength()); +        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { +          pinSize += "-" + pinSpec.getMaxLength(); +        } +        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; +      } else { //if (type == DIALOG.UNBLOCK) { +        title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN; +        message = PINManagementGUIFacade.MESSAGE_UNBLOCKPIN_PINPAD; +        String pinSize = String.valueOf(pinSpec.getMinLength()); +        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { +          pinSize += "-" + pinSpec.getMaxLength(); +        } +        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; +      } +      gui.showMessageDialog(title, message, params);      }    } -  public abstract PINProvider getVerifyPINProvider(); -  public abstract PINProvider getActivatePINProvider(); +  class SoftwareGenericPinProvider extends AbstractPINProvider { + +//    protected PINManagementGUIFacade gui; +    protected PINManagementGUIFacade.DIALOG type; + +    private SoftwareGenericPinProvider(PINManagementGUIFacade.DIALOG type) { +      this.type = type; +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      ((PINManagementGUIFacade) gui).showPINDialog(type, spec, +              (retry) ? retries : -1, +              this, "exec", +              this, "back"); + +      waitForAction(); + +      if ("exec".equals(action)) { +        gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, +                BKUGUIFacade.MESSAGE_WAIT); +        retry = true; +        return gui.getPin(); +      } else if ("back".equals(action)) { +        throw new CancelledException(); +      } else { +        log.error("unsupported command " + action); +        throw new CancelledException(); +      } +    } +  } + +  class ChangePinProvider extends AbstractPINProvider +          implements ChangePINProvider { -  public abstract ChangePINProvider getChangePINProvider(); +//    protected PINManagementGUIFacade gui; -  public abstract PINProvider getUnblockPINProvider(); +    private char[] oldPin; +    private char[] newPin; +    private ChangePinProvider() { +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { +      if (newPin == null) { +        getPINs(spec, retries); +      } +      char[] pin = newPin; +      newPin = null; +      return pin; +    } + +    @Override +    public char[] provideOldPIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { +      if (oldPin == null) { +        getPINs(spec, retries); +      } +      char[] pin = oldPin; +      oldPin = null; +      return pin; +    } + +    private void getPINs(PINSpec spec, int retries) +            throws InterruptedException, CancelledException { + +      ((PINManagementGUIFacade) gui).showPINDialog( +              PINManagementGUIFacade.DIALOG.CHANGE, spec, +              (retry) ? retries : -1, +              this, "exec", +              this, "back"); + +      waitForAction(); + +      if ("exec".equals(action)) { +        gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, +                BKUGUIFacade.MESSAGE_WAIT); +        retry = true; +        oldPin = ((PINManagementGUIFacade) gui).getOldPin(); +        newPin = gui.getPin(); +      } else if ("back".equals(action)) { +        throw new CancelledException(); +      } else { +        log.error("unsupported command " + action); +        throw new CancelledException(); +      } +    } +  }  } 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 6b565b26..72a7c4cc 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 @@ -25,6 +25,9 @@ import at.gv.egiz.bku.smccstal.PINProviderFactory;  import at.gv.egiz.smcc.CancelledException;  import at.gv.egiz.smcc.LockedException;  import at.gv.egiz.smcc.NotActivatedException; +import at.gv.egiz.smcc.PINConfirmationException; +import at.gv.egiz.smcc.PINFormatException; +import at.gv.egiz.smcc.PINOperationAbortedException;  import at.gv.egiz.smcc.PINProvider;  import at.gv.egiz.smcc.PINSpec;  import at.gv.egiz.smcc.STARCOSCard; @@ -58,7 +61,6 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {    protected static final Log log = LogFactory.getLog(PINManagementRequestHandler.class);    protected Map<PINSpec, STATUS> pinStatuses; -  private ManagementPINProviderFactory pinProviderFactory;    @Override    public STALResponse handleRequest(STALRequest request) throws InterruptedException { @@ -89,16 +91,14 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {              throw new NullPointerException("no PIN selected for activation/change");            } -          if (pinProviderFactory == null) { -            pinProviderFactory = -                    ManagementPINProviderFactory.getInstance(card, gui); -          } +          ManagementPINProviderFactory ppfac = +                  new ManagementPINProviderFactory(card.getReader(), gui);            try {              if ("activate_enterpin".equals(actionCommand)) {                log.info("activate " + selectedPIN.getLocalizedName()); -              card.activatePIN(selectedPIN,  -                      pinProviderFactory.getActivatePINProvider()); +              card.activatePIN(selectedPIN, +                      ppfac.getActivatePINProvider());                updatePINStatus(selectedPIN, STATUS.ACTIV);                gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS,                        PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS, @@ -108,7 +108,7 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {              } else if ("change_enterpin".equals(actionCommand)) {                log.info("change " + selectedPIN.getLocalizedName());                card.changePIN(selectedPIN,  -                      pinProviderFactory.getChangePINProvider()); +                      ppfac.getChangePINProvider());                updatePINStatus(selectedPIN, STATUS.ACTIV);                gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS,                        PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS, @@ -119,11 +119,11 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {              } else if ("unblock_enterpuk".equals(actionCommand)) {                log.info("unblock " + selectedPIN.getLocalizedName());                card.unblockPIN(selectedPIN, -                      pinProviderFactory.getUnblockPINProvider()); +                      ppfac.getUnblockPINProvider());              } else if ("verify_enterpin".equals(actionCommand)) {                log.info("verify " + selectedPIN.getLocalizedName());                card.verifyPIN(selectedPIN, -                      pinProviderFactory.getVerifyPINProvider()); +                      ppfac.getVerifyPINProvider());                updatePINStatus(selectedPIN, STATUS.ACTIV);              }            } catch (CancelledException ex) { @@ -149,6 +149,29 @@ public class PINManagementRequestHandler extends AbstractRequestHandler {                      new Object[] {selectedPIN.getLocalizedName()},                      this, null);              waitForAction(); +          } catch (PINConfirmationException ex) { +            log.error("confirmation pin does not match new " + selectedPIN.getLocalizedName()); +            gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_CONFIRMATION, +                    new Object[] {selectedPIN.getLocalizedName()}, +                    this, null); +            waitForAction(); +          } catch (PINOperationAbortedException ex) { +            log.error("pin operation aborted without further details"); +            gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_OPERATION_ABORTED, +                    new Object[] {selectedPIN.getLocalizedName()}, +                    this, null); +            waitForAction(); +          } catch (PINFormatException ex) { +            log.error("wrong format of new " + selectedPIN.getLocalizedName()); +//            updatePINStatus(selectedPIN, STATUS.NOT_ACTIV); +            String pinSize = String.valueOf(selectedPIN.getMinLength()); +            if (selectedPIN.getMinLength() != selectedPIN.getMaxLength()) { +                pinSize += "-" + selectedPIN.getMaxLength(); +            } +            gui.showErrorDialog(PINManagementGUIFacade.ERR_PIN_FORMAT, +                    new Object[] {selectedPIN.getLocalizedName(), pinSize}, +                    this, null); +            waitForAction();            }          } // end if diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java deleted file mode 100644 index a9ad5ef8..00000000 --- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/PinpadPINProviderFactory.java +++ /dev/null @@ -1,133 +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.smcc.ChangePINProvider; -import at.gv.egiz.bku.gui.BKUGUIFacade; -import at.gv.egiz.bku.gui.PINManagementGUIFacade; -import at.gv.egiz.bku.gui.PINManagementGUIFacade.DIALOG; -import at.gv.egiz.bku.smccstal.AbstractPINProvider; -import at.gv.egiz.smcc.CancelledException; -import at.gv.egiz.smcc.PINProvider; -import at.gv.egiz.smcc.PINSpec; - -/** - * - * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> - */ -public class PinpadPINProviderFactory extends ManagementPINProviderFactory { - -  protected PinpadPINProviderFactory(PINManagementGUIFacade gui) { -    this.gui = gui; -  } - -  @Override -  public PINProvider getVerifyPINProvider() { -    return new SimplePinProvider(DIALOG.VERIFY); -  } - -  @Override -  public PINProvider getActivatePINProvider() { -    return new SimplePinProvider(DIALOG.ACTIVATE); -  } - -  @Override -  public ChangePINProvider getChangePINProvider() { -    return new SimplePinProvider(DIALOG.CHANGE); -  } - -  @Override -  public PINProvider getUnblockPINProvider() { -    return new SimplePinProvider(DIALOG.UNBLOCK); -  } - - -  class SimplePinProvider extends AbstractPINProvider -          implements ChangePINProvider { - -//    protected PINManagementGUIFacade gui; -    protected PINManagementGUIFacade.DIALOG type; - -    private SimplePinProvider(PINManagementGUIFacade.DIALOG type) { -      this.type = type; -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      showPinpadPINDialog(retries, spec); -      retry = true; -      return null; -    } - -    /** -     * do not call this method without calling providePIN() -     * (no message is displayed) -     * @param spec -     * @param retries -     * @return -     */ -    @Override -    public char[] provideOldPIN(PINSpec spec, int retries) { -      return null; -    } - -    private void showPinpadPINDialog(int retries, PINSpec pinSpec) { -      String title, message; -      Object[] params; -      if (retry) { -        title = BKUGUIFacade.TITLE_RETRY; -        message = BKUGUIFacade.MESSAGE_RETRIES; -        params = new Object[]{String.valueOf(retries)}; -      } else if (type == DIALOG.VERIFY) { -        title = PINManagementGUIFacade.TITLE_VERIFY_PIN; -        message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD; -        String pinSize = String.valueOf(pinSpec.getMinLength()); -        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { -          pinSize += "-" + pinSpec.getMaxLength(); -        } -        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; -      } else if (type == DIALOG.ACTIVATE) { -        title = PINManagementGUIFacade.TITLE_ACTIVATE_PIN; -        message = PINManagementGUIFacade.MESSAGE_ACTIVATEPIN_PINPAD; -        String pinSize = String.valueOf(pinSpec.getMinLength()); -        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { -          pinSize += "-" + pinSpec.getMaxLength(); -        } -        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; -      } else if (type == DIALOG.CHANGE) { -        title = PINManagementGUIFacade.TITLE_CHANGE_PIN; -        message = PINManagementGUIFacade.MESSAGE_CHANGEPIN_PINPAD; -        String pinSize = String.valueOf(pinSpec.getMinLength()); -        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { -          pinSize += "-" + pinSpec.getMaxLength(); -        } -        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; -      } else { //if (type == DIALOG.UNBLOCK) { -        title = PINManagementGUIFacade.TITLE_UNBLOCK_PIN; -        message = PINManagementGUIFacade.MESSAGE_UNBLOCKPIN_PINPAD; -        String pinSize = String.valueOf(pinSpec.getMinLength()); -        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { -          pinSize += "-" + pinSpec.getMaxLength(); -        } -        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; -      } -      gui.showMessageDialog(title, message, params); -    } -  } -} diff --git a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java b/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java deleted file mode 100644 index e87512d0..00000000 --- a/BKUAppletExt/src/main/java/at/gv/egiz/bku/smccstal/ext/SoftwarePINProviderFactory.java +++ /dev/null @@ -1,148 +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.BKUGUIFacade; -import at.gv.egiz.smcc.ChangePINProvider; -import at.gv.egiz.bku.gui.PINManagementGUIFacade; -import at.gv.egiz.bku.gui.PINManagementGUIFacade.DIALOG; -import at.gv.egiz.bku.smccstal.AbstractPINProvider; -import at.gv.egiz.smcc.CancelledException; -import at.gv.egiz.smcc.PINProvider; -import at.gv.egiz.smcc.PINSpec; - -/** - * - * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> - */ -public class SoftwarePINProviderFactory extends ManagementPINProviderFactory { - -  protected SoftwarePINProviderFactory(PINManagementGUIFacade gui) { -    this.gui = gui; -  } - -  @Override -  public PINProvider getVerifyPINProvider() { -    return new SimplePinProvider(DIALOG.VERIFY); -  } - -  @Override -  public PINProvider getActivatePINProvider() { -    return new SimplePinProvider(DIALOG.ACTIVATE); -  } - -  @Override -  public ChangePINProvider getChangePINProvider() { -    return new ChangePinProvider(); -  } - -  @Override -  public PINProvider getUnblockPINProvider() { -    return new SimplePinProvider(DIALOG.UNBLOCK); -  } - -  class SimplePinProvider extends AbstractPINProvider { - -//    protected PINManagementGUIFacade gui; -    protected PINManagementGUIFacade.DIALOG type; - -    private SimplePinProvider(DIALOG type) { -      this.type = type; -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      gui.showPINDialog(type, spec, (retry) ? retries : -1, -              this, "exec", -              this, "back"); - -      waitForAction(); - -      if ("exec".equals(action)) { -        gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, -                BKUGUIFacade.MESSAGE_WAIT); -        retry = true; -        return gui.getPin(); -      } else if ("back".equals(action)) { -        throw new CancelledException(); -      } else { -        log.error("unsupported command " + action); -        throw new CancelledException(); -      } -    } -  } - -  class ChangePinProvider extends AbstractPINProvider -          implements ChangePINProvider { - -//    protected PINManagementGUIFacade gui; - -    private char[] oldPin; -    private char[] newPin; - -    private ChangePinProvider() { -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { -      if (newPin == null) { -        getPINs(spec, retries); -      } -      char[] pin = newPin; -      newPin = null; -      return pin; -    } - -    @Override -    public char[] provideOldPIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { -      if (oldPin == null) { -        getPINs(spec, retries); -      } -      char[] pin = oldPin; -      oldPin = null; -      return pin; -    } - -    private void getPINs(PINSpec spec, int retries) -            throws InterruptedException, CancelledException { - -      gui.showPINDialog(PINManagementGUIFacade.DIALOG.CHANGE, spec, -              (retry) ? retries : -1, -              this, "exec", -              this, "back"); - -      waitForAction(); - -      if ("exec".equals(action)) { -        gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, -                BKUGUIFacade.MESSAGE_WAIT); -        retry = true; -        oldPin = gui.getOldPin(); -        newPin = gui.getPin(); -      } else if ("back".equals(action)) { -        throw new CancelledException(); -      } else { -        log.error("unsupported command " + action); -        throw new CancelledException(); -      } -    } -  } -} 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 c6d219d4..15fc2827 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 @@ -55,9 +55,12 @@ 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>  err.verify=<html>VERIFY ERROR (TODO)</html> -err.retries=<html>Falscher {0}, noch {1} Versuche</html> +err.retries=<html>Falsche {0}, noch {1} Versuche</html>  err.locked=<html>{0} gesperrt.</html>  err.not.active=<html>{0} nicht aktiviert.</html> +err.pin.format=<html>Ung\u00FCltige {0} L\u00E4nge, verlangt sind {1} Stellen.</html> +err.pin.confirmation=<html>{0} und Best\u00E4tigung stimmen nicht \u00FCberein.</html> +err.pin.operation.aborted=<html>Der Vorgang f\u00FCr {0} wurde abgebrochen.</html>  status.not.active=NICHT AKTIV  status.active=AKTIV 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 b4bededf..8cc9d01a 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 @@ -55,6 +55,9 @@ err.unblock=<html>Unblocking of {0} is not supported.</html>  err.retries=<html>Wrong {0}, {1} tries remaining</html>  err.locked=<html>{0} locked</html>  err.not.active=<html>{0} not activated.</html> +err.pin.format=<html>Invalid {0} length, {1} digit(s) required.</html> +err.pin.confirmation=<html>{0} and confirmation do not match.</html> +err.pin.operation.aborted=<html>The operation on {0} was aborted.</html>  status.not.active=NOT ACTIVE  status.active=ACTIVE diff --git a/nbactions.xml b/nbactions.xml new file mode 100644 index 00000000..4c3d57a9 --- /dev/null +++ b/nbactions.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<actions> +        <action> +            <actionName>CUSTOM-Install_SkipTest</actionName> +            <displayName>Install_SkipTest</displayName> +            <goals> +                <goal>install</goal> +            </goals> +            <properties> +                <maven.test.skip>true</maven.test.skip> +            </properties> +        </action> +    </actions> 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 06e4a018..d064b821 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -401,15 +401,16 @@ public class ACOSCard extends AbstractSignatureCard {    @Override    protected int verifyPIN(byte kid, char[] pin) -          throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { +          throws LockedException, NotActivatedException, CancelledException, TimeoutException, PINFormatException, PINOperationAbortedException, SignatureCardException {      try {        byte[] sw;        if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { -        log.debug("verify PIN on IFD"); -        sw = reader.transmitControlCommand( -                CCID.FEATURE_VERIFY_PIN_DIRECT, -                getPINVerifyStructure(kid)); +        log.debug("verify pin on cardreader"); +        sw = reader.verifyPinDirect(getPINVerifyStructure(kid));  //        int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; +      } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { +        log.debug("verify pin on cardreader"); +        sw = reader.verifyPin(getPINVerifyStructure(kid));        } else {          byte[] pinBlock = encodePINBlock(pin);          CardChannel channel = getCardChannel(); @@ -442,6 +443,8 @@ public class ACOSCard extends AbstractSignatureCard {          throw new TimeoutException("[64:00]");        } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {          throw new CancelledException("[64:01]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { +        throw new PINFormatException("[64:03]");        }        log.error("Failed to verify pin: SW="                + SMCCHelper.toString(sw)); @@ -465,15 +468,15 @@ public class ACOSCard extends AbstractSignatureCard {     */    @Override    protected int changePIN(byte kid, char[] oldPin, char[] newPin) -          throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { +          throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {      try {         byte[] sw;        if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { -        log.debug("modify PIN on IFD"); -        sw = reader.transmitControlCommand( -                CCID.FEATURE_MODIFY_PIN_DIRECT, -                getPINModifyStructure(kid)); -//        int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; +        log.debug("modify pin on cardreader"); +        sw = reader.modifyPinDirect(getPINModifyStructure(kid)); +      } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { +        log.debug("modify pin on cardreader"); +        sw = reader.modifyPin(getPINModifyStructure(kid));        } else {          byte[] cmd = new byte[16];          System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8); @@ -504,6 +507,13 @@ public class ACOSCard extends AbstractSignatureCard {          throw new TimeoutException("[64:00]");        } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {          throw new CancelledException("[64:01]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) { +        throw new PINConfirmationException("[64:02]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { +        throw new PINFormatException("[64:03]"); +      } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) { +        log.info("invalid parameter, assume wrong pin size"); +        throw new PINFormatException("[6a:80]");        }        log.error("Failed to change pin: SW="                + SMCCHelper.toString(sw)); @@ -559,7 +569,7 @@ public class ACOSCard extends AbstractSignatureCard {        byte bmPINLengthFormat = (byte) 0x00;   // 000 0 0000                                                //     ^-------- System bit units is bit                                                //       ^^^^--- no PIN length -      byte wPINMaxExtraDigitL = +      byte wPINMaxExtraDigitL = //TODO compare ints, not bytes                (reader.getwPINMaxExtraDigitL() < (byte) 0x08) ?                  reader.getwPINMaxExtraDigitL() : (byte) 0x08;        byte wPINMaxExtraDigitH =                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 47c27369..7dd3ee78 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java @@ -29,21 +29,16 @@  package at.gv.egiz.smcc;  import at.gv.egiz.smcc.ccid.CCID; -import at.gv.egiz.smcc.ccid.DefaultReader;  import at.gv.egiz.smcc.ccid.ReaderFactory;  import at.gv.egiz.smcc.util.SMCCHelper;  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 java.util.logging.Level; -import java.util.logging.Logger;  import javax.smartcardio.ATR;  import javax.smartcardio.Card;  import javax.smartcardio.CardChannel; @@ -152,8 +147,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {     * @throws at.gv.egiz.smcc.SignatureCardException     */    protected abstract int verifyPIN(byte kid, char[] pin) -          throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException; - +          throws LockedException, NotActivatedException, CancelledException, PINFormatException, TimeoutException, PINOperationAbortedException, SignatureCardException; +      /**     * CHANGE(?) APDU     * If IFD supports VERIFY_PIN on pinpad, parameter pin may be empty. @@ -162,7 +157,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {     * @throws at.gv.egiz.smcc.SignatureCardException if activation fails     */    protected abstract void activatePIN(byte kid, char[] pin) -          throws CancelledException, TimeoutException, SignatureCardException; +          throws CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException;    /**     * CHANGE(?) APDU @@ -173,7 +168,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {     * @throws at.gv.egiz.smcc.SignatureCardException if change fails     */    protected abstract int changePIN(byte kid, char[] oldPin, char[] newPin) -          throws CancelledException, TimeoutException, SignatureCardException; +          throws LockedException, NotActivatedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException;    /**     * encode the pin as needed in VERIFY/CHANGE APDUs @@ -595,7 +590,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {     */    @Override    public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider) -          throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException, InterruptedException { +          throws LockedException, NotActivatedException, CancelledException, +          TimeoutException, SignatureCardException, InterruptedException {      try {        getCard().beginExclusive(); diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java new file mode 100644 index 00000000..115e6d5f --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/PINConfirmationException.java @@ -0,0 +1,43 @@ +/* +* 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.smcc; + +/** + * TODO check whether card readers distinguish specific reason (pin too short?) + * and add getters/setters + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class PINConfirmationException extends SignatureCardException { + +  public PINConfirmationException() { +    super(); +  } + +  public PINConfirmationException(String message, Throwable cause) { +    super(message, cause); +  } + +  public PINConfirmationException(String message) { +    super(message); +  } + +  public PINConfirmationException(Throwable cause) { +    super(cause); +  } + +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java new file mode 100644 index 00000000..28a13fdb --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/PINFormatException.java @@ -0,0 +1,43 @@ +/* +* 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.smcc; + +/** + * TODO check whether card readers distinguish specific reason (pin too short?) + * and add getters/setters + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class PINFormatException extends SignatureCardException { + +  public PINFormatException() { +    super(); +  } + +  public PINFormatException(String message, Throwable cause) { +    super(message, cause); +  } + +  public PINFormatException(String message) { +    super(message); +  } + +  public PINFormatException(Throwable cause) { +    super(cause); +  } + +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java b/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java new file mode 100644 index 00000000..7337f59e --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/PINOperationAbortedException.java @@ -0,0 +1,43 @@ +/* +* 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.smcc; + +/** + * TODO check whether card readers distinguish specific reason (pin too short?) + * and add getters/setters + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class PINOperationAbortedException extends SignatureCardException { + +  public PINOperationAbortedException() { +    super(); +  } + +  public PINOperationAbortedException(String message, Throwable cause) { +    super(message, cause); +  } + +  public PINOperationAbortedException(String message) { +    super(message); +  } + +  public PINOperationAbortedException(Throwable cause) { +    super(cause); +  } + +} 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 bc6a2316..b9c68b06 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java @@ -28,7 +28,7 @@  //  package at.gv.egiz.smcc; -import at.gv.egiz.smcc.ccid.DefaultReader; +import at.gv.egiz.smcc.ccid.CCID;  import at.gv.egiz.smcc.util.SMCCHelper;  import java.util.Arrays;  import javax.smartcardio.CardChannel; @@ -319,6 +319,8 @@ public class STARCOSCard extends AbstractSignatureCard {              return createSignature(hash, AID_DF_SS, pin, KID_PIN_SS, DST_SS);            } catch (VerificationFailedException e) {              retries = e.getRetries(); +          } catch (PINFormatException e) { +            log.debug("wrong pin size entered, retry");            } finally {              getCard().endExclusive();            } @@ -454,15 +456,16 @@ public class STARCOSCard extends AbstractSignatureCard {    @Override    protected int verifyPIN(byte kid, char[] pin) -          throws LockedException, NotActivatedException, SignatureCardException { +          throws LockedException, NotActivatedException, TimeoutException, CancelledException, PINFormatException, PINOperationAbortedException, SignatureCardException {      try {        byte[] sw; -      if (reader.hasFeature(DefaultReader.FEATURE_VERIFY_PIN_DIRECT)) { -        log.debug("verify PIN on IFD"); -        sw = reader.transmitControlCommand( -                DefaultReader.FEATURE_VERIFY_PIN_DIRECT, -                getPINVerifyStructure(kid)); +      if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +        log.debug("verify pin on cardreader"); +        sw = reader.verifyPinDirect(getPINVerifyStructure(kid));  //        int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; +      } else if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START)) { +        log.debug("verify pin on cardreader"); +        sw = reader.verifyPin(getPINVerifyStructure(kid));        } else {          byte[] pinBlock = encodePINBlock(pin);          CardChannel channel = getCardChannel(); @@ -492,6 +495,8 @@ public class STARCOSCard extends AbstractSignatureCard {          throw new TimeoutException("[64:00]");        } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {          throw new CancelledException("[64:01]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { +        throw new PINFormatException("[64:03]");        }        log.error("Failed to verify pin: SW="                + SMCCHelper.toString(sw)); @@ -539,15 +544,15 @@ public class STARCOSCard extends AbstractSignatureCard {    @Override    protected int changePIN(byte kid, char[] oldPin, char[] newPin) -          throws LockedException, NotActivatedException, CancelledException, TimeoutException, SignatureCardException { +          throws LockedException, CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {      try {        byte[] sw; -      if (reader.hasFeature(DefaultReader.FEATURE_MODIFY_PIN_DIRECT)) { -        log.debug("modify PIN on IFD"); -        sw = reader.transmitControlCommand( -                DefaultReader.FEATURE_MODIFY_PIN_DIRECT, -                getPINModifyStructure(kid)); -//        int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; +      if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { +        log.debug("modify pin on cardreader"); +        sw = reader.modifyPinDirect(getPINModifyStructure(kid)); +      } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { +        log.debug("modify pin on cardreader"); +        sw = reader.modifyPin(getPINModifyStructure(kid));        } else {          byte[] cmd = new byte[16];          System.arraycopy(encodePINBlock(oldPin), 0, cmd, 0, 8); @@ -583,6 +588,13 @@ public class STARCOSCard extends AbstractSignatureCard {          throw new TimeoutException("[64:00]");        } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {          throw new CancelledException("[64:01]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) { +        throw new PINConfirmationException("[64:02]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { +        throw new PINFormatException("[64:03]"); +      } else if (sw[0] == (byte) 0x6a && sw[1] == (byte) 0x80) { +        log.info("invalid parameter, assume wrong pin size"); +        throw new PINFormatException("[6a:80]");        }        log.error("Failed to change pin: SW="                + SMCCHelper.toString(sw)); @@ -595,15 +607,15 @@ public class STARCOSCard extends AbstractSignatureCard {    @Override    protected void activatePIN(byte kid, char[] pin) -          throws CancelledException, TimeoutException, SignatureCardException { +          throws CancelledException, PINFormatException, PINConfirmationException, TimeoutException, PINOperationAbortedException, SignatureCardException {      try {        byte[] sw; -      if (reader.hasFeature(DefaultReader.FEATURE_MODIFY_PIN_DIRECT)) { -        log.debug("activate PIN on IFD"); -        sw = reader.transmitControlCommand( -                DefaultReader.FEATURE_MODIFY_PIN_DIRECT, -                getActivatePINModifyStructure(kid)); -//        int sw = (resp[resp.length-2] & 0xff) << 8 | resp[resp.length-1] & 0xff; +      if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_DIRECT)) { +        log.debug("activate pin on cardreader"); +        sw = reader.modifyPinDirect(getActivatePINModifyStructure(kid)); +      } else if (reader.hasFeature(CCID.FEATURE_MODIFY_PIN_START)) { +        log.debug("activate pin on cardreader"); +        sw = reader.modifyPin(getActivatePINModifyStructure(kid));        } else {          CardChannel channel = getCardChannel();          ResponseAPDU resp = transmit(channel, @@ -630,6 +642,10 @@ public class STARCOSCard extends AbstractSignatureCard {          throw new TimeoutException("[64:00]");        } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x01) {          throw new CancelledException("[64:01]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x02) { +        throw new PINConfirmationException("[64:02]"); +      } else if (sw[0] == (byte) 0x64 && sw[1] == (byte) 0x03) { +        throw new PINFormatException("[64:03]");        }        log.error("Failed to activate pin: SW="                + SMCCHelper.toString(sw)); @@ -683,6 +699,7 @@ public class STARCOSCard extends AbstractSignatureCard {        byte bmPINLengthFormat = (byte) 0x04;   // 000 0 0100                                                //     ^-------- System bit units is bit                                                //       ^^^^--- PIN length is at the 4th position bit +      //TODO compare ints, not bytes        byte wPINMaxExtraDigitL =               // Max=12 digits (Gemplus support max 8)                (reader.getwPINMaxExtraDigitL() < (byte) 0x12) ?                  reader.getwPINMaxExtraDigitL() : (byte) 0x12; 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 253ac7a0..2ed1fe64 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java @@ -430,13 +430,6 @@ public class SWCard implements SignatureCard {        }        @Override -      public byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) -              throws SignatureCardException { -        throw new SignatureCardException(CCID.FEATURES[feature.intValue()] + -                " not supported"); -      } - -      @Override        public byte getbTimeOut() {          return 0;        } @@ -465,6 +458,31 @@ public class SWCard implements SignatureCard {        public Card connect() {          return null;        } + +      @Override +      public String getName() { +        return "Software CardReader"; +      } + +      @Override +      public byte[] verifyPin(byte[] PIN_VERIFY) throws CardException { +        throw new UnsupportedOperationException("Not supported yet."); +      } + +      @Override +      public byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException { +        throw new UnsupportedOperationException("Not supported yet."); +      } + +      @Override +      public byte[] modifyPin(byte[] PIN_MODIFY) throws CardException { +        throw new UnsupportedOperationException("Not supported yet."); +      } + +      @Override +      public byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException { +        throw new UnsupportedOperationException("Not supported yet."); +      }      };    }  } 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 ad530ad5..c06074f2 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java @@ -128,7 +128,7 @@ public interface SignatureCard {            throws LockedException, NotActivatedException, CancelledException, SignatureCardException, InterruptedException;    public void changePIN(PINSpec pinSpec, ChangePINProvider pinProvider) -          throws LockedException, NotActivatedException, CancelledException, SignatureCardException, InterruptedException; +          throws LockedException, NotActivatedException, CancelledException, PINFormatException, SignatureCardException, InterruptedException;    public void activatePIN(PINSpec pinSpec, PINProvider pinProvider)            throws CancelledException, SignatureCardException, InterruptedException; diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java index 2c56ce98..56ebaffe 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java @@ -45,17 +45,48 @@ public interface CCID {      "FEATURE_WRITE_DISPLAY",      "FEATURE_GET_KEY",      "FEATURE_IFD_DISPLAY_PROPERTIES"}; -   -  Byte FEATURE_IFD_PIN_PROPERTIES = new Byte((byte) 10); -  Byte FEATURE_MCT_READER_DIRECT = new Byte((byte) 8); -  Byte FEATURE_MODIFY_PIN_DIRECT = new Byte((byte) 7); -  Byte FEATURE_VERIFY_PIN_DIRECT = new Byte((byte) 6); -   + +  Byte FEATURE_VERIFY_PIN_START = new Byte((byte) 0x01); +  Byte FEATURE_VERIFY_PIN_FINISH = new Byte((byte) 0x02); +  Byte FEATURE_MODIFY_PIN_START = new Byte((byte) 0x03); +  Byte FEATURE_MODIFY_PIN_FINISH = new Byte((byte) 0x04); +  Byte FEATURE_GET_KEY_PRESSED = new Byte((byte) 0x05); +  Byte FEATURE_VERIFY_PIN_DIRECT = new Byte((byte) 0x06); +  Byte FEATURE_MODIFY_PIN_DIRECT = new Byte((byte) 0x07); +  Byte FEATURE_MCT_READER_DIRECT = new Byte((byte) 0x08); +  Byte FEATURE_MCT_UNIVERSAL = new Byte((byte) 0x09); +  Byte FEATURE_IFD_PIN_PROPERTIES = new Byte((byte) 0x0a); +  //TODO continue list + +  String getName(); +    Card connect() throws CardException;    boolean hasFeature(Byte feature);    /** +   * not supported by OMNIKEY CardMan 3621 with ACOS card +   * @param PIN_VERIFY +   * @return +   * @throws at.gv.egiz.smcc.PINOperationAbortedException +   * @throws javax.smartcardio.CardException +   */ +  byte[] verifyPin(byte[] PIN_VERIFY) throws PINOperationAbortedException, CardException; +   +  byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException; + +  /** +   * not supported by OMNIKEY CardMan 3621 with ACOS card +   * @param PIN_MODIFY +   * @return +   * @throws at.gv.egiz.smcc.PINOperationAbortedException +   * @throws javax.smartcardio.CardException +   */ +  byte[] modifyPin(byte[] PIN_MODIFY) throws PINOperationAbortedException, CardException; + +  byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException; + +  /**     *     * @param feature the corresponding control code will be transmitted     * @param ctrlCommand @@ -63,7 +94,7 @@ public interface CCID {     * @throws at.gv.egiz.smcc.SignatureCardException if feature is not supported     * or card communication fails     */ -  byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) throws SignatureCardException; +//  byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) throws SignatureCardException;    /**     * allow subclasses to override default (deal with reader bugs) diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java index 2cc77dc9..9b1787a0 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java @@ -20,6 +20,8 @@ import at.gv.egiz.smcc.*;  import at.gv.egiz.smcc.util.SMCCHelper;  import java.util.HashMap;  import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger;  import javax.smartcardio.Card;  import javax.smartcardio.CardException;  import javax.smartcardio.CardTerminal; @@ -35,12 +37,17 @@ public class DefaultReader implements CCID {    protected final static Log log = LogFactory.getLog(DefaultReader.class);    private static int CTL_CODE(int code) { -    return 0x42000000 + code; +    String os_name = System.getProperty("os.name").toLowerCase(); +    if (os_name.indexOf("windows") > -1) { +      // cf. WinIOCTL.h +      return (0x31 << 16 | (code) << 2); +    } +    // cf. reader.h +    return 0x42000000 + (code);    }    int IOCTL_GET_FEATURE_REQUEST = CTL_CODE(3400); -    protected Card icc;    protected CardTerminal ct; @@ -58,14 +65,19 @@ public class DefaultReader implements CCID {      features = queryFeatures();     } -  public Card connect() throws CardException { //SignatureCardException { -//      try { +  /** +   * +   * @return the card terminals name +   */ +  @Override +  public String getName() { +    return ct.getName(); +  } + +  @Override +  public Card connect() throws CardException {       icc = ct.connect("*");      return icc; -//      } catch (CardException ex) { -//        log.error(ex.getMessage(), ex); -//        throw new SignatureCardException("Failed to connect to card: " + ex.getMessage()); -//      }    }    Map<Byte, Integer> queryFeatures() { @@ -81,7 +93,7 @@ public class DefaultReader implements CCID {                    " on " + ct.getName());          }          byte[] resp = icc.transmitControlCommand(IOCTL_GET_FEATURE_REQUEST, -                new byte[]{}); +                new byte[0]);          if (log.isTraceEnabled()) {            log.trace("Response TLV " + SMCCHelper.toString(resp)); @@ -91,8 +103,10 @@ public class DefaultReader implements CCID {          // control code value for supported feature (in big endian)          for (int i = 0; i < resp.length; i += 6) {            Byte feature = new Byte(resp[i]); -          int ioctlBigEndian = (resp[i + 2] << 24) | -                  (resp[i + 3] << 16) | (resp[i + 4] << 8) | resp[i + 5]; +          int ioctlBigEndian = ((0xff & resp[i + 2]) << 24) | +                  ((0xff & resp[i + 3]) << 16) | +                  ((0xff & resp[i + 4]) << 8) | +                  (0xff & resp[i + 5]);            Integer ioctl = new Integer(ioctlBigEndian);            if (log.isInfoEnabled()) {              log.info("CCID supports " + FEATURES[feature.intValue()] + @@ -117,37 +131,29 @@ public class DefaultReader implements CCID {      return false;    } -//  public Integer getIOCTL(Byte feature) { -//    if (features != null) { -//      return features.get(feature); +//  protected byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) +//          throws CardException { +//    try { +//      if (!features.containsKey(feature)) { +//        throw new CardException(FEATURES[feature.intValue()] + " not supported"); +//      } +//      int ioctl = features.get(feature); +//      if (log.isTraceEnabled()) { +//        log.trace("CtrlCommand (" + Integer.toHexString(ioctl) + +//                ")  " + SMCCHelper.toString(ctrlCommand)); +//      } +//      byte[] resp = icc.transmitControlCommand(ioctl, ctrlCommand); +//      if (log.isTraceEnabled()) { +//        log.trace("CtrlCommand Response " + SMCCHelper.toString(resp)); +//      } +//      return resp; +//    } catch (CardException ex) { +//      log.error(ex.getMessage()); +//      throw new SignatureCardException("Failed to transmit CtrlCommand for " + +//              FEATURES[feature.intValue()]);  //    } -//    return null;  //  } -  @Override -  public byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) -          throws SignatureCardException { -    try { -      if (!features.containsKey(feature)) { -        throw new SignatureCardException(FEATURES[feature.intValue()] + " not supported"); -      } -      int ioctl = features.get(feature); -      if (log.isTraceEnabled()) { -        log.trace("CtrlCommand (" + Integer.toHexString(ioctl) + -                ")  " + SMCCHelper.toString(ctrlCommand)); -      } -      byte[] resp = icc.transmitControlCommand(ioctl, ctrlCommand); -      if (log.isTraceEnabled()) { -        log.trace("CtrlCommand Response " + SMCCHelper.toString(resp)); -      } -      return resp; -    } catch (CardException ex) { -      log.error(ex.getMessage()); -      throw new SignatureCardException("Failed to transmit CtrlCommand for " + -              FEATURES[feature.intValue()]); -    } -  } -    @Override    public byte getbTimeOut() { @@ -162,7 +168,7 @@ public class DefaultReader implements CCID {    @Override    public byte getwPINMaxExtraDigitL() { -    return (byte) 0x12; +    return (byte) 0x12;     // signed int    }    @Override @@ -175,6 +181,265 @@ public class DefaultReader implements CCID {      return (byte) 0x02;    // validation key pressed    } +  void verifyPinStart(byte[] PIN_VERIFY) throws CardException { +    if (!features.containsKey(FEATURE_VERIFY_PIN_START)) { +      throw new CardException("FEATURE_VERIFY_PIN_START not supported"); +    } +    int ioctl = features.get(FEATURE_VERIFY_PIN_START); +    if (log.isTraceEnabled()) { +      log.trace("VERIFY_PIN_START (" + Integer.toHexString(ioctl) + +              ")  " + SMCCHelper.toString(PIN_VERIFY)); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, PIN_VERIFY); +    if (resp != null && resp.length > 0) { +      if (resp[0] == (byte) 0x57) { +        log.error("Invalid parameter in PIN_VERIFY structure"); +        throw new CardException("ERROR_INVALID_PARAMETER"); +      } else { +        log.error("unexpected response to VERIFY_PIN_START: " + +                SMCCHelper.toString(resp)); +        throw new CardException("unexpected response to VERIFY_PIN_START: " + +                SMCCHelper.toString(resp)); +      } +    } +  } + +  byte[] verifyPinFinish() throws CardException { +    if (!features.containsKey(FEATURE_VERIFY_PIN_FINISH)) { +      throw new CardException("FEATURE_VERIFY_FINISH_FINISH not supported"); +    } +    int ioctl = features.get(FEATURE_VERIFY_PIN_FINISH); +    if (log.isTraceEnabled()) { +      log.trace("VERIFY_PIN_FINISH (" + Integer.toHexString(ioctl) + ")"); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]); +    if (resp != null && resp.length == 2) { +      if (log.isTraceEnabled()) { +        log.trace("response " + SMCCHelper.toString(resp)); +      } +      return resp; +    } +    log.error("unexpected response to VERIFY_PIN_FINISH: " + +            SMCCHelper.toString(resp)); +    throw new CardException("unexpected response to VERIFY_PIN_FINISH: " + +            SMCCHelper.toString(resp)); +  } + +  void modifyPinStart(byte[] PIN_MODIFY) throws CardException { +    if (!features.containsKey(FEATURE_MODIFY_PIN_START)) { +      throw new CardException("FEATURE_MODIFY_PIN_START not supported"); +    } +    int ioctl = features.get(FEATURE_MODIFY_PIN_START); +    if (log.isTraceEnabled()) { +      log.trace("MODFIY_PIN_START (" + Integer.toHexString(ioctl) + +              ")  " + SMCCHelper.toString(PIN_MODIFY)); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, PIN_MODIFY); +    if (resp != null && resp.length > 0) { +      if (resp[0] == (byte) 0x57) { +        log.error("Invalid parameter in PIN_MODIFY structure"); +        throw new CardException("ERROR_INVALID_PARAMETER"); +      } else { +        log.error("unexpected response to MODIFY_PIN_START: " + +                SMCCHelper.toString(resp)); +        throw new CardException("unexpected response to MODIFY_PIN_START: " + +                SMCCHelper.toString(resp)); +      } +    } +  } + +  byte[] modifyPinFinish() throws CardException { +    if (!features.containsKey(FEATURE_MODIFY_PIN_FINISH)) { +      throw new CardException("FEATURE_MODIFY_FINISH_FINISH not supported"); +    } +    int ioctl = features.get(FEATURE_MODIFY_PIN_FINISH); +    if (log.isTraceEnabled()) { +      log.trace("MODIFY_PIN_FINISH (" + Integer.toHexString(ioctl) + ")"); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]); +    if (resp != null && resp.length == 2) { +      if (log.isTraceEnabled()) { +        log.trace("response " + SMCCHelper.toString(resp)); +      } +      return resp; +    } +    log.error("unexpected response to MODIFY_PIN_FINISH: " + +            SMCCHelper.toString(resp)); +    throw new CardException("unexpected response to MODIFY_PIN_FINISH: " + +            SMCCHelper.toString(resp)); +  } + + +  byte getKeyPressed() throws CardException { +    if (!features.containsKey(FEATURE_GET_KEY_PRESSED)) { +      throw new CardException("FEATURE_GET_KEY_PRESSED not supported"); +    } +    int ioctl = features.get(FEATURE_GET_KEY_PRESSED); +//    if (log.isTraceEnabled()) { +//      log.trace("GET_KEY_PRESSED (" + Integer.toHexString(ioctl) + ")"); +//    } +    byte[] resp = icc.transmitControlCommand(ioctl, new byte[0]); +    if (resp != null && resp.length == 1) { +//      if (log.isTraceEnabled()) { +//        log.trace("response " + SMCCHelper.toString(resp)); +//      } +      return resp[0]; +    } +    log.error("unexpected response to GET_KEY_PRESSED: " + +            SMCCHelper.toString(resp)); +    throw new CardException("unexpected response to GET_KEY_PRESSED: " + +            SMCCHelper.toString(resp)); +  } + + + +  @Override +  public byte[] verifyPinDirect(byte[] PIN_VERIFY) throws CardException { +    if (!features.containsKey(FEATURE_VERIFY_PIN_DIRECT)) { +      throw new CardException("FEATURE_VERIFY_PIN_DIRECT not supported"); +    } +    int ioctl = features.get(FEATURE_VERIFY_PIN_DIRECT); +    if (log.isTraceEnabled()) { +      log.trace("VERIFY_PIN_DIRECT (" + Integer.toHexString(ioctl) + +              ")  " + SMCCHelper.toString(PIN_VERIFY)); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, PIN_VERIFY); +    if (log.isTraceEnabled()) { +      log.trace("response " + SMCCHelper.toString(resp)); +    } +    return resp; +  } + +  @Override +  public byte[] verifyPin(byte[] PIN_VERIFY) throws PINOperationAbortedException, CardException { +    verifyPinStart(PIN_VERIFY); +    byte resp; +    do { +      resp = getKeyPressed(); +      if (resp == (byte) 0x00) { +        synchronized(this) { +          try { +            wait(200); +          } catch (InterruptedException ex) { +            log.error("interrupted in VERIFY_PIN"); +          } +        } +      } else if (resp == (byte) 0x0d) { +        log.trace("user confirmed"); +        break; +      } else if (resp == (byte) 0x2b) { +        log.trace("user entered valid key (0-9)"); +      } else if (resp == (byte) 0x1b) { +        log.info("user cancelled VERIFY_PIN via cancel button"); +        return verifyPinFinish(); +//        return new byte[] { (byte) 0x64, (byte) 0x01 }; +      } else if (resp == (byte) 0x08) { +        log.trace("user pressed correction/backspace button"); +      } else if (resp == (byte) 0x0e) { +        log.trace("timeout occured"); +        return verifyPinFinish(); // return 0x64 0x00 +      } else if (resp == (byte) 0x40) { +        log.trace("PIN_Operation_Aborted"); +        throw new PINOperationAbortedException("PIN_Operation_Aborted"); +      } else if (resp == (byte) 0x0a) { +        log.trace("all keys cleared"); +      } else { +        log.error("unexpected response to GET_KEY_PRESSED: " + +            Integer.toHexString(resp)); +        throw new CardException("unexpected response to GET_KEY_PRESSED: " + +            Integer.toHexString(resp)); +      } +    } while (true); //resp != (byte) 0x0d); + +    return verifyPinFinish(); +  } + +  @Override +  public byte[] modifyPin(byte[] PIN_MODIFY) throws PINOperationAbortedException, CardException { +    modifyPinStart(PIN_MODIFY); +    log.debug(PIN_MODIFY[9] + " pin confirmations expected"); + +    byte resp; +    short pinConfirmations = 0; +    do { +      resp = getKeyPressed(); +      if (resp == (byte) 0x00) { +        synchronized(this) { +          try { +            wait(200); +          } catch (InterruptedException ex) { +            log.error("interrupted in MODIFY_PIN"); +          } +        } +      } else if (resp == (byte) 0x0d) { +        log.trace("user confirmed"); +        pinConfirmations++; +        continue; +      } else if (resp == (byte) 0x2b) { +        log.trace("user entered valid key (0-9)"); +      } else if (resp == (byte) 0x1b) { +        log.info("user cancelled MODIFY_PIN via cancel button"); +//        return verifyPinFinish(); +        return new byte[] { (byte) 0x64, (byte) 0x01 }; +      } else if (resp == (byte) 0x08) { +        log.trace("user pressed correction/backspace button"); +      } else if (resp == (byte) 0x0e) { +        log.trace("timeout occured"); +        return new byte[] { (byte) 0x64, (byte) 0x00 }; +//        return verifyPinFinish(); // return 0x64 0x00 +      } else if (resp == (byte) 0x40) { +        log.trace("PIN_Operation_Aborted"); +        throw new PINOperationAbortedException("PIN_Operation_Aborted"); +      } else if (resp == (byte) 0x0a) { +        log.trace("all keys cleared"); +      } else { +        log.error("unexpected response to GET_KEY_PRESSED: " + +            Integer.toHexString(resp)); +        throw new CardException("unexpected response to GET_KEY_PRESSED: " + +            Integer.toHexString(resp)); +      } +    } while (pinConfirmations < PIN_MODIFY[9]);  + +    return modifyPinFinish(); +  } + +  /** +   * NOT SUPPORTED FOR ACOS ON OMNIKEY CardMan 3621 +   *  +   * @param PIN_MODIFY +   * @return +   * @throws javax.smartcardio.CardException +   */ +  @Override +  public byte[] modifyPinDirect(byte[] PIN_MODIFY) throws CardException { +    if (!features.containsKey(FEATURE_MODIFY_PIN_DIRECT)) { +      throw new CardException("FEATURE_MODIFY_PIN_DIRECT not supported"); +    } +    int ioctl = features.get(FEATURE_MODIFY_PIN_DIRECT); +    if (log.isTraceEnabled()) { +      log.trace("MODIFY_PIN_DIRECT (" + Integer.toHexString(ioctl) + +              ")  " + SMCCHelper.toString(PIN_MODIFY)); +    } +    byte[] resp = icc.transmitControlCommand(ioctl, PIN_MODIFY); +    if (log.isTraceEnabled()) { +      log.trace("response " + SMCCHelper.toString(resp)); +    } +    return resp; +  } + + +//[TRACE] SmartCardIO - terminal 'PC/SC terminal OMNIKEY CardMan 3621 0' card inserted : PC/SC card in OMNIKEY CardMan 3621 0, protocol T=1, state OK +//[TRACE] DefaultReader - GET_FEATURE_REQUEST 313520 on OMNIKEY CardMan 3621 0 +//[TRACE] DefaultReader - Response TLV [01:04:00:31:30:00:02:04:00:31:2f:d4:03:04:00:31:30:04:04:04:00:31:2f:dc:05:04:00:31:2f:e0:0a:04 +//00:31:30:08] +//[INFO] DefaultReader - CCID supports FEATURE_VERIFY_PIN_START: 313000 +//[INFO] DefaultReader - CCID supports FEATURE_VERIFY_PIN_FINISH: ffffffd4 +//[INFO] DefaultReader - CCID supports FEATURE_MODIFY_PIN_START: 313004 +//[INFO] DefaultReader - CCID supports FEATURE_MODIFY_PIN_FINISH: ffffffdc +//[INFO] DefaultReader - CCID supports FEATURE_GET_KEY_PRESSED: ffffffe0 +//[INFO] DefaultReader - CCID supports FEATURE_IFD_PIN_PROPERTIES: 313008 +//[TRACE] AbstractSignatureCard - Setting IFS (information field size) to 254 +    //  protected byte ifdGetKeyPressed() throws CardException {  //    if (ifdSupportsFeature(FEATURE_VERIFY_PIN_DIRECT)) { diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java new file mode 100644 index 00000000..35dd4f99 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java @@ -0,0 +1,39 @@ +/* + * 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.smcc.ccid; + +import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Fails with ACOS cards (Problem might be 'short' VERIFY which is not supported by ACOS) + * TODO + * + * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> + */ +public class OMNIKEYCardMan3621 extends DefaultReader { + +  protected static final Log log = LogFactory.getLog(OMNIKEYCardMan3621.class); +   +  public OMNIKEYCardMan3621(Card icc, CardTerminal ct) { +    super(icc, ct); +    log.warn("This card reader does not support ACOS cards."); +    log.debug("TODO: fall back to software pin entry"); +  } +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java index 2cfcef19..07c16c3e 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java @@ -29,6 +29,8 @@ public class ReaderFactory {    public static CCID getReader(Card icc, CardTerminal ct) {      if ("Gemplus GemPC Pinpad 00 00".equals(ct.getName())) {        return new GemplusGemPCPinpad(icc, ct); +    } else if ("OmniKey CardMan 3621 00 00".equals(ct.getName())) { +      return new OMNIKEYCardMan3621(icc, ct);      }      return new DefaultReader(icc, ct);    } diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java index 94444922..eeb97290 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java @@ -37,21 +37,20 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {    private static Log log = LogFactory.getLog(InfoBoxReadRequestHandler.class); -  protected PINProviderFactory pinProviderFactory; +//  protected PINProviderFactory pinProviderFactory;    @Override    public STALResponse handleRequest(STALRequest request) throws InterruptedException {      if (request instanceof InfoboxReadRequest) {        InfoboxReadRequest infoBox = (InfoboxReadRequest) request; -      if (pinProviderFactory == null) { -        pinProviderFactory = PINProviderFactory.getInstance(card, gui); -      } +              try {          if (infoBox.getInfoboxIdentifier().equals("IdentityLink")) {            newSTALMessage("Message.RequestCaption", "Message.IdentityLink");            log.debug("Handling identitylink infobox");            byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(), -                  pinProviderFactory.getCardPINProvider(), +                  new PINProviderFactory(card.getReader(), gui) +                  .getCardPINProvider(),                    infoBox.getDomainIdentifier());            if (resp == null) {              log.info("Got null as result->user cancelled"); @@ -98,7 +97,8 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler {            log.warn("Unknown infobox identifier: "                + infoBox.getInfoboxIdentifier() + " trying generic request");            byte[] resp = card.getInfobox(infoBox.getInfoboxIdentifier(), -                  pinProviderFactory.getCardPINProvider(), +                  new PINProviderFactory(card.getReader(), gui) +                  .getCardPINProvider(),                    infoBox.getDomainIdentifier());            if (resp == null) {              return new ErrorResponse(6001); diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java index ce1b2d00..78ae6c2b 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java @@ -18,31 +18,305 @@  package at.gv.egiz.bku.smccstal;  import at.gv.egiz.bku.gui.BKUGUIFacade; +import at.gv.egiz.smcc.CancelledException;  import at.gv.egiz.smcc.ccid.CCID;  import at.gv.egiz.smcc.PINProvider; -import at.gv.egiz.smcc.SignatureCard; +import at.gv.egiz.smcc.PINSpec;  import at.gv.egiz.stal.signedinfo.SignedInfoType; +import java.security.DigestException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory;  /**   *   * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at>   */ -public abstract class PINProviderFactory { +public class PINProviderFactory { + +  protected static final Log log = LogFactory.getLog(PINProviderFactory.class); + +  protected CCID reader; +  protected BKUGUIFacade gui; + +  /** +   * don't reuse the instance if the card reader might have changed! +   * @param reader +   * @param gui +   */ +  public PINProviderFactory(CCID reader, BKUGUIFacade gui) { +    log.trace("PINProviderFactory for " + reader.getName()); +    this.reader = reader; +    this.gui = gui; +  } + -  BKUGUIFacade gui; -  public static PINProviderFactory getInstance(SignatureCard forCard, -          BKUGUIFacade gui) { -    if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { -      return new PinpadPINProviderFactory(gui); +//  public static PINProviderFactory getInstance(SignatureCard forCard, +//          BKUGUIFacade gui) { +//    if (forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT) || +//            forCard.getReader().hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +//      return new PinpadPINProviderFactory(gui); +//    } else { +//      return new SoftwarePINProviderFactory(gui); +//    } +//  } + +  /** +   * don't reuse the instance if the card reader might have changed! +   * @param reader +   * @param gui +   * @return +   */ +//  public static PINProviderFactory getInstance(CCID reader, BKUGUIFacade gui) { +//    log.trace("PINProviderFactory for " + reader.getName()); +//    return new PINProviderFactory(reader, gui); +//  } + +  public PINProvider getSignaturePINProvider(SecureViewer viewer, +          SignedInfoType signedInfo) { +    if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START) || +            reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +      log.debug("pinpad signature-pin provider"); +      return new PinpadSignaturePinProvider(viewer, signedInfo);      } else { -      return new SoftwarePINProviderFactory(gui); +      log.debug("software signature-pin provider"); +      return new SoftwareSignaturePinProvider(viewer, signedInfo);      }    } -  public abstract PINProvider getSignaturePINProvider(SecureViewer viewer, -          SignedInfoType signedInfo); -   -  public abstract PINProvider getCardPINProvider(); +  public PINProvider getCardPINProvider() { +    if (reader.hasFeature(CCID.FEATURE_VERIFY_PIN_START) || +            reader.hasFeature(CCID.FEATURE_VERIFY_PIN_DIRECT)) { +      log.debug("pinpad card-pin provider"); +      return new PinpadCardPinProvider(); +    } else { +      log.debug("software card-pin provider"); +      return new SoftwareCardPinProvider(); +    } +  } + +  class SoftwareSignaturePinProvider extends AbstractPINProvider { + +    protected SecureViewer viewer; +    protected SignedInfoType signedInfo; + +    private SoftwareSignaturePinProvider(SecureViewer viewer, +            SignedInfoType signedInfo) { +      this.viewer = viewer; +      this.signedInfo = signedInfo; +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      gui.showSignaturePINDialog(spec, (retry) ? retries : -1, +              this, "sign", +              this, "cancel", +              this, "secureViewer"); + +      do { +        waitForAction(); + +        if ("secureViewer".equals(action)) { +          try { +            viewer.displayDataToBeSigned(signedInfo, this, "pinEntry"); +          } catch (DigestException ex) { +            log.error("Bad digest value: " + ex.getMessage()); +            gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH, +                    new Object[]{ex.getMessage()}, +                    this, "error"); +          } catch (Exception ex) { +            log.error("Could not display hashdata inputs: " + +                    ex.getMessage()); +            gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA, +                    new Object[]{ex.getMessage()}, +                    this, "error"); +          } +        } else if ("sign".equals(action)) { +          gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, +                BKUGUIFacade.MESSAGE_WAIT); +          retry = true; +          return gui.getPin(); +        } else if ("pinEntry".equals(action)) { +          gui.showSignaturePINDialog(spec, (retry) ? retries : -1, +                  this, "sign", +                  this, "cancel", +                  this, "secureViewer"); +        } else if ("cancel".equals(action) || +                "error".equals(action)) { +          gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, +                BKUGUIFacade.MESSAGE_WAIT); +          throw new CancelledException(spec.getLocalizedName() + +                  " entry cancelled"); +        } else { +          log.error("unknown action command " + action); +        } +      } while (true); +    } +  } + +  class SoftwareCardPinProvider extends AbstractPINProvider { + +    private SoftwareCardPinProvider() { +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      gui.showCardPINDialog(spec, (retry) ? retries : -1, +              this, "ok", +              this, "cancel"); + +      waitForAction(); + +      gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, +              BKUGUIFacade.MESSAGE_WAIT); + +      if ("cancel".equals(action)) { +        throw new CancelledException(spec.getLocalizedName() + +                  " entry cancelled"); +      } +      retry = true; +      return gui.getPin(); +    } +  } + +    class PinpadSignaturePinProvider extends AbstractPINProvider { +//    protected BKUGUIFacade gui; +    protected SecureViewer viewer; +    protected ViewerThread viewerThread; +    protected SignedInfoType signedInfo; + + +    private PinpadSignaturePinProvider(SecureViewer viewer, +            SignedInfoType signedInfo) { +      this.viewer = viewer; +      this.signedInfo = signedInfo; +    } + +    protected class ViewerThread extends Thread { + +      PINSpec pinSpec; +      int retries; + +      public ViewerThread(PINSpec pinSpec, int retries) { +        this.pinSpec = pinSpec; +        this.retries = retries; +      } + +      @Override +      public void run() { + +        try { + +          gui.showPinpadSignaturePINDialog(pinSpec, retries, +              PinpadSignaturePinProvider.this, "secureViewer"); + +          while (true) { +            waitForAction(); + +            if ("secureViewer".equals(action)) { +              viewer.displayDataToBeSigned(signedInfo, +                      PinpadSignaturePinProvider.this, "pinEntry"); +            } else if ("pinEntry".equals(action)) { +              gui.showPinpadSignaturePINDialog(pinSpec, retries, +                      PinpadSignaturePinProvider.this, "secureViewer"); +            } else { +              log.error("unsupported action command: " + action); +            } +          } + +        } catch (DigestException ex) { +          log.error("Bad digest value: " + ex.getMessage()); +          gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH, +                  new Object[]{ex.getMessage()}); +        } catch (InterruptedException ex) { +          log.info("pinpad secure viewer thread interrupted"); +        } catch (Exception ex) { +          log.error("Could not display hashdata inputs: " + +                  ex.getMessage()); +          gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA, +                  new Object[]{ex.getMessage()}); +        } +      } +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      if (viewerThread != null) { +        updateViewerThread(retries); +      } else { +        viewerThread = new ViewerThread(spec, -1); +        viewerThread.start(); +      } +//      if (viewerThread != null) { +//        log.trace("interrupt old secure viewer thread"); +//        viewerThread.interrupt(); +//      } +//      viewerThread = new ViewerThread(spec, (retry) ? retries : -1); +//      log.trace("start new secure viewer thread"); +//      viewerThread.start(); + +      retry = true; +      return null; +    } + +    private synchronized void updateViewerThread(int retries) { +      log.trace("update viewer thread"); +      viewerThread.retries = retries; +      action = "pinEntry"; +      actionPerformed = true; +      notify(); +    } + + +//    @Override +//    protected void finalize() throws Throwable { +//      if (viewerThread != null) { +//        viewerThread.interrupt(); +//      } +//      log.info("finalizing Pinpad SignaturePinProvider"); +//      super.finalize(); +//    } +  } + +  class PinpadCardPinProvider extends AbstractPINProvider { + +    private PinpadCardPinProvider() { +    } + +    @Override +    public char[] providePIN(PINSpec spec, int retries) +            throws CancelledException, InterruptedException { + +      showPinpadPINDialog(retries, spec); +      retry = true; +      return null; + +    } + +    private void showPinpadPINDialog(int retries, PINSpec pinSpec) { +      String title, message; +      Object[] params; +      if (retry) { +        title = BKUGUIFacade.TITLE_RETRY; +        message = BKUGUIFacade.MESSAGE_RETRIES; +        params = new Object[]{String.valueOf(retries)}; +      } else { +        title = BKUGUIFacade.TITLE_CARDPIN; +        message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD; +        String pinSize = String.valueOf(pinSpec.getMinLength()); +        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { +          pinSize += "-" + pinSpec.getMaxLength(); +        } +        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; +      } +      gui.showMessageDialog(title, message, params); +    } +  }  } diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java deleted file mode 100644 index c109ceba..00000000 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PinpadPINProviderFactory.java +++ /dev/null @@ -1,186 +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; - -import at.gv.egiz.bku.gui.BKUGUIFacade; -import at.gv.egiz.smcc.CancelledException; -import at.gv.egiz.smcc.PINProvider; -import at.gv.egiz.smcc.PINSpec; -import at.gv.egiz.stal.signedinfo.SignedInfoType; -import java.security.DigestException; - -/** - * - * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> - */ -public class PinpadPINProviderFactory extends PINProviderFactory { - -  protected PinpadPINProviderFactory(BKUGUIFacade gui) { -    this.gui = gui; -  } - -  @Override -  public PINProvider getSignaturePINProvider(SecureViewer viewer, -          SignedInfoType signedInfo) { - -    return new SignaturePinProvider(viewer, signedInfo); -  } - -  @Override -  public PINProvider getCardPINProvider() { -    return new CardPinProvider(); -  } - -  class SignaturePinProvider extends AbstractPINProvider { - -//    protected BKUGUIFacade gui; -    protected SecureViewer viewer; -    protected ViewerThread viewerThread; -    protected SignedInfoType signedInfo; - - -    private SignaturePinProvider(SecureViewer viewer, -            SignedInfoType signedInfo) { -      this.viewer = viewer; -      this.signedInfo = signedInfo; -    } - -    protected class ViewerThread extends Thread { - -      PINSpec pinSpec; -      int retries; - -      public ViewerThread(PINSpec pinSpec, int retries) { -        this.pinSpec = pinSpec; -        this.retries = retries; -      } - -      @Override -      public void run() { - -        try { - -          gui.showPinpadSignaturePINDialog(pinSpec, retries, -              SignaturePinProvider.this, "secureViewer"); - -          while (true) { -            waitForAction(); - -            if ("secureViewer".equals(action)) { -              viewer.displayDataToBeSigned(signedInfo, -                      SignaturePinProvider.this, "pinEntry"); -            } else if ("pinEntry".equals(action)) { -              gui.showPinpadSignaturePINDialog(pinSpec, retries, -                      SignaturePinProvider.this, "secureViewer"); -            } else { -              log.error("unsupported action command: " + action); -            } -          } - -        } catch (DigestException ex) { -          log.error("Bad digest value: " + ex.getMessage()); -          gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH, -                  new Object[]{ex.getMessage()}); -        } catch (InterruptedException ex) { -          log.info("pinpad secure viewer thread interrupted"); -        } catch (Exception ex) { -          log.error("Could not display hashdata inputs: " + -                  ex.getMessage()); -          gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA, -                  new Object[]{ex.getMessage()}); -        } -      } -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      if (viewerThread != null) { -        updateViewerThread(retries); -      } else { -        viewerThread = new ViewerThread(spec, -1); -        viewerThread.start(); -      } -//      if (viewerThread != null) { -//        log.trace("interrupt old secure viewer thread"); -//        viewerThread.interrupt(); -//      } -//      viewerThread = new ViewerThread(spec, (retry) ? retries : -1); -//      log.trace("start new secure viewer thread"); -//      viewerThread.start(); - -      retry = true; -      return null; -    } - -    private synchronized void updateViewerThread(int retries) { -      log.trace("update viewer thread"); -      viewerThread.retries = retries; -      action = "pinEntry"; -      actionPerformed = true; -      notify(); -    } - - -//    @Override -//    protected void finalize() throws Throwable { -//      if (viewerThread != null) { -//        viewerThread.interrupt(); -//      } -//      log.info("finalizing Pinpad SignaturePinProvider"); -//      super.finalize(); -//    } -  } - -  class CardPinProvider extends AbstractPINProvider { - -    private CardPinProvider() { -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      showPinpadPINDialog(retries, spec); -      retry = true; -      return null; - -    } - -    private void showPinpadPINDialog(int retries, PINSpec pinSpec) { -      String title, message; -      Object[] params; -      if (retry) { -        title = BKUGUIFacade.TITLE_RETRY; -        message = BKUGUIFacade.MESSAGE_RETRIES; -        params = new Object[]{String.valueOf(retries)}; -      } else { -        title = BKUGUIFacade.TITLE_CARDPIN; -        message = BKUGUIFacade.MESSAGE_ENTERPIN_PINPAD; -        String pinSize = String.valueOf(pinSpec.getMinLength()); -        if (pinSpec.getMinLength() != pinSpec.getMaxLength()) { -          pinSize += "-" + pinSpec.getMaxLength(); -        } -        params = new Object[]{pinSpec.getLocalizedName(), pinSize}; -      } -      gui.showMessageDialog(title, message, params); -    } -  } -  } - diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java index 7a4f6572..56fc8804 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java @@ -50,7 +50,7 @@ public class SignRequestHandler extends AbstractRequestHandler {      private static Log log = LogFactory.getLog(SignRequestHandler.class);      private static JAXBContext jaxbContext; -    private PINProviderFactory pinProviderFactory; +//    private PINProviderFactory pinProviderFactory;      private SecureViewer secureViewer;      static { @@ -86,11 +86,9 @@ public class SignRequestHandler extends AbstractRequestHandler {                  md.update(signReq.getSignedInfo());                  KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier()); -                if (pinProviderFactory == null) { -                  pinProviderFactory = PINProviderFactory.getInstance(card, gui); -                } -                byte[] resp = card.createSignature(md.digest(), kb,  -                        pinProviderFactory.getSignaturePINProvider(secureViewer, si.getValue())); +                byte[] resp = card.createSignature(md.digest(), kb, +                        new PINProviderFactory(card.getReader(), gui) +                        .getSignaturePINProvider(secureViewer, si.getValue()));                  if (resp == null) {                      return new ErrorResponse(6001);                  } diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java deleted file mode 100644 index 7d36c2c3..00000000 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SoftwarePINProviderFactory.java +++ /dev/null @@ -1,137 +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; - -import at.gv.egiz.bku.gui.BKUGUIFacade; -import at.gv.egiz.smcc.*; -import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.stal.signedinfo.SignedInfoType; -import java.security.DigestException; -import java.util.List; - -/** - * - * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> - */ -public class SoftwarePINProviderFactory extends PINProviderFactory { - -  protected SoftwarePINProviderFactory(BKUGUIFacade gui) { -    this.gui = gui; -  } - -  @Override -  public PINProvider getSignaturePINProvider(SecureViewer viewer, -          SignedInfoType signedInfo) { -    return new SignaturePinProvider(viewer, signedInfo); -  } - -  @Override -  public PINProvider getCardPINProvider() { -    return new CardPinProvider(); -  } - -  class SignaturePinProvider extends AbstractPINProvider { - -//    protected BKUGUIFacade gui; -    protected SecureViewer viewer; -    protected SignedInfoType signedInfo; - -    private SignaturePinProvider(SecureViewer viewer, -            SignedInfoType signedInfo) { -      this.viewer = viewer; -      this.signedInfo = signedInfo; -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      gui.showSignaturePINDialog(spec, (retry) ? retries : -1, -              this, "sign", -              this, "cancel", -              this, "secureViewer"); - -      do { -        waitForAction(); - -        if ("secureViewer".equals(action)) { -          try { -            viewer.displayDataToBeSigned(signedInfo, this, "pinEntry"); -          } catch (DigestException ex) { -            log.error("Bad digest value: " + ex.getMessage()); -            gui.showErrorDialog(BKUGUIFacade.ERR_INVALID_HASH, -                    new Object[]{ex.getMessage()}, -                    this, "error"); -          } catch (Exception ex) { -            log.error("Could not display hashdata inputs: " + -                    ex.getMessage()); -            gui.showErrorDialog(BKUGUIFacade.ERR_DISPLAY_HASHDATA, -                    new Object[]{ex.getMessage()}, -                    this, "error"); -          } -        } else if ("sign".equals(action)) { -          gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, -                BKUGUIFacade.MESSAGE_WAIT); -          retry = true; -          return gui.getPin(); -        } else if ("pinEntry".equals(action)) { -          gui.showSignaturePINDialog(spec, (retry) ? retries : -1, -                  this, "sign", -                  this, "cancel", -                  this, "secureViewer"); -        } else if ("cancel".equals(action) || -                "error".equals(action)) { -          gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, -                BKUGUIFacade.MESSAGE_WAIT); -          throw new CancelledException(spec.getLocalizedName() + -                  " entry cancelled"); -        } else { -          log.error("unknown action command " + action); -        } -      } while (true); -    } -  } - -  class CardPinProvider extends AbstractPINProvider { - -//    protected BKUGUIFacade gui; - -    private CardPinProvider() { -    } - -    @Override -    public char[] providePIN(PINSpec spec, int retries) -            throws CancelledException, InterruptedException { - -      gui.showCardPINDialog(spec, (retry) ? retries : -1, -              this, "ok", -              this, "cancel"); - -      waitForAction(); -       -      gui.showMessageDialog(BKUGUIFacade.TITLE_WAIT, -              BKUGUIFacade.MESSAGE_WAIT); - -      if ("cancel".equals(action)) { -        throw new CancelledException(spec.getLocalizedName() + -                  " entry cancelled"); -      } -      retry = true; -      return gui.getPin(); -    } -  } -} | 
