summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-11-11 15:51:08 +0000
committermcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>2009-11-11 15:51:08 +0000
commit68941b57df2caeead67a5bede2ef5a635d07db32 (patch)
tree78c93c71a20b4775af3991f4395c2267cc39fab8
parentcaca721368d8c24559b1cd5ea2018884b4874f6b (diff)
downloadmocca-68941b57df2caeead67a5bede2ef5a635d07db32.tar.gz
mocca-68941b57df2caeead67a5bede2ef5a635d07db32.tar.bz2
mocca-68941b57df2caeead67a5bede2ef5a635d07db32.zip
Added support for SHA-256 and partial support for e-card G3, BELPIC and Italian cards.
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@540 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
-rw-r--r--STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java51
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java71
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java26
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java86
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java6
-rw-r--r--bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java23
-rw-r--r--bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties2
-rw-r--r--bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties2
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java55
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java283
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/ITCard.java297
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java192
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SWCard.java8
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java11
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java96
-rw-r--r--smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java11
-rw-r--r--smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties3
-rw-r--r--smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties3
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/CardTest.java62
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java62
-rw-r--r--smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java62
-rw-r--r--smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java21
-rw-r--r--smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java5
-rw-r--r--utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java15
24 files changed, 1145 insertions, 308 deletions
diff --git a/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java b/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java
deleted file mode 100644
index c162eed4..00000000
--- a/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-* Copyright 2008 Federal Chancellery Austria and
-* Graz University of Technology
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package at.gv.egiz.stal.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Maps XML Algorithms to JCE Hash names.
- *
- */
-public class JCEAlgorithmNames {
-
- private Map<String, String> hashNameMap = new HashMap<String, String>();
-
- public static String[] JCE_HASH_NAMES = { "SHA-1" };
-
- public static String[] SHA_1_ALGORITMS = {
- "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1",
- "http://www.w3.org/2000/09/xmldsig#rsa-sha1" };
-
- private static JCEAlgorithmNames instance = new JCEAlgorithmNames();
-
- private JCEAlgorithmNames() {
- for (String alg : SHA_1_ALGORITMS) {
- registerHash(alg, JCE_HASH_NAMES[0]);
- }
- }
-
- public static String getJCEHashName(String xmlAlgorithmURI) {
- return instance.hashNameMap.get(xmlAlgorithmURI);
- }
-
- public void registerHash(String xmlAlgorithmURI, String jceName) {
- hashNameMap.put(xmlAlgorithmURI, jceName);
- }
-}
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
index 41c2512f..50f5d2b4 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java
@@ -166,31 +166,62 @@ public abstract class Configurator {
protected void configureProviders() {
log.debug("Registering security providers");
- Security.insertProviderAt(new IAIK(), 1);
- Security.insertProviderAt(new ECCProvider(false), 2);
+
+ IAIK iaikProvider = new IAIK();
+ if (Security.getProvider(iaikProvider.getName()) == null) {
+ // register IAIK provider at first position
+ Security.insertProviderAt(iaikProvider, 1);
+ } else {
+ // IAIK provider already registered
+ log.info("Provider " + iaikProvider.getName() + " already registered.");
+ }
+
+ ECCProvider eccProvider = new ECCProvider(false);
+ if (Security.getProvider(eccProvider.getName()) == null) {
+ // register ECC Provider at second position
+ Security.insertProviderAt(eccProvider, 2);
+ } else {
+ // ECC Provider already registered
+ log.info("Provider " + eccProvider.getName() + " already registered.");
+ }
// registering STALProvider as delegation provider for XSECT
STALProvider stalProvider = new STALProvider();
- Set<Service> services = stalProvider.getServices();
- StringBuilder sb = new StringBuilder();
- for (Service service : services) {
- String algorithm = service.getType() + "." + service.getAlgorithm();
- XSecProvider.setDelegationProvider(algorithm, stalProvider.getName());
- sb.append("\n" + algorithm);
+ if (Security.getProvider(stalProvider.getName()) == null) {
+ // register STAL provider
+ Set<Service> services = stalProvider.getServices();
+ StringBuilder sb = new StringBuilder();
+ for (Service service : services) {
+ String algorithm = service.getType() + "." + service.getAlgorithm();
+ XSecProvider.setDelegationProvider(algorithm, stalProvider.getName());
+ sb.append("\n" + algorithm);
+ }
+ log
+ .debug("Registered STALProvider as XSecProvider delegation provider for the following services : "
+ + sb.toString());
+
+ Security.addProvider(stalProvider);
+ } else {
+ // STAL Provider already registered
+ log.info("Provider " + stalProvider.getName() + " already registered.");
}
- log
- .debug("Registered STALProvider as XSecProvider delegation provider for the following services : "
- + sb.toString());
-
- Security.addProvider(stalProvider);
- XSecProvider.addAsProvider(false);
- sb = new StringBuilder();
- sb.append("Registered providers: ");
- int i = 1;
- for (Provider prov : Security.getProviders()) {
- sb.append((i++) + ". : " + prov);
+
+ if (Security.getProvider(XSecProvider.NAME) == null) {
+ // register XML Security provider
+ XSecProvider.addAsProvider(false);
+ } else {
+ log.info("Provider " + XSecProvider.NAME + " already registered.");
+ }
+
+ if (log.isDebugEnabled()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Registered providers: ");
+ int i = 1;
+ for (Provider prov : Security.getProviders()) {
+ sb.append((i++) + ". : " + prov);
+ }
+ log.debug(sb.toString());
}
- log.debug(sb.toString());
}
protected void configViewer() {
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
index 0c7ce3f5..e903c608 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java
@@ -18,8 +18,15 @@ package at.gv.egiz.bku.slcommands.impl;
import iaik.asn1.CodingException;
import iaik.asn1.DerCoder;
+import iaik.utils.Base64OutputStream;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -174,7 +181,24 @@ public class STALHelper {
try {
certificates.add((X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(cert)));
} catch (CertificateException e) {
- log.info("Failed to decode certificate.", e);
+ if (log.isDebugEnabled()) {
+ ByteArrayOutputStream certDump = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(certDump);
+ try {
+ writer.write("-----BEGIN CERTIFICATE-----\n");
+ writer.flush();
+ Base64OutputStream b64os = new Base64OutputStream(certDump);
+ b64os.write(cert);
+ b64os.flush();
+ writer.write("\n-----END CERTIFICATE-----");
+ writer.flush();
+ } catch (IOException e1) {
+ log.info("Failed to decode certificate.", e);
+ }
+ log.debug("Failed to decode certificate.\n" + certDump.toString(), e);
+ } else {
+ log.info("Failed to decode certificate.", e);
+ }
throw new SLCommandException(4000,
SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID,
new Object[] { "Certificates" });
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
index 6b963465..061fe707 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java
@@ -16,18 +16,23 @@
*/
package at.gv.egiz.bku.slcommands.impl.xsect;
-import iaik.xml.crypto.XmldsigMore;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
-
-import javax.xml.crypto.dsig.CanonicalizationMethod;
-import javax.xml.crypto.dsig.DigestMethod;
-import javax.xml.crypto.dsig.SignatureMethod;
-import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
-import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
-import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+import iaik.security.ecc.interfaces.ECDSAParams;
+import iaik.xml.crypto.XmldsigMore;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECParameterSpec;
+
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
/**
* An implementation of the AlgorithmMethod factory that uses the signing
@@ -40,7 +45,12 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
/**
* The signature algorithm URI.
*/
- private String signatureAlgorithmURI;
+ private String signatureAlgorithmURI;
+
+ /**
+ * the digest algorithm URI.
+ */
+ private String digestAlgorithmURI = DigestMethod.SHA1;
/**
* The algorithm parameters for the signature algorithm.
@@ -51,23 +61,55 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
* Creates a new AlgrithmMethodFactory with the given
* <code>signingCertificate</code>.
*
- * @param siginingCertificate
+ * @param signingCertificate
*
* @throws NoSuchAlgorithmException
* if the public key algorithm of the given
* <code>signingCertificate</code> is not supported
*/
- public AlgorithmMethodFactoryImpl(X509Certificate siginingCertificate)
+ public AlgorithmMethodFactoryImpl(X509Certificate signingCertificate)
throws NoSuchAlgorithmException {
-
- String algorithm = siginingCertificate.getPublicKey().getAlgorithm();
+
+ PublicKey publicKey = signingCertificate.getPublicKey();
+ String algorithm = publicKey.getAlgorithm();
if ("DSA".equals(algorithm)) {
signatureAlgorithmURI = SignatureMethod.DSA_SHA1;
- } else if ("RSA".equals(algorithm)) {
- signatureAlgorithmURI = SignatureMethod.RSA_SHA1;
- } else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) {
- signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA1;
+ } else if ("RSA".equals(algorithm)) {
+
+ int keyLength = 0;
+ if (publicKey instanceof RSAPublicKey) {
+ keyLength = ((RSAPublicKey) publicKey).getModulus().bitLength();
+ }
+
+ if (keyLength >= 2048) {
+ signatureAlgorithmURI = XmldsigMore.SIGNATURE_RSA_SHA256;
+ digestAlgorithmURI = DigestMethod.SHA256;
+ } else {
+ signatureAlgorithmURI = SignatureMethod.RSA_SHA1;
+ }
+
+ } else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) {
+
+ int fieldSize = 0;
+ if (publicKey instanceof iaik.security.ecc.ecdsa.ECPublicKey) {
+ ECDSAParams params = ((iaik.security.ecc.ecdsa.ECPublicKey) publicKey).getParameter();
+ fieldSize = params.getG().getCurve().getField().getSize().bitLength();
+ } else if (publicKey instanceof ECPublicKey) {
+ ECParameterSpec params = ((ECPublicKey) publicKey).getParams();
+ fieldSize = params.getCurve().getField().getFieldSize();
+ }
+
+ if (fieldSize < 256) {
+ signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA1;
+ } else if (fieldSize < 512) {
+ signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA256;
+ digestAlgorithmURI = DigestMethod.SHA256;
+ } else {
+ signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA512;
+ digestAlgorithmURI = DigestMethod.SHA512;
+ }
+
} else {
throw new NoSuchAlgorithmException("Public key algorithm '" + algorithm
+ "' not supported.");
@@ -104,7 +146,7 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory {
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
return signatureContext.getSignatureFactory().newDigestMethod(
- DigestMethod.SHA1, (DigestMethodParameterSpec) null);
+ digestAlgorithmURI, (DigestMethodParameterSpec) null);
}
/*
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
index 0ab30530..42c6a4c5 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java
@@ -49,7 +49,11 @@ public class STALProvider extends Provider {
map.put("Signature." + SignatureMethod.RSA_SHA1,
IMPL_PACKAGE_NAME + ".STALSignature");
map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA1,
- IMPL_PACKAGE_NAME + ".STALSignature");
+ IMPL_PACKAGE_NAME + ".STALSignature");
+ map.put("Signature." + XmldsigMore.SIGNATURE_RSA_SHA256,
+ IMPL_PACKAGE_NAME + ".STALSignature");
+ map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA256,
+ IMPL_PACKAGE_NAME + ".STALSignature");
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
index 26ddb153..3cebb6a3 100644
--- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
+++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java
@@ -628,9 +628,20 @@ public class Signature {
String target = "#" + signatureId;
+ DigestMethod dm;
+ try {
+ dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get DigestMethod algorithm.", e);
+ throw new SLCommandException(4006);
+ } catch (InvalidAlgorithmParameterException e) {
+ log.error("Failed to get DigestMethod algorithm.", e);
+ throw new SLCommandException(4006);
+ }
+
JAXBElement<QualifyingPropertiesType> qualifyingProperties;
try {
- qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats);
+ qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats, dm);
} catch (QualifyingPropertiesException e) {
log.error("Failed to create QualifyingProperties.", e);
throw new SLCommandException(4000);
@@ -665,7 +676,10 @@ public class Signature {
String referenceURI = "#xmlns(xades=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('"
+ objectIdValue
+ "')/child::xades:QualifyingProperties/child::xades:SignedProperties)";
- DigestMethod dm;
+
+ String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference");
+ String referenceType = QualifyingPropertiesFactory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1;
+
try {
dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx);
} catch (NoSuchAlgorithmException e) {
@@ -675,10 +689,7 @@ public class Signature {
log.error("Failed to get DigestMethod algorithm.", e);
throw new SLCommandException(4006);
}
-
- String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference");
- String referenceType = QualifyingPropertiesFactory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1;
-
+
Reference reference = ctx.getSignatureFactory().newReference(referenceURI, dm, null, referenceType, referenceIdValue);
references.add(reference);
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
index db56184e..c5bfce18 100644
--- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties
@@ -91,7 +91,7 @@ ec3002.invalid=XML-Struktur der Befehlsanfrage entspricht nicht dem Schema des S
# 4xxx
#
-ec4000.infobox.invalid=Die Infobox '{0}' enthält ungültige Daten.
+ec4000.infobox.invalid=Die Infobox {0} enthält ungültige Daten.
ec4000.idlink.transfomation.failed=Die komprimierte Personenbindung konnte mit dem Stylesheet {0} nicht transformiert werden.
ec4002.infobox.unknown=Unbekannter Infoboxbezeichner {0}.
ec4003.not.resolved=Zu signierendes Datum kann nicht aufgelöst werden (URI={0}).
diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
index 6c67ba87..a8bffdc6 100644
--- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
+++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties
@@ -91,7 +91,7 @@ ec3002.invalid=XML structure of the command request does not comply with the Sec
# 4xxx
#
-ec4000.infobox.invalid=The infobox '{0}' contains invalid content.
+ec4000.infobox.invalid=The infobox {0} contains invalid content.
ec4000.idlink.transfomation.failed=Failed to transform CompressedIdentityLink with Stylesheet {0}.
ec4002.infobox.unknown=Unknown info box identifier {0}.
ec4003.not.resolved=Data to be signed cannot be resolved from URI={0}.
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 414d4678..a63d4076 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java
@@ -16,9 +16,13 @@
*/
package at.gv.egiz.smcc;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
@@ -375,12 +379,46 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
@Override
@Exclusive
- public byte[] createSignature(byte[] hash, KeyboxName keyboxName,
- PINProvider provider) throws SignatureCardException, InterruptedException {
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
- if (hash.length != 20) {
- throw new IllegalArgumentException("Hash value must be of length 20.");
+ ByteArrayOutputStream dst = new ByteArrayOutputStream();
+ // key ID
+ dst.write(new byte[]{(byte) 0x84, (byte) 0x01, (byte) 0x88});
+ // algorithm ID
+ dst.write(new byte[]{(byte) 0x80, (byte) 0x01});
+
+ MessageDigest md;
+ try {
+ if ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) {
+ dst.write((byte) 0x14); // SHA-1/ECC
+ md = MessageDigest.getInstance("SHA-1");
+ } else if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) {
+ dst.write((byte) 0x12); // SHA-1 with padding according to PKCS#1 block type 01
+ md = MessageDigest.getInstance("SHA-1");
+ } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ && appVersion >= 2
+ && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) {
+ dst.write((byte) 0x44); // SHA-256/ECC
+ md = MessageDigest.getInstance("SHA256");
+ } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)
+ && appVersion >= 2
+ && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) {
+ dst.write((byte) 0x41); // SHA-256 with padding according to PKCS#1
+ md = MessageDigest.getInstance("SHA256");
+ } else {
+ throw new SignatureCardException("Card does not support signature algorithm " + alg + ".");
+ }
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get MessageDigest.", e);
+ throw new SignatureCardException(e);
}
+
+ byte[] digest = new byte[md.getDigestLength()];
+ for (int l; (l = input.read(digest)) != -1;) {
+ md.update(digest, 0, l);
+ }
+ digest = md.digest();
try {
@@ -393,11 +431,11 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
// SELECT application
execSELECT_AID(channel, AID_SIG);
// MANAGE SECURITY ENVIRONMENT : SET DST
- execMSE(channel, 0x41, 0xb6, DST_SIG);
+ execMSE(channel, 0x41, 0xb6, dst.toByteArray());
// VERIFY
verifyPINLoop(channel, spec, provider);
// PERFORM SECURITY OPERATION : HASH
- execPSO_HASH(channel, hash);
+ execPSO_HASH(channel, digest);
// PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE
return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel);
@@ -413,7 +451,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
while (true) {
try {
// INTERNAL AUTHENTICATE
- return execINTERNAL_AUTHENTICATE(channel, hash);
+ return execINTERNAL_AUTHENTICATE(channel, digest);
} catch (SecurityStatusNotSatisfiedException e) {
verifyPINLoop(channel, spec, provider);
}
@@ -711,6 +749,9 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC
ResponseAPDU resp = channel.transmit(
new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256));
+ if (resp.getSW() == 0x6982) {
+ throw new SecurityStatusNotSatisfiedException();
+ }
if (resp.getSW() != 0x9000) {
throw new SignatureCardException(
"PSO - COMPUTE DIGITAL SIGNATRE failed: SW="
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java
new file mode 100644
index 00000000..15b47fb0
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java
@@ -0,0 +1,283 @@
+/*
+* 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.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.SMCCHelper;
+
+public class BELPICCard extends AbstractSignatureCard implements SignatureCard {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(BELPICCard.class);
+
+ public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 };
+
+ public static final byte[] DF_BELPIC = new byte[] { (byte) 0xDF,
+ (byte) 0x00 };
+
+ public static final byte[] DF_ID = new byte[] { (byte) 0xDF, (byte) 0x01 };
+
+ public static final byte[] SIGN_CERT = new byte[] { (byte) 0x50,
+ (byte) 0x39 };
+
+// public static final byte MSE_SET_ALGO_REF = (byte) 0x02;
+
+// public static final byte MSE_SET_PRIV_KEY_REF = (byte) 0x83;
+
+ public static final int SIGNATURE_LENGTH = (int) 0x80;
+
+ public static final byte KID = (byte) 0x01;
+
+ public static final int READ_BUFFER_LENGTH = 256;
+
+ public static final int PINSPEC_SS = 0;
+
+ private static final PINSpec SS_PIN_SPEC =
+ new PINSpec(4, 12, "[0-9]",
+ "at/gv/egiz/smcc/BelpicCard", "sig.pin", KID, DF_BELPIC);
+
+ /**
+ * Creates a new instance.
+ */
+ public BELPICCard() {
+ super("at/gv/egiz/smcc/BelpicCard");
+ pinSpecs.add(SS_PIN_SPEC);
+ }
+
+ @Override
+ @Exclusive
+ public byte[] getCertificate(KeyboxName keyboxName)
+ throws SignatureCardException {
+
+ if (keyboxName != KeyboxName.SECURE_SIGNATURE_KEYPAIR) {
+ throw new IllegalArgumentException("Keybox " + keyboxName
+ + " not supported");
+ }
+
+ try {
+ CardChannel channel = getCardChannel();
+ // SELECT MF
+ execSELECT_FID(channel, MF);
+ // SELECT application
+ execSELECT_FID(channel, DF_BELPIC);
+ // SELECT file
+ execSELECT_FID(channel, SIGN_CERT);
+ // READ BINARY
+ byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30);
+ if (certificate == null) {
+ throw new NotActivatedException();
+ }
+ return certificate;
+ } catch (FileNotFoundException e) {
+ throw new NotActivatedException();
+ } catch (CardException e) {
+ log.info("Failed to get certificate.", e);
+ throw new SignatureCardException(e);
+ }
+
+ }
+
+ @Override
+ @Exclusive
+ public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ throws SignatureCardException, InterruptedException {
+
+ throw new IllegalArgumentException("Infobox '" + infobox
+ + "' not supported.");
+ }
+
+ @Override
+ @Exclusive
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
+
+ if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) {
+ throw new SignatureCardException("Card does not support key " + keyboxName + ".");
+ }
+ if (!"http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) {
+ throw new SignatureCardException("Card does not support algorithm " + alg + ".");
+ }
+
+ byte[] dst = new byte[] { (byte) 0x04, // number of following
+ // bytes
+ (byte) 0x80, // tag for algorithm reference
+ (byte) 0x02, // algorithm reference
+ (byte) 0x84, // tag for private key reference
+ (byte) 0x83 // private key reference
+ };
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get MessageDigest.", e);
+ throw new SignatureCardException(e);
+ }
+ // calculate message digest
+ byte[] digest = new byte[md.getDigestLength()];
+ for (int l; (l = input.read(digest)) != -1;) {
+ md.update(digest, 0, l);
+ }
+ digest = md.digest();
+
+ try {
+
+ CardChannel channel = getCardChannel();
+
+ // SELECT MF
+ execSELECT_FID(channel, MF);
+ // VERIFY
+ execMSE(channel, 0x41, 0xb6, dst);
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
+ verifyPINLoop(channel, SS_PIN_SPEC, provider);
+ // MANAGE SECURITY ENVIRONMENT : SET DST
+ return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest);
+
+ } catch (CardException e) {
+ log.warn(e);
+ throw new SignatureCardException("Failed to access card.", e);
+ }
+
+ }
+
+ public String toString() {
+ return "Belpic Card";
+ }
+
+ protected void verifyPINLoop(CardChannel channel, PINSpec spec,
+ PINProvider provider) throws LockedException, NotActivatedException,
+ SignatureCardException, InterruptedException, CardException {
+
+ int retries = -1; //verifyPIN(channel, spec, null, -1);
+ do {
+ retries = verifyPIN(channel, spec, provider, retries);
+ } while (retries > 0);
+ }
+
+ protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
+ PINProvider provider, int retries) throws SignatureCardException,
+ LockedException, NotActivatedException, InterruptedException,
+ CardException {
+
+ VerifyAPDUSpec apduSpec = new VerifyAPDUSpec(
+ new byte[] {
+ (byte) 0x00, (byte) 0x20, (byte) 0x00, pinSpec.getKID(), (byte) 0x08,
+ (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4);
+
+ ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+
+ if (resp.getSW() == 0x9000) {
+ return -1;
+ }
+ if (resp.getSW() >> 4 == 0x63c) {
+ return 0x0f & resp.getSW();
+ }
+
+ switch (resp.getSW()) {
+ case 0x6983:
+ // authentication method blocked
+ throw new LockedException();
+ case 0x6984:
+ // reference data not usable
+ throw new NotActivatedException();
+ case 0x6985:
+ // conditions of use not satisfied
+ throw new NotActivatedException();
+
+ default:
+ String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ throw new SignatureCardException(msg);
+ }
+
+ }
+
+ protected byte[] execSELECT_FID(CardChannel channel, byte[] fid)
+ throws SignatureCardException, CardException {
+
+ ResponseAPDU resp = channel.transmit(
+ new CommandAPDU(0x00, 0xA4, 0x02, 0x0C, fid, 256));
+
+ if (resp.getSW() == 0x6A82) {
+ String msg = "File or application not found FID="
+ + SMCCHelper.toString(fid) + " SW="
+ + Integer.toHexString(resp.getSW()) + ".";
+ log.info(msg);
+ throw new FileNotFoundException(msg);
+ } else if (resp.getSW() != 0x9000) {
+ String msg = "Failed to select application FID="
+ + SMCCHelper.toString(fid) + " SW="
+ + Integer.toHexString(resp.getSW()) + ".";
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ } else {
+ return resp.getBytes();
+ }
+
+ }
+
+ protected void execMSE(CardChannel channel, int p1, int p2, byte[] data)
+ throws CardException, SignatureCardException {
+ ResponseAPDU resp = channel.transmit(
+ new CommandAPDU(0x00, 0x22, p1, p2, data, 256));
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("MSE:SET failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ }
+ }
+
+ protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel, byte[] hash)
+ throws CardException, SignatureCardException {
+ ResponseAPDU resp;
+ resp = channel.transmit(
+ new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, hash, 256));
+ if (resp.getSW() == 0x6982) {
+ throw new SecurityStatusNotSatisfiedException();
+ } else if (resp.getSW() == 0x6983) {
+ throw new LockedException();
+ } else if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException(
+ "PSO: COMPUTE DIGITAL SIGNATRE failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ } else {
+ return resp.getData();
+ }
+ }
+
+
+
+
+} \ No newline at end of file
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java
new file mode 100644
index 00000000..831a1f9b
--- /dev/null
+++ b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java
@@ -0,0 +1,297 @@
+/*
+* 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.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.smartcardio.CardChannel;
+import javax.smartcardio.CardException;
+import javax.smartcardio.CommandAPDU;
+import javax.smartcardio.ResponseAPDU;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import at.gv.egiz.smcc.util.ISO7816Utils;
+import at.gv.egiz.smcc.util.SMCCHelper;
+
+public class ITCard extends AbstractSignatureCard {
+
+ /**
+ * Logging facility.
+ */
+ private static Log log = LogFactory.getLog(STARCOSCard.class);
+
+ public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 };
+
+ public static final byte[] DF1 = new byte[] { (byte) 0x11, (byte) 0x00 };
+
+ public static final byte[] EF_C_Carta = new byte[] { (byte) 0x11, (byte) 0x01 };
+
+ private static final PINSpec SS_PIN_SPEC =
+ new PINSpec(5, 8, "[0-9]",
+ "at/gv/egiz/smcc/ITCard", "sig.pin", (byte) 0x10,
+ new byte[] { (byte) 0x11, (byte) 0x00 });
+
+ /**
+ * Creates a new instance.
+ */
+ public ITCard() {
+ super("at/gv/egiz/smcc/ITCard");
+ pinSpecs.add(SS_PIN_SPEC);
+ }
+
+ @Override
+ @Exclusive
+ public byte[] getCertificate(KeyboxName keyboxName)
+ throws SignatureCardException, InterruptedException {
+
+ if (keyboxName != KeyboxName.SECURE_SIGNATURE_KEYPAIR) {
+ throw new IllegalArgumentException("Keybox " + keyboxName
+ + " not supported");
+ }
+
+ try {
+ CardChannel channel = getCardChannel();
+ // SELECT MF
+ execSELECT_FID(channel, MF);
+ // SELECT application
+ execSELECT_FID(channel, DF1);
+ // SELECT EF_C_Carta
+ byte[] fcx = execSELECT_FID(channel, EF_C_Carta);
+ int maxsize = ISO7816Utils.getLengthFromFCx(fcx);
+ // READ BINARY
+ byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, maxsize, (byte) 0x30);
+ if (certificate == null) {
+ throw new NotActivatedException();
+ }
+ return certificate;
+ } catch (FileNotFoundException e) {
+ throw new NotActivatedException();
+ } catch (CardException e) {
+ log.info("Failed to get certificate.", e);
+ throw new SignatureCardException(e);
+ }
+
+ }
+
+ @Override
+ @Exclusive
+ public byte[] getInfobox(String infobox, PINProvider provider, String domainId)
+ throws SignatureCardException, InterruptedException {
+
+ throw new IllegalArgumentException("Infobox '" + infobox
+ + "' not supported.");
+ }
+
+ @Override
+ @Exclusive
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException,
+ InterruptedException, IOException {
+
+ if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) {
+ throw new SignatureCardException("Card does not support key " + keyboxName + ".");
+ }
+ if (!"http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) {
+ throw new SignatureCardException("Card does not support algorithm " + alg + ".");
+ }
+
+ byte[] dst = new byte[] {
+ (byte) 0x83, // tag for algorithm reference
+ (byte) 0x01, // algorithm reference
+ (byte) 0x01 // private key reference
+ };
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get MessageDigest.", e);
+ throw new SignatureCardException(e);
+ }
+ // calculate message digest
+ byte[] digest = new byte[md.getDigestLength()];
+ for (int l; (l = input.read(digest)) != -1;) {
+ md.update(digest, 0, l);
+ }
+ digest = md.digest();
+
+ try {
+
+ CardChannel channel = getCardChannel();
+
+ // SELECT MF
+ execSELECT_FID(channel, MF);
+ // VERIFY
+ verifyPINLoop(channel, SS_PIN_SPEC, provider);
+ // MANAGE SECURITY ENVIRONMENT : RESTORE SE
+ execMSE(channel, 0xF3, 0x03, null);
+ // MANAGE SECURITY ENVIRONMENT : SET DST
+ execMSE(channel, 0xF1, 0xB8, dst);
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
+ return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest);
+
+ } catch (CardException e) {
+ log.warn(e);
+ throw new SignatureCardException("Failed to access card.", e);
+ }
+
+ }
+
+ protected void verifyPINLoop(CardChannel channel, PINSpec spec,
+ PINProvider provider) throws LockedException, NotActivatedException,
+ SignatureCardException, InterruptedException, CardException {
+
+ int retries = -1;
+ do {
+ retries = verifyPIN(channel, spec, provider, retries);
+ } while (retries >= -1);
+ }
+
+ protected int verifyPIN(CardChannel channel, PINSpec pinSpec,
+ PINProvider provider, int retries) throws SignatureCardException,
+ LockedException, NotActivatedException, InterruptedException,
+ CardException {
+
+ VerifyAPDUSpec apduSpec = new VerifyAPDUSpec(
+ new byte[] {
+ (byte) 0x00, (byte) 0x20, (byte) 0x00, pinSpec.getKID(), (byte) 0x08,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8);
+
+ ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries);
+
+ if (resp.getSW() == 0x9000) {
+ return -2;
+ }
+ if (resp.getSW() >> 4 == 0x63c) {
+ return 0x0f & resp.getSW();
+ }
+
+ switch (resp.getSW()) {
+ case 0x6300:
+ // incorrect PIN, number of retries not provided
+ return -1;
+ case 0x6983:
+ // authentication method blocked
+ throw new LockedException();
+ case 0x6984:
+ // reference data not usable
+ throw new NotActivatedException();
+ case 0x6985:
+ // conditions of use not satisfied
+ throw new NotActivatedException();
+
+ default:
+ String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW());
+ log.info(msg);
+ throw new SignatureCardException(msg);
+ }
+
+ }
+
+ protected byte[] execSELECT_FID(CardChannel channel, byte[] fid)
+ throws SignatureCardException, CardException {
+
+ ResponseAPDU resp = channel.transmit(
+ new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256));
+
+ if (resp.getSW() == 0x6A82) {
+ String msg = "File or application not found FID="
+ + SMCCHelper.toString(fid) + " SW="
+ + Integer.toHexString(resp.getSW()) + ".";
+ log.info(msg);
+ throw new FileNotFoundException(msg);
+ } else if (resp.getSW() != 0x9000) {
+ String msg = "Failed to select application FID="
+ + SMCCHelper.toString(fid) + " SW="
+ + Integer.toHexString(resp.getSW()) + ".";
+ log.error(msg);
+ throw new SignatureCardException(msg);
+ } else {
+ return resp.getBytes();
+ }
+
+ }
+
+ protected void execMSE(CardChannel channel, int p1, int p2, byte[] data)
+ throws CardException, SignatureCardException {
+
+ ResponseAPDU resp;
+ if (data == null) {
+ resp = channel.transmit(new CommandAPDU(0x00, 0x22, p1, p2));
+ } else {
+ resp = channel.transmit(new CommandAPDU(0x00, 0x22, p1, p2, data));
+ }
+
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("MSE:SET failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ }
+ }
+
+ protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel,
+ byte[] hash) throws CardException, SignatureCardException {
+
+ byte[] oid = 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, (byte) 0x14 };
+
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+
+ try {
+ // header
+ data.write(new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x01 });
+ // padding
+ for (int i = 0, len = 125 - hash.length - oid.length; i < len; i++) {
+ data.write((byte) 0xFF);
+ }
+ data.write((byte) 0x00);
+ // oid
+ data.write(oid);
+ // hash
+ data.write(hash);
+ } catch (IOException e) {
+ throw new SignatureCardException(e);
+ }
+
+ ResponseAPDU resp = channel
+ .transmit(new CommandAPDU(0x00, 0x2A, 0x80, 0x86, data.toByteArray(), 0x81));
+
+
+ if (resp.getSW() == 0x6982) {
+ throw new SecurityStatusNotSatisfiedException();
+ } else if (resp.getSW() == 0x6983) {
+ throw new LockedException();
+ } else if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException(
+ "PSO: COMPUTE DIGITAL SIGNATRE failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ } else {
+ return resp.getData();
+ }
+}
+
+}
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 a0c2391d..01de8a77 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java
@@ -19,11 +19,16 @@ package at.gv.egiz.smcc;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
+import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
+import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
@@ -41,6 +46,8 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
private static Log log = LogFactory.getLog(STARCOSCard.class);
public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 };
+
+ public static final byte[] EF_VERSION = new byte[] { (byte) 0x00, (byte) 0x32 };
/**
* Application ID <em>SV-Personendaten</em>.
@@ -106,19 +113,6 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
public static final byte[] EF_C_X509_CA_CS_DS = new byte[] { (byte) 0xc6,
(byte) 0x08 };
- public static final byte[] DST_SS = new byte[] { (byte) 0x84, (byte) 0x03, // tag
- // ,
- // length
- // (
- // key
- // desc
- // .
- // )
- (byte) 0x80, (byte) 0x02, (byte) 0x00, // local, key ID, key version
- (byte) 0x89, (byte) 0x03, // tag, length (algorithm ID)
- (byte) 0x13, (byte) 0x35, (byte) 0x10 // ECDSA
- };
-
public static final byte KID_PIN_SS = (byte) 0x81;
// Gewöhnliche Signatur (GS)
@@ -133,19 +127,6 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
public static final byte[] EF_C_X509_CA_CS = new byte[] { (byte) 0x2f,
(byte) 0x02 };
- public static final byte[] DST_GS = new byte[] { (byte) 0x84, (byte) 0x03, // tag
- // ,
- // length
- // (
- // key
- // desc
- // .
- // )
- (byte) 0x80, (byte) 0x02, (byte) 0x00, // local, key ID, key version
- (byte) 0x89, (byte) 0x03, // tag, length (algorithm ID)
- (byte) 0x13, (byte) 0x35, (byte) 0x10 // ECDSA
- };
-
public static final byte KID_PIN_CARD = (byte) 0x01;
private static final PINSpec CARD_PIN_SPEC =
@@ -155,9 +136,11 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
private static final PINSpec SS_PIN_SPEC =
new PINSpec(6, 12, "[0-9]",
"at/gv/egiz/smcc/STARCOSCard", "sig.pin", KID_PIN_SS, AID_DF_SS);
+
+ protected double version = 1.1;
/**
- * Creates an new instance.
+ * Creates a new instance.
*/
public STARCOSCard() {
super("at/gv/egiz/smcc/STARCOSCard");
@@ -165,6 +148,35 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
pinSpecs.add(SS_PIN_SPEC);
}
+ /* (non-Javadoc)
+ * @see at.gv.egiz.smcc.AbstractSignatureCard#init(javax.smartcardio.Card, javax.smartcardio.CardTerminal)
+ */
+ @Override
+ public void init(Card card, CardTerminal cardTerminal) {
+ super.init(card, cardTerminal);
+
+ // determine application version
+ CardChannel channel = getCardChannel();
+ try {
+ // SELECT MF
+ execSELECT_MF(channel);
+ // SELECT EF_VERSION
+ execSELECT_FID(channel, EF_VERSION);
+ // READ BINARY
+ byte[] ver = ISO7816Utils.readRecord(channel, 1);
+ if (ver[0] == (byte) 0xa5 && ver[2] == (byte) 0x53) {
+ version = (0x0F & ver[4]) + (0xF0 & ver[5])/160.0 + (0x0F & ver[5])/100.0;
+ String generation = (version < 1.2) ? "<= G2" : "G3";
+ log.info("e-card version=" + version + " (" + generation + ")");
+ }
+ } catch (CardException e) {
+ log.warn(e);
+ } catch (SignatureCardException e) {
+ log.warn(e);
+ }
+
+ }
+
@Override
@Exclusive
public byte[] getCertificate(KeyboxName keyboxName)
@@ -281,19 +293,57 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
@Override
@Exclusive
- public byte[] createSignature(byte[] hash, KeyboxName keyboxName,
- PINProvider provider) throws SignatureCardException, InterruptedException {
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
- if (hash.length != 20) {
- throw new IllegalArgumentException("Hash value must be of length 20.");
+ ByteArrayOutputStream dst = new ByteArrayOutputStream();
+ byte[] ht = null;
+
+ MessageDigest md = null;
+ try {
+ if (version < 1.2 && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) {
+ // local key ID '02' version '00'
+ dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00});
+ // algorithm ID ECDSA with SHA-1
+ dst.write(new byte[] {(byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x35, (byte) 0x10});
+ md = MessageDigest.getInstance("SHA-1");
+ } else if (version >= 1.2 && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) {
+ // local key ID '02' version '00'
+ dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00});
+ // portable algorithm reference
+ dst.write(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x04});
+ // hash template
+ ht = new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x40};
+ md = MessageDigest.getInstance("SHA256");
+ } else if (version >= 1.2 && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) {
+ // local key ID '03' version '00'
+ dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x03, (byte) 0x00});
+ // portable algorithm reference
+ dst.write(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x02});
+ // hash template
+ ht = new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x40};
+ md = MessageDigest.getInstance("SHA256");
+ } else {
+ throw new SignatureCardException("e-card versio " + version + " does not support signature algorithm " + alg + ".");
+ }
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to get MessageDigest.", e);
+ throw new SignatureCardException(e);
}
-
+
+ // calculate message digest
+ byte[] digest = new byte[md.getDigestLength()];
+ for (int l; (l = input.read(digest)) != -1;) {
+ md.update(digest, 0, l);
+ }
+ digest = md.digest();
+
try {
CardChannel channel = getCardChannel();
if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) {
-
+
PINSpec spec = SS_PIN_SPEC;
// SELECT MF
@@ -303,11 +353,21 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// VERIFY
verifyPINLoop(channel, spec, provider);
// MANAGE SECURITY ENVIRONMENT : SET DST
- execMSE(channel, 0x41, 0xb6, DST_SS);
- // PERFORM SECURITY OPERATION : HASH
- execPSO_HASH(channel, hash);
- // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
- return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel);
+ execMSE(channel, 0x41, 0xb6, dst.toByteArray());
+ if (ht != null) {
+ // PERFORM SECURITY OPERATION : SET HT
+ execMSE(channel, 0x41, 0xaa, ht);
+ }
+ if (version < 1.2) {
+ // PERFORM SECURITY OPERATION : HASH
+ execPSO_HASH(channel, digest);
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
+ return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, null);
+ } else {
+ // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
+ return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest);
+ }
+
} else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) {
@@ -316,14 +376,17 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
// SELECT application
execSELECT_AID(channel, AID_DF_GS);
// MANAGE SECURITY ENVIRONMENT : SET DST
- execMSE(channel, 0x41, 0xb6, DST_GS);
+ execMSE(channel, 0x41, 0xb6, dst.toByteArray());
+ if (ht != null) {
+ // PERFORM SECURITY OPERATION : SET HT
+ execMSE(channel, 0x41, 0xaa, ht);
+ }
// PERFORM SECURITY OPERATION : HASH
- execPSO_HASH(channel, hash);
-
+ execPSO_HASH(channel, digest);
while (true) {
try {
// PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE
- return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel);
+ return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, null);
} catch (SecurityStatusNotSatisfiedException e) {
verifyPINLoop(channel, spec, provider);
}
@@ -682,7 +745,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
ResponseAPDU resp = channel.transmit(
new CommandAPDU(0x00, 0x22, p1, p2, data));
if (resp.getSW() != 0x9000) {
- throw new SignatureCardException("MSE:SET DST failed: SW="
+ throw new SignatureCardException("MSE:SET failed: SW="
+ Integer.toHexString(resp.getSW()));
}
}
@@ -701,10 +764,47 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu
}
}
- protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel)
+ protected void execPSO_HASH(CardChannel channel, InputStream input)
+ throws SignatureCardException, CardException {
+ ResponseAPDU resp;
+ int blockSize = 64;
+ byte[] b = new byte[blockSize];
+ try {
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+ // initialize
+ data.write((byte) 0x90);
+ data.write((byte) 0x00);
+ resp = channel.transmit(
+ new CommandAPDU(0x10, 0x2A, 0x90, 0xA0, data.toByteArray()));
+ data.reset();
+ for (int l; (l = input.read(b)) != -1;) {
+ data.write((byte) 0x80);
+ data.write(l);
+ data.write(b, 0, l);
+ resp = channel.transmit(
+ new CommandAPDU((l == blockSize) ? 0x10 : 0x00, 0x2A, 0x90, 0xA0, data.toByteArray()));
+ if (resp.getSW() != 0x9000) {
+ throw new SignatureCardException("PSO:HASH failed: SW="
+ + Integer.toHexString(resp.getSW()));
+ }
+ data.reset();
+ }
+ } catch (IOException e) {
+ throw new SignatureCardException(e);
+ }
+
+ }
+
+ protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel, byte[] hash)
throws CardException, SignatureCardException {
- ResponseAPDU resp = channel.transmit(
- new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256));
+ ResponseAPDU resp;
+ if (hash != null) {
+ resp = channel.transmit(
+ new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, hash, 256));
+ } else {
+ resp = channel.transmit(
+ new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256));
+ }
if (resp.getSW() == 0x6982) {
throw new SecurityStatusNotSatisfiedException();
} else if (resp.getSW() == 0x6983) {
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 279362c0..670704d5 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java
@@ -20,6 +20,7 @@ import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
@@ -308,7 +309,7 @@ public class SWCard implements SignatureCard {
}
@Override
- public byte[] createSignature(byte[] hash, KeyboxName keyboxName, PINProvider provider) throws SignatureCardException, InterruptedException {
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName, PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException {
// KeyStore password
char[] password = getPassword(keyboxName);
@@ -363,7 +364,10 @@ public class SWCard implements SignatureCard {
try {
Signature signature = Signature.getInstance(algorithm);
signature.initSign(privateKey);
- signature.update(hash);
+ int l;
+ for (byte[] b = new byte[20]; (l = input.read(b)) != -1;) {
+ signature.update(b, 0, l);
+ }
return signature.sign();
} catch (NoSuchAlgorithmException e) {
String msg = "Algorithm + '" + algorithm + "' not supported for signing.";
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 1a163783..3d56f97b 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java
@@ -18,6 +18,9 @@
package at.gv.egiz.smcc;
import at.gv.egiz.smcc.ccid.CCID;
+
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Locale;
import javax.smartcardio.Card;
@@ -101,15 +104,17 @@ public interface SignatureCard {
/**
*
- * @param hash
+ * @param input
* @param keyboxName
* @param provider
+ * @param alg TODO
* @return
* @throws at.gv.egiz.smcc.SignatureCardException
* @throws java.lang.InterruptedException if applet is destroyed while in pin dialog
+ * @throws IOException
*/
- public byte[] createSignature(byte[] hash, KeyboxName keyboxName,
- PINProvider provider) throws SignatureCardException, InterruptedException;
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException;
public CCID getReader();
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 26844473..47053f98 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java
@@ -170,21 +170,21 @@ public class SignatureCardFactory {
},
"at.gv.egiz.smcc.STARCOSCard"));
-// // e-card G3
-// supportedCards.add(new SupportedCard(
-// // ATR (3b:dd:96:ff:81:b1:fe:45:1f:03:80:31:b0:52:02:03:64:04:1b:b4:22:81:05:18)
-// new byte[] {
-// (byte) 0x3b, (byte) 0xdd, (byte) 0x96, (byte) 0xff, (byte) 0x81, (byte) 0xb1, (byte) 0xfe, (byte) 0x45,
-// (byte) 0x1f, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
-// },
-// // mask (
-// new byte[] {
-// (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-// (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
-// },
-// "at.gv.egiz.smcc.STARCOSCard"));
+ // e-card G3
+ supportedCards.add(new SupportedCard(
+ // ATR (3b:dd:96:ff:81:b1:fe:45:1f:03:80:31:b0:52:02:03:64:04:1b:b4:22:81:05:18)
+ new byte[] {
+ (byte) 0x3b, (byte) 0xdd, (byte) 0x96, (byte) 0xff, (byte) 0x81, (byte) 0xb1, (byte) 0xfe, (byte) 0x45,
+ (byte) 0x1f, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ },
+ // mask (
+ new byte[] {
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ },
+ "at.gv.egiz.smcc.STARCOSCard"));
// a-sign premium
supportedCards.add(new SupportedCard(
@@ -202,6 +202,72 @@ public class SignatureCardFactory {
},
"at.gv.egiz.smcc.ACOSCard"));
+ // BELPIC
+ supportedCards.add(new SupportedCard(
+ // ATR (3b:98:13:40:0A:A5:03:01:01:01:AD:13:11)
+ new byte[] { (byte) 0x3b, (byte) 0x98, (byte) 0x13,
+ (byte) 0x40, (byte) 0x0a, (byte) 0xa5, (byte) 0x03,
+ (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0xad,
+ (byte) 0x13, (byte) 0x11 },
+ // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff)
+ new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff },
+ "at.gv.egiz.smcc.BELPICCard"));
+
+ // ITCards
+ supportedCards.add(new SupportedCard(
+ // ATR =
+ // [3b:ff:18:00:ff:81:31:fe:55:00:6b:02:09:02:00:01:11:01:43:4e:53:11:31:80:8e]
+ new byte[] { (byte) 0x3b, (byte) 0xff, (byte) 0x18,
+ (byte) 0x00, (byte) 0xff, (byte) 0x81, (byte) 0x31,
+ (byte) 0xfe, (byte) 0x55, (byte) 0x00, (byte) 0x6b,
+ (byte) 0x02, (byte) 0x09 /*
+ * , (byte) 0x02, (byte) 0x00,
+ * (byte) 0x01, (byte) 0x11,
+ * (byte) 0x01, (byte) 0x43,
+ * (byte) 0x4e, (byte) 0x53,
+ * (byte) 0x11, (byte) 0x31,
+ * (byte) 0x80, (byte) 0x8e
+ */
+ },
+ // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff)
+ new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff /*
+ * , (byte) 0xff, (byte) 0xff,
+ * (byte) 0xff, (byte) 0xff,
+ * (byte) 0xff, (byte) 0xff,
+ * (byte) 0xff, (byte) 0xff,
+ * (byte) 0xff, (byte) 0xff,
+ * (byte) 0xff, (byte) 0xff
+ */
+ }, "at.gv.egiz.smcc.ITCard"));
+ supportedCards.add(new SupportedCard(
+ // ATR
+ // (3B:FF:18:00:FF:C1:0A:31:FE:55:00:6B:05:08:C8:05:01:01:01:43:4E:53:10:31:80:1C)
+ new byte[] { (byte) 0x3b, (byte) 0xff, (byte) 0x18,
+ (byte) 0x00, (byte) 0xFF, (byte) 0xC1, (byte) 0x0a,
+ (byte) 0x31, (byte) 0xfe, (byte) 0x55, (byte) 0x00,
+ (byte) 0x6B, (byte) 0x05, (byte) 0x08, (byte) 0xC8,
+ (byte) 0x05, (byte) 0x01, (byte) 0x01, (byte) 0x01,
+ (byte) 0x43, (byte) 0x4E, (byte) 0x53, (byte) 0x10,
+ (byte) 0x31, (byte) 0x80, (byte) 0x1C },
+ // mask
+ // (ff:ff:ff:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00)
+ new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff },
+ "at.gv.egiz.smcc.ITCard"));
+
+
+
}
/**
diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java
index c5c7cbc9..fcd0b876 100644
--- a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java
+++ b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java
@@ -103,6 +103,14 @@ public class ISO7816Utils {
TransparentFileInputStream is = openTransparentFileInputStream(channel,
maxSize);
+
+ return readTransparentFileTLV(is, maxSize, expectedType);
+
+ }
+
+ public static byte[] readTransparentFileTLV(TransparentFileInputStream is, int maxSize,
+ byte expectedType) throws CardException, SignatureCardException {
+
try {
@@ -170,7 +178,8 @@ public class ISO7816Utils {
while (pos < (fcx[1] - 2)) {
switch (fcx[pos]) {
- case (byte) 0x80: {
+ case (byte) 0x80:
+ case (byte) 0x81: {
len = 0xFF & fcx[pos + 2];
for (int i = 1; i < fcx[pos + 1]; i++) {
len<<=8;
diff --git a/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties b/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties
new file mode 100644
index 00000000..71267394
--- /dev/null
+++ b/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties
@@ -0,0 +1,3 @@
+#pin.name=PIN
+sig.pin.name=PIN
+sig.pin.length=4-12 \ No newline at end of file
diff --git a/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties b/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties
new file mode 100644
index 00000000..e0222a70
--- /dev/null
+++ b/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties
@@ -0,0 +1,3 @@
+#pin.name=PIN
+sig.pin.name=PIN
+sig.pin.length=5-8 \ No newline at end of file
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
index 2a55357d..b3bd07ab 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java
@@ -18,6 +18,8 @@ package at.gv.egiz.smcc;
import static org.junit.Assert.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -178,13 +180,10 @@ public abstract class CardTest {
@Test(expected = CancelledException.class)
public void testSignSIGCancel() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -193,21 +192,19 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, pinProvider,
+ null);
}
@Test(expected = CancelledException.class)
public void testSignDECCancel() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -216,21 +213,19 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = InterruptedException.class)
public void testSignSIGInterrrupted() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -239,21 +234,19 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = InterruptedException.class)
public void testSignDECInterrrupted() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -262,21 +255,19 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = CancelledException.class)
public void testSignSIGConcurrent() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
final SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -294,21 +285,19 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = CancelledException.class)
public void testSignDECConcurrent() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
final SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
PINProvider pinProvider = new PINProvider() {
@Override
public char[] providePIN(PINSpec spec, int retries)
@@ -326,8 +315,9 @@ public abstract class CardTest {
}
};
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
index 90bb039e..56d1e4b2 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -125,7 +127,7 @@ public abstract class ACOSCardTest extends CardTest {
@Test
public void testSignSIG() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
char[] pin = "123456".toCharArray();
@@ -134,11 +136,9 @@ public abstract class ACOSCardTest extends CardTest {
ACOSApplSIG appl = (ACOSApplSIG) card.getApplication(ACOSAppl.AID_SIG);
appl.setPin(ACOSApplSIG.KID_PIN_SIG, pin);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
- byte[] signature = signatureCard.createSignature(hash,
- KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin));
+ byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")),
+ KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null);
assertNotNull(signature);
@@ -147,7 +147,7 @@ public abstract class ACOSCardTest extends CardTest {
@Test
public void testSignDEC() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
char[] pin = "1234".toCharArray();
@@ -156,11 +156,9 @@ public abstract class ACOSCardTest extends CardTest {
ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC);
appl.setPin(ACOSApplDEC.KID_PIN_DEC, pin);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
- byte[] signature = signatureCard.createSignature(hash,
- KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin));
+ byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")),
+ KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null);
assertNotNull(signature);
@@ -169,74 +167,66 @@ public abstract class ACOSCardTest extends CardTest {
@Test(expected = LockedException.class)
public void testSignSIGInvalidPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignDECInvalidPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignSIGBlockedPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
CardEmul card = (CardEmul) signatureCard.getCard();
ACOSApplSIG appl = (ACOSApplSIG) card.getApplication(ACOSAppl.AID_SIG);
appl.setPin(ACOSApplSIG.KID_PIN_SIG, null);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignDECBlockedPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
CardEmul card = (CardEmul) signatureCard.getCard();
ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC);
appl.setPin(ACOSApplDEC.KID_PIN_DEC, null);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
index 89e2ca65..b7dc9a0c 100644
--- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
+++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -147,7 +149,7 @@ public class STARCOSCardTest extends CardTest {
@Test
public void testSignSichereSignatur() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
char[] pin = "123456".toCharArray();
@@ -156,11 +158,9 @@ public class STARCOSCardTest extends CardTest {
STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, pin);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
- byte[] signature = signatureCard.createSignature(hash,
- KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin));
+ byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")),
+ KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null);
assertNotNull(signature);
@@ -169,7 +169,7 @@ public class STARCOSCardTest extends CardTest {
@Test
public void testSignGewoehnlicheSignatur() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
char[] pin = "1234".toCharArray();
@@ -178,11 +178,9 @@ public class STARCOSCardTest extends CardTest {
STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, pin);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
- byte[] signature = signatureCard.createSignature(hash,
- KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin));
+ byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")),
+ KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null);
assertNotNull(signature);
@@ -191,75 +189,67 @@ public class STARCOSCardTest extends CardTest {
@Test(expected = LockedException.class)
public void testSignSichereSignaturInvalidPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignGewoehnlicheSignaturInvalidPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("1234".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignSichereSignaturBlockedPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
CardEmul card = (CardEmul) signatureCard.getCard();
STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur);
appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, null);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray());
assertTrue(pinProvider.getProvided() <= 0);
- signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR,
+ pinProvider, null);
}
@Test(expected = LockedException.class)
public void testSignGewoehnlicheSignaturBlockedPin() throws SignatureCardException,
InterruptedException, CardNotSupportedException,
- NoSuchAlgorithmException, UnsupportedEncodingException {
+ NoSuchAlgorithmException, IOException {
SignatureCard signatureCard = createSignatureCard();
CardEmul card = (CardEmul) signatureCard.getCard();
STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel();
channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, null);
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] hash = md.digest("MOCCA".getBytes("ASCII"));
-
TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray());
- signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR,
- pinProvider);
+ signatureCard.createSignature(new ByteArrayInputStream("MOCCA"
+ .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR,
+ pinProvider, null);
}
diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
index 560f1373..58d7b305 100644
--- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
+++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java
@@ -18,9 +18,8 @@ package at.gv.egiz.bku.smccstal;
import at.gv.egiz.bku.gui.BKUGUIFacade;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
@@ -44,7 +43,6 @@ import at.gv.egiz.stal.SignRequest;
import at.gv.egiz.stal.SignResponse;
import at.gv.egiz.stal.signedinfo.ObjectFactory;
import at.gv.egiz.stal.signedinfo.SignedInfoType;
-import at.gv.egiz.stal.util.JCEAlgorithmNames;
public class SignRequestHandler extends AbstractRequestHandler {
@@ -77,18 +75,11 @@ public class SignRequestHandler extends AbstractRequestHandler {
JAXBElement<SignedInfoType> si = (JAXBElement<SignedInfoType>) unmarshaller.unmarshal(is);
String signatureMethod = si.getValue().getSignatureMethod().getAlgorithm();
log.debug("Found signature method: " + signatureMethod);
- String jceName = JCEAlgorithmNames.getJCEHashName(signatureMethod);
- if (jceName == null) {
- log.error("Hash algorithm not supported:");
- return new ErrorResponse(4006);
- }
- MessageDigest md = MessageDigest.getInstance(jceName);
- md.update(signReq.getSignedInfo());
KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier());
- byte[] resp = card.createSignature(md.digest(), kb,
+ byte[] resp = card.createSignature(new ByteArrayInputStream(signReq.getSignedInfo()), kb,
new PINProviderFactory(card.getReader(), gui)
- .getSignaturePINProvider(secureViewer, si.getValue()));
+ .getSignaturePINProvider(secureViewer, si.getValue()), signatureMethod);
if (resp == null) {
return new ErrorResponse(6001);
}
@@ -127,9 +118,9 @@ public class SignRequestHandler extends AbstractRequestHandler {
} catch (JAXBException e) {
log.error("Cannot unmarshall signed info", e);
return new ErrorResponse(1000);
- } catch (NoSuchAlgorithmException e) {
- log.error(e);
- return new ErrorResponse(1000);
+ } catch (IOException e) {
+ log.error("Error while creating signature: " + e);
+ return new ErrorResponse(4000);
}
} else {
log.fatal("Got unexpected STAL request: " + request);
diff --git a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
index 36880e68..16d3efa9 100644
--- a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
+++ b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java
@@ -1,5 +1,6 @@
package at.gv.egiz.smcc;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -37,8 +38,8 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements
signatureCard = new SignatureCard() {
@Override
- public byte[] createSignature(byte[] hash, KeyboxName keyboxName,
- PINProvider provider) throws SignatureCardException {
+ public byte[] createSignature(InputStream input, KeyboxName keyboxName,
+ PINProvider provider, String alg) throws SignatureCardException {
// TODO Auto-generated method stub
return null;
}
diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java
index 82cba624..6f694b91 100644
--- a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java
+++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java
@@ -104,14 +104,14 @@ public class QualifyingPropertiesFactory {
}
- public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate) throws QualifyingPropertiesException {
+ public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate, DigestMethod dm) throws QualifyingPropertiesException {
DigestMethodType digestMethodType = dsFactory.createDigestMethodType();
- digestMethodType.setAlgorithm(DigestMethod.SHA1);
-
+ digestMethodType.setAlgorithm(dm.getAlgorithm());
+
byte[] digest;
try {
- MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+ MessageDigest messageDigest = MessageDigest.getInstance(dm.getAlgorithm());
digest = messageDigest.digest(certificate.getEncoded());
} catch (CertificateEncodingException e) {
throw new QualifyingPropertiesException(e);
@@ -155,7 +155,10 @@ public class QualifyingPropertiesFactory {
return dataObjectFormatType;
}
- public JAXBElement<QualifyingPropertiesType> createQualifyingProperties111(String target, Date signingTime, List<X509Certificate> certificates, String idValue, List<DataObjectFormatType> dataObjectFormats) throws QualifyingPropertiesException {
+ public JAXBElement<QualifyingPropertiesType> createQualifyingProperties111(
+ String target, Date signingTime, List<X509Certificate> certificates,
+ String idValue, List<DataObjectFormatType> dataObjectFormats,
+ DigestMethod digestMethod) throws QualifyingPropertiesException {
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -175,7 +178,7 @@ public class QualifyingPropertiesFactory {
for (X509Certificate certificate : certificates) {
CertIDType certIDType = qpFactory.createCertIDType();
- certIDType.setCertDigest(createDigestAlgAndValueType(certificate));
+ certIDType.setCertDigest(createDigestAlgAndValueType(certificate, digestMethod));
certIDType.setIssuerSerial(createX509IssuerSerialType(certificate));
certIDs.add(certIDType);