package gov.pr.celepar.tabeliao.client.applet.cms; /* Este programa � licenciado de acordo com a LPG-AP (LICEN�A P�BLICA GERAL PARA PROGRAMAS DE COMPUTADOR DA ADMINISTRA��O P�BLICA), vers�o 1.1 ou qualquer vers�o posterior. A LPG-AP deve acompanhar todas PUBLICA��ES, DISTRIBUI��ES e REPRODU��ES deste Programa. Caso uma c�pia da LPG-AP n�o esteja dispon�vel junto com este Programa, voc� pode contatar o LICENCIANTE ou ent�o acessar diretamente: http://www.celepar.pr.gov.br/licenca/LPG-AP.pdf Para poder USAR, PUBLICAR, DISTRIBUIR, REPRODUZIR ou ALTERAR este Programa � preciso estar de acordo com os termos da LPG-AP */ import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.CMSException; import org.bouncycastle.x509.NoSuchStoreException; import org.bouncycastle.x509.X509CollectionStoreParameters; import org.bouncycastle.x509.X509Store; import org.bouncycastle.x509.X509V2AttributeCertificate; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Signature; import java.security.cert.CRLException; import java.security.cert.CertStore; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Classe com metodos auxiliares para efetuar Assinatura em formato PKCS#7/CMS * * @author Thiago Meneghello - GIC/CELEPAR * */ // Classe implementada para possibilitar a assinatura do Hash do Arquivo. class CMSSignedHelper { static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); private static final Map<String, String> encryptionAlgs = new HashMap<String, String>(); private static final Map<String, String> digestAlgs = new HashMap<String, String>(); static { encryptionAlgs.put(X9ObjectIdentifiers.id_dsa_with_sha1.getId(), "DSA"); encryptionAlgs.put(X9ObjectIdentifiers.id_dsa.getId(), "DSA"); encryptionAlgs.put(OIWObjectIdentifiers.dsaWithSHA1.getId(), "DSA"); encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption.getId(), "RSA"); encryptionAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "RSA"); encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa.getId(), "RSA"); encryptionAlgs.put(CMSTabeliaoSignedDataGenerator.ENCRYPTION_ECDSA, "ECDSA"); encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA2.getId(), "ECDSA"); encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA224.getId(), "ECDSA"); encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA256.getId(), "ECDSA"); encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA384.getId(), "ECDSA"); encryptionAlgs.put(X9ObjectIdentifiers.ecdsa_with_SHA512.getId(), "ECDSA"); encryptionAlgs.put(CMSTabeliaoSignedDataGenerator.ENCRYPTION_RSA_PSS, "RSAandMGF1"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94.getId(), "GOST3410"); encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001.getId(), "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.6.2", "ECGOST3410"); encryptionAlgs.put("1.3.6.1.4.1.5849.1.1.5", "GOST3410"); digestAlgs.put(PKCSObjectIdentifiers.md5.getId(), "MD5"); digestAlgs.put(OIWObjectIdentifiers.idSHA1.getId(), "SHA1"); digestAlgs.put(NISTObjectIdentifiers.id_sha224.getId(), "SHA224"); digestAlgs.put(NISTObjectIdentifiers.id_sha256.getId(), "SHA256"); digestAlgs.put(NISTObjectIdentifiers.id_sha384.getId(), "SHA384"); digestAlgs.put(NISTObjectIdentifiers.id_sha512.getId(), "SHA512"); digestAlgs.put(PKCSObjectIdentifiers.sha1WithRSAEncryption.getId(), "SHA1"); digestAlgs.put(PKCSObjectIdentifiers.sha224WithRSAEncryption.getId(), "SHA224"); digestAlgs.put(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), "SHA256"); digestAlgs.put(PKCSObjectIdentifiers.sha384WithRSAEncryption.getId(), "SHA384"); digestAlgs.put(PKCSObjectIdentifiers.sha512WithRSAEncryption.getId(), "SHA512"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128.getId(), "RIPEMD128"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160.getId(), "RIPEMD160"); digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256.getId(), "RIPEMD256"); digestAlgs.put(CryptoProObjectIdentifiers.gostR3411.getId(), "GOST3411"); digestAlgs.put("1.3.6.1.4.1.5849.1.2.1", "GOST3411"); } /** * * Return the digest algorithm using one of the standard JCA string * representations rather than the algorithm identifier (if possible). * * @param digestAlgOID * @return Retorna o algoritimo de resumo usando um dos formatos padroes de representacao JCA em vez do * identificador (se possivel). */ String getDigestAlgName( String digestAlgOID) { String algName = (String)digestAlgs.get(digestAlgOID); if (algName != null) { return algName; } return digestAlgOID; } /** * * Return the digest encryption algorithm using one of the standard * JCA string representations rather the the algorithm identifier (if * possible). * * @param encryptionAlgOID * @return Retorma o algoritimo de encriptacao de resumo usando um dos padroes de representacao JCA * em vez do identificador (se possivel). */ String getEncryptionAlgName( String encryptionAlgOID) { String algName = (String)encryptionAlgs.get(encryptionAlgOID); if (algName != null) { return algName; } return encryptionAlgOID; } /** * * @param algorithm * @param provider * @return instancia do resumo -> MessageDigest * @see java.security.MessageDigest * @throws NoSuchProviderException * @throws NoSuchAlgorithmException */ MessageDigest getDigestInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { try { return MessageDigest.getInstance(algorithm, provider); } catch (NoSuchAlgorithmException e) { return MessageDigest.getInstance(algorithm); // tentar retornar } } else { return MessageDigest.getInstance(algorithm); } } /** * * @param algorithm * @param provider * @return Instancia da Assinatura -> Signature * @see java.security.Signature * @throws NoSuchProviderException * @throws NoSuchAlgorithmException */ Signature getSignatureInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { return Signature.getInstance(algorithm, provider); } else { return Signature.getInstance(algorithm); } } /** * * @param type * @param provider * @param certSet -> conjunto/cadeia de cerficados * @return X509Store * @see org.bouncycastle.x509.X509Store * @throws NoSuchStoreException * @throws NoSuchProviderException * @throws CMSException */ X509Store createAttributeStore( String type, String provider, ASN1Set certSet) throws NoSuchStoreException, NoSuchProviderException, CMSException { List<Object> certs = new ArrayList<Object>(); if (certSet != null) { Enumeration<?> e = certSet.getObjects(); while (e.hasMoreElements()) { try { DERObject obj = ((DEREncodable)e.nextElement()).getDERObject(); if (obj instanceof ASN1TaggedObject) { ASN1TaggedObject tagged = (ASN1TaggedObject)obj; if (tagged.getTagNo() == 2) { certs.add(new X509V2AttributeCertificate(ASN1Sequence.getInstance(tagged, false).getEncoded())); } } } catch (IOException ex) { throw new CMSException( "Nao e possivel recodificar o atributo do certificado: ", ex); } } } try { return X509Store.getInstance( "AttributeCertificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("N�o � possivel setar/gerar o X509Store", e); } } /** * * @param type * @param provider * @param certSet -> conjunto/cadeia de certificados * @return X509Store * @see org.bouncycastle.x509.X509Store * @throws NoSuchStoreException * @throws NoSuchProviderException * @throws CMSException */ X509Store createCertificateStore( String type, String provider, ASN1Set certSet) throws NoSuchStoreException, NoSuchProviderException, CMSException { List<Object> certs = new ArrayList<Object>(); if (certSet != null) { addCertsFromSet(certs, certSet, provider); } try { return X509Store.getInstance( "Certificate/" +type, new X509CollectionStoreParameters(certs), provider); } catch (IllegalArgumentException e) { throw new CMSException("Nao e possivel setar/gerar o X509Store", e); } } /** * * @param type * @param provider * @param crlSet -> Conjunto de listas de certificados revogados * @return X509Store * @see org.bouncycastle.x509.X509Store * @throws NoSuchStoreException * @throws NoSuchProviderException * @throws CMSException */ X509Store createCRLsStore( String type, String provider, ASN1Set crlSet) throws NoSuchStoreException, NoSuchProviderException, CMSException { List<Object> crls = new ArrayList<Object>(); if (crlSet != null) { addCRLsFromSet(crls, crlSet, provider); } try { return X509Store.getInstance( "CRL/" +type, new X509CollectionStoreParameters(crls), provider); } catch (IllegalArgumentException e) { throw new CMSException("Nao e possivel setar/gerar o X509Store", e); } } /** * carrega os certificados e listas de revogacao se houver * @param type * @param provider * @param certSet -> Conjunto/cadeia de certificados * @param crlSet -> Conjunto de listas de certificados revogados * @return CertStore * @see java.security.cert.CertStore * @throws NoSuchProviderException * @throws CMSException * @throws NoSuchAlgorithmException */ CertStore createCertStore( String type, String provider, ASN1Set certSet, ASN1Set crlSet) throws NoSuchProviderException, CMSException, NoSuchAlgorithmException { List<Object> certsAndcrls = new ArrayList<Object>(); // // carrega os certificados e listas de revoga��o se houver // if (certSet != null) { addCertsFromSet(certsAndcrls, certSet, provider); } if (crlSet != null) { addCRLsFromSet(certsAndcrls, crlSet, provider); } try { return CertStore.getInstance(type, new CollectionCertStoreParameters(certsAndcrls), provider); } catch (InvalidAlgorithmParameterException e) { throw new CMSException("Nao e possivel gerar/setar o CertStore", e); } } /** * * @param certs -> lista de objetos * @param certSet -> conjunto/cadeia de certificados * @param provider * @throws NoSuchProviderException * @throws CMSException */ private void addCertsFromSet(List<Object> certs, ASN1Set certSet, String provider) throws NoSuchProviderException, CMSException { CertificateFactory cf; try { cf = CertificateFactory.getInstance("X.509", provider); } catch (CertificateException ex) { throw new CMSException("Nao e possivel pegar o certificate factory.", ex); } Enumeration<?> e = certSet.getObjects(); while (e.hasMoreElements()) { try { DERObject obj = ((DEREncodable)e.nextElement()).getDERObject(); if (obj instanceof ASN1Sequence) { certs.add(cf.generateCertificate( new ByteArrayInputStream(obj.getEncoded()))); } } catch (IOException ex) { throw new CMSException( "Nao e possivel recodificar o certificado!", ex); } catch (CertificateException ex) { throw new CMSException( "Nao e possivel recodificar o certificado!", ex); } } } /** * * @param crls -> lista de certificados revogados * @param certSet -> conjunto/cadeia de certificados * @param provider * @throws NoSuchProviderException * @throws CMSException */ private void addCRLsFromSet(List<Object> crls, ASN1Set certSet, String provider) throws NoSuchProviderException, CMSException { CertificateFactory cf; try { cf = CertificateFactory.getInstance("X.509", provider); } catch (CertificateException ex) { throw new CMSException("Nao e possivel pegar o certificate factory.", ex); } Enumeration<?> e = certSet.getObjects(); while (e.hasMoreElements()) { try { DERObject obj = ((DEREncodable)e.nextElement()).getDERObject(); crls.add(cf.generateCRL( new ByteArrayInputStream(obj.getEncoded()))); } catch (IOException ex) { throw new CMSException("Nao e possivel recodificar o certificado!", ex); } catch (CRLException ex) { throw new CMSException("Nao e possivel recodificar o certificado!", ex); } } } /* private boolean anyCertHasTypeOther() { // not supported return false; } private boolean anyCertHasV1Attribute() { // obsolete return false; } private boolean anyCertHasV2Attribute() { // TODO - N�o implmentado Bouncy return false; } private boolean anyCrlHasTypeOther() { // not supported return false; } */ }