From 68941b57df2caeead67a5bede2ef5a635d07db32 Mon Sep 17 00:00:00 2001
From: mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4>
Date: Wed, 11 Nov 2009 15:51:08 +0000
Subject: 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
---
 .../java/at/gv/egiz/bku/conf/Configurator.java     | 71 +++++++++++++-----
 .../at/gv/egiz/bku/slcommands/impl/STALHelper.java | 26 ++++++-
 .../impl/xsect/AlgorithmMethodFactoryImpl.java     | 86 ++++++++++++++++------
 .../bku/slcommands/impl/xsect/STALProvider.java    |  6 +-
 .../egiz/bku/slcommands/impl/xsect/Signature.java  | 23 ++++--
 5 files changed, 162 insertions(+), 50 deletions(-)

(limited to 'bkucommon/src/main/java/at/gv')

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);
-- 
cgit v1.2.3