From 2dbf2347bc78fd835c857ad438514fb6251f6f7a Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 2 Apr 2009 19:13:48 +0000 Subject: 1.1-RC7 (pinpad revisited) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@325 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../gv/egiz/bku/smccstal/PINProviderFactory.java | 298 ++++++++++++++++++++- 1 file changed, 286 insertions(+), 12 deletions(-) (limited to 'smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/PINProviderFactory.java') 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 */ -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); + } + } } -- cgit v1.2.3