Hola, estamos utilizando la clase CMSSignatureVerifier para verificar la
firma CMS, y solo es capaz de verificar la firma cuando ésta es realizada
con un certificado personal de la FNMT mientras que si la firma se realiza
mediante DNIe no es capaz de verificarla. En el código de la clase
CMSSignatureVerifier entra en verifyAgainstCA por lo que el formato de la
firma y su composición deducimos que es válido pero a la hora de crear los
parámetros para validar la firma realizada con el DNI no es capaz de
hacerlo, mostrando siempre la siguiente excepción:
"Trust anchor for certification path not found"
El certPath contiene el certificado del DNIe con el que se ha firmado y el
certificado de la CA con la que se ha firmado (ACDNIE001-SHA1.crt) mientras
que el trust anchor lo ceramos con el certificado de la CA
ACDNIE001-SHA1.crt
Haciendo eso exactamente igual con el de la FNMT funciona, sin embargo con
el DNIe salta la excepción comentada anteriormente. ¿Alguna sugerencia?
El código de CMSSignatureVerifier que estamos utilizando es el siguiente (lo
hemos modificado ligeramente):

package es.uji.security.crypto.cms;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;


public class CMSSignatureVerifier
{


    private boolean verifyAgainstCA(X509Certificate[] caCertificates,
CertStore certs,
            Provider provider) throws CertStoreException,
InvalidAlgorithmParameterException,
            NoSuchAlgorithmException, CertificateException,
CertPathValidatorException, IOException
    {

        try{

            for (int i=0;i<caCertificates.length;i++){
                List<Certificate> certChain = new ArrayList<Certificate>();
                if (caCertificates.length > 0)
                {
                    certChain.add(rootCert);
                }

                //certificado de firma del mensaje
                Collection<? extends Certificate> certCollection =
certs.getCertificates(null);
                for (Certificate c : certCollection)
                {
                    certChain.add(c);
                }

                Set<TrustAnchor> trust = new HashSet<TrustAnchor>();
                CertPath certPath = null;
                certPath = CertificateFactory.getInstance("X.509",
provider).generateCertPath(certChain);
                pw2.println("CertPath: "+certPath.toString());

                for (int k=0; k<certChain.size();k++){
                    if (!trust.isEmpty()){
                        trust.clear();
                    }
                    X509Certificate certificado = (X509Certificate)
certChain.get(k);
                    trust.add(new TrustAnchor(certificado, null));
                    try {
                        PKIXParameters param = new PKIXParameters(trust);
                        param.setSigProvider("BC");
                        param.setRevocationEnabled(false);
                        param.setTrustAnchors(trust);
                        CertPathValidator cpv =
CertPathValidator.getInstance("PKIX", provider);
                        CertPathValidatorResult r = cpv.validate(certPath,
param);
                        return true;
                    }
                    catch(Exception e){
                          System.out.println(e.getMessage());
                    }
                }
            }
        }
        catch(Exception e){
                  System.out.println(e.getMessage());
        }
        return false;
    }

    /**
     *
     * Check the signature is correct, conform to plain data and the
certificate chain is ok
     *
     * @throws CertPathValidatorException
     * @throws CertificateException
     * @throws InvalidAlgorithmParameterException
     *
     */

    @SuppressWarnings("unchecked")
    public boolean verify(byte[] data, byte[] signedData, X509Certificate[]
caCertificates,
            Provider provider) throws NoSuchProviderException,
NoSuchAlgorithmException, CertStoreException, CMSException,
InvalidAlgorithmParameterException, CertificateException,
CertPathValidatorException, IOException
    {

        try{
            CMSProcessableByteArray processableByteArray = new
CMSProcessableByteArray(data);
            CMSSignedData cmsSignedData = new
CMSSignedData(processableByteArray, signedData);
            CertStore certs =
cmsSignedData.getCertificatesAndCRLs("Collection", provider);
            SignerInformationStore signers = cmsSignedData.getSignerInfos();
            Collection<SignerInformation> c = signers.getSigners();

            boolean result = false;

            for (SignerInformation signer : c)
            {

                SignerId signerId = signer.getSID();
                Collection certCollection = certs.getCertificates(signerId);

                Iterator certIt = certCollection.iterator();
                X509Certificate cert = (X509Certificate) certIt.next();
                //validacion del mensaje cms (certificado y mensaje cifrado)
                result = signer.verify(cert, provider);

                //mensaje valido
                if (result)
                {
                    //se comprueba que aceptamos la firma
                    result = verifyAgainstCA(caCertificates, certs,
provider);
                    return result;
                }
                else
                {
                    return false;
                }
            }

        }
        catch(Exception e){
            return false;
        }

        return false;

    }
}
_______________________________________________
CryptoApplet mailing list
[email protected]
http://llistes.uji.es/mailman/listinfo/cryptoapplet

Responder a