From ecc11bdb13ae27385486ad1c944ee01ffd0440e7 Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 5 Jan 2010 10:06:43 +0000 Subject: Features [#437] Handle pinpad [64:03] response apdu correctly [#445] pin entry feedback for VERIFY_PIN_START/FINISH [#471] Provide SecureViewer Link before Pinpad PinEntry timeout starts Bugs [#479] PIN Managment Applet allows unmatching new pin and pin confirmation [#480] PIN Management displays blocked PINs as ACTIVE [#486] Not possible to select 3 times in series the same item from signedReferencesList for display in secureViewer [#506] change pin dialog (gui) issues [#508] e-card G3 PIN activation (with TransportPIN) not supported [#509] closing secure viewer window (WINDOW_CLOSING) leaves "signature data is displayed in viewer" dialog in applet git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@564 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java | 136 ---- .../at/gv/egiz/smcc/ccid/CherrySmartBoardXX44.java | 42 -- .../java/at/gv/egiz/smcc/ccid/DefaultReader.java | 771 --------------------- .../at/gv/egiz/smcc/ccid/GemplusGemPCPinpad.java | 46 -- .../at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java | 44 -- .../java/at/gv/egiz/smcc/ccid/ReaderFactory.java | 89 --- .../gv/egiz/smcc/ccid/SCMMicrosystemsSPRx32.java | 51 -- 7 files changed, 1179 deletions(-) delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/CherrySmartBoardXX44.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/GemplusGemPCPinpad.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ccid/SCMMicrosystemsSPRx32.java 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 deleted file mode 100644 index d73ff0e9..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CCID.java +++ /dev/null @@ -1,136 +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.smcc.ccid; - -import javax.smartcardio.Card; -import javax.smartcardio.CardChannel; -import javax.smartcardio.CardException; -import javax.smartcardio.ResponseAPDU; - -import at.gv.egiz.smcc.CancelledException; -import at.gv.egiz.smcc.ChangePINProvider; -import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec; -import at.gv.egiz.smcc.NewReferenceDataAPDUSpec; -import at.gv.egiz.smcc.PINOperationAbortedException; -import at.gv.egiz.smcc.PINProvider; -import at.gv.egiz.smcc.PINSpec; -import at.gv.egiz.smcc.SignatureCardException; -import at.gv.egiz.smcc.VerifyAPDUSpec; - -/** - * - * @author Clemens Orthacker - */ -public interface CCID { - - - String[] FEATURES = new String[]{"NO_FEATURE", - "FEATURE_VERIFY_PIN_START", - "FEATURE_VERIFY_PIN_FINISH", - "FEATURE_MODIFY_PIN_START", - "FEATURE_MODIFY_PIN_FINISH", - "FEATURE_GET_KEY_PRESSED", - "FEATURE_VERIFY_PIN_DIRECT", - "FEATURE_MODIFY_PIN_DIRECT", - "FEATURE_MCT_READER_DIRECT", - "FEATURE_MCT_UNIVERSAL", - "FEATURE_IFD_PIN_PROPERTIES", - "FEATURE_ABORT", - "FEATURE_SET_SPE_MESSAGE", - "FEATURE_VERIFY_PIN_DIRECT_APP_ID", - "FEATURE_MODIFY_PIN_DIRECT_APP_ID", - "FEATURE_WRITE_DISPLAY", - "FEATURE_GET_KEY", - "FEATURE_IFD_DISPLAY_PROPERTIES"}; - - 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; - - void setDisablePinpad(boolean disable); - - boolean hasFeature(Byte feature); - - ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec, - PINSpec pinSpec, PINProvider provider, int retries) - throws CancelledException, InterruptedException, CardException, - SignatureCardException; - - ResponseAPDU modify(CardChannel channel, - ChangeReferenceDataAPDUSpec apduSpec, PINSpec pinSpec, - ChangePINProvider provider, int retries) throws CancelledException, - InterruptedException, CardException, SignatureCardException; - - /** - * 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 - * @return - * @throws at.gv.egiz.smcc.SignatureCardException if feature is not supported - * or card communication fails - */ -// byte[] transmitControlCommand(Byte feature, byte[] ctrlCommand) throws SignatureCardException; - - /** - * allow subclasses to override default (deal with reader bugs) - * @return - */ - byte getbTimeOut(); - byte getbTimeOut2(); - byte getwPINMaxExtraDigitL(); - byte getwPINMaxExtraDigitH(); - byte getbEntryValidationCondition(); - - ResponseAPDU activate(CardChannel channel, NewReferenceDataAPDUSpec apduSpec, - PINSpec pinSpec, PINProvider provider) - throws CancelledException, InterruptedException, CardException, - SignatureCardException; -} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CherrySmartBoardXX44.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/CherrySmartBoardXX44.java deleted file mode 100644 index a7e45765..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/CherrySmartBoardXX44.java +++ /dev/null @@ -1,42 +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.smcc.ccid; - -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * - * @author Clemens Orthacker - */ -public class CherrySmartBoardXX44 extends DefaultReader { - - protected static final Log log = LogFactory.getLog(CherrySmartBoardXX44.class); - - public static final byte wPINMaxExtraDigitH = 0x01; - - public CherrySmartBoardXX44(Card icc, CardTerminal ct) { - super(icc, ct); - } - - @Override - public byte getwPINMaxExtraDigitH() { - return wPINMaxExtraDigitH; - } -} 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 deleted file mode 100644 index 2004db45..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/DefaultReader.java +++ /dev/null @@ -1,771 +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.smcc.ccid; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import javax.smartcardio.Card; -import javax.smartcardio.CardChannel; -import javax.smartcardio.CardException; -import javax.smartcardio.CardTerminal; -import javax.smartcardio.ResponseAPDU; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.smcc.CancelledException; -import at.gv.egiz.smcc.ChangePINProvider; -import at.gv.egiz.smcc.ChangeReferenceDataAPDUSpec; -import at.gv.egiz.smcc.NewReferenceDataAPDUSpec; -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.SignatureCardException; -import at.gv.egiz.smcc.TimeoutException; -import at.gv.egiz.smcc.VerifyAPDUSpec; -import at.gv.egiz.smcc.util.ISO7816Utils; -import at.gv.egiz.smcc.util.SMCCHelper; - -/** - * - * @author Clemens Orthacker - */ -public class DefaultReader implements CCID { - public static final int PIN_ENTRY_POLLING_INTERVAL = 20; - - public static final byte bEntryValidationCondition = 0x02; // validation key pressed - public static final byte bTimeOut = 0x3c; // 60sec (= max on ReinerSCT) - public static final byte bTimeOut2 = 0x00; // default (attention with SCM) - public static final byte wPINMaxExtraDigitH = 0x00; // min pin length zero digits - public static final byte wPINMaxExtraDigitL = 0x0c; // max pin length 12 digits - - protected final static Log log = LogFactory.getLog(DefaultReader.class); - - private static int CTL_CODE(int 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; - protected boolean disablePinpad = false; - - /** - * supported features and respective control codes - */ - protected Map features; - - public DefaultReader(Card icc, CardTerminal ct) { - if (icc == null || ct == null) { - throw new NullPointerException("no card or card terminal provided"); - } - log.info("Initializing " + ct.getName()); - - this.icc = icc; - this.ct = ct; - features = queryFeatures(); - - log.debug("setting pin timeout: " + getbTimeOut()); - log.debug("setting pin timeout (after key pressed): " + getbTimeOut2()); - log.debug("setting pin entry validation condition: " + getbEntryValidationCondition()); - log.debug("setting min pin length: " + getwPINMaxExtraDigitH()); - log.debug("setting max pin length: " + getwPINMaxExtraDigitL()); - } - - @Override - public void setDisablePinpad(boolean disable) { - disablePinpad = disable; - } - - /** - * - * @return the card terminals name - */ - @Override - public String getName() { - return ct.getName(); - } - - @Override - public Card connect() throws CardException { - icc = ct.connect("*"); - return icc; - } - - Map queryFeatures() { - Map features = new HashMap(); - - if (icc == null) { - log.warn("invalid card handle, cannot query ifd features"); - } else { - try { - if (log.isTraceEnabled()) { - log.trace("GET_FEATURE_REQUEST " + - Integer.toHexString(IOCTL_GET_FEATURE_REQUEST) + - " on " + ct.getName()); - } - byte[] resp = icc.transmitControlCommand(IOCTL_GET_FEATURE_REQUEST, - new byte[0]); - - if (log.isTraceEnabled()) { - log.trace("Response TLV " + SMCCHelper.toString(resp)); - } - // tag - // length in bytes (always 4) - // control code value for supported feature (in big endian) - for (int i = 0; i < resp.length; i += 6) { - Byte feature = new Byte(resp[i]); - Integer ioctl = new Integer((0xff & resp[i + 2]) << 24) | - ((0xff & resp[i + 3]) << 16) | - ((0xff & resp[i + 4]) << 8) | - (0xff & resp[i + 5]); - if (log.isInfoEnabled()) { - log.info("CCID supports " + FEATURES[feature.intValue()] + - ": " + Integer.toHexString(ioctl.intValue())); - } - features.put(feature, ioctl); - } - } catch (CardException ex) { - log.debug("Failed to query CCID features: " + ex.getMessage()); - log.trace(ex); - log.info("CCID does not support PINPad"); - } - } - return features; - } - - @Override - public boolean hasFeature(Byte feature) { - if (features != null && !disablePinpad) { - return features.containsKey(feature); - } - return false; - } - - @Override - public byte getbTimeOut() { - return bTimeOut; - } - - @Override - public byte getbTimeOut2() { - return bTimeOut2; - } - - @Override - public byte getwPINMaxExtraDigitL() { - return wPINMaxExtraDigitL; - } - - @Override - public byte getwPINMaxExtraDigitH() { - return wPINMaxExtraDigitH; - } - - @Override - public byte getbEntryValidationCondition() { - return bEntryValidationCondition; - } - - 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); - 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(PIN_ENTRY_POLLING_INTERVAL); - } 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); - - 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(PIN_ENTRY_POLLING_INTERVAL); - } 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(); - } - - /** - * - * @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; - } - - - - protected byte[] createPINModifyStructure(NewReferenceDataAPDUSpec apduSpec, PINSpec pinSpec) { - - ByteArrayOutputStream s = new ByteArrayOutputStream(); - // bTimeOut - s.write(getbTimeOut()); - // bTimeOut2 - s.write(getbTimeOut2()); - // bmFormatString - s.write(1 << 7 // system unit = byte - | (0xF & apduSpec.getPinPosition()) << 3 - | (0x1 & apduSpec.getPinJustification() << 2) - | (0x3 & apduSpec.getPinFormat())); - // bmPINBlockString - s.write((0xF & apduSpec.getPinLengthSize()) << 4 - | (0xF & apduSpec.getPinLength())); - // bmPINLengthFormat - s.write(// system unit = bit - (0xF & apduSpec.getPinLengthPos())); - // bInsertionOffsetOld - s.write(0x00); - // bInsertionOffsetNew - s.write(apduSpec.getPinInsertionOffsetNew()); - // wPINMaxExtraDigit - s.write(Math.min(pinSpec.getMaxLength(), getwPINMaxExtraDigitL())); - s.write(Math.max(pinSpec.getMinLength(), getwPINMaxExtraDigitH())); - // bConfirmPIN - s.write(0x01); - // bEntryValidationCondition - s.write(getbEntryValidationCondition()); - // bNumberMessage - s.write(0x02); - // wLangId English (United States), see http://www.usb.org/developers/docs/USB_LANGIDs.pdf - s.write(0x09); - s.write(0x04); - // bMsgIndex1 - s.write(0x01); - // bMsgIndex2 - s.write(0x02); - // bMsgIndex3 - s.write(0x00); - - // bTeoPrologue - s.write(0x00); - s.write(0x00); - s.write(0x00); - // ulDataLength - s.write(apduSpec.getApdu().length); - s.write(0x00); - s.write(0x00); - s.write(0x00); - // abData - try { - s.write(apduSpec.getApdu()); - } catch (IOException e) { - // As we are dealing with ByteArrayOutputStreams no exception is to be - // expected. - throw new RuntimeException(e); - } - - return s.toByteArray(); - - } - - protected byte[] createPINModifyStructure(ChangeReferenceDataAPDUSpec apduSpec, PINSpec pinSpec) { - - ByteArrayOutputStream s = new ByteArrayOutputStream(); - // bTimeOut - s.write(getbTimeOut()); - // bTimeOut2 - s.write(getbTimeOut2()); - // bmFormatString - s.write(1 << 7 // system unit = byte - | (0xF & apduSpec.getPinPosition()) << 3 - | (0x1 & apduSpec.getPinJustification() << 2) - | (0x3 & apduSpec.getPinFormat())); - // bmPINBlockString - s.write((0xF & apduSpec.getPinLengthSize()) << 4 - | (0xF & apduSpec.getPinLength())); - // bmPINLengthFormat - s.write(// system unit = bit - (0xF & apduSpec.getPinLengthPos())); - // bInsertionOffsetOld - s.write(apduSpec.getPinInsertionOffsetOld()); - // bInsertionOffsetNew - s.write(apduSpec.getPinInsertionOffsetNew()); - // wPINMaxExtraDigit - s.write(Math.min(pinSpec.getMaxLength(), getwPINMaxExtraDigitL())); - s.write(Math.max(pinSpec.getMinLength(), getwPINMaxExtraDigitH())); - // bConfirmPIN - s.write(0x03); - // bEntryValidationCondition - s.write(getbEntryValidationCondition()); - // bNumberMessage - s.write(0x03); - // wLangId English (United States), see http://www.usb.org/developers/docs/USB_LANGIDs.pdf - s.write(0x09); - s.write(0x04); - // bMsgIndex1 - s.write(0x00); - // bMsgIndex2 - s.write(0x01); - // bMsgIndex3 - s.write(0x02); - - // bTeoPrologue - s.write(0x00); - s.write(0x00); - s.write(0x00); - // ulDataLength - s.write(apduSpec.getApdu().length); - s.write(0x00); - s.write(0x00); - s.write(0x00); - // abData - try { - s.write(apduSpec.getApdu()); - } catch (IOException e) { - // As we are dealing with ByteArrayOutputStreams no exception is to be - // expected. - throw new RuntimeException(e); - } - - return s.toByteArray(); - - } - - protected byte[] createPINVerifyStructure(VerifyAPDUSpec apduSpec, PINSpec pinSpec) { - - ByteArrayOutputStream s = new ByteArrayOutputStream(); - // bTimeOut - s.write(getbTimeOut()); - // bTimeOut2 - s.write(getbTimeOut2()); - // bmFormatString - s.write(1 << 7 // system unit = byte - | (0xF & apduSpec.getPinPosition()) << 3 - | (0x1 & apduSpec.getPinJustification() << 2) - | (0x3 & apduSpec.getPinFormat())); - // bmPINBlockString - s.write((0xF & apduSpec.getPinLengthSize()) << 4 - | (0xF & apduSpec.getPinLength())); - // bmPINLengthFormat - s.write(// system unit = bit - (0xF & apduSpec.getPinLengthPos())); - // wPINMaxExtraDigit - s.write(Math.min(pinSpec.getMaxLength(), getwPINMaxExtraDigitL())); // max PIN length - s.write(Math.max(pinSpec.getMinLength(), getwPINMaxExtraDigitH())); // min PIN length - // bEntryValidationCondition - s.write(getbEntryValidationCondition()); - // bNumberMessage - s.write(0x01); - // wLangId - s.write(0x09); - s.write(0x04); - // bMsgIndex - s.write(0x00); - // bTeoPrologue - s.write(0x00); - s.write(0x00); - s.write(0x00); - // ulDataLength - s.write(apduSpec.getApdu().length); - s.write(0x00); - s.write(0x00); - s.write(0x00); - // abData - try { - s.write(apduSpec.getApdu()); - } catch (IOException e) { - // As we are dealing with ByteArrayOutputStreams no exception is to be - // expected. - throw new RuntimeException(e); - } - - return s.toByteArray(); - - } - - @Override - public ResponseAPDU verify(CardChannel channel, VerifyAPDUSpec apduSpec, - PINSpec pinSpec, PINProvider provider, int retries) - throws CancelledException, InterruptedException, CardException, - SignatureCardException { - - char[] pin = provider.providePIN(pinSpec, retries); - - ResponseAPDU resp = null; - if (!disablePinpad && hasFeature(FEATURE_MODIFY_PIN_DIRECT)) { - log.debug("VERIFY using " + FEATURES[FEATURE_VERIFY_PIN_DIRECT] + "."); - byte[] s = createPINVerifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(verifyPinDirect(s)); - } else if (!disablePinpad && hasFeature(FEATURE_VERIFY_PIN_START)) { - log.debug("VERIFY using " + FEATURES[FEATURE_MODIFY_PIN_START] + "."); - byte[] s = createPINVerifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(verifyPin(s)); - } - - if (resp != null) { - - switch (resp.getSW()) { - - case 0x6400: - log.debug("SPE operation timed out."); - throw new TimeoutException(); - case 0x6401: - log.debug("SPE operation was cancelled by the 'Cancel' button."); - throw new CancelledException(); - case 0x6103: - log.debug("User entered too short or too long PIN " - + "regarding MIN/MAX PIN length."); - throw new PINFormatException(); - case 0x6480: - log.debug("SPE operation was aborted by the 'Cancel' operation " - + "at the host system."); - case 0x6b80: - log.info("Invalid parameter in passed structure."); - - default: - return resp; - } - - } else { - log.debug("VERIFY using software pin entry."); - return channel.transmit(ISO7816Utils.createVerifyAPDU(apduSpec, pin)); - } - - } - - @Override - public ResponseAPDU modify(CardChannel channel, - ChangeReferenceDataAPDUSpec apduSpec, PINSpec pinSpec, - ChangePINProvider provider, int retries) throws CancelledException, - InterruptedException, CardException, SignatureCardException { - - char[] oldPin = provider.provideOldPIN(pinSpec, retries); - char[] newPin = provider.providePIN(pinSpec, retries); - - ResponseAPDU resp = null; - if (!disablePinpad && hasFeature(FEATURE_MODIFY_PIN_DIRECT)) { - log.debug("MODIFY using " + FEATURES[FEATURE_MODIFY_PIN_DIRECT] + "."); - byte[] s = createPINModifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(modifyPinDirect(s)); - } else if (!disablePinpad && hasFeature(FEATURE_MODIFY_PIN_START)) { - log.debug("MODIFY using " + FEATURES[FEATURE_MODIFY_PIN_START] + "."); - byte[] s = createPINModifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(modifyPin(s)); - } - - if (resp != null) { - - switch (resp.getSW()) { - - case 0x6400: - log.debug("SPE operation timed out."); - throw new TimeoutException(); - case 0x6401: - log.debug("SPE operation was cancelled by the 'Cancel' button."); - throw new CancelledException(); - case 0x6103: - log.debug("User entered too short or too long PIN " - + "regarding MIN/MAX PIN length."); - throw new PINFormatException(); - case 0x6480: - log.debug("SPE operation was aborted by the 'Cancel' operation " - + "at the host system."); - case 0x6b80: - log.info("Invalid parameter in passed structure."); - - default: - return resp; - } - - } else { - log.debug("MODIFY using software pin entry."); - return channel.transmit(ISO7816Utils.createChangeReferenceDataAPDU(apduSpec, oldPin, newPin)); - } - - } - - @Override - public ResponseAPDU activate(CardChannel channel, - NewReferenceDataAPDUSpec apduSpec, PINSpec pinSpec, - PINProvider provider) throws CancelledException, - InterruptedException, CardException, SignatureCardException { - - char[] newPin = provider.providePIN(pinSpec, -1); - - ResponseAPDU resp = null; - if (!disablePinpad && hasFeature(FEATURE_MODIFY_PIN_DIRECT)) { - log.debug("MODIFY using " + FEATURES[FEATURE_MODIFY_PIN_DIRECT] + "."); - byte[] s = createPINModifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(modifyPinDirect(s)); - } else if (!disablePinpad && hasFeature(FEATURE_MODIFY_PIN_START)) { - log.debug("MODIFY using " + FEATURES[FEATURE_MODIFY_PIN_START] + "."); - byte[] s = createPINModifyStructure(apduSpec, pinSpec); - resp = new ResponseAPDU(modifyPin(s)); - } - - if (resp != null) { - - switch (resp.getSW()) { - - case 0x6400: - log.debug("SPE operation timed out."); - throw new TimeoutException(); - case 0x6401: - log.debug("SPE operation was cancelled by the 'Cancel' button."); - throw new CancelledException(); - case 0x6103: - log.debug("User entered too short or too long PIN " - + "regarding MIN/MAX PIN length."); - throw new PINFormatException(); - case 0x6480: - log.debug("SPE operation was aborted by the 'Cancel' operation " - + "at the host system."); - case 0x6b80: - log.info("Invalid parameter in passed structure."); - - default: - return resp; - } - - } else { - log.debug("MODIFY using software pin entry."); - return channel.transmit(ISO7816Utils.createNewReferenceDataAPDU(apduSpec, newPin)); - } - - } - - - - -} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/GemplusGemPCPinpad.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/GemplusGemPCPinpad.java deleted file mode 100644 index ff6d004b..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/GemplusGemPCPinpad.java +++ /dev/null @@ -1,46 +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.smcc.ccid; - -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * bTimeOut = 15sec (too short, leave value from DefaultRearder), - * however, max is something near 40sec - * @author Clemens Orthacker - */ -public class GemplusGemPCPinpad extends DefaultReader { - - protected final static Log log = LogFactory.getLog(GemplusGemPCPinpad.class); - - public GemplusGemPCPinpad(Card icc, CardTerminal ct) { - super(icc, ct); - } - - @Override - public byte getwPINMaxExtraDigitL() { - return (byte) 0x08; - } - - @Override - public byte getwPINMaxExtraDigitH() { - return (byte) 0x04; - } -} 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 deleted file mode 100644 index d8a6b40d..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/OMNIKEYCardMan3621.java +++ /dev/null @@ -1,44 +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.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 - */ -public class OMNIKEYCardMan3621 extends DefaultReader { - - public static final byte wPINMaxExtraDigitH = 0x01; - - protected static final Log log = LogFactory.getLog(OMNIKEYCardMan3621.class); - - public OMNIKEYCardMan3621(Card icc, CardTerminal ct) { - super(icc, ct); - } - - @Override - public byte getwPINMaxExtraDigitH() { - return wPINMaxExtraDigitH; - } -} 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 deleted file mode 100644 index 43949f42..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/ReaderFactory.java +++ /dev/null @@ -1,89 +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.smcc.ccid; - -import at.gv.egiz.smcc.conf.SMCCConfiguration; -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * - * @author Clemens Orthacker - */ -public class ReaderFactory { - - protected final static Log log = LogFactory.getLog(ReaderFactory.class); - - protected SMCCConfiguration configuration; - private static ReaderFactory instance; - - private ReaderFactory() { - } - - public static ReaderFactory getInstance() { - if (instance == null) { - instance = new ReaderFactory(); - } - return instance; - } - - /** - * @param configuration the configuration to set - */ - public void setConfiguration(SMCCConfiguration configuration) { - this.configuration = configuration; - } - - public CCID getReader(Card icc, CardTerminal ct) { - CCID reader; - String name = ct.getName(); - if (name != null) { - log.info("creating reader " + name); - name = name.toLowerCase(); - //ReinerSCT: http://support.reiner-sct.de/downloads/LINUX - // http://www.linux-club.de/viewtopic.php?f=61&t=101287&start=0 - //old: REINER SCT CyberJack 00 00 - //new (CCID): 0C4B/0300 Reiner-SCT cyberJack pinpad(a) 00 00 - //Mac "Snow Leopard": Reiner-SCT cyberJack pinpad(a) 00 00 - //display: REINER SCT CyberJack 00 00 - if(name.startsWith("gemplus gempc pinpad") || name.startsWith("gemalto gempc pinpad")) { - reader = new GemplusGemPCPinpad(icc, ct); - } else if (name.startsWith("omnikey cardman 3621")) { - reader = new OMNIKEYCardMan3621(icc, ct); - } else if (name.startsWith("scm spr 532") || name.startsWith("scm microsystems inc. sprx32 usb smart card reader")) { - reader = new SCMMicrosystemsSPRx32(icc, ct); - } else if (name.startsWith("cherry smartboard xx44")) { - reader = new CherrySmartBoardXX44(icc, ct); - } else { - log.info("no suitable implementation found, using default"); - reader = new DefaultReader(icc, ct); - } - } else { - reader = new DefaultReader(icc, ct); - } - - if (configuration != null) { - String disablePinpad = configuration.getProperty(SMCCConfiguration.DISABLE_PINPAD_P); - log.debug("setting disablePinpad to " + Boolean.parseBoolean(disablePinpad)); - reader.setDisablePinpad(Boolean.parseBoolean(disablePinpad)); - } - return reader; - } -} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ccid/SCMMicrosystemsSPRx32.java b/smcc/src/main/java/at/gv/egiz/smcc/ccid/SCMMicrosystemsSPRx32.java deleted file mode 100644 index 133bc350..00000000 --- a/smcc/src/main/java/at/gv/egiz/smcc/ccid/SCMMicrosystemsSPRx32.java +++ /dev/null @@ -1,51 +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.smcc.ccid; - -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * bTimeOut: spr532 (win driver) interprets 0x00 as zero sec - * instead of default - * - * @author Clemens Orthacker - */ -public class SCMMicrosystemsSPRx32 extends DefaultReader { - - public static final byte bTimeOut = 0x3c; - public static final byte bTimeOut2 = 0x0f; - - protected final static Log log = LogFactory.getLog(SCMMicrosystemsSPRx32.class); - - public SCMMicrosystemsSPRx32(Card icc, CardTerminal ct) { - super(icc, ct); - } - - @Override - public byte getbTimeOut() { - return bTimeOut; - } - - @Override - public byte getbTimeOut2() { - return bTimeOut2; - } - -} -- cgit v1.2.3