Ir para conteúdo
  • Cadastre-se

dev botao

Falha Para Validar Ct-E Com Openssl


Ver Solução Respondido por andrejsilva,
  • Este tópico foi criado há 3633 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Boa noite

 

Estou tentando validar um CT-e, mas sempre gera um access violation na MSVCRT.DLL.

 

Estou tentando usando o ACBR_CTE DEMO com todas as configurações informadas.

post-14320-0-69952900-1404780938_thumb.j

  • Consultores
Postado

Bom dia André,

Se esta ocorrendo Violação de acesso na validação, verifique se o componente esta configurado corretamente quanto ao PathSchemas e verifique também se todos os schemas da versão 2.00 estão presentes na pasta.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Italo Boa tarde,

 

Verifiquei o caminho para o pathschemas esta correto, e este é o exemplo que vem com o acbr os schemas são os que vem com o acbr, mudei para a versão capicom e funcionou, mas gostaria que funcionasse com a versão openssl.

Postado

Italo

 

Boa noite

 

Então a violação de acesso esta ocorrendo na segunte função:

 

{$IFDEF ACBrCTeOpenSSL}

function ValidaLibXML(const AXML: AnsiString;
  var AMsg: AnsiString; const APathSchemas: string = ''): Boolean;

 

no seguinte local

 

schema_doc := xmlReadFile(Pansichar(AnsiToUtf8(schema_filename)), nil, XML_DETECT_IDS);

 

O trecho do código abaixo, que fica antes deste local onde esta ocorrendo o erro, estava comentado, ele verifica se o arquivo schema_filename existe, ai eu descomentei para testar se realmente o arquivo estava sendo encontrado, e esta sendo encontrando normalmente.

 

  if not FileExists(schema_filename) then
    raise Exception.Create('Arquivo de Schema não encontrado' + sLineBreak + schema_filename);

  • 3 semanas depois ...
Postado

Bom dia André,

 

A dll "MSVCRT.DLL" está na mesma pasta que o executável? Caso não, tenta colocá-la junto com o executável.

Passei por alguns problemas parecidos e resolvi colocando as dlls junto com o executável.

  • 3 semanas depois ...
Postado

Italo Boa noite

 

Constatei que no Lazarus ocorre o seguinte problema, o ct-e é assinado normalmente, quando vai validar

 

class function CTeUtil.Valida(const AXML: AnsiString;
  var AMsg: AnsiString; const APathSchemas: string = ''): Boolean;

 

o conteudo da const AXML aonde consta a assinatura, fica invalida.

 

Fiz um teste carregando manualmente o arquivo depois de assinado

 

class function CTeUtil.Valida(const AXML: AnsiString;
  var AMsg: AnsiString; const APathSchemas: string = ''): Boolean;
var
  arq: TStringList;
begin
{$IFDEF ACBrCTeOpenSSL}
//  Result := ValidaLibXML(AXML, AMsg, APathSchemas);


  arq := TStringList.Create;
  arq.LoadFromFile('C:\Erp\DFe\35140750386473000147570010000001321610801331-cte.xml');

  Result := ValidaLibXML(arq.Text, AMsg, APathSchemas);

 

E ai sim o arquivo é validado com sucesso.

assinado-cte.xml

validar.xml

Postado (editado)

Italo Boa noite

 

Acha não precisa de desculpa não, me desculpe eu pela insistência, eu tenho um ERP/TMS, que funciona em 4 filiais na transportadora que eu trabalho, ele é desenvolvido no lazarus usando SQLDB e banco MySQL todas as filiais gravam no mesmo BD em um datacenter o sistema é grande. E assim tudo funciona o CT-e eu utilizo assim, o XML é gerado usando o ACBR, ai para validar assinar e transmitir uso o unimake, funciona muito bem.

É que eu queria fazer tudo no Lazarus mesmo, seria legal se desse certo.

Mas voltando ao assunto, fiz vários teste do jeito que eu fiz passando para a validação usando uma StringList, ele transmitiu para a sefaz, mas não validou na sefaz. Acho que o problema também acontece quando vai ser enviando para a sefaz, a assinatura fica invalida.

 

Então mas você viu como fica os arquivos XML, é estranho mesmo, pois eles ficam diferentes, e o estranho é que só a parte da assinatura no XML fica diferente.

Editado por andrejsilva
  • Consultores
Postado

Bom dia Andre,

 

Você postou dois arquivos XML.

 

O arquivo chamado assinado-cte.xml foi gerado e assinado pelo ACBrCTe?

Pois ele esta OK segundo o validador da SEFAZ-RS, inclusive a assinatura.

 

Por outro lado o arquivo validar.xml contem erro na assinatura mais precisamente no elemento SignatureValue, diz que o tamanho é invalido (Invalid length for a Base-64 char array).

 

Este arquivo Validar.xml foi gerado e assinado pelo ACBrCTe?

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Italo

 

Bom dia

 

Sim os dois arquivos foram gerado pelo ACBR. Acontece que o primeiro arquivo assinado-cte.xml, depois que o acbr assinou eu coloquei modifiquei o código para testar e salvei o arquivo, ai verifiquei a assinatura, e tudo esta correto. Ai quando o mesmo arquivo que continua na memória vai passar pela validação 'validar.xml' o mesmo, fica com a assinatura inválida.

Eu estou achando que pode ser alguma limitação de alguma variável.

 

Assim, nessa função

 

class function CTeUtil.Valida(const AXML: AnsiString;
  var AMsg: AnsiString; const APathSchemas: string = ''): Boolean;

 

Se você observar e passar o conteúdo de AXML, ele esta como a assinatura inválida,

 

Eu testei assim

 

Assinei -> Assinou corretamente

 

Salvei o arquivo em disco para verificar, assinado-cte.xml - Assinatura correta.

 

Validar -> Aí esta o problema, o conteúdo passado para AXML fica com a assinatuda inválida. Mas se eu pegar o mesmo arquivo que foi assinado e carregar novamente

 

arq := TStringList.Create;
  arq.LoadFromFile("assinado-cte.xml")

  Result := ValidaLibXML(arq.Text, AMsg, APathSchemas);

 

Aí é validado corretamente.

  • Consultores
Postado

Andre,

 

Não sei exatamente os comandos que você esta utilizando, mas vamos descrever alguns:

 

Assinar;    -> Gera o XML, assina e salva o XML assinado em disco

 

Valida; -> Checa se o XML em memória contem a assinatura se sim submete ao validador, caso contrario executa o Assinar antes de validar.

                O comando não altera o conteúdo do XML em memória e nem salva nada em disco, exceto quando ele executa o comando Assinar. 

 

Enviar; -> Executa o Assinar e depois o Valida antes de realizar o envio.

 

Quais os comandos que você esta utilizando?

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Na sequencia

 

Assinar -> Nessa função, se passar direto para o validar, ele não valida da erro na assinatura. Então fiz este teste alterei e salvei o arquivo em disco, e observei que o arquivo salvo esta com a assinatura correta, mas o que fica na memória, fica com a assinatura errada.

 

Validar

Enviar

  • Consultores
Postado

Boa tarde Andre,

 

Estou desconfiado que o problema seja o trecho de código abaixo (Unit ACBrCTeConhecimentos - procedure Assinar):

 

        Leitor := TLeitor.Create;
        try
          leitor.Grupo := vAssinada;
          Self.Items.CTe.signature.URI := Leitor.rAtributo('Reference URI=');
          Self.Items.CTe.signature.DigestValue := Leitor.rCampo(tcStr, 'DigestValue');
          Self.Items.CTe.signature.SignatureValue := Leitor.rCampo(tcStr, 'SignatureValue');
          Self.Items.CTe.signature.X509Certificate := Leitor.rCampo(tcStr, 'X509Certificate');
        finally
          Leitor.Free;
        end;
 
Estou desconfiando das linhas em negrito pois é justamente os valores que ficam diferentes.
 
A minha sugestão é alterar o tipo de dado a ser lido, em vez de tcStr mudar para tcEsp.
Motivação para a troca: ao ler uma tag segundo o tipo tcStr antes de retornar o seu conteúdo, ele é submetido a uma função chamada: ReverterFiltroTextoXML, por outro lado ao ler segundo o tipo tcEsp, o conteúdo é retornado na integra sem submete-lo a nenhum tratamento.
 
Por favor altere as linhas em negrito para:
 
          Self.Items.CTe.signature.SignatureValue := Leitor.rCampo(tcEsp, 'SignatureValue');
          Self.Items.CTe.signature.X509Certificate := Leitor.rCampo(tcEsp, 'X509Certificate');
 
Realize novos testes e report o resultado.
Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado

Italo

 

Boa noite

 

Tentei mas continua com o mesmo erro, a assinatura ocorre normalmente, tanto que a função que assina, salva o arquivo em disco, o arquivo fica com 7kb, com a assinatura correta. Ai quando vou chamar a função validar o conteudo da variavel AXML na função, esta com 5KB e a assinatura fica invalida.

class function CTeUtil.Valida(const AXML: String; var AMsg: AnsiString;
  const APathSchemas: string): Boolean;

 

 

Este é o resultado do validador da sefaz rs do conteudo AXML

 

  The 'http://www.w3.org/2000/09/xmldsig#:SignatureValue' element is invalid - The value 'Hpo+LEpY3PlOcTqpo51l8/GmmOQlreOFGCWXKyLw1MYeSyRkLIwZSQScOooXtU0OGyKvPnqcHluwVav8mRLGQmM7AwpcKP+FNTeQDIgrvQP069MWTdcBfJBcicdW78Y+cQyigqOAdsLPYx1KpAQFtb+Y0TpKL3a0AVfmqRh08TpkXtSp173XYvvne9g3uHOpuWAEi+UQJdYMwz4VNIYoqXodV1157W6NQQdt77ssnU3EjmRODaqyCE44rUvkiGi' is invalid according to its datatype 'http://www.w3.org/2000/09/xmldsig#:SignatureValueType' - Invalid length for a Base-64 char array.
The 'http://www.w3.org/2000/09/xmldsig#:X509Certificate' element is invalid - The value 'MIIIADCCBeigAwIBAgIQPLHvXz9Lg6a3S73ygByUFTANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCQlIxEzARBgNVBAoTCklDUC1CcmFzaWwxSDBGBgNVBAsTP1NJTkNPUi1TUCAtIFNpbmRpY2F0byBkb3MgQ29ycmV0b3JlcyBkZSBTZWd1cm9zIG5vIEVzdGFkbyBkZSBTUDEVMBMGA1UEAxMMQUMgU0lOQ09SIEczMB4XDTEzMTAyMjA' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:base64Binary' - Invalid length for a Base-64 char array.

 

Não sei mas acho que pode ser algum problema com a propriedade XML da Classe Conhecimento. Ou em neste ponto em function TCTeW.GerarXml: boolean; na unit pcteCTeW neste ponto

 

  if FOpcoes.GerarTagAssinatura <> taNunca then
  begin
    Gerar := true;
    if FOpcoes.GerarTagAssinatura = taSomenteSeAssinada then
      Gerar := ((trim(CTe.signature.DigestValue) <> '') and
                (trim(CTe.signature.SignatureValue) <> '') and
                (trim(CTe.signature.X509Certificate) <> ''));
    if FOpcoes.GerarTagAssinatura = taSomenteParaNaoAssinada then
      Gerar := ((trim(CTe.signature.DigestValue) = '') and
                (trim(CTe.signature.SignatureValue) = '') and
                (trim(CTe.signature.X509Certificate) = ''));
    if Gerar then
    begin
      FCTe.signature.URI := somenteNumeros(CTe.infCTe.ID);
      FCTe.signature.Gerador.Opcoes.IdentarXML := Gerador.Opcoes.IdentarXML;
      FCTe.signature.GerarXMLCTe;
      Gerador.ArquivoFormatoXML := Gerador.ArquivoFormatoXML + FCTe.signature.Gerador.ArquivoFormatoXML;
    end;
  end;

  • Consultores
Postado

Bom dia Andre,

 

Vamos analisar os códigos do Assinar e Valida.

 

Na procedure Assinar temos o XML assinado armazenado na variável vAssinada, cujo conteúdo é atribuído a Self.Items.XML.

No final da procedure salvo em disco (se configurado) o conteúdo de vAssinada gerando assim o arquivo: <chave>-cte.xml

 

A procedure Valida por sua vez, primeiramente checa se o conteúdo de Self.Items.XML contem a TAG Signature, caso negativo a procedure Assinar é executada.

Depois é utilizado o conteúdo de Self.Items.XML para realizar a validação.

 

Notei que ao ler o conteudo de Self.Items.XML é executado o GetCTeXML que por sua vez executa o GerarXML ou seja gera novamente o XML.

 

Vamos a mais um teste, na definição da propriedade XML na unit ACBrCTeConhecimentos altere a linha em negrito:

 

    property CTe: TCTe                         read FCTe                   write FCTe;
    property XML: AnsiString                   read GetCTeXML              write FXML;
    property XMLOriginal: AnsiString           read FXMLOriginal           write FXMLOriginal;
 
para:
 
    property CTe: TCTe                         read FCTe                   write FCTe;
    property XML: AnsiString                   read FXML              write FXML;
    property XMLOriginal: AnsiString           read FXMLOriginal           write FXMLOriginal;
 

Isso vai fazer com que o XML não seja gerado toda vez que a propriedade é lida.

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado (editado)

Italo

Boa tarde

<?xml version="1.0"?>

-<retConsReciCTe xmlns="http://www.portalfiscal.inf.br/cte" versao="2.00">

<tpAmb>2</tpAmb>

<verAplic>SP-CTe-29-07-2014</verAplic>

<nRec>351000006571229</nRec>

<cStat>104</cStat>

<xMotivo>Lote processado</xMotivo>

<cUF>35</cUF>


-<protCTe versao="2.00">


-<infProt>

<tpAmb>2</tpAmb>

<verAplic>SP-CTe-29-07-2014</verAplic>

<chCTe>35140850386473000147570010000001561844769626</chCTe>

<dhRecbto>2014-08-29T15:05:43</dhRecbto>

<nProt>135140006729502</nProt>

<digVal>ZQwpUDOmnlR3B00wVPgTG9rtS3s=</digVal>

<cStat>100</cStat>

<xMotivo>Autorizado o uso do CT-e</xMotivo>

</infProt>

</protCTe>

</retConsReciCTe>

Autorizou, só que percebi que o arquivo autorizado, fica com a assinatura invalida. Vou anexar para você ver, percebi porque o arquivo com a assinatura correta, fica mais mais ou menos 7KB.

35140850386473000147570010000001561844769626-cte.xml

Editado por andrejsilva
  • Consultores
Postado

Boa tarde Andre,

 

Faça uma cópia do CT-e protocolado (este que você postou), e gere novamente e assine o mesmo CT-e.

 

Não precisa validar.

 

Depois compare o conteúdo das TAGs do grupo Signature, mais precisamente as TAGs: SignatureValue e X509Certificate.

Se não me falha a memória a assinatura fica inválida porque o X509Certificate fica com apenas 256 caracteres.

 

Uma pergunta: os arquivos de envio e retorno estão sendo salvos em disco?

Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

  • Este tópico foi criado há 3633 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.