Ir para conteúdo
  • Cadastre-se

dev botao

Melhoria no método de leitura de dados do certificado Pfx


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

Recommended Posts

Bom dia,

Iniciei alguns testes com Delphi + Linux + ACBNFSeX. Verifiquei que ao carregar os dados do certificado digital .pfx no Linux causa erro ERangeError, quando Range checking está habilitado nas configurações do projeto (estranhamente que em ambiente windows mesmo com RangeChecking habilitado nao causa erro)

Identifiquei onde o problema é causado e melhorei o método para evitar esse erro. Segue a unit modificada. 

Testado em Win32/Win64/Linux64 para carregamento de certificados A1.

ACBrDFeOpenSSL.pas

Método alterado: BioToStr

 

function BioToStr(ABio : pBIO) : AnsiString ;
Var
  Ret : Integer ;
  Lin : AnsiString ;
begin
  Result := '';
  Ret := BIO_ctrl(ABio, BIO_CTRL_PENDING, 0, nil);
  if Ret > 0 then
  begin
    SetLength(Lin, Ret);
    BioRead( ABio, Lin, Ret);
    Result := Lin;
  end;
end ;

 

Link para o comentário
Compartilhar em outros sites

  • Consultores

Boa tarde João,

Passei a sua contribuição para a Equipe ACBr avaliar.

Estando tudo OK, com certeza vai para o SVN.

Desde já muito obrigado pela contribuição.

  • Curtir 1
Consultor SAC ACBr

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

Projeto ACBr

Analista de Sistemas / e-mail: [email protected] / Fone: (16) 9-9701-5030 / Araraquara-SP

Araraquara - A era dos Trólebus

Link para o comentário
Compartilhar em outros sites

  • Fundadores

@João Antônio, em qual linha exatamente, ocorria o erro de RangeChecking ?

function BioToStr(ABio : pBIO) : AnsiString ;
Var
  Ret : Integer ;
  Lin : AnsiString ;
begin
  Result := '';
  repeat
    SetLength(Lin,1024);
    Ret := BioRead( ABio, Lin, 1024);
    if Ret > 0 then
    begin
      Lin := copy(Lin,1,Ret) ;
      Result := Result + Lin;
    end ;
  until (Ret <= 0);
end ;

Eu prefiro essa implementação, pois ela trabalha com um Buffer de 1K, e não teria problemas de memória, mesmo que o conteúdo de pBio, fosse muito grande..

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.

Link para o comentário
Compartilhar em outros sites

O erro ocorre em 

Ret := BioRead( ABio, Lin, 1024);

Esse método é chamado a primeira vez e lê os dados, sem erros. Nesse momentos os dados são lidos por completo, pois é menor que 1024. 

Prossegue-se o loop e ao chamar o metodo BioRead novamente ocorre o erro. Justamente por não há mais dados a serem lidos. 

Editado por João Antônio
Erro de escrita
Link para o comentário
Compartilhar em outros sites

  • Fundadores

Obrigado pela resposta...

É esperado que BioRead retorne 0 ou algum valor negativo.. mas por "Ret" ser Integer, isso não seria problema.. e o IF abaixo, trata valores não positivos...

Qual a sua IDE ? Como você compila no Linux ?

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.

Link para o comentário
Compartilhar em outros sites

Uso Delphi 10.4.2 Sydney compilando para Linux Ubuntu 20.04. 

Alterei a modificação que tinha feito BioToStr para continue lendo buffers de 1k e não gere a exceção de RangeCheck:

function BioToStr(ABio : pBIO) : AnsiString ;
Var
  RetTotal : Integer ;
  BufferLen: Integer;
  Lin : AnsiString ;
begin
  Result := '';
  RetTotal := BIO_ctrl(ABio, BIO_CTRL_PENDING, 0, nil);
  if RetTotal > 0 then
  begin
    BufferLen := 1024;
    while RetTotal > 0 do
    begin
      if RetTotal < BufferLen then
        BufferLen := RetTotal;

      SetLength(Lin, BufferLen);
      BioRead(ABio, Lin, BufferLen);
      Result := Result + Lin;
      Dec(RetTotal, BufferLen);
    end;
  end;
end ;

 

Segue anexo a unit alterada e um projeto teste que compila delphi win32,win64 e LInux64

ACBrDFeOpenSSL.pas OpenSSLACBr.zip

Editado por João Antônio
Erro de escrita
Link para o comentário
Compartilhar em outros sites

  • Fundadores

Mas nesse caso, não temos o mesmo problema ?

    BioRead(ABio, Lin, BufferLen);

Estou tentando compreender o que pode gerar o problema de RangeChecking

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.

Link para o comentário
Compartilhar em outros sites

23 minutos atrás, Daniel Simoes disse:

Mas nesse caso, não temos o mesmo problema ?

    BioRead(ABio, Lin, BufferLen);

Estou tentando compreender o que pode gerar o problema de RangeChecking

Não terá o problema porque só irá ler a quantidades de bytes restantes para leitura que foi obtido inicialmente pelo método BIO_ctrl.

Pelo que pude entender, o método original causa erro porque a posição de leitura já está no final de pBIO e quando tenta ler novamente causa o erro. 

Algo que não consegui entender é porque em ambiente Windows esse erro não acontece mesmo com o RangeCheck habilitado. Talvez seja um bug do Delphi na compilação Linux.

Link para o comentário
Compartilhar em outros sites

  • Fundadores
1 minuto atrás, João Antônio disse:

Pelo que pude entender, o método original causa erro porque a posição de leitura já está no final de pBIO e quando tenta ler novamente causa o erro. 

Não parece ser o caso.. ele pode ler de 0 a 1024 Bytes, pois BufferLen é 1024...  "RetTotal" não está sendo usado na chamada de "BioRead"...

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.

Link para o comentário
Compartilhar em outros sites

15 horas atrás, Daniel Simoes disse:

Não parece ser o caso.. ele pode ler de 0 a 1024 Bytes, pois BufferLen é 1024...  "RetTotal" não está sendo usado na chamada de "BioRead"...

Com certeza RetTotal é usado. Se o RetTotal é menor que 1024 BufferLen assume o valor de RetTotal. Quando RetTotal é maior que 1024 lê-se o buffer de 1024 e subtrai o valor de RetTotal para obter o valor restante a ser lido e retorna ao inicio do loop.

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Mas se 1024, causa o erro de RangeChecking (o que não deveria, pois estamos falando de um Integer)... então essa implementação ainda corre o risco de ocorrer problema...

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.

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois ...
  • Administradores

Tópico fechado por falta de retorno do usuário

Consultora SAC ACBr

Juliana Tamizou

Gerente de Projetos ACBr / Diretora de Marketing AFRAC
Ajude o Projeto ACBr crescer - Seja Pro

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

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil


Participe de nosso canal no Discord e fique ainda mais próximo da Comunidade !!

Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 507 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • 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.

The popup will be closed in 10 segundos...