From 22001c93bca360d1b15c252cb22d2a4147ff350d Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 20 Aug 2009 16:24:55 +0000 Subject: [#430] Activation/PIN-management in MOCCA Web Start - new Modules: smccSTALExt, BKUGuiExt in order not to depend on BKUAppletExt in BKULocal - provide stal-request handler de-registration in abstractSMCCSTAL git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@448 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smccSTALExt/pom.xml | 27 +++ .../egiz/bku/smccstal/CardMgmtRequestHandler.java | 177 ++++++++++++++ .../egiz/bku/smccstal/GetPINStatusException.java | 41 ++++ .../bku/smccstal/ManagementPINProviderFactory.java | 262 +++++++++++++++++++++ .../bku/smccstal/PINManagementRequestHandler.java | 245 +++++++++++++++++++ 5 files changed, 752 insertions(+) create mode 100644 smccSTALExt/pom.xml create mode 100644 smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/CardMgmtRequestHandler.java create mode 100644 smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/GetPINStatusException.java create mode 100644 smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java create mode 100644 smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java (limited to 'smccSTALExt') diff --git a/smccSTALExt/pom.xml b/smccSTALExt/pom.xml new file mode 100644 index 00000000..481993e1 --- /dev/null +++ b/smccSTALExt/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + bku + at.gv.egiz + 1.2.2-SNAPSHOT + + at.gv.egiz + smccSTALExt + ${project.parent.version} + smcc STAL Extension + + + at.gv.egiz + smccSTAL + ${project.parent.version} + + + at.gv.egiz + BKUGuiExt + ${project.parent.version} + + + + diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/CardMgmtRequestHandler.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/CardMgmtRequestHandler.java new file mode 100644 index 00000000..533206b3 --- /dev/null +++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/CardMgmtRequestHandler.java @@ -0,0 +1,177 @@ +/* +* 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.ActivationGUIFacade; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.smartcardio.Card; +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.smccstal.AbstractRequestHandler; +import at.gv.egiz.smcc.SignatureCardException; +import at.gv.egiz.stal.ErrorResponse; +import at.gv.egiz.stal.STALRequest; +import at.gv.egiz.stal.STALResponse; +import at.gv.egiz.stal.ext.APDUScriptRequest; +import at.gv.egiz.stal.ext.APDUScriptResponse; +import at.gv.egiz.stal.ext.APDUScriptRequest.Command; +import at.gv.egiz.stal.ext.APDUScriptRequest.RequestScriptElement; +import at.gv.egiz.stal.ext.APDUScriptRequest.Reset; +import at.gv.egiz.stal.ext.APDUScriptResponse.Response; +import at.gv.egiz.stal.ext.APDUScriptResponse.ATR; +import at.gv.egiz.stal.ext.APDUScriptResponse.ResponseScriptElement; +import java.awt.event.ActionListener; + +/** + * @author mcentner + * + */ +public class CardMgmtRequestHandler extends AbstractRequestHandler implements ActionListener { + + /** + * Logging facility. + */ + private static Log log = LogFactory.getLog(CardMgmtRequestHandler.class); + + /** + * The sequence counter. + */ + private int sequenceNum = 0; + + /** + * display script num + */ + private int currentActivationScript = 0; + + @Override + public STALResponse handleRequest(STALRequest request) + throws InterruptedException { + + // APDU Script Request + if (request instanceof APDUScriptRequest) { + + currentActivationScript++; + log.debug("handling APDU script " + currentActivationScript); + + Card icc = card.getCard(); + + if (icc == null) { + log.error("SignatureCard instance '" + card.getClass().getName() + "' does not support card management requests."); + return new ErrorResponse(1000); + } + + List script = ((APDUScriptRequest) request).getScript(); + ArrayList responses = new ArrayList(script.size()); + + ((ActivationGUIFacade) gui).showActivationProgressDialog(currentActivationScript, script.size(), this, "cancel"); + + try { + log.trace("begin exclusive"); + icc.beginExclusive(); + + for (RequestScriptElement scriptElement : script) { + ((ActivationGUIFacade) gui).incrementProgress(); + + if (scriptElement instanceof Command) { + log.trace("handling APDU script element COMMAND"); + Command command = (Command) scriptElement; + CommandAPDU commandAPDU = new CommandAPDU(command.getCommandAPDU()); + + log.trace("get basicchannel"); + CardChannel channel = icc.getBasicChannel(); + + sequenceNum = command.getSequence(); + log.debug("Transmit APDU (sequence=" + sequenceNum + ")"); + log.trace(commandAPDU.toString()); + ResponseAPDU responseAPDU = channel.transmit(commandAPDU); + log.trace(responseAPDU.toString()); + + byte[] sw = new byte[] { + (byte) (0xFF & responseAPDU.getSW1()), + (byte) (0xFF & responseAPDU.getSW2()) }; + + responses.add(new Response(sequenceNum, responseAPDU.getData(), sw, 0)); + + if (command.getExpectedSW() != null && + !Arrays.equals(sw, command.getExpectedSW())) { + // unexpected SW + log.warn("Got unexpected SW. APDU-script execution stopped."); + break; + } + + } else if (scriptElement instanceof Reset) { + + log.trace("handling APDU script element RESET"); + sequenceNum = 0; + card.reset(); + javax.smartcardio.ATR atr = icc.getATR(); + log.trace("got ATR: " + atr.toString()); + responses.add(new ATR(atr.getBytes())); + + log.trace("regain exclusive access to card"); + icc = card.getCard(); + icc.beginExclusive(); + } + + } + + } catch (CardException e) { + log.info("Failed to execute APDU script.", e); + responses.add(new Response(sequenceNum, null, null, Response.RC_UNSPECIFIED)); + } catch (SignatureCardException e) { + log.info("Failed to reset smart card.", e); + responses.add(new Response(sequenceNum, null, null, Response.RC_UNSPECIFIED)); + } catch (RuntimeException e) { + log.error(e); + throw e; + } finally { + try { + icc.endExclusive(); + } catch (CardException e) { + log.info(e); + } + } + + log.trace("done handling APDU script " + currentActivationScript + ", return response containing " + responses.size() + " elements"); + ((ActivationGUIFacade) gui).showIdleDialog(this, "cancel"); + return new APDUScriptResponse(responses); + + } else { + log.error("Got unexpected STAL request: " + request); + return new ErrorResponse(1000); + } + + } + + @Override + public boolean requireCard() { + return true; + } + +} diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/GetPINStatusException.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/GetPINStatusException.java new file mode 100644 index 00000000..66b15887 --- /dev/null +++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/GetPINStatusException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.smccstal; + +import at.gv.egiz.smcc.SignatureCardException; + +/** + * + * @author Clemens Orthacker + */ +public class GetPINStatusException extends SignatureCardException { + + /** + * Creates a new instance of GetStatusException without detail message. + */ + public GetPINStatusException() { + } + + + /** + * Constructs an instance of GetStatusException with the specified detail message. + * @param msg the detail message. + */ + public GetPINStatusException(String msg) { + super(msg); + } +} diff --git a/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java new file mode 100644 index 00000000..34bcbf5c --- /dev/null +++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/ManagementPINProviderFactory.java @@ -0,0 +1,262 @@ +/* + * 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.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 + */ +public class ManagementPINProviderFactory extends PINProviderFactory { + + 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)) { +// 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 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) { + if (retries == 1) { + message = BKUGUIFacade.MESSAGE_LAST_RETRY_PINPAD; + } else { + message = BKUGUIFacade.MESSAGE_RETRIES_PINPAD; + } + title = BKUGUIFacade.TITLE_RETRY; + 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); + } + } + + + 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 { + +// 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 { + + ((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/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java new file mode 100644 index 00000000..bfeb90b0 --- /dev/null +++ b/smccSTALExt/src/main/java/at/gv/egiz/bku/smccstal/PINManagementRequestHandler.java @@ -0,0 +1,245 @@ +/* + * 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 java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.gui.BKUGUIFacade; +import at.gv.egiz.bku.gui.PINManagementGUIFacade; +import at.gv.egiz.bku.gui.PINManagementGUIFacade.STATUS; +import at.gv.egiz.bku.smccstal.AbstractRequestHandler; +import at.gv.egiz.smcc.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.PINMgmtSignatureCard; +import at.gv.egiz.smcc.PINOperationAbortedException; +import at.gv.egiz.smcc.PINSpec; +import at.gv.egiz.smcc.SignatureCardException; +import at.gv.egiz.smcc.TimeoutException; +import at.gv.egiz.smcc.PINMgmtSignatureCard.PIN_STATE; +import at.gv.egiz.stal.ErrorResponse; +import at.gv.egiz.stal.STALRequest; +import at.gv.egiz.stal.STALResponse; +import at.gv.egiz.stal.ext.PINManagementRequest; +import at.gv.egiz.stal.ext.PINManagementResponse; + +/** + * + * @author Clemens Orthacker + */ +public class PINManagementRequestHandler extends AbstractRequestHandler { + + protected static final Log log = LogFactory.getLog(PINManagementRequestHandler.class); + + protected Map pinStates = new HashMap(); + + @Override + public STALResponse handleRequest(STALRequest request) throws InterruptedException { + if (request instanceof PINManagementRequest) { + + PINManagementGUIFacade gui = (PINManagementGUIFacade) this.gui; + + PINSpec selectedPIN = null; + + try { + + if (card instanceof PINMgmtSignatureCard) { + + // update all PIN states + for (PINSpec pinSpec : ((PINMgmtSignatureCard) card).getPINSpecs()) { + updatePINState(pinSpec, STATUS.UNKNOWN); + } + + gui.showPINManagementDialog(pinStates, this, "activate_enterpin", + "change_enterpin", "unblock_enterpuk", "verify_enterpin", this, + "cancel"); + + } else { + + // card does not support PIN management + gui.showErrorDialog(PINManagementGUIFacade.ERR_UNSUPPORTED_CARD, + null, this, "cancel"); + + } + + while (true) { + + waitForAction(); + + if ("cancel".equals(actionCommand)) { + log.debug("pin management cancel"); + return new PINManagementResponse(); + } else { + selectedPIN = gui.getSelectedPINSpec(); + + if (selectedPIN == null) { + throw new NullPointerException("no PIN selected for activation/change"); + } + + ManagementPINProviderFactory ppfac = + new ManagementPINProviderFactory(card.getReader(), gui); + + try { + if ("activate_enterpin".equals(actionCommand)) { + log.info("activate " + selectedPIN.getLocalizedName()); + ((PINMgmtSignatureCard) card).activatePIN(selectedPIN, + ppfac.getActivatePINProvider()); + updatePINState(selectedPIN, STATUS.ACTIV); + gui.showMessageDialog(PINManagementGUIFacade.TITLE_ACTIVATE_SUCCESS, + PINManagementGUIFacade.MESSAGE_ACTIVATE_SUCCESS, + new Object[] {selectedPIN.getLocalizedName()}, + BKUGUIFacade.BUTTON_OK, this, "ok"); + waitForAction(); + } else if ("change_enterpin".equals(actionCommand)) { + log.info("change " + selectedPIN.getLocalizedName()); + ((PINMgmtSignatureCard) card).changePIN(selectedPIN, + ppfac.getChangePINProvider()); + updatePINState(selectedPIN, STATUS.ACTIV); + gui.showMessageDialog(PINManagementGUIFacade.TITLE_CHANGE_SUCCESS, + PINManagementGUIFacade.MESSAGE_CHANGE_SUCCESS, + new Object[] {selectedPIN.getLocalizedName()}, + BKUGUIFacade.BUTTON_OK, this, "ok"); + waitForAction(); + + } else if ("unblock_enterpuk".equals(actionCommand)) { + log.info("unblock " + selectedPIN.getLocalizedName()); + ((PINMgmtSignatureCard) card).unblockPIN(selectedPIN, + ppfac.getUnblockPINProvider()); + } else if ("verify_enterpin".equals(actionCommand)) { + log.info("verify " + selectedPIN.getLocalizedName()); + ((PINMgmtSignatureCard) card).verifyPIN(selectedPIN, + ppfac.getVerifyPINProvider()); + updatePINState(selectedPIN, STATUS.ACTIV); + } + } catch (CancelledException ex) { + log.trace("cancelled"); + } catch (TimeoutException ex) { + log.error("Timeout during pin entry"); + gui.showMessageDialog(BKUGUIFacade.TITLE_ENTRY_TIMEOUT, + BKUGUIFacade.ERR_PIN_TIMEOUT, + new Object[] {selectedPIN.getLocalizedName()}, + BKUGUIFacade.BUTTON_OK, this, null); + waitForAction(); + } catch (LockedException ex) { + log.error(selectedPIN.getLocalizedName() + " locked"); + updatePINState(selectedPIN, STATUS.BLOCKED); + gui.showErrorDialog(PINManagementGUIFacade.ERR_LOCKED, + new Object[] {selectedPIN.getLocalizedName()}, + this, null); + waitForAction(); + } catch (NotActivatedException ex) { + log.error(selectedPIN.getLocalizedName() + " not active"); + updatePINState(selectedPIN, STATUS.NOT_ACTIV); + gui.showErrorDialog(PINManagementGUIFacade.ERR_NOT_ACTIVE, + 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 + + selectedPIN = null; + gui.showPINManagementDialog(pinStates, + this, "activate_enterpin", "change_enterpin", "unblock_enterpuk", "verify_enterpin", + this, "cancel"); + } // end while + + } catch (GetPINStatusException ex) { + String pin = (selectedPIN != null) ? selectedPIN.getLocalizedName() : "pin"; + log.error("failed to get " + pin + " status: " + ex.getMessage()); + gui.showErrorDialog(PINManagementGUIFacade.ERR_STATUS, null, + this, "ok"); + waitForAction(); + return new ErrorResponse(1000); + } catch (SignatureCardException ex) { + log.error(ex.getMessage(), ex); + gui.showErrorDialog(PINManagementGUIFacade.ERR_UNKNOWN, null, + this, "ok"); + waitForAction(); + return new ErrorResponse(1000); + } + } else { + log.error("Got unexpected STAL request: " + request); + return new ErrorResponse(1000); + } + } + + @Override + public boolean requireCard() { + return true; + } + + /** + * query status for STARCOS card, + * assume provided status for ACOS card + * @param pinSpec + * @param status + * @throws at.gv.egiz.smcc.SignatureCardException if query status fails + */ + private void updatePINState(PINSpec pinSpec, STATUS status) + throws GetPINStatusException { + + PINMgmtSignatureCard pmCard = ((PINMgmtSignatureCard) card); + PIN_STATE pinState; + try { + pinState = pmCard.getPINState(pinSpec); + } catch (SignatureCardException e) { + String msg = "Failed to get PIN status for pin '" + + pinSpec.getLocalizedName() + "'."; + log.info(msg, e); + throw new GetPINStatusException(msg); + } + if (pinState == PIN_STATE.ACTIV) { + pinStates.put(pinSpec, STATUS.ACTIV); + } else if (pinState == PIN_STATE.NOT_ACTIV) { + pinStates.put(pinSpec, STATUS.NOT_ACTIV); + } else if (pinState == PIN_STATE.BLOCKED) { + pinStates.put(pinSpec, STATUS.BLOCKED); + } else { + pinStates.put(pinSpec, status); + } + } + +} -- cgit v1.2.3