From b1c8641a63a67e3c64d948f9e8dce5c01e11e2dd Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 5 May 2010 15:29:01 +0000 Subject: Merged feature branch mocca-1.2.13-id@r724 back to trunk. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@725 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/smcc/util/ISO7816Utils.java | 51 ++- .../main/java/at/gv/egiz/smcc/util/SMCCHelper.java | 268 +++++++-------- .../java/at/gv/egiz/smcc/util/SmartCardIO.java | 358 ++++++++++----------- 3 files changed, 350 insertions(+), 327 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/util') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java index fcd0b876..05249a5e 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java @@ -286,12 +286,18 @@ public class ISO7816Utils { public static CommandAPDU createVerifyAPDU(VerifyAPDUSpec apduSpec, char[] pin) { // format pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; + int l = (apduSpec.getPinLength() > 0) ? apduSpec.getPinLength() : pin.length; + byte[] fpin = new byte[l]; + byte[] mask = new byte[l]; formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, pin); - byte[] apdu = apduSpec.getApdu(); - + byte[] template = apduSpec.getApdu(); + byte[] apdu = new byte[Math.max(template.length, 5 + apduSpec.getPinPosition() + l)]; + System.arraycopy(template, 0, apdu, 0, template.length); + if (template.length < 5) { + apdu[4] = (byte) (apdu.length - 5); + } + // insert formated pin insertPIN(apdu, apduSpec.getPinPosition() + 5, fpin, mask); @@ -307,13 +313,24 @@ public class ISO7816Utils { public static CommandAPDU createChangeReferenceDataAPDU( ChangeReferenceDataAPDUSpec apduSpec, char[] oldPin, char[] newPin) { + int lo = (apduSpec.getPinLength() > 0) ? apduSpec.getPinLength() : oldPin.length; + int ln = (apduSpec.getPinLength() > 0) ? apduSpec.getPinLength() : newPin.length; + // format old pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; + byte[] fpin = new byte[lo]; + byte[] mask = new byte[lo]; formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, oldPin); - byte[] apdu = apduSpec.getApdu(); - + byte[] template = apduSpec.getApdu(); + byte[] apdu = new byte[Math.max(template.length, + 5 + apduSpec.getPinPosition() + + Math.max(apduSpec.getPinInsertionOffsetOld() + lo, + apduSpec.getPinInsertionOffsetNew() + ln))]; + System.arraycopy(template, 0, apdu, 0, template.length); + if (template.length < 5) { + apdu[4] = (byte) (apdu.length - 5); + } + // insert formated old pin insertPIN(apdu, apduSpec.getPinPosition() + apduSpec.getPinInsertionOffsetOld() + 5, fpin, mask); @@ -324,8 +341,8 @@ public class ISO7816Utils { } // format new pin - fpin = new byte[apduSpec.getPinLength()]; - mask = new byte[apduSpec.getPinLength()]; + fpin = new byte[ln]; + mask = new byte[ln]; formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, newPin); // insert formated new pin @@ -345,12 +362,18 @@ public class ISO7816Utils { NewReferenceDataAPDUSpec apduSpec, char[] newPin) { // format old pin - byte[] fpin = new byte[apduSpec.getPinLength()]; - byte[] mask = new byte[apduSpec.getPinLength()]; + int l = (apduSpec.getPinLength() > 0) ? apduSpec.getPinLength() : newPin.length; + byte[] fpin = new byte[l]; + byte[] mask = new byte[l]; formatPIN(apduSpec.getPinFormat(), apduSpec.getPinJustification(), fpin, mask, newPin); - byte[] apdu = apduSpec.getApdu(); - + byte[] template = apduSpec.getApdu(); + byte[] apdu = new byte[Math.max(template.length, 5 + apduSpec.getPinPosition() + l)]; + System.arraycopy(template, 0, apdu, 0, template.length); + if (template.length < 5) { + apdu[4] = (byte) (apdu.length - 5); + } + // insert formated new pin insertPIN(apdu, apduSpec.getPinPosition() + apduSpec.getPinInsertionOffsetNew() + 5, fpin, mask); diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java b/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java index f7d3bab7..a06fb624 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java @@ -14,137 +14,137 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.smcc.util; - -import java.util.Locale; -import java.util.Map; - -import javax.smartcardio.ATR; -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.smcc.CardNotSupportedException; -import at.gv.egiz.smcc.SignatureCard; -import at.gv.egiz.smcc.SignatureCardFactory; - -public class SMCCHelper { - - public final static int NO_CARD = 0; - public final static int PC_SC_NOT_SUPPORTED = 1; - public final static int TERMINAL_NOT_PRESENT = 2; - public final static int CARD_NOT_SUPPORTED = 3; - public final static int CARD_FOUND = 4; - - private final static Log log = LogFactory.getLog(SMCCHelper.class); - - protected SmartCardIO smartCardIO = new SmartCardIO(); - protected int resultCode = NO_CARD; - protected SignatureCard signatureCard = null; - protected static boolean useSWCard = false; - - public SMCCHelper() { - update(); - } - - public synchronized void update() { - update(-1); - } - - public synchronized void update(int sleep) { - SignatureCardFactory factory = SignatureCardFactory.getInstance(); - if (useSWCard) { - try { - signatureCard = factory.createSignatureCard(null, null); - resultCode = CARD_FOUND; - } catch (CardNotSupportedException e) { - resultCode = CARD_NOT_SUPPORTED; - signatureCard = null; - } - return; - } - signatureCard = null; - resultCode = NO_CARD; - // find pcsc support - if (smartCardIO.isPCSCSupported()) { - // find supported card - if (smartCardIO.isTerminalPresent()) { - Map newCards = null; - if (sleep > 0) { - smartCardIO.waitForInserted(sleep); - - } - newCards = smartCardIO.getCards(); - for (CardTerminal cardTerminal : newCards.keySet()) { - try { - Card c = newCards.get(cardTerminal); - if (c == null) { - throw new CardNotSupportedException(); - } - signatureCard = factory.createSignatureCard(c, cardTerminal); - ATR atr = newCards.get(cardTerminal).getATR(); - log.trace("Found supported card (" + signatureCard.toString() + ") " - + "in terminal '" + cardTerminal.getName() + "', ATR = " - + toString(atr.getBytes()) + "."); - resultCode = CARD_FOUND; - break; - - } catch (CardNotSupportedException e) { - Card c = newCards.get(cardTerminal); - if (c != null) { - ATR atr = c.getATR(); - log.info("Found unsupported card" + " in terminal '" - + cardTerminal.getName() + "', ATR = " - + toString(atr.getBytes()) + "."); - } else { - log.info("Found unsupported card in terminal '" - + cardTerminal.getName() + "' without ATR"); - } - resultCode = CARD_NOT_SUPPORTED; - } - } - } else { - resultCode = TERMINAL_NOT_PRESENT; - } - } else { - resultCode = PC_SC_NOT_SUPPORTED; - } - } - - public synchronized SignatureCard getSignatureCard(Locale locale) { - if (signatureCard != null) { - signatureCard.setLocale(locale); - } - return signatureCard; - } - - public int getResultCode() { - return resultCode; - } - - public static String toString(byte[] b) { - StringBuffer sb = new StringBuffer(); - sb.append('['); - if (b != null && b.length > 0) { - sb.append(Integer.toHexString((b[0] & 240) >> 4)); - sb.append(Integer.toHexString(b[0] & 15)); - for (int i = 1; i < b.length; i++) { - sb.append((i % 32 == 0) ? '\n' : ':'); - sb.append(Integer.toHexString((b[i] & 240) >> 4)); - sb.append(Integer.toHexString(b[i] & 15)); - } - } - sb.append(']'); - return sb.toString(); - } - - public static boolean isUseSWCard() { - return useSWCard; - } - - public static void setUseSWCard(boolean useSWCard) { - SMCCHelper.useSWCard = useSWCard; - } -} +package at.gv.egiz.smcc.util; + +import java.util.Locale; +import java.util.Map; + +import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.smcc.CardNotSupportedException; +import at.gv.egiz.smcc.SignatureCard; +import at.gv.egiz.smcc.SignatureCardFactory; + +public class SMCCHelper { + + public final static int NO_CARD = 0; + public final static int PC_SC_NOT_SUPPORTED = 1; + public final static int TERMINAL_NOT_PRESENT = 2; + public final static int CARD_NOT_SUPPORTED = 3; + public final static int CARD_FOUND = 4; + + private final Logger log = LoggerFactory.getLogger(SMCCHelper.class); + + protected SmartCardIO smartCardIO = new SmartCardIO(); + protected int resultCode = NO_CARD; + protected SignatureCard signatureCard = null; + protected static boolean useSWCard = false; + + public SMCCHelper() { + update(); + } + + public synchronized void update() { + update(-1); + } + + public synchronized void update(int sleep) { + SignatureCardFactory factory = SignatureCardFactory.getInstance(); + if (useSWCard) { + try { + signatureCard = factory.createSignatureCard(null, null); + resultCode = CARD_FOUND; + } catch (CardNotSupportedException e) { + resultCode = CARD_NOT_SUPPORTED; + signatureCard = null; + } + return; + } + signatureCard = null; + resultCode = NO_CARD; + // find pcsc support + if (smartCardIO.isPCSCSupported()) { + // find supported card + if (smartCardIO.isTerminalPresent()) { + Map newCards = null; + if (sleep > 0) { + smartCardIO.waitForInserted(sleep); + + } + newCards = smartCardIO.getCards(); + for (CardTerminal cardTerminal : newCards.keySet()) { + try { + Card c = newCards.get(cardTerminal); + if (c == null) { + throw new CardNotSupportedException(); + } + signatureCard = factory.createSignatureCard(c, cardTerminal); + if (log.isTraceEnabled()) { + Object[] args = { signatureCard, cardTerminal.getName(), + toString(newCards.get(cardTerminal).getATR().getBytes()) }; + log.trace("Found supported card ({}) in terminal '{}', ATR = {}.", args); + } + resultCode = CARD_FOUND; + break; + + } catch (CardNotSupportedException e) { + Card c = newCards.get(cardTerminal); + if (c != null) { + Object[] args = { cardTerminal.getName(), + toString(c.getATR().getBytes()) }; + log.info("Found unsupported card in terminal '{}', ATR = {}.", + args); + } else { + log.info("Found unsupported card in terminal '{}' without ATR.", + cardTerminal.getName()); + } + resultCode = CARD_NOT_SUPPORTED; + } + } + } else { + resultCode = TERMINAL_NOT_PRESENT; + } + } else { + resultCode = PC_SC_NOT_SUPPORTED; + } + } + + public synchronized SignatureCard getSignatureCard(Locale locale) { + if (signatureCard != null) { + signatureCard.setLocale(locale); + } + return signatureCard; + } + + public int getResultCode() { + return resultCode; + } + + public static String toString(byte[] b) { + StringBuffer sb = new StringBuffer(); + sb.append('['); + if (b != null && b.length > 0) { + sb.append(Integer.toHexString((b[0] & 240) >> 4)); + sb.append(Integer.toHexString(b[0] & 15)); + for (int i = 1; i < b.length; i++) { + sb.append((i % 32 == 0) ? '\n' : ':'); + sb.append(Integer.toHexString((b[i] & 240) >> 4)); + sb.append(Integer.toHexString(b[i] & 15)); + } + } + sb.append(']'); + return sb.toString(); + } + + public static boolean isUseSWCard() { + return useSWCard; + } + + public static void setUseSWCard(boolean useSWCard) { + SMCCHelper.useSWCard = useSWCard; + } +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java b/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java index b1866894..14ee7549 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java @@ -14,191 +14,191 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.smcc.util; - +package at.gv.egiz.smcc.util; + import java.security.NoSuchAlgorithmException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.smartcardio.Card; -import javax.smartcardio.CardException; -import javax.smartcardio.CardTerminal; -import javax.smartcardio.CardTerminals; -import javax.smartcardio.TerminalFactory; -import javax.smartcardio.CardTerminals.State; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * - * @author mcentner - */ -public class SmartCardIO { - - private static final int STATE_INITIALIZED = 1; - - private static final int STATE_TERMINAL_FACTORY = 2; - - private static final int STATE_TERMINALS = 3; - - private static Log log = LogFactory.getLog(SmartCardIO.class); - - final Map terminalCard_ = new HashMap(); - - int state_ = STATE_INITIALIZED; - - TerminalFactory terminalFactory_ = null; - - CardTerminals cardTerminals_; - - private void updateTerminalFactory() { +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.smartcardio.Card; +import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; +import javax.smartcardio.CardTerminals; +import javax.smartcardio.TerminalFactory; +import javax.smartcardio.CardTerminals.State; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author mcentner + */ +public class SmartCardIO { + + private static final int STATE_INITIALIZED = 1; + + private static final int STATE_TERMINAL_FACTORY = 2; + + private static final int STATE_TERMINALS = 3; + + private final Logger log = LoggerFactory.getLogger(SmartCardIO.class); + + final Map terminalCard_ = new HashMap(); + + int state_ = STATE_INITIALIZED; + + TerminalFactory terminalFactory_ = null; + + CardTerminals cardTerminals_; + + private void updateTerminalFactory() { TerminalFactory terminalFactory; try { terminalFactory = TerminalFactory.getInstance("PC/SC", null); } catch (NoSuchAlgorithmException e) { log.info("Failed to get TerminalFactory of type 'PC/SC'.", e); terminalFactory = TerminalFactory.getDefault(); - } - log.debug("TerminalFactory : " + terminalFactory); - if ("PC/SC".equals(terminalFactory.getType())) { - terminalFactory_ = terminalFactory; - } - if(state_ < STATE_TERMINAL_FACTORY) { - state_ = STATE_TERMINAL_FACTORY; - } - } - - public boolean isPCSCSupported() { - if(state_ < STATE_TERMINAL_FACTORY) { - updateTerminalFactory(); - } - return terminalFactory_ != null; - } - - private void updateCardTerminals() { - if(terminalFactory_ != null) { - cardTerminals_ = terminalFactory_.terminals(); - } - log.debug("CardTerminals : " + cardTerminals_); - if (state_ < STATE_TERMINALS) { - state_ = STATE_TERMINALS; - } - } - - public CardTerminals getCardTerminals() { - if(state_ < STATE_TERMINAL_FACTORY) { - updateTerminalFactory(); - } - if(state_ < STATE_TERMINALS) { - updateCardTerminals(); - } - return cardTerminals_; - } - - public boolean isTerminalPresent() { - CardTerminals cardTerminals = getCardTerminals(); - if (cardTerminals != null) { - List terminals = null; - try { - terminals = cardTerminals.list(State.ALL); - - // logging - if(log.isInfoEnabled()) { - if (terminals == null || terminals.isEmpty()) { - log.info("No card terminal found."); - } else { - StringBuffer msg = new StringBuffer(); - msg.append("Found " + terminals.size() + " card terminal(s):"); - for (CardTerminal terminal : terminals) { - msg.append("\n " + terminal.getName()); - } - log.info(msg.toString()); - } - } - - return terminals != null && !terminals.isEmpty(); - } catch (CardException e) { - log.info("Failed to list card terminals.", e); - return false; - } - } else { - return false; - } - } - - private Map updateCards() { - - // clear card references if removed - try { - log.trace("terminals.list(State.CARD_REMOVAL)"); - for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_REMOVAL)) { - Card card = terminalCard_.remove(terminal); - log.trace("card removed : " + card); - } - } catch (CardException e) { - log.debug(e); - } - - // check inserted cards - Map newCards = new HashMap(); - try { - log.trace("terminals.list(State.CARD_INSERTION)"); - for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_INSERTION)) { - - Card card = null; + } + log.debug("TerminalFactory : {}.", terminalFactory); + if ("PC/SC".equals(terminalFactory.getType())) { + terminalFactory_ = terminalFactory; + } + if(state_ < STATE_TERMINAL_FACTORY) { + state_ = STATE_TERMINAL_FACTORY; + } + } + + public boolean isPCSCSupported() { + if(state_ < STATE_TERMINAL_FACTORY) { + updateTerminalFactory(); + } + return terminalFactory_ != null; + } + + private void updateCardTerminals() { + if(terminalFactory_ != null) { + cardTerminals_ = terminalFactory_.terminals(); + } + log.debug("CardTerminals : {}.", cardTerminals_); + if (state_ < STATE_TERMINALS) { + state_ = STATE_TERMINALS; + } + } + + public CardTerminals getCardTerminals() { + if(state_ < STATE_TERMINAL_FACTORY) { + updateTerminalFactory(); + } + if(state_ < STATE_TERMINALS) { + updateCardTerminals(); + } + return cardTerminals_; + } + + public boolean isTerminalPresent() { + CardTerminals cardTerminals = getCardTerminals(); + if (cardTerminals != null) { + List terminals = null; + try { + terminals = cardTerminals.list(State.ALL); + + // logging + if(log.isInfoEnabled()) { + if (terminals == null || terminals.isEmpty()) { + log.info("No card terminal found."); + } else { + StringBuffer msg = new StringBuffer(); + msg.append("Found " + terminals.size() + " card terminal(s):"); + for (CardTerminal terminal : terminals) { + msg.append("\n " + terminal.getName()); + } + log.info(msg.toString()); + } + } + + return terminals != null && !terminals.isEmpty(); + } catch (CardException e) { + log.info("Failed to list card terminals.", e); + return false; + } + } else { + return false; + } + } + + private Map updateCards() { + + // clear card references if removed + try { + log.trace("terminals.list(State.CARD_REMOVAL)"); + for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_REMOVAL)) { + Card card = terminalCard_.remove(terminal); + log.trace("card removed : {}", card); + } + } catch (CardException e) { + log.debug("Failed to list terminals.", e); + } + + // check inserted cards + Map newCards = new HashMap(); + try { + log.trace("terminals.list(State.CARD_INSERTION)"); + for (CardTerminal terminal : cardTerminals_.list(CardTerminals.State.CARD_INSERTION)) { + + Card card = null; try { log.trace("Trying to connect to card."); - // try to connect to card - card = terminal.connect("*"); - } catch (CardException e) { - log.trace("Failed to connect to card.", e); - } - - // have we seen this card before? - if (terminalCard_.put(terminal, card) == null) { - terminalCard_.put(terminal, card); - newCards.put(terminal, card); - log.trace("terminal '" + terminal + "' card inserted : " + card); - } - } - } catch (CardException e) { - log.debug(e); - } - return newCards; - - } - - public Map getCards() { - if(state_ < STATE_TERMINAL_FACTORY) { - updateTerminalFactory(); - } - if(state_ < STATE_TERMINALS) { - updateCardTerminals(); - } - updateCards(); - Map terminalCard = new HashMap(); - terminalCard.putAll(terminalCard_); - return Collections.unmodifiableMap(terminalCard); - } - - public Map waitForInserted(int timeout) { - if(state_ < STATE_TERMINAL_FACTORY) { - updateTerminalFactory(); - } - if(state_ < STATE_TERMINALS) { - updateCardTerminals(); - } - try { - // just waiting for a short period of time to allow for abort - cardTerminals_.waitForChange(timeout); - } catch (CardException e) { - log.debug("CardTerminals.waitForChange(" + timeout + ") failed.", e); - } - Map newCards = new HashMap(); - newCards.putAll(updateCards()); - return Collections.unmodifiableMap(newCards); - } -} \ No newline at end of file + // try to connect to card + card = terminal.connect("*"); + } catch (CardException e) { + log.trace("Failed to connect to card.", e); + } + + // have we seen this card before? + if (terminalCard_.put(terminal, card) == null) { + terminalCard_.put(terminal, card); + newCards.put(terminal, card); + log.trace("terminal '{}' card inserted : {}", terminal, card); + } + } + } catch (CardException e) { + log.debug("Failed to list cards.", e); + } + return newCards; + + } + + public Map getCards() { + if(state_ < STATE_TERMINAL_FACTORY) { + updateTerminalFactory(); + } + if(state_ < STATE_TERMINALS) { + updateCardTerminals(); + } + updateCards(); + Map terminalCard = new HashMap(); + terminalCard.putAll(terminalCard_); + return Collections.unmodifiableMap(terminalCard); + } + + public Map waitForInserted(int timeout) { + if(state_ < STATE_TERMINAL_FACTORY) { + updateTerminalFactory(); + } + if(state_ < STATE_TERMINALS) { + updateCardTerminals(); + } + try { + // just waiting for a short period of time to allow for abort + cardTerminals_.waitForChange(timeout); + } catch (CardException e) { + log.debug("CardTerminals.waitForChange({}) failed.", timeout, e); + } + Map newCards = new HashMap(); + newCards.putAll(updateCards()); + return Collections.unmodifiableMap(newCards); + } +} -- cgit v1.2.3