2013-12-21 56 views
0

在調用實現了墨西哥電子賬單的DLL的應用程序中,錯誤OPENSSL_UPLINK OPENSSL_APPLINK終止進程(崩潰)。Openssl_Uplink no Openssl_Applink

當您調試DLL時,我看到錯誤是當我加載CER文件。和.KEY

以下是我的主碼。

function TFacturacion.Validar_Certificado : boolean; 
var 
    Certificado : TCertificado; 
begin 
    Certificado := TCertificado.Create; 
try 
begin 
    Certificado.LoadFromFile(DmDatos.IBDs_SistemaCERTFNAME.AsString); 
    case TipoCertificado(Certificado.Base64) of 
tcDESCONOCIDO : begin 
    FRespuestaCFD := 'Certificado Desconocido o de Pruebas'; 
    Result := False; 
    end; 
    tcFIEL : begin 
    FRespuestaCFD := 'Certificado FIEL'; 
    Result := False; 
    end; 
    tcCSD : begin 
    Result := True; 
    end; 
end;   // Fin Case 
end;   // Fin Begin protegido(TRY) 
Except 
Result := False; 
FRespuestaCFD := 'Error en Certificado....No se pudo localizar el Archivo .CER'; 
end; 

if Result = False then 
begin 
    Certificado.Free; 
    Certificado := NIl; 
    Exit; 
end; 

CertificadoB64 := Certificado.Base64; 
Certificado.Free; 
Certificado := Nil; 

end; 

function TFacturacion.Validar_Llave : Boolean; 
var Llave : TLlavePrivada; 
begin 
Result := False; 
Llave := TLlavePrivada.Create; 

if Llave.DER_LoadFromFile(DmDatos.IBDs_SistemaKEYFNAME.AsString,   DmDatos.IBDs_SistemaCLAVEPRIVADA.AsString) then 
begin 
    FLlaveB64 := Llave.Base64; 
    Result := True; 
end 
else 
    begin 
    FRespuestaCFD := 'Error al abrir la Llave, es posible que la clave no sea la correcta'; 
end; 

Llave.Free; 
Llave := Nil; 

end; 

以下是我其中函數被編碼

procedure TX509Certificate.LoadFromFile(FileName: string); 
begin 
    LoadFromFile(Filename, auto); 
end; 

procedure TX509Certificate.LoadFromFile(FileName: string; Encoding: TEncoding); 
var 
certfile: pBIO; 
p12: pPKCS12; 
a: pEVP_PKEY; 
c: pX509; 
ca: pSTACK_OFX509; 
begin 
c := nil; 

if not(Encoding in [auto, DER, PEM, NETSCAPE, PKCS12]) then 
raise EOpenSSL.Create('Bad certificate encoding.'); 

if not FileExists(FileName) then 
raise EOpenSSL.Create('Certificate file not found ('+FileName+')'); 

certfile := BIO_new(BIO_s_file()); 

if certfile = nil then 
raise EOpenSSL.Create('Error creating BIO.'); 

BIO_read_filename(certfile, ToChar(FileName)); 

if (Encoding = auto) or (encoding = DER) then 
    begin 
fCertificate := d2i_X509_bio(certfile, nil); 
if (Encoding = auto) and (fCertificate = nil) then 
    BIO_reset(certfile); 
    end; 

if ((Encoding = auto) and (fCertificate = nil)) or (encoding = NETSCAPE) then 
    begin 
// See apps.c 
    end; 

if ((Encoding = auto) and (fCertificate = nil)) or (encoding = PEM) then 
    begin 
fCertificate := PEM_read_bio_X509_AUX(certfile, c, nil, nil); 
if (Encoding = auto) and (fCertificate = nil) then 
BIO_reset(certfile); 
    end; 

if ((Encoding = auto) and (fCertificate = nil)) or (encoding = PKCS12) then 
    begin 
p12 := d2i_PKCS12_bio(certfile, nil); 
PKCS12_parse(p12, nil, a, c, ca); 
fCertificate := c; 
PKCS12_free(p12); 
p12 := nil; 
    end; 

    BIO_free(certfile); 
    if fCertificate = nil then 
raise EOpenSSL.Create('Unable to read certificate from file ' + FileName + '.'); 
end; 

function TPKCS8.DER_LoadFromFile(DERFname, PrivateKey: string) : boolean; 
var 
bioDER : pBIO; 
p8 : pX509_SIG; 
p8inf : pPKCS8_Priv_Key_Info; 
begin 
//OpenSSL pkcs8 -inform DER -in DERFName -passin pass:PrivateKey 

Result := false; 

bioDER := nil; p8 := nil; 

if FileExists(DERFname) then 
    try 
bioDER := BIO_new(BIO_s_file()); 
BIO_read_filename(bioDER,ToChar(DERFName)); 
p8 := d2i_PKCS8_bio(bioDER,nil); 
if p8 = nil then exit; //El archivo no es un .key bien formado 
//------HERE CRASH----------------------------------------------- 
p8inf := PKCS8_decrypt(p8,ToChar(PrivateKey),length(PrivateKey)); 
//------------------------------------------------------------- 
if p8inf = nil then exit; //No es la clave de llave privada correcta 
    fLlave := EVP_PKCS82PKEY(p8inf); 
    Result := true; 
    finally 
X509_SIG_free(p8); 
BIO_free(bioDER); 
EVP_cleanup; 
    end; 
end; 

在該單元的代碼。 KEY和它的私鑰是正確的,這是我在調試中檢查的第一件事。

最奇怪的是,我有2個文件夾,其中應用程序正在生產和其他測試。並且只在測試文件夾中工作不正常。

應用程序應該在Citrix下運行。

開發計算機的一切完美的作品上

,錯誤是在執行和測試文件夾,

Citrix服務器是贏服務器提前2003

感謝,如果有人可以幫我找到這個錯誤

+0

由於Citrix有時會根據未知規則工作,因此我建議您驗證這些文件夾的屬性以及該過程的應用程序權限。 – RBA

回答

0

我來自墨西哥,也爲Delphi開發了數字發票(Facturacion Electronica)的開源庫,並且還與OpenSSL和Delphi的Delphi實現戰鬥。

其實我們的代碼看起來非常相似,你可以看看我的「ClaseOpenSSL.pas」的代碼中,我打開私鑰:

function TOpenSSL.AbrirLlavePrivada(Ruta, ClaveLlavePrivada : String) : pPKCS8_Priv_Key_Info; 
var 
    bioArchivoLlave : pBIO; 
    sMsgErr: String; 
    p8 : pX509_SIG; 
    p8inf : pPKCS8_Priv_Key_Info; 
    {$IF CompilerVersion >= 20} 
     p8pass: PAnsiChar; 
    {$ELSE} 
     p8pass: PChar; 
    {$IFEND} 
begin 
    // Creamos el objeto en memoria para leer la llave en formato binario .DER (.KEY) 
    bioArchivoLlave := BIO_new(BIO_s_file()); 

    if Not FileExists(Ruta) then 
     Raise ENoExisteArchivoException.Create('El archivo de llave privada no existe.'); 

    // Checamos que la extension de la llave privada sea la correcta 
    if AnsiPos('.PEM', Uppercase(Ruta)) > 0 then 
     Raise ELlaveFormatoIncorrectoException.Create('La llave privada debe de ser el archivo binario (.key, .cer) y ' + 
      'no el formato base64 .pem'); 

    // Leemos el archivo de llave binario en el objeto creado en memoria 
    // DIferentes parametros si usa Delphi 2009 o superior... 
    {$IF CompilerVersion >= 20} 
     if BIO_read_filename(bioArchivoLlave, PWideChar(AnsiString(Ruta))) = 0 then 
    {$ELSE} 
     if BIO_read_filename(bioArchivoLlave, PChar(AnsiString(Ruta))) = 0 then 
    {$IFEND} 
      raise ELlaveLecturaException.Create('Error al leer llave privada. Error reportado: '+ 
       ObtenerUltimoMensajeDeError); 

    // Checamos que la clave no est� vacia 
    if Trim(ClaveLlavePrivada) = '' then 
     raise ELlavePrivadaClaveIncorrectaException.Create('La clave de la llave privada esta vacia'); 

    // Convertimos al tipo adecuado de acuerdo a la version de Delphi... 
    {$IF CompilerVersion >= 20} 
     // Delphi 2009 o superior 
     p8pass:=PAnsiChar(AnsiString(ClaveLlavePrivada)); 
    {$ELSE} 
     p8pass:=PChar(AnsiString(ClaveLlavePrivada)); 
    {$IFEND} 

    p8:=nil; 
    p8inf:=nil; 

    try 
     // Leemos la llave en formato binario (PKCS8) 
     p8 := d2i_PKCS8_bio(bioArchivoLlave, nil); 
     if not Assigned(p8) then 
      raise ELlaveLecturaException.Create('Error al leer llave privada. Error reportado: '+ 
       ObtenerUltimoMensajeDeError); 

     // Des encriptamos la llave en memoria usando la clave proporcionada 
     p8inf := PKCS8_decrypt(p8, p8pass, StrLen(p8pass)); 
     if Not Assigned(p8inf) then 
     begin 
      sMsgErr:=ObtenerUltimoMensajeDeError; 
      // TODO: Crear excepciones para los diferentes tipos de error que puede haber al 
      // tratar de desencriptar la llave privada 
      // Llave incorrecta (Mensaje exacto: 23077074:PKCS12 routines:PKCS12_pbe_crype:pkcs12 cipherfinal error) 
      if ((AnsiPos('cipherfinal error', sMsgErr) > 0) or // clave incorrecta 
       (AnsiPos('bad decrypt', sMsgErr) > 0)) // clave incorrecta 
      then 
       raise ELlavePrivadaClaveIncorrectaException.Create('La clave de la llave privada fue incorrecta') 
      else 
       if (AnsiPos('unknown pbe algorithm', sMsgErr) > 0) then // Clave vacia o pertenece a la FIEL 
       Raise ELlavePareceSerFiel.Create('Al parecer la llave privada pertenece a la FIEL') 
       else 
       raise ELlaveLecturaException.Create('Error desconocido al desencriptar llave privada. Error reportado: '+ 
         ObtenerUltimoMensajeDeError); 
     end; 
    finally 
     // Liberamos las variables usadas en memoria 
     X509_SIG_free(p8); 
      BIO_free(bioArchivoLlave); 
    end; 

    Result:=p8inf; 
end; 

OpenSSL的是C庫往往是非常非常挑剔的參數並傳遞正確的數據類型和緩衝區等,這對於您釋放分配的「pBIO」變量也非常重要。

如果你想,幫助始終歡迎您向圖書館歡迎:)

GitHub的項目是: http://github.com/bambucode/tfacturaelectronica

而且我們的(很新)支持組爲: http://groups.google.com/forum/#!forum/tfacturaelectronica

問候!