From c2ae3db1bc6dcb8ba3eb3461c05e293917c004ca Mon Sep 17 00:00:00 2001 From: mcentner Date: Thu, 30 Oct 2008 10:33:29 +0000 Subject: Updated SMCC to use exclusive access and to throw exceptions upon locked or not activated cards. Improved locale support in the security layer request and response processing. Fixed issue in STAL which prevented the use of RSA-SHA1 signatures. Added additional parameters to the applet test pages. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@128 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/smcc/SignatureCardFactory.java | 223 ++++++++++++++++++--- 1 file changed, 198 insertions(+), 25 deletions(-) (limited to 'smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java index 2131a737..777299d9 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java @@ -28,19 +28,189 @@ // package at.gv.egiz.smcc; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import javax.smartcardio.ATR; import javax.smartcardio.Card; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A factory for creating {@link SignatureCard}s from {@link Card}s. + */ public class SignatureCardFactory { + + /** + * This class represents a supported smart card. + */ + private class SupportedCard { + + /** + * The ATR pattern. + */ + private byte[] atrPattern; + + /** + * The ATR mask. + */ + private byte[] atrMask; + + /** + * The implementation class. + */ + private String impl; - public static SignatureCardFactory getInstance() { - return new SignatureCardFactory(); + /** + * Creates a new SupportedCard instance with the given ATR pattern and mask + * und the corresponding implementation class. + * + * @param atrPattern + * the ATR pattern + * @param atrMask + * the ATR mask + * @param implementationClass + * the name of the implementation class + * + * @throws NullPointerException + * if atrPattern or atrMask is + * null. + * @throws IllegalArgumentException + * if the lengths of atrPattern and + * atrMask of not equal. + */ + public SupportedCard(byte[] atrPattern, byte[] atrMask, String implementationClass) { + if (atrPattern.length != atrMask.length) { + throw new IllegalArgumentException("Length of 'atr' and 'mask' must be equal."); + } + this.atrPattern = atrPattern; + this.atrMask = atrMask; + this.impl = implementationClass; + } + + /** + * Returns true if the given ATR matches the ATR pattern and mask this + * SupportedCard object. + * + * @param atr + * the ATR + * + * @return true if the given ATR matches the ATR pattern and + * mask of this SupportedCard object, or false + * otherwise. + */ + public boolean matches(ATR atr) { + + byte[] bytes = atr.getBytes(); + if (bytes == null) { + return false; + } + if (bytes.length < atrMask.length) { + // we cannot test for equal length here, as we get ATRs with + // additional bytes on systems using PCSClite (e.g. linux and OS X) sometimes + return false; + } + + int l = Math.min(atrMask.length, bytes.length); + for (int i = 0; i < l; i++) { + if ((bytes[i] & atrMask[i]) != atrPattern[i]) { + return false; + } + } + return true; + + } + + /** + * @return the corresponding implementation class. + */ + public String getImplementationClassName() { + return impl; + } + + } + + /** + * Logging facility. + */ + private static Log log = LogFactory.getLog(SignatureCardFactory.class); + + /** + * The instance to be returned by {@link #getInstance()}. + */ + private static SignatureCardFactory instance; + + /** + * The list of supported smart cards. + */ + private List supportedCards; + + /** + * @return an instance of this SignatureCardFactory. + */ + public static synchronized SignatureCardFactory getInstance() { + if (instance == null) { + instance = new SignatureCardFactory(); + } + return instance; } + /** + * Private constructor. + */ private SignatureCardFactory() { + + supportedCards = new ArrayList(); + + // e-card + supportedCards.add(new SupportedCard( + // ATR (3b:bd:18:00:81:31:fe:45:80:51:02:00:00:00:00:00:00:00:00:00:00:00) + new byte[] { + (byte) 0x3b, (byte) 0xbd, (byte) 0x18, (byte) 0x00, (byte) 0x81, (byte) 0x31, (byte) 0xfe, (byte) 0x45, + (byte) 0x80, (byte) 0x51, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00:00) + new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + "at.gv.egiz.smcc.STARCOSCard")); + // a-sign premium + supportedCards.add(new SupportedCard( + // ATR (3b:bf:11:00:81:31:fe:45:45:50:41:00:00:00:00:00:00:00:00:00:00:00:00:00) + new byte[] { + (byte) 0x3b, (byte) 0xbf, (byte) 0x11, (byte) 0x00, (byte) 0x81, (byte) 0x31, (byte) 0xfe, (byte) 0x45, + (byte) 0x45, (byte) 0x50, (byte) 0x41, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00:00:00:00:00:00) + new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + "at.gv.egiz.smcc.ACOSCard")); + } + /** + * Creates a SignatureCard instance with the given smart card. + * + * @param card + * the smart card, or null if a software card should be + * created + * + * @return a SignatureCard instance + * + * @throws CardNotSupportedException + * if no implementation of the given card could be + * found + */ public SignatureCard createSignatureCard(Card card) throws CardNotSupportedException { @@ -51,31 +221,34 @@ public class SignatureCardFactory { } ATR atr = card.getATR(); - byte[] historicalBytes = atr.getHistoricalBytes(); - if(historicalBytes == null || historicalBytes.length < 3) { - throw new CardNotSupportedException("Card not supported: ATR=" + toString(atr.getBytes())); + Iterator cards = supportedCards.iterator(); + while (cards.hasNext()) { + SupportedCard supportedCard = cards.next(); + if(supportedCard.matches(atr)) { + + ClassLoader cl = SignatureCardFactory.class.getClassLoader(); + SignatureCard sc; + try { + Class scClass = cl.loadClass(supportedCard.getImplementationClassName()); + sc = (SignatureCard) scClass.newInstance(); + sc.init(card); + return sc; + + } catch (ClassNotFoundException e) { + log.warn("Cannot find signature card implementation class.", e); + throw new CardNotSupportedException("Cannot find signature card implementation class.", e); + } catch (InstantiationException e) { + log.warn("Failed to instantiate signature card implementation.", e); + throw new CardNotSupportedException("Failed to instantiate signature card implementation.", e); + } catch (IllegalAccessException e) { + log.warn("Failed to instantiate signature card implementation.", e); + throw new CardNotSupportedException("Failed to instantiate signature card implementation.", e); + } + + } } - int t = ((0xFF & (int) historicalBytes[0]) << 16) + - ((0xFF & (int) historicalBytes[1]) << 8) + - (0xFF & (int) historicalBytes[2]); - - SignatureCard sCard; - switch (t) { - case 0x455041 : - case 0x4D4341 : - sCard = new ACOSCard(); - break; - - case 0x805102 : - sCard = new STARCOSCard(); - break; - - default : - throw new CardNotSupportedException("Card not supported: ATR=" + toString(atr.getBytes())); - } - sCard.init(card); - return sCard; + throw new CardNotSupportedException("Card not supported: ATR=" + toString(atr.getBytes())); } -- cgit v1.2.3