From 2df9621154ad057f6cace73efe49c9ef42515fde Mon Sep 17 00:00:00 2001 From: mcentner Date: Tue, 9 Dec 2008 08:14:43 +0000 Subject: Refactored STAL interface. Additional infobox functionality. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@236 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/smcc/AbstractSignatureCard.java | 30 ++++++++++++++++++++-- smcc/src/main/java/at/gv/egiz/smcc/SWCard.java | 12 ++++++++- .../main/java/at/gv/egiz/smcc/SignatureCard.java | 12 ++++++++- .../java/at/gv/egiz/smcc/SignatureCardFactory.java | 8 +++--- .../main/java/at/gv/egiz/smcc/util/SMCCHelper.java | 4 +-- .../java/at/gv/egiz/smcc/util/SmartCardIO.java | 9 ++++++- 6 files changed, 65 insertions(+), 10 deletions(-) (limited to 'smcc/src') diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java index b828e8cd..e34c4899 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java @@ -36,6 +36,7 @@ import javax.smartcardio.ATR; import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; @@ -53,7 +54,12 @@ public abstract class AbstractSignatureCard implements SignatureCard { int ifs_ = 254; - Card card_; + private Card card_; + + /** + * The card terminal that connects the {@link #card_}. + */ + private CardTerminal cardTerminal; protected AbstractSignatureCard(String resourceBundleName) { this.resourceBundleName = resourceBundleName; @@ -331,8 +337,9 @@ public abstract class AbstractSignatureCard implements SignatureCard { } - public void init(Card card) { + public void init(Card card, CardTerminal cardTerminal) { card_ = card; + this.cardTerminal = cardTerminal; ATR atr = card.getATR(); byte[] atrBytes = atr.getBytes(); if (atrBytes.length >= 6) { @@ -340,6 +347,11 @@ public abstract class AbstractSignatureCard implements SignatureCard { log.trace("Setting IFS (information field size) to " + ifs_); } } + + @Override + public Card getCard() { + return card_; + } protected CardChannel getCardChannel() { return card_.getBasicChannel(); @@ -372,4 +384,18 @@ public abstract class AbstractSignatureCard implements SignatureCard { } } + @Override + public void reset() throws SignatureCardException { + try { + log.debug("Disconnect and reset smart card."); + card_.disconnect(true); + log.debug("Reconnect smart card."); + if (cardTerminal != null) { + card_ = cardTerminal.connect("*"); + } + } catch (CardException e) { + throw new SignatureCardException("Failed to reset card.", e); + } + } + } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java index 42943541..439be034 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java @@ -40,6 +40,7 @@ import java.util.Enumeration; import java.util.Locale; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -102,7 +103,12 @@ public class SWCard implements SignatureCard { SWCard.swCardDir = swCardDir; } - public void init(Card card) { + public void init(Card card, CardTerminal cardTerminal) { + } + + @Override + public Card getCard() { + return null; } private String getFileName(String fileName) { @@ -379,4 +385,8 @@ public class SWCard implements SignatureCard { public void disconnect(boolean reset) { } + @Override + public void reset() throws SignatureCardException { + } + } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java index b6a453df..d7e76dd8 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java @@ -31,6 +31,7 @@ package at.gv.egiz.smcc; import java.util.Locale; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; public interface SignatureCard { @@ -75,12 +76,21 @@ public interface SignatureCard { } - public void init(Card card); + public void init(Card card, CardTerminal cardTerminal); + + public Card getCard(); public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException; public void disconnect(boolean reset); + + /** + * Performs a reset of the card. + * + * @throws SignatureCardException if reset fails. + */ + public void reset() throws SignatureCardException; /** * 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 777299d9..ab66e9a1 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java @@ -34,6 +34,7 @@ import java.util.List; import javax.smartcardio.ATR; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -204,6 +205,7 @@ public class SignatureCardFactory { * @param card * the smart card, or null if a software card should be * created + * @param cardTerminal TODO * * @return a SignatureCard instance * @@ -211,12 +213,12 @@ public class SignatureCardFactory { * if no implementation of the given card could be * found */ - public SignatureCard createSignatureCard(Card card) + public SignatureCard createSignatureCard(Card card, CardTerminal cardTerminal) throws CardNotSupportedException { if(card == null) { SignatureCard sCard = new SWCard(); - sCard.init(card); + sCard.init(card, cardTerminal); return sCard; } @@ -231,7 +233,7 @@ public class SignatureCardFactory { try { Class scClass = cl.loadClass(supportedCard.getImplementationClassName()); sc = (SignatureCard) scClass.newInstance(); - sc.init(card); + sc.init(card, cardTerminal); return sc; } catch (ClassNotFoundException e) { 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 4dae7975..f7d3bab7 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 @@ -57,7 +57,7 @@ public class SMCCHelper { SignatureCardFactory factory = SignatureCardFactory.getInstance(); if (useSWCard) { try { - signatureCard = factory.createSignatureCard(null); + signatureCard = factory.createSignatureCard(null, null); resultCode = CARD_FOUND; } catch (CardNotSupportedException e) { resultCode = CARD_NOT_SUPPORTED; @@ -83,7 +83,7 @@ public class SMCCHelper { if (c == null) { throw new CardNotSupportedException(); } - signatureCard = factory.createSignatureCard(c); + signatureCard = factory.createSignatureCard(c, cardTerminal); ATR atr = newCards.get(cardTerminal).getATR(); log.trace("Found supported card (" + signatureCard.toString() + ") " + "in terminal '" + cardTerminal.getName() + "', ATR = " 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 b70b44a7..b1866894 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 @@ -16,6 +16,7 @@ */ package at.gv.egiz.smcc.util; +import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -54,7 +55,13 @@ public class SmartCardIO { CardTerminals cardTerminals_; private void updateTerminalFactory() { - TerminalFactory terminalFactory = TerminalFactory.getDefault(); + 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; -- cgit v1.2.3 From 887f6727479f3ae3d89a08ba619f9382b450e4c1 Mon Sep 17 00:00:00 2001 From: mcentner Date: Fri, 12 Dec 2008 11:48:47 +0000 Subject: Updated SMCC to support non-blocking PIN entry. Added SV-Personendaten infobox implementation. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@248 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../src/main/webapp/WEB-INF/applicationContext.xml | 3 + .../gv/egiz/bku/binding/DataUrlConnectionImpl.java | 1 + .../bku/binding/LegacyDataUrlConnectionImpl.java | 3 + .../slcommands/impl/AbstractAssocArrayInfobox.java | 96 +++-- .../impl/SVPersonendatenInfoboxImpl.java | 323 +++++++++++++++++ .../impl/SVPersonendatenInfoboxImplTest.java | 147 ++++++++ smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 320 +++++++++-------- .../at/gv/egiz/smcc/AbstractSignatureCard.java | 214 +++++++----- .../src/main/java/at/gv/egiz/smcc/STARCOSCard.java | 386 +++++++++++++-------- .../smcc/SecurityStatusNotSatisfiedException.java | 38 ++ .../gv/egiz/smcc/VerificationFailedException.java | 65 ++++ .../test/java/at/gv/egiz/smcc/STARCOSCardTest.java | 40 ++- .../bku/smccstal/InfoBoxReadRequestHandler.java | 3 + 13 files changed, 1219 insertions(+), 420 deletions(-) create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java create mode 100644 bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java create mode 100644 smcc/src/main/java/at/gv/egiz/smcc/SecurityStatusNotSatisfiedException.java create mode 100644 smcc/src/main/java/at/gv/egiz/smcc/VerificationFailedException.java (limited to 'smcc/src') diff --git a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml index eb7d5b7a..2ddd46a1 100644 --- a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml +++ b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml @@ -82,6 +82,9 @@ + diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java index 408330cc..57d89c89 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java @@ -100,6 +100,7 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } if (hostnameVerifier != null) { log.debug("Setting custom hostname verifier"); + https.setHostnameVerifier(hostnameVerifier); } } else { log.trace("No secure connection with: "+url+ " class="+connection.getClass()); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java index ef8034aa..452c45e5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java @@ -80,6 +80,7 @@ public class LegacyDataUrlConnectionImpl implements DataUrlConnectionSPI { } if (hostnameVerifier != null) { log.debug("Setting custom hostname verifier"); + https.setHostnameVerifier(hostnameVerifier); } } connection.setDoOutput(true); @@ -229,6 +230,8 @@ public class LegacyDataUrlConnectionImpl implements DataUrlConnectionSPI { public DataUrlConnectionSPI newInstance() { DataUrlConnectionSPI uc = new LegacyDataUrlConnectionImpl(); uc.setConfiguration(config); + uc.setSSLSocketFactory(sslSocketFactory); + uc.setHostnameVerifier(hostnameVerifier); return uc; } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java index e49ed6c0..e7f96c06 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java @@ -16,12 +16,17 @@ */ package at.gv.egiz.bku.slcommands.impl; +import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Pattern; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,6 +41,7 @@ import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayTy import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadValue; import at.gv.egiz.bku.slcommands.InfoboxReadResult; import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slcommands.SLCommandFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; /** @@ -54,7 +60,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl /** * The search string pattern. */ - public static final String SEARCH_STRING_PATTERN = ".&&[^/](/.&&[^/])*"; + public static final String SEARCH_STRING_PATTERN = "(.&&[^/])+(/.&&[^/])*"; /** * @return the keys available in this infobox. @@ -93,6 +99,11 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl return Arrays.asList(getKeys()); } + if (!searchString.contains("*")) { + Arrays.asList(getKeys()).contains(searchString); + return Collections.singletonList(searchString); + } + if (Pattern.matches(SEARCH_STRING_PATTERN, searchString)) { // for (int i = 0; i < searchString.length(); i++) { @@ -160,15 +171,10 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl protected InfoboxReadResult readPairs(ReadPairs readPairs, SLCommandContext cmdCtx) throws SLCommandException { if (readPairs.isValuesAreXMLEntities() && !isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readPairs + " but infobox type is binary."); + log.info("Got valuesAreXMLEntities=" + readPairs.isValuesAreXMLEntities() + " but infobox type is binary."); throw new SLCommandException(4010); } - if (!readPairs.isValuesAreXMLEntities() && isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readPairs + " but infobox type is XML."); - throw new SLCommandException(4010); - } - List selectedKeys = selectKeys(readPairs.getSearchString()); if (readPairs.isUserMakesUnique() && selectedKeys.size() > 1) { @@ -177,26 +183,10 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl throw new SLCommandException(4010); } - ObjectFactory objectFactory = new ObjectFactory(); - - InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory.createInfoboxReadDataAssocArrayType(); - - Map values = getValues(selectedKeys, cmdCtx); - for (String key : selectedKeys) { - InfoboxAssocArrayPairType infoboxAssocArrayPairType = objectFactory.createInfoboxAssocArrayPairType(); - infoboxAssocArrayPairType.setKey(key); - Object value = values.get(key); - if (value instanceof byte[]) { - infoboxAssocArrayPairType.setBase64Content((byte[]) value); - } else { - infoboxAssocArrayPairType.setXMLContent((XMLContentType) value); - } - infoboxReadDataAssocArrayType.getPair().add(infoboxAssocArrayPairType); - } - - return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); + return new InfoboxReadResultImpl(marshallPairs(selectedKeys, getValues( + selectedKeys, cmdCtx), readPairs.isValuesAreXMLEntities())); } - + /** * Read the value specified by readPairs. * @@ -213,12 +203,7 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl protected InfoboxReadResult readValue(ReadValue readValue, SLCommandContext cmdCtx) throws SLCommandException { if (readValue.isValueIsXMLEntity() && !isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readValue + " but infobox type is binary."); - throw new SLCommandException(4010); - } - - if (!readValue.isValueIsXMLEntity() && isValuesAreXMLEntities()) { - log.info("Got valuesAreXMLEntities=" + readValue + " but infobox type is XML."); + log.info("Got valuesAreXMLEntities=" + readValue.isValueIsXMLEntity() + " but infobox type is binary."); throw new SLCommandException(4010); } @@ -230,24 +215,59 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl selectedKeys = Collections.emptyList(); } + return new InfoboxReadResultImpl(marshallPairs(selectedKeys, getValues( + selectedKeys, cmdCtx), readValue.isValueIsXMLEntity())); + + } + + protected InfoboxReadDataAssocArrayType marshallPairs(List selectedKeys, Map values, boolean areXMLEntities) throws SLCommandException { + ObjectFactory objectFactory = new ObjectFactory(); - + InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory.createInfoboxReadDataAssocArrayType(); - Map values = getValues(selectedKeys, cmdCtx); for (String key : selectedKeys) { InfoboxAssocArrayPairType infoboxAssocArrayPairType = objectFactory.createInfoboxAssocArrayPairType(); infoboxAssocArrayPairType.setKey(key); + Object value = values.get(key); - if (value instanceof byte[]) { - infoboxAssocArrayPairType.setBase64Content((byte[]) value); + if (areXMLEntities) { + if (value instanceof byte[]) { + log.info("Got valuesAreXMLEntities=" + areXMLEntities + " but infobox type is binary."); + throw new SLCommandException(4122); + } else { + XMLContentType contentType = objectFactory.createXMLContentType(); + contentType.getContent().add(value); + infoboxAssocArrayPairType.setXMLContent(contentType); + } } else { - infoboxAssocArrayPairType.setXMLContent((XMLContentType) value); + infoboxAssocArrayPairType.setBase64Content((value instanceof byte[]) ? (byte[]) value : marshallValue(value)); } + infoboxReadDataAssocArrayType.getPair().add(infoboxAssocArrayPairType); } + + return infoboxReadDataAssocArrayType; - return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); + } + + protected byte[] marshallValue(Object jaxbElement) throws SLCommandException { + SLCommandFactory commandFactory = SLCommandFactory.getInstance(); + JAXBContext jaxbContext = commandFactory.getJaxbContext(); + + ByteArrayOutputStream result; + try { + Marshaller marshaller = jaxbContext.createMarshaller(); + + result = new ByteArrayOutputStream(); + marshaller.marshal(jaxbElement, result); + } catch (JAXBException e) { + log.info("Failed to marshall infobox content.", e); + throw new SLCommandException(4122); + } + + return result.toByteArray(); + } @Override diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java new file mode 100644 index 00000000..7e204632 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImpl.java @@ -0,0 +1,323 @@ +/* +* 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.slcommands.impl; + +import iaik.asn1.ASN; +import iaik.asn1.ASN1Object; +import iaik.asn1.CodingException; +import iaik.asn1.DerCoder; +import iaik.asn1.NumericString; +import iaik.asn1.OCTET_STRING; +import iaik.asn1.ObjectID; +import iaik.asn1.SEQUENCE; +import iaik.asn1.SET; +import iaik.asn1.UNKNOWN; +import iaik.asn1.structures.ChoiceOfTime; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.charset.Charset; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.buergerkarte.namespaces.cardchannel.AttributeList; +import at.buergerkarte.namespaces.cardchannel.AttributeType; +import at.buergerkarte.namespaces.cardchannel.ObjectFactory; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLExceptionMessages; +import at.gv.egiz.stal.InfoboxReadRequest; +import at.gv.egiz.stal.InfoboxReadResponse; +import at.gv.egiz.stal.STALRequest; + +/** + * An implementation of the {@link Infobox} Certificates as + * specified in Security Layer 1.2. + * + * @author mcentner + */ +public class SVPersonendatenInfoboxImpl extends AbstractAssocArrayInfobox { + + /** + * Logging facility. + */ + private static Log log = LogFactory.getLog(SVPersonendatenInfoboxImpl.class); + + public static final String EHIC = "EHIC"; + + public static final String GRUNDDATEN = "Grunddaten"; + + public static final String STATUS = "Status"; + + public static final String SV_PERSONENBINDUNG = "SV-Personenbindung"; + + /** + * The valid keys. + */ + public static final String[] KEYS = new String[] { + GRUNDDATEN, EHIC, STATUS, SV_PERSONENBINDUNG + }; + + @Override + public String getIdentifier() { + return "SV-Personendaten"; + } + + @Override + public String[] getKeys() { + return KEYS; + } + + @Override + public boolean isValuesAreXMLEntities() { + return true; + } + + @Override + public Map getValues(List keys, SLCommandContext cmdCtx) throws SLCommandException { + + STALHelper stalHelper = new STALHelper(cmdCtx.getSTAL()); + + if (keys != null && !keys.isEmpty()) { + + List stalRequests = new ArrayList(); + + // get values + InfoboxReadRequest infoboxReadRequest; + for (int i = 0; i < keys.size(); i++) { + infoboxReadRequest = new InfoboxReadRequest(); + infoboxReadRequest.setInfoboxIdentifier(keys.get(i)); + stalRequests.add(infoboxReadRequest); + } + + stalHelper.transmitSTALRequest(stalRequests); + + Map values = new HashMap(); + + try { + for (int i = 0; i < keys.size(); i++) { + + String key = keys.get(i); + InfoboxReadResponse nextResponse = (InfoboxReadResponse) stalHelper.nextResponse(InfoboxReadResponse.class); + + + ObjectFactory objectFactory = new ObjectFactory(); + + if (EHIC.equals(key)) { + AttributeList attributeList = createAttributeList(nextResponse.getInfoboxValue()); + values.put(key, objectFactory.createEHIC(attributeList)); + } else if (GRUNDDATEN.equals(key)) { + AttributeList attributeList = createAttributeList(nextResponse.getInfoboxValue()); + values.put(key, objectFactory.createGrunddaten(attributeList)); + } else if (SV_PERSONENBINDUNG.equals(key)) { + values.put(key, objectFactory.createSVPersonenbindung(nextResponse.getInfoboxValue())); + } else if (STATUS.equals(key)) { + AttributeList attributeList = createAttributeListFromRecords(nextResponse.getInfoboxValue()); + values.put(key, objectFactory.createStatus(attributeList)); + } + + } + } catch (CodingException e) { + log.info("Failed to decode '" + getIdentifier() + "' infobox.", e); + throw new SLCommandException(4000, + SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, + new Object[] { "IdentityLink" }); + + } + + return values; + + } else { + + return new HashMap(); + + } + + + } + + public static AttributeList createAttributeList(byte[] infoboxValue) throws CodingException { + + ObjectFactory objectFactory = new ObjectFactory(); + + ASN1Object asn1 = DerCoder.decode(infoboxValue); + + AttributeList attributeList = objectFactory.createAttributeList(); + List attributes = attributeList.getAttribute(); + + if (asn1.isA(ASN.SEQUENCE)) { + for (int i = 0; i < ((SEQUENCE) asn1).countComponents(); i++) { + + AttributeType attributeType = objectFactory.createAttributeType(); + + if (asn1.getComponentAt(i).isA(ASN.SEQUENCE)) { + SEQUENCE attribute = (SEQUENCE) asn1.getComponentAt(i); + if (attribute.getComponentAt(0).isA(ASN.ObjectID)) { + ObjectID objectId = (ObjectID) attribute.getComponentAt(0); + attributeType.setOid("urn:oid:" + objectId.getID()); + } + if (attribute.getComponentAt(1).isA(ASN.SET)) { + SET values = (SET) attribute.getComponentAt(1); + for (int j = 0; j < values.countComponents(); j++) { + setAttributeValue(attributeType, values.getComponentAt(j)); + } + } + } + + attributes.add(attributeType); + + } + + } + + return attributeList; + + } + + public static AttributeList createAttributeListFromRecords(byte[] infoboxValue) throws CodingException { + + ObjectFactory objectFactory = new ObjectFactory(); + + AttributeList attributeList = objectFactory.createAttributeList(); + List attributes = attributeList.getAttribute(); + + byte[] records = infoboxValue; + + while (records != null && records.length > 0) { + + int length; + + if (records[0] != 0x00) { + + ASN1Object asn1 = DerCoder.decode(records); + + AttributeType attributeType = objectFactory.createAttributeType(); + + if (asn1.isA(ASN.SEQUENCE)) { + SEQUENCE attribute = (SEQUENCE) asn1; + if (attribute.getComponentAt(0).isA(ASN.ObjectID)) { + ObjectID objectId = (ObjectID) attribute.getComponentAt(0); + attributeType.setOid("urn:oid:" + objectId.getID()); + } + if (attribute.getComponentAt(1).isA(ASN.SET)) { + SET values = (SET) attribute.getComponentAt(1); + for (int j = 0; j < values.countComponents(); j++) { + setAttributeValue(attributeType, values.getComponentAt(j)); + } + } + } + + attributes.add(attributeType); + + length = DerCoder.encode(asn1).length; + + } else { + length = 1; + } + + if (length < records.length) { + records = Arrays.copyOfRange(records, length + 1, records.length); + } else { + records = null; + } + + } + + return attributeList; + + } + + private static void setAttributeValue(AttributeType attributeType, ASN1Object value) { + + if (value.isA(ASN.OCTET_STRING)) { + + try { + byte[] octets = ((OCTET_STRING) value).getWholeValue(); + attributeType.setLatin1String(new String(octets, Charset.forName("ISO-8859-1"))); + } catch (IOException e) { + log.info("Failed to set Latin1String.", e); + } + + } else if (value.isA(ASN.NumericString)) { + + attributeType.setNumericString((String) ((NumericString) value).getValue()); + + } else if (value.isA(ASN.GeneralizedTime)) { + + try { + ChoiceOfTime choiceOfTime = new ChoiceOfTime(value); + + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); + gregorianCalendar.setTime(choiceOfTime.getDate()); + + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); + xmlGregorianCalendar.setTimezone(0); + + attributeType.setGeneralizedTime(xmlGregorianCalendar); + } catch (Exception e) { + log.info("Failed to set GeneralizedTime.", e); + } + + } else if (value.isA(ASN.INTEGER)) { + + attributeType.setInteger((BigInteger) value.getValue()); + + } else if (value.isA(ASN.UTF8String)) { + + attributeType.setUTF8String((String) value.getValue()); + + } else if (value.isA(ASN.PrintableString)) { + + attributeType.setPrintableString((String) value.getValue()); + + } else if (value.isA(ASN.UNKNOWN)) { + + byte[] bytes = (byte[]) ((UNKNOWN) value).getValue(); + + try { + BigInteger bigInteger = new BigInteger(bytes); + String string = bigInteger.toString(16); + + Date date = new SimpleDateFormat("yyyyMMdd").parse(string); + attributeType.setDate(new SimpleDateFormat("yyyy-MM-dd").format(date)); + } catch (Exception e) { + log.info("Failed to set Date.", e); + } + } + + } + + + + + +} diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java new file mode 100644 index 00000000..f9c60b86 --- /dev/null +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java @@ -0,0 +1,147 @@ +/* +* 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.slcommands.impl; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import iaik.asn1.CodingException; + +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import at.buergerkarte.namespaces.cardchannel.AttributeList; +import at.buergerkarte.namespaces.cardchannel.ObjectFactory; +import at.gv.egiz.bku.slcommands.ErrorResult; +import at.gv.egiz.bku.slcommands.InfoboxReadCommand; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLResult; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLRequestException; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.stal.STAL; +import at.gv.egiz.stal.dummy.DummySTAL; + +//@Ignore +public class SVPersonendatenInfoboxImplTest { + + private byte[] EHIC = new byte[] { + (byte) 0x30, (byte) 0x6b, (byte) 0x30, (byte) 0x12, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x28, + (byte) 0x00, (byte) 0x0a, (byte) 0x01, (byte) 0x04, (byte) 0x01, (byte) 0x14, (byte) 0x31, (byte) 0x06, + (byte) 0x04, (byte) 0x04, (byte) 0x42, (byte) 0x47, (byte) 0x4b, (byte) 0x4b, (byte) 0x30, (byte) 0x12, + (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x28, (byte) 0x00, (byte) 0x0a, (byte) 0x01, (byte) 0x04, + (byte) 0x01, (byte) 0x15, (byte) 0x31, (byte) 0x06, (byte) 0x12, (byte) 0x04, (byte) 0x31, (byte) 0x33, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x22, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x28, + (byte) 0x00, (byte) 0x0a, (byte) 0x01, (byte) 0x04, (byte) 0x01, (byte) 0x16, (byte) 0x31, (byte) 0x16, + (byte) 0x12, (byte) 0x14, (byte) 0x38, (byte) 0x30, (byte) 0x30, (byte) 0x34, (byte) 0x30, (byte) 0x30, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x30, + (byte) 0x34, (byte) 0x37, (byte) 0x30, (byte) 0x37, (byte) 0x35, (byte) 0x39, (byte) 0x30, (byte) 0x1d, + (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x28, (byte) 0x00, (byte) 0x0a, (byte) 0x01, (byte) 0x04, + (byte) 0x01, (byte) 0x17, (byte) 0x31, (byte) 0x11, (byte) 0x18, (byte) 0x0f, (byte) 0x32, (byte) 0x30, + (byte) 0x30, (byte) 0x35, (byte) 0x30, (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, + (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x30, (byte) 0x5a + }; + + private static ApplicationContext appCtx; + + private SLCommandFactory factory; + + private STAL stal; + +// @BeforeClass + public static void setUpClass() { + appCtx = new ClassPathXmlApplicationContext("at/gv/egiz/bku/slcommands/testApplicationContext.xml"); + } + +// @Before + public void setUp() { + factory = SLCommandFactory.getInstance(); + stal = new DummySTAL(); + } + + @Test + public void testEHIC() throws SLCommandException, JAXBException, CodingException, IOException { + + AttributeList attributeList = SVPersonendatenInfoboxImpl.createAttributeList(EHIC); + + JAXBElement ehic = new ObjectFactory().createEHIC(attributeList); + + JAXBContext jaxbContext = SLCommandFactory.getInstance().getJaxbContext(); + + Marshaller marshaller = jaxbContext.createMarshaller(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + marshaller.marshal(ehic, System.out); + + } + + @Ignore + @Test + public void testInfboxReadRequest() throws SLCommandException, SLRuntimeException, SLRequestException { + InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.xml"); + assertNotNull(inputStream); + + SLCommandContext context = new SLCommandContext(); + context.setSTAL(stal); + SLCommand command = factory.createSLCommand(new StreamSource(inputStream), context); + assertTrue(command instanceof InfoboxReadCommand); + + SLResult result = command.execute(); + result.writeTo(new StreamResult(System.out)); + } + + @Ignore + @Test(expected=SLCommandException.class) + public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException { + InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-1.xml"); + assertNotNull(inputStream); + + SLCommandContext context = new SLCommandContext(); + context.setSTAL(stal); + SLCommand command = factory.createSLCommand(new StreamSource(inputStream), context); + assertTrue(command instanceof InfoboxReadCommand); + } + + @Ignore + public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException { + InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-2.xml"); + assertNotNull(inputStream); + + SLCommandContext context = new SLCommandContext(); + context.setSTAL(stal); + SLCommand command = factory.createSLCommand(new StreamSource(inputStream), context); + assertTrue(command instanceof InfoboxReadCommand); + + SLResult result = command.execute(); + assertTrue(result instanceof ErrorResult); + } + +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java index 2baff834..6d96599c 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -30,7 +30,6 @@ package at.gv.egiz.smcc; import java.nio.charset.Charset; -import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; @@ -110,41 +109,47 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException { - byte[] aid; - byte[] efc; - int maxsize; - if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { - aid = AID_SIG; - efc = EF_C_CH_DS; - maxsize = EF_C_CH_DS_MAX_SIZE; - } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - aid = AID_DEC; - efc = EF_C_CH_EKEY; - maxsize = EF_C_CH_EKEY_MAX_SIZE; - } else { - throw new IllegalArgumentException("Keybox " + keyboxName - + " not supported."); - } - - log.debug("Get certificate for keybox '" + keyboxName.getKeyboxName() + "'" + - " (AID=" + toString(aid) + " EF=" + toString(efc) + ")."); - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - return readTLVFile(aid, efc, maxsize + 15000); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + + if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + + try { + getCard().beginExclusive(); + byte[] certificate = readTLVFile(AID_SIG, EF_C_CH_DS, EF_C_CH_DS_MAX_SIZE); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } + + } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { + + try { + getCard().beginExclusive(); + byte[] certificate = readTLVFile(AID_DEC, EF_C_CH_EKEY, EF_C_CH_EKEY_MAX_SIZE); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } + + } else { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } - } @@ -155,30 +160,47 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { public byte[] getInfobox(String infobox, PINProvider provider, String domainId) throws SignatureCardException, InterruptedException { - if ("IdentityLink".equals(infobox)) { - - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); - - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - return readTLVFilePIN(AID_DEC, EF_INFOBOX, KID_PIN_INF, provider, - spec, EF_INFOBOX_MAX_SIZE); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); - } - } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + try { + if ("IdentityLink".equals(infobox)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("inf.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + return readTLVFile(AID_DEC, EF_INFOBOX, pin, KID_PIN_INF, EF_INFOBOX_MAX_SIZE); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); } - - } else { - throw new IllegalArgumentException("Infobox '" + infobox - + "' not supported."); + + } catch (CardException e) { + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } } @@ -192,68 +214,103 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - - if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - - // SELECT DF - selectFileFID(DF_SIG); - // VERIFY - verifyPIN(provider, new PINSpec(6, 10, "[0-9]", getResourceBundle() - .getString("sig.pin.name")), KID_PIN_SIG); - // MSE: SET DST - mseSetDST(0x81, 0xb6, DST_SIG); - // PSO: HASH - psoHash(hash); - // PSO: COMPUTE DIGITAL SIGNATURE - return psoComputDigitalSiganture(); - } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - - // SELECT DF - selectFileFID(DF_DEC); - // VERIFY - verifyPIN(provider, new PINSpec(4, 4, "[0-9]", getResourceBundle() - .getString("dec.pin.name")), KID_PIN_DEC); - // MSE: SET DST - mseSetDST(0x41, 0xa4, DST_DEC); - // INTERNAL AUTHENTICATE - return internalAuthenticate(hash); - - - // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 54 26 F0 EA AF EA F0 4E D4 A1 AD BF 66 D4 A5 9B 45 6F AF 79 00 - // 00 88 10 00 23 30 21 30 09 06 05 2B 0E 03 02 1A 05 00 04 14 DF 8C AB 8F E2 AD AC 7B 5A AF BE E9 44 5E 95 99 FA AF 2F 48 00 - - } else { - throw new IllegalArgumentException("KeyboxName '" + keyboxName - + "' not supported."); - } + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { + + PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); + + int retries = -1; + String pin = null; + + do { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + try { + getCard().beginExclusive(); + + // SELECT DF + selectFileFID(DF_SIG); + // VERIFY + retries = verifyPIN(pin, KID_PIN_SIG); + if (retries != -1) { + throw new VerificationFailedException(retries); + } + // MSE: SET DST + mseSetDST(0x81, 0xb6, DST_SIG); + // PSO: HASH + psoHash(hash); + // PSO: COMPUTE DIGITAL SIGNATURE + return psoComputDigitalSiganture(); + + } catch (SecurityStatusNotSatisfiedException e) { + retries = verifyPIN(null, KID_PIN_SIG); + } catch (VerificationFailedException e) { + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("dec.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + + // SELECT DF + selectFileFID(DF_DEC); + // VERIFY + retries = verifyPIN(pin, KID_PIN_DEC); + if (retries != -1) { + throw new VerificationFailedException(retries); + } + // MSE: SET DST + mseSetDST(0x41, 0xa4, DST_DEC); + // INTERNAL AUTHENTICATE + return internalAuthenticate(hash); + + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + retries = verifyPIN(null, KID_PIN_DEC); + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + } else { + throw new IllegalArgumentException("KeyboxName '" + keyboxName + + "' not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); - } - - } - - protected byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { - CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, - 0x00, fid, 256)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("Failed to select file (AID=" - + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + "."); - } else { - return resp.getBytes(); - } + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); + } + } protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { @@ -262,6 +319,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { 0x00, fid, 256)); } + @Override protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); @@ -290,35 +348,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } - /** - * - * @param pinProvider - * @param spec - * the PIN spec to be given to the pinProvider - * @param kid - * the KID (key identifier) of the PIN to be verified - * @throws CancelledException - * if the user canceld the operation - * @throws javax.smartcardio.CardException - * @throws at.gv.egiz.smcc.SignatureCardException - */ - @Override - protected void verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid) - throws CardException, CancelledException, SignatureCardException, InterruptedException { - - int retries = -1; - do { - String pin = pinProvider.providePIN(spec, retries); - if (pin == null) { - // user canceled operation - throw new CancelledException("User canceled operation"); - } - retries = verifyPIN(pin, kid); - } while (retries > 0); - - } - - void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { + private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, p1, p2, dst)); @@ -328,7 +358,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - void psoHash(byte[] hash) throws CardException, SignatureCardException { + private void psoHash(byte[] hash) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x90, 0x81, hash)); @@ -338,7 +368,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - byte[] psoComputDigitalSiganture() throws CardException, + private byte[] psoComputDigitalSiganture() throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x9E, @@ -352,7 +382,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard { } } - byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { + private byte[] internalAuthenticate(byte[] hash) throws CardException, SignatureCardException { byte[] digestInfo = new byte[] { (byte) 0x30, (byte) 0x21, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2B, (byte) 0x0E, (byte) 0x03, (byte) 0x02, (byte) 0x1A, (byte) 0x05, (byte) 0x00, (byte) 0x04 diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java index e34c4899..633cc90d 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java @@ -28,6 +28,8 @@ // package at.gv.egiz.smcc; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Locale; import java.util.ResourceBundle; @@ -79,45 +81,56 @@ public abstract class AbstractSignatureCard implements SignatureCard { return sb.toString(); } - protected abstract byte[] selectFileAID(byte[] fid) throws CardException, - SignatureCardException; - - protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException, - SignatureCardException; - /** - * VERIFY PIN + * Select an application using AID as DF name according to ISO/IEC 7816-4 + * section 8.2.2.2. * - *

- * Implementations of this method should call - * {@link PINProvider#providePIN(PINSpec, int)} to retrieve the PIN entered by - * the user and VERIFY PIN on the smart card until the PIN has been - * successfully verified. - *

+ * @param dfName + * AID of the application to be selected * - * @param pinProvider - * the PINProvider - * @param spec - * the PINSpec - * @param kid - * the key ID (KID) of the PIN to verify + * @return the response data of the response APDU if SW=0x9000 * * @throws CardException - * if smart card communication fails - * - * @throws CancelledException - * if the PINProvider indicated that the user canceled the PIN entry - * @throws NotActivatedException - * if the card application has not been activated - * @throws LockedException - * if the card application is locked + * if card communication fails * * @throws SignatureCardException - * if VERIFY PIN fails + * if application selection fails (e.g. an application with the + * given AID is not present on the card) */ - protected abstract void verifyPIN(PINProvider pinProvider, PINSpec spec, - byte kid) throws CardException, SignatureCardException, InterruptedException; + protected byte[] selectFileAID(byte[] dfName) throws CardException, SignatureCardException { + CardChannel channel = getCardChannel(); + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, + 0x00, dfName, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("Failed to select application AID=" + + toString(dfName) + ": SW=" + Integer.toHexString(resp.getSW()) + "."); + } else { + return resp.getBytes(); + } + } + + protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException, + SignatureCardException; + protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException; + + + protected byte[] readRecord(int recordNumber) throws SignatureCardException, CardException { + return readRecord(getCardChannel(), recordNumber); + } + + protected byte[] readRecord(CardChannel channel, int recordNumber) throws SignatureCardException, CardException { + + ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xB2, + recordNumber, 0x04, 256)); + if (resp.getSW() == 0x9000) { + return resp.getData(); + } else { + throw new SignatureCardException("Failed to read records. SW=" + Integer.toHexString(resp.getSW())); + } + + } + protected byte[] readBinary(CardChannel channel, int offset, int len) throws CardException, SignatureCardException { @@ -125,6 +138,8 @@ public abstract class AbstractSignatureCard implements SignatureCard { 0x7F & (offset >> 8), offset & 0xFF, len)); if (resp.getSW() == 0x9000) { return resp.getData(); + } else if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); } else { throw new SignatureCardException("Failed to read bytes (" + offset + "+" + len + "): SW=" + Integer.toHexString(resp.getSW())); @@ -188,43 +203,10 @@ public abstract class AbstractSignatureCard implements SignatureCard { } - /** - * Read the content of a TLV file. - * - * @param aid the application ID (AID) - * @param ef the elementary file (EF) - * @param maxLength the maximum length of the file - * - * @return the content of the file - * - * @throws SignatureCardException - */ - protected byte[] readTLVFile(byte[] aid, byte[] ef, int maxLength) - throws SignatureCardException, InterruptedException { - return readTLVFilePIN(aid, ef, (byte) 0, null, null, maxLength); - } - - - /** - * Read the content of a TLV file wich may require a PIN. - * - * @param aid the application ID (AID) - * @param ef the elementary file (EF) - * @param kid the key ID (KID) of the corresponding PIN - * @param provider the PINProvider - * @param spec the PINSpec - * @param maxLength the maximum length of the file - * - * @return the content of the file - * - * @throws SignatureCardException - */ - protected byte[] readTLVFilePIN(byte[] aid, byte[] ef, byte kid, - PINProvider provider, PINSpec spec, int maxLength) - throws SignatureCardException, InterruptedException { - + protected byte[] readRecords(byte[] aid, byte[] ef, int start, int end) throws SignatureCardException, InterruptedException { + try { - + // SELECT FILE (AID) byte[] rb = selectFileAID(aid); if (rb[rb.length - 2] != (byte) 0x90 || rb[rb.length - 1] != (byte) 0x00) { @@ -256,37 +238,89 @@ public abstract class AbstractSignatureCard implements SignatureCard { + Integer.toHexString(resp.getSW()) + ")."); } - - // try to READ BINARY - byte[] b = new byte[1]; - int sw = readBinary(0, 1, b); - if (provider != null && sw == 0x6982) { - - // VERIFY - verifyPIN(provider, spec, kid); - - } else if (sw == 0x9000) { - // not expected type - if (b[0] != 0x30) { - throw new NotActivatedException(); - } - } else { - throw new SignatureCardException("READ BINARY failed (SW=" - + Integer.toHexString(sw) + ")."); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + + for (int i = start; i <= end; i++) { + bytes.write(readRecord(i)); } - - // READ BINARY - byte[] data = readBinaryTLV(maxLength, (byte) 0x30); - - return data; - + + return bytes.toByteArray(); + } catch (CardException e) { throw new SignatureCardException("Failed to acces card.", e); + } catch (IOException e) { + throw new SignatureCardException("Failed to read records.", e); } - + + } + + /** + * Read the content of a TLV file. + * + * @param aid the application ID (AID) + * @param ef the elementary file (EF) + * @param maxLength the maximum length of the file + * + * @return the content of the file + * + * @throws SignatureCardException + * @throws CardException + */ + protected byte[] readTLVFile(byte[] aid, byte[] ef, int maxLength) + throws SignatureCardException, InterruptedException, CardException { + return readTLVFile(aid, ef, null, (byte) 0, maxLength); } + /** + * Read the content of a TLV file wich may require a PIN. + * + * @param aid the application ID (AID) + * @param ef the elementary file (EF) + * @param kid the key ID (KID) of the corresponding PIN + * @param provider the PINProvider + * @param spec the PINSpec + * @param maxLength the maximum length of the file + * + * @return the content of the file + * + * @throws SignatureCardException + * @throws CardException + */ + protected byte[] readTLVFile(byte[] aid, byte[] ef, String pin, byte kid, int maxLength) + throws SignatureCardException, InterruptedException, CardException { + + + // SELECT FILE (AID) + selectFileAID(aid); + + // SELECT FILE (EF) + ResponseAPDU resp = selectFileFID(ef); + if (resp.getSW() == 0x6a82) { + // EF not found + throw new FileNotFoundException("EF " + toString(ef) + " not found."); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException("SELECT FILE with " + + "FID=" + + toString(ef) + + " failed (" + + "SW=" + + Integer.toHexString(resp.getSW()) + ")."); + } + + // VERIFY + if (pin != null) { + int retries = verifyPIN(pin, kid); + if (retries != -1) { + throw new VerificationFailedException(retries); + } + } + + return readBinaryTLV(maxLength, (byte) 0x30); + + + } + /** * Transmit the given command APDU using the given card channel. * diff --git a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java index d6d02475..2a6e90bf 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java @@ -31,7 +31,6 @@ package at.gv.egiz.smcc; import java.math.BigInteger; import java.util.Arrays; -import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; @@ -49,6 +48,42 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 }; + /** + * Application ID SV-Personendaten. + */ + public static final byte[] AID_SV_PERSONENDATEN = new byte[] { + (byte) 0xD0, (byte) 0x40, (byte) 0x00, (byte) 0x00, + (byte) 0x17, (byte) 0x01, (byte) 0x01, (byte) 0x01 + }; + + /** + * File ID Grunddaten ({@link #AID_SV_PERSONENDATEN}). + */ + public static final byte[] FID_GRUNDDATEN = new byte[] { + (byte) 0xEF, (byte) 0x01 + }; + + /** + * File ID EHIC ({@link #AID_SV_PERSONENDATEN}). + */ + public static final byte[] FID_EHIC = new byte[] { + (byte) 0xEF, (byte) 0x02 + }; + + /** + * File ID Status ({@link #AID_SV_PERSONENDATEN}). + */ + public static final byte[] FID_SV_PERSONENBINDUNG = new byte[] { + (byte) 0xEF, (byte) 0x03 + }; + + /** + * File ID Status ({@link #AID_SV_PERSONENDATEN}). + */ + public static final byte[] FID_STATUS = new byte[] { + (byte) 0xEF, (byte) 0x04 + }; + public static final byte[] AID_INFOBOX = new byte[] { (byte) 0xd0, (byte) 0x40, (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00, (byte) 0x18, (byte) 0x01 }; @@ -126,85 +161,134 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard super("at/gv/egiz/smcc/STARCOSCard"); } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.SignatureCard#getCertificate(at.gv.egiz.smcc.SignatureCard.KeyboxName) - */ @Override public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException { - byte[] aid; - byte[] efc; - if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { - aid = AID_DF_SS; - efc = EF_C_X509_CH_DS; - } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - aid = AID_DF_GS; - efc = EF_C_X509_CH_AUT; - } else { - throw new IllegalArgumentException("Keybox " + keyboxName - + " not supported."); - } + try { + + if (keyboxName == KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + + try { + getCard().beginExclusive(); + return readTLVFile(AID_DF_SS, EF_C_X509_CH_DS, 2000); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } + + } else if (keyboxName == KeyboxName.CERITIFIED_KEYPAIR) { - log.debug("Get certificate for keybox '" + keyboxName.getKeyboxName() + "'" + - " (AID=" + toString(aid) + " EF=" + toString(efc) + ")."); + try { + getCard().beginExclusive(); + return readTLVFile(AID_DF_GS, EF_C_X509_CH_AUT, 2000); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } finally { + getCard().endExclusive(); + } - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - return readTLVFile(aid, efc, 2000); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + } else { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } - - } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.SignatureCard#getInfobox(java.lang.String, at.gv.egiz.smcc.PINProvider, java.lang.String) - */ + } + @Override public byte[] getInfobox(String infobox, PINProvider provider, String domainId) throws SignatureCardException, InterruptedException { - if ("IdentityLink".equals(infobox)) { - - PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name")); - - try { - Card card = getCardChannel().getCard(); + try { + if ("IdentityLink".equals(infobox)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + return readTLVFile(AID_INFOBOX, EF_INFOBOX, pin, KID_PIN_CARD, 2000); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + retries = verifyPIN(null, KID_PIN_CARD); + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + + } else if ("EHIC".equals(infobox)) { + try { - card.beginExclusive(); - return readTLVFilePIN(AID_INFOBOX, EF_INFOBOX, KID_PIN_CARD, - provider, spec, 2000); - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); + getCard().beginExclusive(); + return readTLVFile(AID_SV_PERSONENDATEN, FID_EHIC, 126); } finally { - card.endExclusive(); + getCard().endExclusive(); } - } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + + } else if ("Grunddaten".equals(infobox)) { + + try { + getCard().beginExclusive(); + return readTLVFile(AID_SV_PERSONENDATEN, FID_GRUNDDATEN, 550); + } finally { + getCard().endExclusive(); + } + + } else if ("SV-Personenbindung".equals(infobox)) { + + try { + getCard().beginExclusive(); + return readTLVFile(AID_SV_PERSONENDATEN, FID_SV_PERSONENBINDUNG, 500); + } finally { + getCard().endExclusive(); + } + + } else if ("Status".equals(infobox)) { + + try { + getCard().beginExclusive(); + return readRecords(AID_SV_PERSONENDATEN, FID_STATUS, 1, 5); + } finally { + getCard().endExclusive(); + } + + } else { + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); } - } else { - throw new IllegalArgumentException("Infobox '" + infobox - + "' not supported."); + } catch (CardException e) { + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.SignatureCard#createSignature(byte[], at.gv.egiz.smcc.SignatureCard.KeyboxName, at.gv.egiz.smcc.PINProvider) - */ + @Override public byte[] createSignature(byte[] hash, KeyboxName keyboxName, PINProvider provider) throws SignatureCardException, InterruptedException { @@ -212,72 +296,115 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard throw new IllegalArgumentException("Hash value must be of length 20."); } - byte[] aid; - byte kid; - byte[] dst; - PINSpec spec; - if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - aid = AID_DF_SS; - kid = KID_PIN_SS; - dst = DST_SS; - spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); - - } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { - aid = AID_DF_GS; - kid = KID_PIN_CARD; - dst = DST_GS; - spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name")); - - } else { - throw new IllegalArgumentException("KeyboxName '" + keyboxName - + "' not supported."); - } - try { - Card card = getCardChannel().getCard(); - try { - card.beginExclusive(); - - // SELECT MF - selectMF(); - // SELECT DF - selectFileAID(aid); - // VERIFY - verifyPIN(provider, spec, kid); - // MSE: SET DST - mseSetDST(dst); - // PSO: HASH - psoHash(hash); - // PSO: COMPUTE DIGITAL SIGNATURE - return psoComputDigitalSiganture(); - - - } catch (FileNotFoundException e) { - // if certificate is not present, - // the citizen card application has not been activated - throw new NotActivatedException(); - } finally { - card.endExclusive(); + + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { + + PINSpec spec = new PINSpec(6, 10, "[0-9]", getResourceBundle().getString("sig.pin.name")); + + int retries = -1; + String pin = null; + + do { + try { + getCard().beginExclusive(); + selectFileAID(AID_DF_SS); + retries = verifyPIN(null, KID_PIN_SS); + } finally { + getCard().endExclusive(); + } + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + try { + getCard().beginExclusive(); + return createSignature(hash, AID_DF_SS, pin, KID_PIN_SS, DST_SS); + } catch (VerificationFailedException e) { + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { + + PINSpec spec = new PINSpec(4, 4, "[0-9]", getResourceBundle().getString("card.pin.name")); + + int retries = -1; + String pin = null; + boolean pinRequiered = false; + + do { + if (pinRequiered) { + pin = provider.providePIN(spec, retries); + if (pin == null) { + throw new CancelledException(); + } + } + try { + getCard().beginExclusive(); + return createSignature(hash, AID_DF_GS, pin, KID_PIN_CARD, DST_GS); + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (SecurityStatusNotSatisfiedException e) { + pinRequiered = true; + retries = verifyPIN(null, KID_PIN_CARD); + } catch (VerificationFailedException e) { + pinRequiered = true; + retries = e.getRetries(); + } finally { + getCard().endExclusive(); + } + } while (retries != 0); + + throw new LockedException(); + + } else { + throw new IllegalArgumentException("KeyboxName '" + keyboxName + + "' not supported."); } + } catch (CardException e) { - throw new SignatureCardException("Failed to get exclusive card access."); + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); } } - protected byte[] selectFileAID(byte[] fid) throws CardException, SignatureCardException { + protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); - ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x04, + return transmit(channel, new CommandAPDU(0x00, 0xA4, 0x02, 0x04, fid, 256)); - if (resp.getSW() != 0x9000) { - throw new SignatureCardException("Failed to select file (AID=" - + toString(fid) + "): SW=" + Integer.toHexString(resp.getSW()) + "."); - } else { - return resp.getBytes(); + } + + private byte[] createSignature(byte[] hash, byte[] aid, String pin, byte kid, + byte[] dst) throws CardException, SignatureCardException { + + // SELECT MF + selectMF(); + // SELECT DF + selectFileAID(aid); + // VERIFY + int retries = verifyPIN(pin, kid); + if (retries != -1) { + throw new VerificationFailedException(retries); } + // MSE: SET DST + mseSetDST(dst); + // PSO: HASH + psoHash(hash); + // PSO: COMPUTE DIGITAL SIGNATURE + return psoComputDigitalSiganture(); + + } - void selectMF() throws CardException, SignatureCardException { + + private void selectMF() throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0xA4, 0x00, 0x0C)); @@ -287,13 +414,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard } } - protected ResponseAPDU selectFileFID(byte[] fid) throws CardException, SignatureCardException { - CardChannel channel = getCardChannel(); - return transmit(channel, new CommandAPDU(0x00, 0xA4, 0x02, - 0x04, fid, 256)); - } - - void mseSetDST(byte[] dst) throws CardException, SignatureCardException { + private void mseSetDST(byte[] dst) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x22, 0x41, 0xB6, dst)); @@ -303,7 +424,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard } } - void psoHash(byte[] hash) throws CardException, SignatureCardException { + private void psoHash(byte[] hash) throws CardException, SignatureCardException { byte[] data = new byte[hash.length + 2]; data[0] = (byte) 0x90; // tag data[1] = (byte) (hash.length); // length @@ -318,7 +439,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard } } - byte[] psoComputDigitalSiganture() throws CardException, + private byte[] psoComputDigitalSiganture() throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); ResponseAPDU resp = transmit(channel, new CommandAPDU(0x00, 0x2A, 0x9E, @@ -353,7 +474,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard * @throws SignatureCardException * if VERIFY PIN fails */ - private int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException { + @Override + protected int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException { CardChannel channel = getCardChannel(); @@ -385,6 +507,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard } else if (resp.getSW1() == 0x63 && resp.getSW2() >> 4 == 0xc) { // return number of possible retries return resp.getSW2() & 0x0f; + } else if (resp.getSW() == 0x6983) { + throw new LockedException(); } else if (resp.getSW() == 0x6984) { // PIN LCS = "Initialized" (-> not activated) throw new NotActivatedException("PIN not set."); @@ -397,26 +521,8 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard } - /* (non-Javadoc) - * @see at.gv.egiz.smcc.AbstractSignatureCard#verifyPIN(at.gv.egiz.smcc.PINProvider, at.gv.egiz.smcc.PINSpec, byte, int) - */ - protected void verifyPIN(PINProvider pinProvider, PINSpec spec, byte kid) - throws CardException, SignatureCardException, InterruptedException { - - int retries = verifyPIN(null, kid); - do { - String pin = pinProvider.providePIN(spec, retries); - if (pin == null) { - // user canceled operation - throw new CancelledException("User canceld operation."); - } - retries = verifyPIN(pin, kid); - } while (retries > 0); - - } - public String toString() { - return "eCard"; + return "e-card"; } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SecurityStatusNotSatisfiedException.java b/smcc/src/main/java/at/gv/egiz/smcc/SecurityStatusNotSatisfiedException.java new file mode 100644 index 00000000..bf0af76c --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/SecurityStatusNotSatisfiedException.java @@ -0,0 +1,38 @@ +/* +* 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; + +public class SecurityStatusNotSatisfiedException extends SignatureCardException { + + private static final long serialVersionUID = 1L; + + public SecurityStatusNotSatisfiedException() { + } + + public SecurityStatusNotSatisfiedException(String message, Throwable cause) { + super(message, cause); + } + + public SecurityStatusNotSatisfiedException(String message) { + super(message); + } + + public SecurityStatusNotSatisfiedException(Throwable cause) { + super(cause); + } + +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/VerificationFailedException.java b/smcc/src/main/java/at/gv/egiz/smcc/VerificationFailedException.java new file mode 100644 index 00000000..fa066ff9 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/VerificationFailedException.java @@ -0,0 +1,65 @@ +/* +* 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; + +public class VerificationFailedException extends SignatureCardException { + + private static final long serialVersionUID = 1L; + + public static final int UNKNOWN = -1; + + private int retries = UNKNOWN; + + public VerificationFailedException() { + } + + public VerificationFailedException(String message, Throwable cause) { + super(message, cause); + } + + public VerificationFailedException(String message) { + super(message); + } + + public VerificationFailedException(Throwable cause) { + super(cause); + } + + public VerificationFailedException(int retries) { + this.retries = retries; + } + + public VerificationFailedException(int retries, String message, Throwable cause) { + super(message, cause); + this.retries = retries; + } + + public VerificationFailedException(int retries, String message) { + super(message); + this.retries = retries; + } + + public VerificationFailedException(int retries, Throwable cause) { + super(cause); + this.retries = retries; + } + + public int getRetries() { + return retries; + } + +} diff --git a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java index 13210540..090e1181 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java @@ -19,6 +19,8 @@ package at.gv.egiz.smcc; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Locale; @@ -27,6 +29,8 @@ import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; +import sun.misc.HexDumpEncoder; + import at.gv.egiz.smcc.SignatureCard.KeyboxName; import at.gv.egiz.smcc.util.SMCCHelper; @@ -34,10 +38,9 @@ public class STARCOSCardTest { /** * @param args - * @throws CardException - * @throws NoSuchAlgorithmException + * @throws Exception */ - public static void main(String[] args) throws CardException, NoSuchAlgorithmException, InterruptedException { + public static void main(String[] args) throws Exception { SMCCHelper helper = new SMCCHelper(); while (helper.getResultCode() != SMCCHelper.CARD_FOUND) { @@ -55,18 +58,41 @@ public class STARCOSCardTest { System.out.println("Found '" + signatureCard + "'."); try { -// signatureCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR); -// signatureCard.getCertificate(KeyboxName.CERITIFIED_KEYPAIR); -// signatureCard.getInfobox("IdentityLink", new CommandLinePINProvider(), null); +// printJavaByteArray( +// signatureCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR), System.out); +// printJavaByteArray( +// signatureCard.getCertificate(KeyboxName.CERITIFIED_KEYPAIR), System.out); +// System.out. println(new String(signatureCard.getInfobox("IdentityLink", new CommandLinePINProvider(), null))); +// byte[] infobox = signatureCard.getInfobox("Status", new CommandLinePINProvider(), null); +// printJavaByteArray(infobox, System.out); MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); byte[] digest = messageDigest.digest("test".getBytes()); - signatureCard.createSignature(digest, KeyboxName.CERITIFIED_KEYPAIR, new CommandLinePINProvider()); + byte[] signature = signatureCard.createSignature(digest, KeyboxName.SECURE_SIGNATURE_KEYPAIR, new CommandLinePINProvider()); + printJavaByteArray(signature, System.out); } catch (SignatureCardException e) { e.printStackTrace(); } } + public static void printJavaByteArray(byte[] bytes, OutputStream os) { + + PrintWriter w = new PrintWriter(os); + + w.write("new byte[] {"); + for (int i = 0; i < bytes.length;) { + if (i % 8 == 0) { + w.write("\n "); + } + w.write("(byte) 0x" + Integer.toHexString(0x0F & (bytes[i] >> 4)) + Integer.toHexString(0x0F & bytes[i])); + if (++i < bytes.length) { + w.write(", "); + } + } + w.write("\n};"); + w.flush(); + } + private static class CommandLinePINProvider implements PINProvider { @Override diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java index 04f179e7..5a54e97f 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/InfoBoxReadRequestHandler.java @@ -103,6 +103,9 @@ public class InfoBoxReadRequestHandler extends AbstractRequestHandler implements stalResp.setInfoboxValue(resp); return stalResp; } + } catch (IllegalArgumentException e) { + log.info("Infobox " + infoBox.getInfoboxIdentifier() + " not supported."); + return new ErrorResponse(4002); } catch (NotActivatedException e) { log.info("Citizen card not activated.", e); gui.showErrorDialog(BKUGUIFacade.ERR_CARD_NOTACTIVATED, null, this, null); -- cgit v1.2.3 From d1cb86eef5158caea65975d9cc62c8b616ea6a73 Mon Sep 17 00:00:00 2001 From: wbauer Date: Wed, 17 Dec 2008 14:24:38 +0000 Subject: Added @Ignore git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@251 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java | 11 +++++++---- smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java | 3 +++ smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'smcc/src') diff --git a/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java b/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java index 5f4bb67e..4835865f 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java @@ -16,10 +16,13 @@ */ package at.gv.egiz.smcc; -import java.util.Locale; - -import at.gv.egiz.smcc.util.SMCCHelper; - +import java.util.Locale; + +import org.junit.Ignore; + +import at.gv.egiz.smcc.util.SMCCHelper; + +@Ignore public class SMCCApplication { /** diff --git a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java index 090e1181..7f421474 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java @@ -29,11 +29,14 @@ import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; +import org.junit.Ignore; + import sun.misc.HexDumpEncoder; import at.gv.egiz.smcc.SignatureCard.KeyboxName; import at.gv.egiz.smcc.util.SMCCHelper; +@Ignore public class STARCOSCardTest { /** diff --git a/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java index 38126a67..115edc16 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java @@ -20,8 +20,11 @@ import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import org.junit.Ignore; + import at.gv.egiz.smcc.SignatureCard.KeyboxName; +@Ignore public class SWCardTest implements PINProvider { SWCard swCard = new SWCard(); -- cgit v1.2.3 From 77a19e106e4128c21dd2d1270fdc8d930e415247 Mon Sep 17 00:00:00 2001 From: wbauer Date: Thu, 18 Dec 2008 08:58:39 +0000 Subject: Fixed BUG #366, changed applet name in BKUOnline to have no version number git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@253 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../gv/egiz/bku/online/applet/AppletBKUWorker.java | 59 ++++-- .../online/applet/InternalSSLSocketFactory.java | 235 +++++++++++---------- .../conf/certs/CACerts/A-CERT GLOBALTRUST.cer | Bin 0 -> 1561 bytes .../local/conf/certs/certStore/A-CERT ADVANCED.cer | Bin 0 -> 1751 bytes .../conf/certs/certStore/A-CERT GLOBALTRUST.cer | Bin 0 -> 1561 bytes .../conf/certs/certStore/A-Trust-Qual-01a.cer | Bin 0 -> 1111 bytes .../conf/certs/certStore/A-Trust-Qual-02a.cer | Bin 0 -> 975 bytes .../conf/certs/certStore/A-Trust-Qual-03a.cer | Bin 0 -> 975 bytes .../conf/certs/certStore/A-Trust-nQual-01a.cer | Bin 0 -> 865 bytes .../conf/certs/certStore/A-Trust-nQual-03.cer | Bin 0 -> 979 bytes BKUOnline/pom.xml | 1 + .../egiz/bku/online/webapp/BKURequestHandler.java | 60 ++++-- .../webapp/applet/BKUApplet-1.0.2-SNAPSHOT.jar | Bin 182140 -> 0 bytes BKUOnline/src/main/webapp/appletPage.jsp | 2 +- .../accesscontroller/AuthenticationClassifier.java | 3 +- .../test/java/at/gv/egiz/smcc/SMCCApplication.java | 49 ----- .../test/java/at/gv/egiz/smcc/STARCOSCardTest.java | 121 ----------- smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java | 66 ------ 18 files changed, 197 insertions(+), 399 deletions(-) create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/CACerts/A-CERT GLOBALTRUST.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT ADVANCED.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT GLOBALTRUST.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-01a.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-02a.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-03a.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-01a.cer create mode 100644 BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-03.cer delete mode 100644 BKUOnline/src/main/webapp/applet/BKUApplet-1.0.2-SNAPSHOT.jar delete mode 100644 smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java delete mode 100644 smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java delete mode 100644 smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java (limited to 'smcc/src') diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java index 03e4b7c9..9fc21df8 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java @@ -38,7 +38,7 @@ import java.util.List; import javax.xml.namespace.QName; /** - * + * * @author Clemens Orthacker */ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { @@ -48,7 +48,8 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { protected String sessionId; protected STALPortType stalPort; - public AppletBKUWorker(BKUGUIFacade gui, AppletContext ctx, AppletParameterProvider paramProvider) { + public AppletBKUWorker(BKUGUIFacade gui, AppletContext ctx, + AppletParameterProvider paramProvider) { super(gui); if (ctx == null) { throw new NullPointerException("Applet context not provided"); @@ -76,7 +77,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { actionCommandList.clear(); actionCommandList.add("ok"); gui.showErrorDialog(BKUGUIFacade.ERR_SERVICE_UNREACHABLE, - new Object[]{e.getMessage()}); + new Object[] { e.getMessage() }); try { waitForAction(); } catch (InterruptedException e1) { @@ -92,8 +93,10 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { GetNextRequestResponseType nextRequestResp = stalPort.connect(sessionId); do { - List requests = nextRequestResp.getInfoboxReadRequestOrSignRequestOrQuitRequest(); - List stalRequests = STALTranslator.translateRequests(requests); + List requests = nextRequestResp + .getInfoboxReadRequestOrSignRequestOrQuitRequest(); + List stalRequests = STALTranslator + .translateRequests(requests); if (log.isInfoEnabled()) { StringBuilder sb = new StringBuilder("Received "); @@ -142,64 +145,76 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { } if (!finished) { - log.info("Not finished yet (BKUWorker: " + this + "), sending responses"); + log.info("Not finished yet (BKUWorker: " + this + + "), sending responses"); GetNextRequestType nextRequest = of.createGetNextRequestType(); nextRequest.setSessionId(sessionId); - nextRequest.getInfoboxReadResponseOrSignResponseOrErrorResponse().addAll(responses); + nextRequest.getInfoboxReadResponseOrSignResponseOrErrorResponse() + .addAll(responses); nextRequestResp = stalPort.getNextRequest(nextRequest); } } while (!finished); log.info("Done " + Thread.currentThread().getName()); } catch (Exception ex) { log.error(ex.getMessage(), ex); - gui.showErrorDialog(BKUGUIFacade.ERR_UNKNOWN, new Object[]{ex.getMessage()}); + gui.showErrorDialog(BKUGUIFacade.ERR_UNKNOWN, new Object[] { ex + .getMessage() }); try { waitForAction(); } catch (InterruptedException e) { log.error(e); } - } - if (signatureCard != null) { - signatureCard.disconnect(false); + if (signatureCard != null) { + signatureCard.disconnect(false); + } } sendRedirect(); } protected void sendRedirect() { try { - URL redirectURL = params.getURLParameter(BKUApplet.REDIRECT_URL, sessionId); - String redirectTarget = params.getAppletParameter(BKUApplet.REDIRECT_TARGET); + URL redirectURL = params.getURLParameter(BKUApplet.REDIRECT_URL, + sessionId); + String redirectTarget = params + .getAppletParameter(BKUApplet.REDIRECT_TARGET); if (redirectTarget == null) { log.info("Done. Redirecting to " + redirectURL + " ..."); ctx.showDocument(redirectURL); } else { - log.info("Done. Redirecting to " + redirectURL + " (target=" + redirectTarget + ") ..."); + log.info("Done. Redirecting to " + redirectURL + " (target=" + + redirectTarget + ") ..."); ctx.showDocument(redirectURL, redirectTarget); } } catch (MalformedURLException ex) { log.warn("Failed to redirect: " + ex.getMessage(), ex); - // gui.showErrorDialog(errorMsg, okListener, actionCommand) + // gui.showErrorDialog(errorMsg, okListener, actionCommand) } } private STALPortType getSTALPort() throws MalformedURLException { URL wsdlURL = params.getURLParameter(BKUApplet.WSDL_URL); log.debug("STAL WSDL at " + wsdlURL); - QName endpointName = new QName(BKUApplet.STAL_WSDL_NS, BKUApplet.STAL_SERVICE); + QName endpointName = new QName(BKUApplet.STAL_WSDL_NS, + BKUApplet.STAL_SERVICE); STALService stal = new STALService(wsdlURL, endpointName); return stal.getSTALPort(); } private void registerSignRequestHandler() throws MalformedURLException { - String hashDataDisplayStyle = params.getAppletParameter(BKUApplet.HASHDATA_DISPLAY); + String hashDataDisplayStyle = params + .getAppletParameter(BKUApplet.HASHDATA_DISPLAY); if (BKUApplet.HASHDATA_DISPLAY_BROWSER.equals(hashDataDisplayStyle)) { - URL hashDataURL = params.getURLParameter(BKUApplet.HASHDATA_URL, sessionId); + URL hashDataURL = params.getURLParameter(BKUApplet.HASHDATA_URL, + sessionId); log.debug("register SignRequestHandler for HashDataURL " + hashDataURL); - addRequestHandler(SignRequest.class, new BrowserHashDataDisplay(ctx, hashDataURL)); + addRequestHandler(SignRequest.class, new BrowserHashDataDisplay(ctx, + hashDataURL)); } else { - //BKUApplet.HASHDATA_DISPLAY_FRAME - log.debug("register SignRequestHandler for STAL port " + BKUApplet.WSDL_URL); - AppletHashDataDisplay handler = new AppletHashDataDisplay(stalPort, sessionId); + // BKUApplet.HASHDATA_DISPLAY_FRAME + log.debug("register SignRequestHandler for STAL port " + + BKUApplet.WSDL_URL); + AppletHashDataDisplay handler = new AppletHashDataDisplay(stalPort, + sessionId); addRequestHandler(SignRequest.class, handler); } } diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java index c3417d63..a02e56eb 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/InternalSSLSocketFactory.java @@ -36,121 +36,122 @@ import org.apache.commons.logging.LogFactory; public class InternalSSLSocketFactory extends SSLSocketFactory { - private final static String GOV_DOMAIN = ".gv.at"; - - private static InternalSSLSocketFactory instance = new InternalSSLSocketFactory(); - - private final static Log log = LogFactory - .getLog(InternalSSLSocketFactory.class); - - private SSLSocket sslSocket; - - private SSLSocketFactory proxy; - - private InternalSSLSocketFactory() { - proxy = HttpsURLConnection.getDefaultSSLSocketFactory(); - } - - public static InternalSSLSocketFactory getInstance() { - return instance; - } - - @Override - public Socket createSocket() throws IOException { - sslSocket = (SSLSocket) proxy.createSocket(); - return sslSocket; - } - - @Override - public Socket createSocket(String arg0, int arg1) throws IOException, - UnknownHostException { - sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1); - - return sslSocket; - } - - @Override - public Socket createSocket(InetAddress arg0, int arg1) throws IOException { - sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1); - return sslSocket; - } - - @Override - public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) - throws IOException, UnknownHostException { - sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); - return sslSocket; - } - - @Override - public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, - int arg3) throws IOException { - sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); - return sslSocket; - } - - @Override - public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3) - throws IOException { - sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); - return sslSocket; - } - - @Override - public String[] getDefaultCipherSuites() { - return proxy.getDefaultCipherSuites(); - } - - @Override - public String[] getSupportedCipherSuites() { - return proxy.getSupportedCipherSuites(); - } - - public boolean isEgovAgency() { - log.info("Checking if server is egov agency"); - if (sslSocket != null) { - try { - X509Certificate cert = (X509Certificate) sslSocket.getSession() - .getPeerCertificates()[0]; - log.info("Server cert: " + cert); - return isGovAgency(cert); - } catch (SSLPeerUnverifiedException e) { - log.error(e); - return false; - } - } - log.info("Not a SSL connection"); - return false; - } - - public static boolean isGovAgency(X509Certificate cert) { - String[] rdns = (cert.getSubjectX500Principal().getName()).split(","); - for (String rdn : rdns) { - if (rdn.startsWith("CN=")) { - String dns = rdn.split("=")[1]; - if (dns.endsWith(GOV_DOMAIN)) { - return true; - } - } - } - try { - Collection> sanList = cert.getSubjectAlternativeNames(); - if (sanList != null) { - for (List san : sanList) { - if ((Integer) san.get(0) == 2) { - String dns = (String) san.get(1); - if (dns.endsWith(GOV_DOMAIN)) { - return true; - } - } - } - } - } catch (CertificateParsingException e) { - log.error(e); - } - if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) { - return true; - } - return false; - } + private final static String GOV_DOMAIN = ".gv.at"; + + private static InternalSSLSocketFactory instance = new InternalSSLSocketFactory(); + + private final static Log log = LogFactory + .getLog(InternalSSLSocketFactory.class); + + private SSLSocket sslSocket; + + private SSLSocketFactory proxy; + + private InternalSSLSocketFactory() { + proxy = HttpsURLConnection.getDefaultSSLSocketFactory(); + } + + public static InternalSSLSocketFactory getInstance() { + return instance; + } + + @Override + public Socket createSocket() throws IOException { + sslSocket = (SSLSocket) proxy.createSocket(); + return sslSocket; + } + + @Override + public Socket createSocket(String arg0, int arg1) throws IOException, + UnknownHostException { + sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1); + + return sslSocket; + } + + @Override + public Socket createSocket(InetAddress arg0, int arg1) throws IOException { + sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1); + return sslSocket; + } + + @Override + public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3) + throws IOException, UnknownHostException { + sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); + return sslSocket; + } + + @Override + public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, + int arg3) throws IOException { + sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); + return sslSocket; + } + + @Override + public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3) + throws IOException { + sslSocket = (SSLSocket) proxy.createSocket(arg0, arg1, arg2, arg3); + return sslSocket; + } + + @Override + public String[] getDefaultCipherSuites() { + return proxy.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return proxy.getSupportedCipherSuites(); + } + + public boolean isEgovAgency() { + log.info("Checking if server is egov agency"); + if (sslSocket != null) { + try { + X509Certificate cert = (X509Certificate) sslSocket.getSession() + .getPeerCertificates()[0]; + log.info("Server cert: " + cert); + return isGovAgency(cert); + } catch (SSLPeerUnverifiedException e) { + log.error(e); + return false; + } + } + log.info("Not a SSL connection"); + return false; + } + + public static boolean isGovAgency(X509Certificate cert) { + String[] rdns = (cert.getSubjectX500Principal().getName()).split(","); + for (String rdn : rdns) { + if (rdn.startsWith("CN=")) { + String dns = rdn.split("=")[1]; + if (dns.endsWith(GOV_DOMAIN)) { + return true; + } + } + } + try { + Collection> sanList = cert.getSubjectAlternativeNames(); + if (sanList != null) { + for (List san : sanList) { + if ((Integer) san.get(0) == 2) { + String dns = (String) san.get(1); + if (dns.endsWith(GOV_DOMAIN)) { + return true; + } + } + } + } + } catch (CertificateParsingException e) { + log.error(e); + } + if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) + || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) { + return true; + } + return false; + } } diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/CACerts/A-CERT GLOBALTRUST.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/CACerts/A-CERT GLOBALTRUST.cer new file mode 100644 index 00000000..9a25e57d Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/CACerts/A-CERT GLOBALTRUST.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT ADVANCED.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT ADVANCED.cer new file mode 100644 index 00000000..66ff251b Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT ADVANCED.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT GLOBALTRUST.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT GLOBALTRUST.cer new file mode 100644 index 00000000..9a25e57d Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-CERT GLOBALTRUST.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-01a.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-01a.cer new file mode 100644 index 00000000..f9fef65f Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-01a.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-02a.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-02a.cer new file mode 100644 index 00000000..36a442b8 Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-02a.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-03a.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-03a.cer new file mode 100644 index 00000000..ab9e0cd7 Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-Qual-03a.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-01a.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-01a.cer new file mode 100644 index 00000000..efa28178 Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-01a.cer differ diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-03.cer b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-03.cer new file mode 100644 index 00000000..33e77636 Binary files /dev/null and b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/certs/certStore/A-Trust-nQual-03.cer differ diff --git a/BKUOnline/pom.xml b/BKUOnline/pom.xml index 1ea2c1a1..5e6ac8ad 100644 --- a/BKUOnline/pom.xml +++ b/BKUOnline/pom.xml @@ -121,6 +121,7 @@ --> at.gv.egiz BKUApplet + true true diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java index 3aa6bc19..12166a5a 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -32,12 +33,12 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.bku.binding.BindingProcessor; import at.gv.egiz.bku.binding.HTTPBindingProcessor; import at.gv.egiz.bku.binding.HttpUtil; import at.gv.egiz.bku.binding.IdFactory; import at.gv.egiz.bku.utils.StreamUtil; import at.gv.egiz.org.apache.tomcat.util.http.AcceptLanguage; -import javax.servlet.RequestDispatcher; /** * Handles SL requests and instantiates BindingProcessors @@ -52,7 +53,8 @@ public class BKURequestHandler extends SpringBKUServlet { protected Log log = LogFactory.getLog(BKURequestHandler.class); - private static String getStringFromStream(InputStream is, String encoding) throws IOException { + private static String getStringFromStream(InputStream is, String encoding) + throws IOException { if (is == null) { return null; } @@ -63,8 +65,7 @@ public class BKURequestHandler extends SpringBKUServlet { StreamUtil.copyStream(is, os); return new String(os.toByteArray(), encoding); } - - + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { log.debug("Got new request"); @@ -75,21 +76,28 @@ public class BKURequestHandler extends SpringBKUServlet { HttpSession session = req.getSession(false); if (session != null) { log.warn("Already a session with id: " + session.getId() - + " active, continuing"); - RequestDispatcher dispatcher = getServletContext().getNamedDispatcher(BKU_APPLET_JSP); - log.debug("forward to applet"); - dispatcher.forward(req, resp); - return; + + " active, trying to get Bindingprocessor"); + BindingProcessor bp = getBindingProcessorManager().getBindingProcessor( + IdFactory.getInstance().createId(session.getId())); + if (bp != null) { + log.debug("Found binding processor, using this one"); + RequestDispatcher dispatcher = getServletContext().getNamedDispatcher( + BKU_APPLET_JSP); + log.debug("forward to applet"); + dispatcher.forward(req, resp); + return; + } + log.debug("Did not find a binding processor, creating new ..."); } session = req.getSession(true); if (log.isDebugEnabled()) { log.debug("Using session id: " + session.getId()); } - - HTTPBindingProcessor bindingProcessor; + HTTPBindingProcessor bindingProcessor; bindingProcessor = (HTTPBindingProcessor) getBindingProcessorManager() - .createBindingProcessor(req.getRequestURL().toString(), session.getId(), locale); + .createBindingProcessor(req.getRequestURL().toString(), + session.getId(), locale); Map headerMap = new HashMap(); for (Enumeration headerName = req.getHeaderNames(); headerName @@ -109,14 +117,20 @@ public class BKURequestHandler extends SpringBKUServlet { bindingProcessor.consumeRequestStream(req.getInputStream()); req.getInputStream().close(); getBindingProcessorManager().process(bindingProcessor); - + log.trace("Trying to find applet parameters in request"); - String width = getStringFromStream(bindingProcessor.getFormData("appletWidth"), charset); - String height = getStringFromStream(bindingProcessor.getFormData("appletHeight"), charset); - String background = getStringFromStream(bindingProcessor.getFormData("appletBackground"), charset); - String guiStyle = getStringFromStream(bindingProcessor.getFormData("appletGuiStyle"), charset); - String hashDataDisplay = getStringFromStream(bindingProcessor.getFormData("appletHashDataDisplay"), charset); - String localeFormParam = getStringFromStream(bindingProcessor.getFormData("locale"), charset); + String width = getStringFromStream(bindingProcessor + .getFormData("appletWidth"), charset); + String height = getStringFromStream(bindingProcessor + .getFormData("appletHeight"), charset); + String background = getStringFromStream(bindingProcessor + .getFormData("appletBackground"), charset); + String guiStyle = getStringFromStream(bindingProcessor + .getFormData("appletGuiStyle"), charset); + String hashDataDisplay = getStringFromStream(bindingProcessor + .getFormData("appletHashDataDisplay"), charset); + String localeFormParam = getStringFromStream(bindingProcessor + .getFormData("locale"), charset); if (width != null) { try { log.trace("Found applet width parameter: " + width); @@ -148,7 +162,8 @@ public class BKURequestHandler extends SpringBKUServlet { session.setAttribute("appletHashDataDisplay", hashDataDisplay); } if (localeFormParam != null) { - log.debug("overrule accept-language locale " + locale + " with form param " + localeFormParam); + log.debug("overrule accept-language locale " + locale + + " with form param " + localeFormParam); locale = new Locale(localeFormParam); } if (locale != null) { @@ -156,8 +171,9 @@ public class BKURequestHandler extends SpringBKUServlet { session.setAttribute("locale", locale.toString()); } - //TODO error if no dispatcher found - RequestDispatcher dispatcher = getServletContext().getNamedDispatcher(BKU_APPLET_JSP); + // TODO error if no dispatcher found + RequestDispatcher dispatcher = getServletContext().getNamedDispatcher( + BKU_APPLET_JSP); log.debug("forward to applet"); dispatcher.forward(req, resp); } diff --git a/BKUOnline/src/main/webapp/applet/BKUApplet-1.0.2-SNAPSHOT.jar b/BKUOnline/src/main/webapp/applet/BKUApplet-1.0.2-SNAPSHOT.jar deleted file mode 100644 index 74f00509..00000000 Binary files a/BKUOnline/src/main/webapp/applet/BKUApplet-1.0.2-SNAPSHOT.jar and /dev/null differ diff --git a/BKUOnline/src/main/webapp/appletPage.jsp b/BKUOnline/src/main/webapp/appletPage.jsp index ee5f429c..b73ed2f4 100644 --- a/BKUOnline/src/main/webapp/appletPage.jsp +++ b/BKUOnline/src/main/webapp/appletPage.jsp @@ -47,7 +47,7 @@ var attributes = { codebase :'applet', code :'at.gv.egiz.bku.online.applet.BKUApplet.class', - archive :'BKUApplet-1.0.2-SNAPSHOT.jar, commons-logging-1.1.1.jar, iaik_jce_me4se-3.04.jar', + archive :'BKUApplet.jar, commons-logging-1.1.1.jar, iaik_jce_me4se-3.04.jar', width : <%=width%>, height :<%=height%> }; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java index ed4b9bda..61d3d7a5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/accesscontroller/AuthenticationClassifier.java @@ -65,7 +65,8 @@ public class AuthenticationClassifier { } catch (CertificateParsingException e) { log.error(e); } - if (cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) { + if ((cert.getExtensionValue("1.2.40.0.10.1.1.1") != null) + || (cert.getExtensionValue("1.2.40.0.10.1.1.2") != null)) { return true; } return false; diff --git a/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java b/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java deleted file mode 100644 index 4835865f..00000000 --- a/smcc/src/test/java/at/gv/egiz/smcc/SMCCApplication.java +++ /dev/null @@ -1,49 +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; - -import java.util.Locale; - -import org.junit.Ignore; - -import at.gv.egiz.smcc.util.SMCCHelper; - -@Ignore -public class SMCCApplication { - - /** - * @param args - */ - public static void main(String[] args) { - - SignatureCard sc = null; - SMCCHelper smccHelper = new SMCCHelper(); - while (smccHelper.getResultCode() != SMCCHelper.CARD_FOUND) { - System.out.println("Did not get a signature card ... "+smccHelper.getResultCode()); - smccHelper.update(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - sc = smccHelper.getSignatureCard(Locale.getDefault()); - System.out.println("Found supported siganture card: "+sc); - } - -} diff --git a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java deleted file mode 100644 index 7f421474..00000000 --- a/smcc/src/test/java/at/gv/egiz/smcc/STARCOSCardTest.java +++ /dev/null @@ -1,121 +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; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Locale; - -import javax.smartcardio.CardException; -import javax.smartcardio.CommandAPDU; -import javax.smartcardio.ResponseAPDU; - -import org.junit.Ignore; - -import sun.misc.HexDumpEncoder; - -import at.gv.egiz.smcc.SignatureCard.KeyboxName; -import at.gv.egiz.smcc.util.SMCCHelper; - -@Ignore -public class STARCOSCardTest { - - /** - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - - SMCCHelper helper = new SMCCHelper(); - while (helper.getResultCode() != SMCCHelper.CARD_FOUND) { - System.out.println("Did not get a signature card ... " + helper.getResultCode()); - helper.update(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - SignatureCard signatureCard = helper.getSignatureCard(Locale.getDefault()); - - System.out.println("Found '" + signatureCard + "'."); - - try { -// printJavaByteArray( -// signatureCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR), System.out); -// printJavaByteArray( -// signatureCard.getCertificate(KeyboxName.CERITIFIED_KEYPAIR), System.out); -// System.out. println(new String(signatureCard.getInfobox("IdentityLink", new CommandLinePINProvider(), null))); -// byte[] infobox = signatureCard.getInfobox("Status", new CommandLinePINProvider(), null); -// printJavaByteArray(infobox, System.out); - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); - byte[] digest = messageDigest.digest("test".getBytes()); - byte[] signature = signatureCard.createSignature(digest, KeyboxName.SECURE_SIGNATURE_KEYPAIR, new CommandLinePINProvider()); - printJavaByteArray(signature, System.out); - } catch (SignatureCardException e) { - e.printStackTrace(); - } - - } - - public static void printJavaByteArray(byte[] bytes, OutputStream os) { - - PrintWriter w = new PrintWriter(os); - - w.write("new byte[] {"); - for (int i = 0; i < bytes.length;) { - if (i % 8 == 0) { - w.write("\n "); - } - w.write("(byte) 0x" + Integer.toHexString(0x0F & (bytes[i] >> 4)) + Integer.toHexString(0x0F & bytes[i])); - if (++i < bytes.length) { - w.write(", "); - } - } - w.write("\n};"); - w.flush(); - } - - private static class CommandLinePINProvider implements PINProvider { - - @Override - public String providePIN(PINSpec spec, int retries) { - - InputStreamReader inputStreamReader = new InputStreamReader(System.in); - BufferedReader in = new BufferedReader(inputStreamReader); - - System.out.print("Enter " + spec.getLocalizedName() + " [" - + spec.getMinLength() + "-" + spec.getMaxLength() + "] (" + retries - + " retries):"); - - try { - return in.readLine(); - } catch (IOException e) { - return null; - } - - } - - } - -} diff --git a/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java deleted file mode 100644 index 115edc16..00000000 --- a/smcc/src/test/java/at/gv/egiz/smcc/SWCardTest.java +++ /dev/null @@ -1,66 +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; - -import java.math.BigInteger; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import org.junit.Ignore; - -import at.gv.egiz.smcc.SignatureCard.KeyboxName; - -@Ignore -public class SWCardTest implements PINProvider { - - SWCard swCard = new SWCard(); - - public static void main(String[] args) throws Exception { - - SWCardTest swCardTest = new SWCardTest(); - swCardTest.test(); - - } - - public void test() throws SignatureCardException, NoSuchAlgorithmException, InterruptedException { - - swCard.getCertificate(KeyboxName.CERITIFIED_KEYPAIR); - swCard.getCertificate(KeyboxName.SECURE_SIGNATURE_KEYPAIR); - - BigInteger t = BigInteger.valueOf(System.currentTimeMillis()); - - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); - byte[] hash = messageDigest.digest(t.toByteArray()); - - byte[] signature; - signature = swCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, this); - System.out.println(SignatureCardFactory.toString(signature)); - - signature = swCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, this); - System.out.println(SignatureCardFactory.toString(signature)); - - byte[] infobox = swCard.getInfobox("IdentityLink", this, null); - System.out.println(SignatureCardFactory.toString(infobox)); - - } - - @Override - public String providePIN(PINSpec spec, int retries) { - return "buerger"; - } - -} -- cgit v1.2.3