demoiselle / signer

Repositório que contém os componentes para facilitar a implementação de assinatura digital nos padrões da ICP-BRASIL
https://www.frameworkdemoiselle.gov.br/v3/signer/
GNU Lesser General Public License v3.0
142 stars 73 forks source link

java.lang.NullPointerException org.demoiselle.signer.policy.impl.cades.pkcs7.impl.CAdESSigner.prepareAlgAndLength() linha 981 #369

Open williamargenton opened 1 year ago

williamargenton commented 1 year ago

Bom dia! Estou tentando fazer uma assinatura com um certificado A1 utilizando o padrão cades, porém, na hora que chamo o método signer.doDetachedSign("documento que vai ser assinado") está retornando um NullPointer. Já verifiquei tanto a KeyStore com o certificado se ambos estavam null, mas não estão, minha pergunta é o seguinte: além dessas informações que informo, precisa mais alguma?

PKCS7Signer signer = PKCS7Factory.getInstance().factoryDefault(); signer.setAlgorithm(SignerAlgorithmEnum.SHA512withRSA); signer.setCertificates(certificateChain); signer.setPrivateKey(privateKey);
signer.setSignaturePolicy(Policies.AD_RB_CADES_2_3);

Desde já agradeço!

esaito commented 1 year ago

Boa tarde,

Está seguindo esse exemplo:?

https://github.com/demoiselle/signer/blob/master/policy-impl-cades/src/test/java/org/demoiselle/signer/policy/impl/cades/pkcs7/impl/CAdESSignerTest.java

williamargenton commented 1 year ago

Bom dia! Analisei o exemplo que você informou, meu algorítimo está na mesma linha, setei as informações necessárias para realizar a assinatura. Para fins de entendimento, segue a instrução problemática:

for (AlgAndLength algLength : signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy()
                .getCommonRules().getAlgorithmConstraintSet().getSignerAlgorithmConstraints().getAlgAndLengths()) {
            listOfAlgAndLength.add(algLength);
        }
signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules()

Até esse get, tudo ok, porém, quando é chamado o próximo get, o objeto está null

signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getAlgorithmConstraintSet() 

Por algum motivo, no momento de converter o arquivo que recebo da rede ( "http://politicas.icpbrasil.gov.br/PA_AD_RB_v2_3.der") para um objeto java, não está caindo em nenhuma condição do case no método parse da classe CommonRules.

danilo-flexdoc commented 1 year ago

Também estou recebendo este erro no momento da assinatura, nos meus teste observei que o problema é a versão do Bouncy Castle, eu estava justamente tentando atualizar para uma versão mais nova (1.70) que não possui vulnerabilidade, mas pelo que vi a assinatura só funciona se utilizar a versão 1.62 que possui 1 vulnerabilidade, @esaito existe plano para uma atualização da dependência?

esaito commented 1 year ago

Também estou recebendo este erro no momento da assinatura, nos meus teste observei que o problema é a versão do Bouncy Castle, eu estava justamente tentando atualizar para uma versão mais nova (1.70) que não possui vulnerabilidade, mas pelo que vi a assinatura só funciona se utilizar a versão 1.62 que possui 1 vulnerabilidade, @esaito existe plano para uma atualização da dependência?

Existe sim, por enquanto o que falta é tempo para desenvolvimento. Houve um colega da comunidade que chegou a fazer o upgrade e submeteu o código mas acabou quebrando uma outra parte que monta os atributos da ICP-Brasil, o código ficou neste branch: https://github.com/demoiselle/signer/tree/revert-346-master

esaito commented 1 year ago

Bom dia! Analisei o exemplo que você informou, meu algorítimo está na mesma linha, setei as informações necessárias para realizar a assinatura. Para fins de entendimento, segue a instrução problemática:

for (AlgAndLength algLength : signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy()
              .getCommonRules().getAlgorithmConstraintSet().getSignerAlgorithmConstraints().getAlgAndLengths()) {
          listOfAlgAndLength.add(algLength);
      }
signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules()

Até esse get, tudo ok, porém, quando é chamado o próximo get, o objeto está null

signaturePolicy.getSignPolicyInfo().getSignatureValidationPolicy().getCommonRules().getAlgorithmConstraintSet() 

Por algum motivo, no momento de converter o arquivo que recebo da rede ( "http://politicas.icpbrasil.gov.br/PA_AD_RB_v2_3.der") para um objeto java, não está caindo em nenhuma condição do case no método parse da classe CommonRules.

Chegou a executar o teste do código de exemplo? Tem como compartilhar o seu código completo?

williamargenton commented 1 year ago

Sim tentei executar o teste do código de exemplo. Está ainda não é a versão final, mas segue os métodos.

    public synchronized byte[] assinarDigitalmenteOnline(String senha, String uuid, Documento documento)
            throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException,
            UnrecoverableKeyException {

                CAManagerConfiguration config = CAManagerConfiguration.getInstance();
        config.setCached(false);
        ConfigurationRepo configRepo = ConfigurationRepo.getInstance();

        configRepo.setOnline(false);
        configRepo.setCrlPath("/tmp/crl_cache/");

        configRepo.setOnlineLPA(false);
        configRepo.setLpaPath("/tmp/lpa/");

        TimeStampConfig tsConfig = TimeStampConfig.getInstance();
        tsConfig.setTimeOut(100);
        tsConfig.setConnectReplay(5);

        CertificadoICPBrasil certficado = this.carregarCertificado(senha, uuid);
        byte[] doc = this.downloadDocumento(documento);

        KeyStore ks = this.criarKeyStore(uuid, senha);

        PKCS7Signer signer = PKCS7Factory.getInstance().factoryDefault();
        signer.setCertificates(ks.getCertificateChain(certficado.getAlias()));
        signer.setPrivateKey((PrivateKey) ks.getKey(certficado.getAlias(), senha.toCharArray()));

        signer.setAlgorithm(SignerAlgorithmEnum.SHA512withRSA);
        if (System.getProperty("os.name").contains("indows")) {
            signer.setAlgorithm(SignerAlgorithmEnum.SHA256withRSA);
        }       
        return signer.doDetachedSign(doc);
    }

private synchronized KeyStore criarKeyStore(String uuid, String senha) {
        return KeyStoreLoaderFactory.factoryKeyStoreLoader(new ByteArrayInputStream(this.downloadCertificado(uuid)))
                .getKeyStore(senha);
}

private CertificadoICPBrasil carregarCertificado(String senha, String uuid)
            throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
    return CertificadoUtil.carregarCertificado(this.downloadCertificado(uuid), senha);
}

public class CertificadoUtil {

    public synchronized static CertificadoICPBrasil carregarCertificado(byte[] certificado, String senha)
            throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {

        X509Certificate x509 = null;
        InputStream cert = new ByteArrayInputStream(certificado);
        KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(cert, senha.toCharArray());
        CertificadoICPBrasil certificadoICPBrasil = null;

        Enumeration<String> enumeration = ks.aliases();
        while (enumeration.hasMoreElements()) {
            String alias = enumeration.nextElement();
            x509 = (X509Certificate) ks.getCertificate(alias);
            CertificateManager cm = new CertificateManager(x509);
            certificadoICPBrasil = cm.load(CertificadoICPBrasil.class);
            certificadoICPBrasil.setAlias(alias);
        }
        return certificadoICPBrasil;
    }
}

OBS: Utilizo o SpringBoot, e já verifiquei tanto o certificado, KeyStore, PrivateKey, CertificateChain, e o próprio documento, e nenhum desses objetos estão nulos.