Ir para conteúdo
  • Cadastre-se

dev botao

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

Recommended Posts

Postado

Olá Amigos,

Fiz os testes no Linux  64. Usei a distribuição CentOS7, o problema ocorre no mesmo ponto.

__emptyExp := xmlExpNodePtrPtr(GetProcAddress(libHandle, 'emptyExp'));

Aparentemente a biblioteca é carregada normalmente, mas quando efetuamos o GetProcAddress, uma exceção é elevada.

Projeto ACBrNFE_Demo elevou classe exceção 'External: SIGSEGV'.

 No endereço 7FFFF7DE4DF0

Eu não consigo continuar porque não entendo o problema.

Sei que o problema não é no ACBr, só estou postando para compartilhar a experiencia. Claro que se alguém tiver uma ideia será bem vinda 

Abraços

André Medeiros

Postado

Olá Daniel,

O cenário não é bem esse. O linux é mais "burocrático" do que windows. No windows por exemplo, mesmo ele sendo 64, você pode instalar e rodar programas 32bits sem problemas, pois a MS manteve a compatibilidade.

No Linux, apesar de falarem por ai que existe a mesma compatibilidade, o trabalho é tão grande que não compensa fazer isso.

Então eu tenho uma maquina Windows 10 com Lazarus 32 bits e Lazarus 64 bits. Onde instalei as bibliotecas da libxml para 32bits e 64 bits. Fiz toda sorte de testes nesta maquina usando 32 e 64. Tive sucesso nas duas arquiteturas, usando certificados A1 e A3, com capicom e com OpenSSL.

Para Linux sou obrigado a ter 2 maquinas uma maquina somente com arquitetura 32bis, com Lazarus 32 e as bibliotecas libxml 32bits, Funciona tudo perfeito também. Neste cenário só fico refém de certificados A1. Mas me atende perfeitamente.

Tenho outra maquina com Linux 64 bits, onde tudo nela é 64bits, Lazarus, FPC, e a libxml. Neste caso nem consigo instalar programas de 32bits pois não ha compatibilidade. É neste ambiente que não consigo assinar a NFe. 

Pesquisando aqui no forum, vi um post do Juliomar falando sobre um possível bug nas units da openssl do Lazarus para 64 bits. Mas até onde eu entendi, usamos funções da openssl para executar funções do Certificado como por exemplo: validar a senha, ler o CNPJ, ler a validade etc ... E todas estas funções no ambiente Linux64bits funcionam sem problemas. 

Os problemas começam quando iniciamos o processo de funções com o XML, leitura, assinaturas, parses ... 

A maquinas são físicas, não uso nenhum ambiente é virtualizado.

Postei a situação no forum do Lazarus também http://forum.lazarus.freepascal.org/index.php?topic=33472.0

Espero encontrar algum caminho para resolver isso.

Se precisar de mais informações, estou a disposição

Abraços,

 

 

André Medeiros

  • Fundadores
Postado

Não se trata da lib do OpenSSL, e sim da Lib XMLSec... a XMLSec usa a OpenSSL... Você precisa da XMLSec e OpenSSL na versão de compilador que estiver usando (e não do S.O.)

Sim, é possível instalar libs 32 em Linux 64 bits...

 

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado

Olá Daniel, 

Pode parecer estranho essa minha "fixação" em relação as arquiteturas. Vou falar da minha necessidade para que entenda o motivo de eu ter desistido da compatibilidade.

Temos um sistema que roda em servidores Apache+Linux, onde eu uso o Lazarus para desenvolver CGIs. E claro, o ACBr em modo console para emissão de notas NFe e NFSe. (É mesmo uma benção este ACBr ;-)).

Neste caso se eu criar um simples CGI apenas com a mensagem "Olá Mundo" em Linux 32 bits e colocar numa maquina Linux 64bits onde o Apache é de 64bits, recebo um erro 500, ou seja, o apache não é capaz de executar um cgi feito em 32bits enquanto ele (o Apache)  é de 64. E colocar um apache de 32 bits em Linux 64 é tão complexo que se torna inviável.

Eu preciso do Linux em arquitetura 64bits por causa de custos e performance. Pois o ambiente de produção, que é virtualizado, não suporta HDs do tipo SSD em arquiteturas  32bits, somente discos magnéticos, ou seja não posso atualizar minha infra estrutura para tecnologias mais recentes devido a isso.

Fico a disposição se precisar de alguma informação

Abraços,

André Medeiros

Postado

Olá Amigos,

Consegui passar pela linha citada acima

__emptyExp := xmlExpNodePtrPtr(GetProcAddress(libHandle, 'emptyExp'));

Na declaração da variável

libHandle: THandle;

Substitui por

libHandle: TLibHandle;

E com isso não ocorreu mais a exceção 

'External: SIGSEGV'.

Agora, pelo menos recebo uma exceção do ACBr informando que não foi possível assinar o XML.

Vou debugar e posto aqui o resultado dos testes.

Obrigado por enquanto,

Abraços

 

  • Curtir 1

André Medeiros

  • 3 semanas depois ...
Postado

Olá amigos, 

Segue mais algumas informações referente ao uso do ACBr em Linux 64 bits.

Fiz uma comparação debugando linha a linha com 2 maquinas lado a lado uma de 32 e outra de 64 bits

Segue as imagens anexas. 

Percebi que na maquina 32bits no debug tenho a seguinte informação 

SignNode = xmlnodeptr($08D57050) = record XMLNODE { _PRIVATE = $0 ....

Já na maquina de 64bits no debug tenho a seguinte informação

SignNode = <XMLNODE> { _PRIVATE = $0, ....

Após algumas pesquisas na internet parece que o libxml2 não encontra o XMLNODE especificado, apesar de não gerar a exceção, ele não traz o nó correto para assinatura.

Ainda continuo dando "tiros no escuro", se alguém tiver alguma ideia de como posso prosseguir daqui ... :-)

Lembrando que no sistema de 32bits tudo funciona perfeitamente.

Abraços

64bits.jpg

32bits.jpg

  • Curtir 1

André Medeiros

Postado

Olá Daniel, tudo bem ?

O problema tem sido a assinatura do XML mesmo.

Não quero me prolongar muito, mas quero tentar te passar as informações de forma clara :) 

Estou usando para testes Linux CentOs 7.0 64 bits. (Já uso CentOs 6.8 de 32 bits com Lazarus 1.4 + FPC 2.6, tudo funciona perfeitamente neste ambiente).

No Linux CentOS 7 64bits, fiz teste usando o conjunto Lazarus 1.6 + FPC 3.0 e também Lazarus 1.4+ FPC 2.6, nas duas versões os resultados foram os mesmos.

As bibliotecas foram baixadas e instaladas do próprio repositório do CentOS (RPM) usando (YUM). Foram instalados os pacotes binários e os de desenvolvimento (devel).

As versões instaladas são as seguinte:
LibXmlSec 1.2.20
LibXml2 2.9.1
LibXslt 1.1.28
OpenSSL 1.0.1
Zlib 1.2.7 (não sei se é importante mas percebi que no windows ela é necessária)
Iconv 1.7.18 (não sei se é importante mas percebi que no windows ela é necessária)  

Elas podem ser baixadas manualmente deste repositório
http://rpmfind.net/linux/rpm2html/search.php?query=libxml2
http://rpmfind.net/linux/rpm2html/search.php?query=libxmlsec
É só efetuar as buscas dos pacotes rpm e efetuar os downloads dos pacotes necessários (mesmo assim eu prefiro o yum, pois ele facilita na resolução das dependências !!!)

Para tentar descartar alguma falha na instalação das bibliotecas descomentei a linha abaixo

  // Assinando com XMLSec //
  //DEBUG
  WriteToTXT('/tmp/XmlToSign.xml', AXml, False, False);

E assinei o XML manualmente

xmlsec1 --sign --output assinado.xml --pkcs12 meucertificado.pfx --pwd senhacertificado XmlToSign.xml  

O resultado foi o xml assinado "quase" no mesmo formato do ACBr :). A diferença é que depois de assinado, o ACBr submete o xml ao método "AjustarXMLAssinado", mas fora isso o resultado é o mesmo.

Outro detalhe importante é que na declaração da variável libhandle precisei mudar para TLibHandle, conforme mencionei em alguns posts atrás

libHandle: TLibHandle;

Quem me ajudou com essa solução foi o próprio pessoal do fórum do Lazarus, onde expliquei minha dificuldade.

http://forum.lazarus.freepascal.org/index.php/topic,33472.msg217113.html#msg217113

Esta mudança não afetou o uso no ambiente Linux 32bis, mas não cheguei a fazer testes no Windows. 

A principio entendo que o problema nem esteja ligado ao ACBr, mas não sei mais a quem recorrer para pedir uma ajuda.

Sem dúvida houve uma evolução em relação a este assunto. E acredito que falta pouco para darmos um ponto final nisso. Estou muito interessado e disposto a ajudar. Porém estou um pouco perdido.

Se precisar de mais informações estou a disposição,

Abraços

 

André Medeiros

  • Fundadores
Postado

As modificações de TLibHandle realmente são necessárias... pois em Linux elas apontam para outra Unit.

  TLibHandle = PtrInt;  

Mesmo assim ele falha ao executar a assinatura, vazando o seguinte erro :

SignResult := xmlSecDSigCtxSign(FdsigCtx, SignNode);    

func=xmlSecDSigCtxProcessKeyInfoNode:file=xmldsig.c:line=871:obj=unknown:subj=unknown:error=45:key is not found:
func=xmlSecDSigCtxProcessSignatureNode:file=xmldsig.c:line=565:obj=unknown:subj=xmlSecDSigCtxProcessKeyInfoNode:error=1:xmlsec library function failed:
func=xmlSecDSigCtxSign:file=xmldsig.c:line=303:obj=unknown:subj=xmlSecDSigCtxSignatureProcessNode:error=1:xmlsec library function failed:
TApplication.HandleException Erro -1: Falha ao assinar o Documento

 

Lendo os fontes do xmlsec, notei que o único ponto onde o erro 45 ( XMLSEC_ERRORS_R_KEY_NOT_FOUND ) poderia ocorrer é em:

https://github.com/lsh123/xmlsec/blob/master/src/xmldsig.c#L947

Mas a chave foi carregada com sucesso em FdsigCtx^.signKey,.. e se chamarmos manualmente o método "xmlSecKeyMatch", ele retorna 1 (sucesso)

    Ret := xmlSecKeyMatch(FdsigCtx^.signKey, nil, @FdsigCtx^.keyInfoReadCtx.keyReq);

Não sei qual pode ser o problema... :(

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado

Olá Daniel, tudo bem ?

Pelo meno você conseguiu extrai o vazamento do erro. Eu parava na "Falha ao assinar o Documento" e ficava no "vácuo"

Vou continuar pesquisando sobre o assunto, mas parece que estamos bem perto de resolver a assinatura com Linux 64 :)

Abraços,

André Medeiros

Postado

Olá Daniel,

Eu avancei mais um pouco, mas não esta totalmente correto ainda.

Baseado na informação de que no Linux TLibHandle é diferente de THandle, me aventurei e substitui na libxmlsec.pas todos os tipos de onde estava LongInt para SizeInt e onde estava Cardinal para ValUInt.

O sistema agora, passa pela assinatura. mas o xml não fica assinado de forma correta. Se você puder dar uma olhada para ver se o caminho é este mesmo continuo minha pesquisa. Caso contrário vou tentar outros caminhos

Abraços,

André Medeiros

  • Fundadores
Postado

Para ver as mensagens de erro da libxmlsec, rode o programa diretamente pela linha de comando...

Baixei os fontes da XMLSEC e fiz algumas modificações, para debugar melhor o problema...

Notei que a Chave está chegando "nula", para a LibXMLSec.. (dsigCtx^.signKey = NULL)... porém nos fontes do ACBrDFeOpenSSL ela está corretamente atribuída...

Deve ser alguma diferença de "tipos", entre 32 e 64 bits, que faz com que a chave fique Nula, quando é informada para a chamada do método da DLL

 

 

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • Fundadores
Postado
1 hora atrás, almp1 disse:

Olá Daniel,

Eu avancei mais um pouco, mas não esta totalmente correto ainda.

Baseado na informação de que no Linux TLibHandle é diferente de THandle, me aventurei e substitui na libxmlsec.pas todos os tipos de onde estava LongInt para SizeInt e onde estava Cardinal para ValUInt.

O sistema agora, passa pela assinatura. mas o xml não fica assinado de forma correta. Se você puder dar uma olhada para ver se o caminho é este mesmo continuo minha pesquisa. Caso contrário vou tentar outros caminhos

Abraços,

Parece fazer sentido, essa modificação... tentei aplicar a mesma, mas continuo sem conseguir a execução na assinatura...

Poderia por favor anexar um Zip com as suas Units da ACBrDFeOpenSSL ?

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • Fundadores
Postado

Obrigado pelos fontes... notei pequenas diferenças com o meu, e já sincronizei... mas mesmo assim... não consegui executar a assinatura...a chave privada carregada em " dsigCtx^.signKey ", pelo método "CreateCtx", continua chegando NULL

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado

Olá Daniel

Eu fiz os ajustes nos que você me enviou... esqueci de te enviar o ACBrDFeOpenSSL.pas da primeira vez.

Para testar aqui, atualizei os fontes para ultima versão do svn e subscrevi com este fonte que estou te enviando anexo e consegui passar pela assinatura. Mesmo assim se continuar com problemas conte comigo para ajuda

Abraços

Fontes.zip

  • Curtir 1

André Medeiros

  • 1 mês depois ...
Postado

Boa tarde.

Em testes realizados com os fontes do André Medeiros no Delphi 10.1 Berlin em ambiente x64, consegui passar pela assinatura modificando os tipos Cardinal para UInt64 e LongInt para Int64.

  {$IFNDEF FPC}
	{$IFDEF CPU64}
	  ValUInt = UInt64;
	  SizeInt = Int64;
	{$ELSE}
	  ValUInt = Cardinal;
	  SizeInt = LongInt;
	{$ENDIF}
	PSizeInt = ^SizeInt;
	TLibHandle = THandle;
  {$ENDIF}

Porém o XML não é assinado corretamente, ficando com as tags DigestValue, SignatureValue e X509Certificate em branco.

Pesquisando sobre o assunto encontrei alguns links interessantes, que podem fazer mais sentido para vocês que conhecem bem o Linux.
https://www.aleksey.com/pipermail/xmlsec/2007/008005.html
https://www.mail-archive.com/[email protected]/msg04837.html
http://www.forum.hr/showthread.php?p=43283545

Basicamente xmlSecSize deve ser um "unsigned int" definido com 4 bytes, porém não obtive sucesso nos meus testes.

Se precisar de algo estou a disposição.
Att.

  • Curtir 1
Postado

Olá Allan,

Infelizmente não estou conseguindo parar para mexer com isso, mas acredito que se o tipo da xmlSecSize deve ser um int de 4 bytes, deveríamos declara-la na libxmlsec.pas como SizeInt e não como Cardinal.

      xmlSecSize = SizeInt;

Assim, tanto em plataformas de 32 como de 64 bits o sistema fica adequado.

http://www.freepascal.org/docs-html/ref/refsu5.html

Não fiz nenhuma alteração e nenhum teste, é apenas um sugestão :) 

Abraços,

 

 

  • Curtir 1

André Medeiros

  • Este tópico foi criado há 2810 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.