Ir para conteúdo
  • Cadastre-se

dev botao

Recommended Posts

Postado
Em 15/03/2024 at 17:40, EMBarbosa disse:

Me parece que você também fez modificações no arquivo OpenSSLExt.pas e não o colocou aqui.

Ou talvez você esteja utilizando outra versão... poderia disponibilizar?

Eu não encontrei o SslMethodTLSV1_3 citado na linha 480 da unit ACBrDFeOpenSSL.pas.

 

Desculpe, só vi sua mensagem agora. Devo ter recebido o e-mail de notificação do fórum, mas também não vi.

Segue em anexo o arquivo atualizado. Modificações somente no arquivo ACBrDFeOpenSSL.pas.

ACBrDFeOpenSSL.pas

  • Consultores
Postado
Em 14/05/2024 at 11:40, galegoga disse:

Desculpe, só vi sua mensagem agora. Devo ter recebido o e-mail de notificação do fórum, mas também não vi.

Pode testar por favor com a unit disponibilizada pelo Daniel acima? Se não funcionar, poderia fazer os ajustes necessários?

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

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

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • Moderadores
Postado
41 minutos atrás, Alexandre Tymoszenko disse:

Srs., se eu baixar os componentes, já terei estas melhorias?

Não!

Para testar precisa baixar a unit a substituir a existente no repositório do seu ACBr.

Postado
Em 16/05/2024 at 17:33, EMBarbosa disse:

Pode testar por favor com a unit disponibilizada pelo Daniel acima? Se não funcionar, poderia fazer os ajustes necessários?

Sim, vou efetuar os testes. Reporto assim que tiver os resultados.

  • Curtir 1
Postado
Em 21/05/2024 at 12:23, Daniel Simoes disse:

Enviei para o SVN... Commit [r33704]

Boa tarde!

No meus testes essa modificação não funcionou. Continua vazando memória.  A linha 576, código: SslCtxCtrl(Fctx, SSL_CTRL_CHAIN, 0, ca); não está sendo executada de acordo com a condicional estabelecida.

Por que ela não pode ser executada somente através da condicional "if Result and (ca <> nil) then" ? porque ela tem que depender da condicional "if LibVersionIsGreaterThan1_0_0 then begin" ser falsa ?

Assim não funcionou:

  //  Set Certificate Verification chain
  if Result and (ca <> nil) then
  begin
    if LibVersionIsGreaterThan1_0_0 then
    begin
      iTotal := OPENSSL_sk_num(ca);
      if iTotal > 0 then
      begin
        Store := SSL_CTX_get_cert_store(Fctx);
        for I := 0 to iTotal - 1 do
        begin
          certx := OPENSSL_sk_value(ca, I);
          if certx <> nil then
          begin
            if X509_STORE_add_cert(Store, pX509(certx)) = 0  then
            begin
              // already exists
            end;
           //X509_free(Cert);
          end;
        end;
      end;
    end
    else
      SslCtxCtrl(Fctx, SSL_CTRL_CHAIN, 0, ca);
  end;

Assim funcionou:

  //  Set Certificate Verification chain
  if Result and (ca <> nil) then
  begin
    if LibVersionIsGreaterThan1_0_0 then
    begin
      iTotal := OPENSSL_sk_num(ca);
      if iTotal > 0 then
      begin
        Store := SSL_CTX_get_cert_store(Fctx);
        for I := 0 to iTotal - 1 do
        begin
          certx := OPENSSL_sk_value(ca, I);
          if certx <> nil then
          begin
            if X509_STORE_add_cert(Store, pX509(certx)) = 0  then
            begin
              // already exists
            end;
           //X509_free(Cert);
          end;
        end;
      end;
    end;    
    SslCtxCtrl(Fctx, SSL_CTRL_CHAIN, 0, ca);
  end;

 

  • Curtir 1
  • Fundadores
Postado

@galegoga,

Por favor teste novamente, com a Unit em anexo...

ACBrDFeOpenSSL.pas

Após reler com atenção, notei que faltava uma chamada de limpeza ao ponteiro "ca"

Como posso detectar o vazamento de memória ?  No Delphi com "ReportMemoryLeaksOnShutdown := True;" não estou pegando nada...  No Lazarus/FPC, também não detecto qualquer vazamento....

 

Abaixo uma explicação "histórica" sobre essas Units... e porque a resistência de adotar a chamada a "SslCtxCtrl"

O uso de "SslCtxCtrl" só é indicado nas versões mais antigas do OpenSSL, pois não existiam métodos de "alto-nível", para fazer tarefas específicas... Podemos ver essa recomendação no manual do OpenSSL
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_ctrl.html

 

Citar

DESCRIPTION

The SSL_*_ctrl() family of functions is used to manipulate settings of the SSL_CTX and SSL objects. Depending on the command cmd the arguments larg, parg, or fp are evaluated. These functions should never be called directly. All functionalities needed are made available via other functions or macros.


A Chamada de SslCtxCtrl, foi um Workaround que implementei, quando tivemos problemas com alguns certificados Veja esse post:

mas notei que essa chamada nunca foi incorporada nos fontes originais da synapse

 

Aqui estão os fontes da Synapse originais (procure pelo método "LoadPFX")

para OpenSSL inferior a 1.0: https://github.com/geby/synapse/blob/master/ssl_openssl.pas

para OpenSSL 1.1: https://github.com/geby/synapse/blob/master/ssl_openssl11.pas

OpenSSL 3.x: https://github.com/geby/synapse/blob/master/ssl_openssl3.pas

 

No ACBr, eu tentei criar uma Unit que consegue se adaptar do OpenSSL 0.9 ao 3.x, baseado nos fontes das 3 Units indicadas acima... o resultado dela, está nessa Unit de nosso SVN:
http://svn.code.sf.net/p/acbr/code/trunk2/Fontes/Terceiros/synalist/ssl_openssl.pas

 

 

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
Em 26/05/2024 at 14:06, Daniel Simoes disse:

@galegoga,

Por favor teste novamente, com a Unit em anexo...

ACBrDFeOpenSSL.pas 21.23 kB · 3 downloads

Após reler com atenção, notei que faltava uma chamada de limpeza ao ponteiro "ca"

Como posso detectar o vazamento de memória ?  No Delphi com "ReportMemoryLeaksOnShutdown := True;" não estou pegando nada...  No Lazarus/FPC, também não detecto qualquer vazamento....

 

Abaixo uma explicação "histórica" sobre essas Units... e porque a resistência de adotar a chamada a "SslCtxCtrl"

O uso de "SslCtxCtrl" só é indicado nas versões mais antigas do OpenSSL, pois não existiam métodos de "alto-nível", para fazer tarefas específicas... Podemos ver essa recomendação no manual do OpenSSL
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_ctrl.html

 


A Chamada de SslCtxCtrl, foi um Workaround que implementei, quando tivemos problemas com alguns certificados Veja esse post:

mas notei que essa chamada nunca foi incorporada nos fontes originais da synapse

 

Aqui estão os fontes da Synapse originais (procure pelo método "LoadPFX")

para OpenSSL inferior a 1.0: https://github.com/geby/synapse/blob/master/ssl_openssl.pas

para OpenSSL 1.1: https://github.com/geby/synapse/blob/master/ssl_openssl11.pas

OpenSSL 3.x: https://github.com/geby/synapse/blob/master/ssl_openssl3.pas

 

No ACBr, eu tentei criar uma Unit que consegue se adaptar do OpenSSL 0.9 ao 3.x, baseado nos fontes das 3 Units indicadas acima... o resultado dela, está nessa Unit de nosso SVN:
http://svn.code.sf.net/p/acbr/code/trunk2/Fontes/Terceiros/synalist/ssl_openssl.pas

 

 

Boa tarde, Daniel!

Fiz o teste e continua apresentando o problema.

Primeiramente quero dizer que meu conhecimento referente as bibliotecas OpenSSL é zero. Também pouco sei sobre certificado digital. Nesses aspectos sou usuário final, dessa forma eu não tenho a capacidade de discutir os detalhes internos da biblioteca. Mas vou te passar os passos que levaram até esse ponto.

Desenvolvi uma aplicação para consultar a Distribuição, é um serviço que roda 24 horas, com mais de 1000 empresas, mas acho que certificados são uns 500, visto que tem muitas filiais.

No decorrer do tempo a aplicação ia crescendo até ficar sem memória. Fiz um rastreio, fui isolando as partes até que descobri que o despejo era quando acessava a certificado. Um detalhe importante é que o problema ocorre somente com alguns certificados.

Depois que descobri em qual unit (ACBrDFeOpenSSL.pas) estava o problema eu comecei estudar o que estava sendo criado e que ficava para trás. Nesse processo descobrir a unit ssl_openssl.pas na qual me ajudou, fui comparando o código vendo as diferenças até que cheguei a um certo ponto, onde existia um código na ssl_openssl.pas que não existia na unit do acbr. O código era:

 

Postado

 Continuação do post acima

        //  Set Certificate Verification chain
        if Result and (ca <> nil) then
          SslCtxCtrl(Fctx, SSL_CTRL_CHAIN, 0, ca);   // <---- AQUI

Adicionei esse código e fiz os testes e vi que parou de vazar memória.

meu código de teste foi (loop de 1000):

procedure TForm2.MetodoTeste(ALoop: Integer);
var
 vDFeSSL:   TDFeSSL;
 vCT:       Integer;
 vSenha:    String;
 vFileName: String;
begin
  vFileName := edtPfxFileName.Text;
  vSenha    := edtSenhaPFX.Text;
  for vCT := 1 to ALoop do begin
    vDFeSSL := TDFeSSL.Create;
    try
      vDFeSSL.SSLCryptLib := cryOpenSSL;
      vDFeSSL.SSLType  := LT_TLSv1_2;
      vDFeSSL.DadosPFX := LoadCertificado(vFileName);
      vDFeSSL.Senha    := AnsiString(vSenha);
      vDFeSSL.CarregarCertificado;
    finally
      vDFeSSL.Free;
    end;
  end;
end;

Realmente os sistema com ReportMemoryLeaksOnShutdown := True; não acusa nada. Mas o memory ocorre.

Aproveitando essa discussão. Acho que você não acompanhou a discussão desde o início. Digo isso porque quando tive o problema cheguei a achar algo parecido com o meu problema. chequei a mencionar no fórum antes de propor essa modificação no código.

Um certo usuário mencionava despejo de memória relacionado a variável "Ca". A solução veio do Dr. Stephen Henson, que informava que ele devia chamar sk_X509_pop_free(Ca, X509_free) ao final. Achei que fosse isso. No acbr também possui ela com o nome SkX509PopFree, mas ela nunca é executada por que me parece que ela não existe na dll. _SkX509PopFree dentro de ssl_openssl_lib.pas sempre está nula. A solução é antiga, acho que no inicio dos anos 2000.  O link é : https://openssl-users.openssl.narkive.com/F1OAAID0/pkcs12-memory-leak#post2

Vou adicionar o código fonte de teste. Se precisar do certificado digital é só me falar.

PrjReadPfx02.zip

  • 3 semanas depois ...
Postado
Em 26/05/2024 at 14:06, Daniel Simoes disse:

@galegoga,

Por favor teste novamente, com a Unit em anexo...

ACBrDFeOpenSSL.pas 21.23 kB · 4 downloads

Após reler com atenção, notei que faltava uma chamada de limpeza ao ponteiro "ca"

Como posso detectar o vazamento de memória ?  No Delphi com "ReportMemoryLeaksOnShutdown := True;" não estou pegando nada...  No Lazarus/FPC, também não detecto qualquer vazamento....

 

Abaixo uma explicação "histórica" sobre essas Units... e porque a resistência de adotar a chamada a "SslCtxCtrl"

O uso de "SslCtxCtrl" só é indicado nas versões mais antigas do OpenSSL, pois não existiam métodos de "alto-nível", para fazer tarefas específicas... Podemos ver essa recomendação no manual do OpenSSL
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_ctrl.html

 


A Chamada de SslCtxCtrl, foi um Workaround que implementei, quando tivemos problemas com alguns certificados Veja esse post:

mas notei que essa chamada nunca foi incorporada nos fontes originais da synapse

 

Aqui estão os fontes da Synapse originais (procure pelo método "LoadPFX")

para OpenSSL inferior a 1.0: https://github.com/geby/synapse/blob/master/ssl_openssl.pas

para OpenSSL 1.1: https://github.com/geby/synapse/blob/master/ssl_openssl11.pas

OpenSSL 3.x: https://github.com/geby/synapse/blob/master/ssl_openssl3.pas

 

No ACBr, eu tentei criar uma Unit que consegue se adaptar do OpenSSL 0.9 ao 3.x, baseado nos fontes das 3 Units indicadas acima... o resultado dela, está nessa Unit de nosso SVN:
http://svn.code.sf.net/p/acbr/code/trunk2/Fontes/Terceiros/synalist/ssl_openssl.pas

 

 

Boa tarde, Daniel.

Você chegou a ver o post acima ? No dia em que postei tive um problema e acabei quebrando ele em dois. Tentei editar para ficar em um só, mas o tempo de edição havia expirado.

Postado
1 hora atrás, Daniel Simoes disse:

Oi @galegoga.. ainda não consegui parar para analisar o código...

Mas agradeço todo apoio, nessa questão... creio que ainda essa semana, concluímos isso...

Tudo bem. Irei aguardar.

Postado
4 horas atrás, Arimateia Jr disse:

Bom dia, @galegoga.

Em anexo, segue a minha implementação da solução sugerida pelo Dr. Stephen Henson (utilização do método OPENSSL_sk_pop_free).

@Daniel Simoes Favor verificar se isso quebra a compatibilidade com alguma versão do OpenSSL.

 

 

ACBrDFeOpenSSL.pas 19.31 kB · 1 download OpenSSLExt.pas 225.27 kB · 1 download

Boa tarde, Arimateia!

Fiz o teste e funcionou muito bem.

Você conseguiu através do link em que postei ? Pergunto porque esse método "OPENSSL_sk_pop_free" não está informado, lá falava sobre "sk_X509_pop_free". Ele são similares ou equivalentes ? (Levando em conta que o artigo no fórum já tem 22 anos e muita coisa pode ter mudado).

 

  • Moderadores
Postado

@galegoga

Na verdade, eu não consegui carregar o método com o "sk_X509_pop_free" diretamente na minha primeira tentativa. Então dei uma pesquisada rápida no google e cheguei nesse outro método. Ao que parece, o "sk_X509_pop_free" é apenas uma macro.

Mas, assim como você, não sou um profundo conhecedor de OpenSSL, por isso marquei o @Daniel Simoes pra dar uma averiguada no código e garantir que irá funcionar em todas as versões atualmente suportadas pelo ACBr.

Seguem alguns links:

image.png

  • Curtir 2
  • Fundadores
  • Solution
Postado

Olá pessoal,

Desculpem pela demora na resposta...

Baseado nas sugestões do @Arimateia Jr, que detectou que a Macro do OpenSSL não é carregada, e achou o métodos correto... enviei ao SVN, o Commit [r34047]

Realmente a rotina de `TDFeOpenSSL.LerPFXInfo` não precisava criar todo o contexto, pois ela só pretende ler o certificado... Ficou bem mais simples..

  • Curtir 4
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.

  • 3 meses depois ...
  • Moderadores
Postado
On 1/3/2024 at 4:24 PM, galegoga said:

Utilizo carregamento de PFX com a configuração cryWinCrypt, além do lixo na memória ele também cria diversos arquivos na pasta "..\AppData\Roaming\Microsoft\Crypto\RSA".  OBS: Se alguém souber uma forma de evitar a criação dos arquivos na pasta RSA ou a exclusão automática ao termino da execução seria de grande ajuda. Minha rotina é com milhares de empresas e com diversas ações, em um dia está estourando o disco.

Olá, @galegoga.

Segue anexo uma modificação para exclusão automática das chaves, conforme recomendado na documentação da função PFXImportCertStore:

Quote

Note: If the PKCS12_NO_PERSIST_KEY flag is *not* set, keys are persisted on disk. If you do not want to persist the keys beyond their usage, you must delete them by calling the CryptAcquireContext function with the CRYPT_DELETEKEYSET flag set in the dwFlags parameter.

@Daniel Simoes Favor revisar a modificação para possível inclusão no código oficial do ACBr no SVN.

Referências:

ACBrDFeWinCrypt.pas

  • Curtir 3
  • 2 semanas depois ...
  • Fundadores
Postado

Olá @Arimateia Jr,

Desculpe a demora na interação desse tópico..

Apliquei nos meus fontes as modificações sugeridas, e parecem corretas...

Mas notei que nos meus testes, os arquivos temporários criados em  ..\AppData\Roaming\Microsoft\Crypto\RSA não foram apagados após a chamada de CryptAcquireContext com CRYPT_DELETEKEYSET

 

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.

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.