jaenicke 13 Posted June 14, 2023 I had activated loSslInfo as LogOption. Then I got an access violation on another machine. The problem is: - TCustomSslWSocket.StartSslHandshake calls FSslContext.InitContext - An exception is raised, because libcrypto-1_1.dll is missing - This exception is handled in TCustomSslWSocket.StartSslHandshake, but inside the except block TriggerSslHandshakeDone is called. This would be no problem, if IcsX509VerifyErrorToStr would not be called there for logging purposes. In this function X509_verify_cert_error_string is used, which is nil, because the library is missing. I think this is a bug. Am I right? Thank you Share this post Link to post
Angus Robertson 577 Posted June 14, 2023 I'd suggest if you call StartSslHandshake without previously loading OpenSSL or initialising an SslContext, you need to revise your code when using low level components. The newer higher level components do all the OpenSSL set-up for you, so errors like this won't happen. This will only be fixed if you can reproduce it in an ICS sample, it really is not possible to check OpenSSL has been opened before every single OpenSSL function. Angus Share this post Link to post
jaenicke 13 Posted June 14, 2023 (edited) I only wanted to make an SSL call, so I don't think this is a very unusual call. A small example is: uses OverbyteIcsHttpProt, OverbyteIcsLogger, OverbyteIcsWSocket; procedure Test; var SslHttpCli: TSslHttpCli; begin SslHttpCli := TSslHttpCli.Create(nil); try SslHttpCli.SslContext := TSslContext.Create(SslHttpCli); SslHttpCli.URL := 'https://www.example.com'; SslHttpCli.IcsLogger := TIcsLogger.Create(SslHttpCli); SslHttpCli.IcsLogger.LogOptions := [loSslInfo]; SslHttpCli.Get; finally SslHttpCli.Free; end; end; The access violation happens, when Get is called. Of course not all calls can be checked, but I would recommend to do it in IcsX509VerifyErrorToStr, because it is used inside the error handling. You could do it this way: function IcsX509VerifyErrorToStr(ErrCode: Integer): String; begin {$IFNDEF OPENSSL_USE_RESOURCE_STRINGS} if Assigned(X509_verify_cert_error_string) then Result := String(AnsiString(X509_verify_cert_error_string(ErrCode))) else {$ENDIF} case ErrCode of X509_V_OK : Result := sX509_V_OK; X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: Result := sX509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; X509_V_ERR_UNABLE_TO_GET_CRL: Result := sX509_V_ERR_UNABLE_TO_GET_CRL; X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: Result := sX509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: Result := sX509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: Result := sX509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; X509_V_ERR_CERT_SIGNATURE_FAILURE: Result := sX509_V_ERR_CERT_SIGNATURE_FAILURE; X509_V_ERR_CRL_SIGNATURE_FAILURE: Result := sX509_V_ERR_CRL_SIGNATURE_FAILURE; X509_V_ERR_CERT_NOT_YET_VALID: Result := sX509_V_ERR_CERT_NOT_YET_VALID; X509_V_ERR_CRL_NOT_YET_VALID: Result := sX509_V_ERR_CRL_NOT_YET_VALID; X509_V_ERR_CERT_HAS_EXPIRED: Result := sX509_V_ERR_CERT_HAS_EXPIRED; X509_V_ERR_CRL_HAS_EXPIRED: Result := sX509_V_ERR_CRL_HAS_EXPIRED; X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: Result := sX509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: Result := sX509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: Result := sX509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: Result := sX509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; X509_V_ERR_OUT_OF_MEM: Result := sX509_V_ERR_OUT_OF_MEM; X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: Result := sX509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: Result := sX509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: Result := sX509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: Result := sX509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; X509_V_ERR_CERT_CHAIN_TOO_LONG: Result := sX509_V_ERR_CERT_CHAIN_TOO_LONG; X509_V_ERR_CERT_REVOKED: Result := sX509_V_ERR_CERT_REVOKED; X509_V_ERR_INVALID_CA: Result := sX509_V_ERR_INVALID_CA; X509_V_ERR_INVALID_NON_CA: Result := sX509_V_ERR_INVALID_NON_CA; X509_V_ERR_PATH_LENGTH_EXCEEDED: Result := sX509_V_ERR_PATH_LENGTH_EXCEEDED; X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: Result := sX509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: Result := sX509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; X509_V_ERR_INVALID_PURPOSE: Result := sX509_V_ERR_INVALID_PURPOSE; X509_V_ERR_CERT_UNTRUSTED: Result := sX509_V_ERR_CERT_UNTRUSTED; X509_V_ERR_CERT_REJECTED: Result := sX509_V_ERR_CERT_REJECTED; X509_V_ERR_APPLICATION_VERIFICATION: Result := sX509_V_ERR_APPLICATION_VERIFICATION; X509_V_ERR_SUBJECT_ISSUER_MISMATCH: Result := sX509_V_ERR_SUBJECT_ISSUER_MISMATCH; X509_V_ERR_AKID_SKID_MISMATCH: Result := sX509_V_ERR_AKID_SKID_MISMATCH; X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: Result := sX509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; X509_V_ERR_KEYUSAGE_NO_CERTSIGN: Result := sX509_V_ERR_KEYUSAGE_NO_CERTSIGN; X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: Result := sX509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: Result := sX509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: Result := sX509_V_ERR_KEYUSAGE_NO_CRL_SIGN; X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: Result := sX509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: Result := sX509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; X509_V_ERR_INVALID_EXTENSION: Result := sX509_V_ERR_INVALID_EXTENSION; X509_V_ERR_INVALID_POLICY_EXTENSION: Result := sX509_V_ERR_INVALID_POLICY_EXTENSION; X509_V_ERR_NO_EXPLICIT_POLICY: Result := sX509_V_ERR_NO_EXPLICIT_POLICY; { V8.39 lots more } X509_V_ERR_UNNESTED_RESOURCE: Result := sX509_V_ERR_UNNESTED_RESOURCE; else Result := sX509_V_ERR_NUMBER + IntToStr(ErrCode); end; end; Of course the resource strings have to be available as well. This way the error handling works correctly, if the DLL is not loaded (if it is neccessary, I don't know, whether any of those errors can occur then) and the correct error is displayed / logged. Edited June 14, 2023 by jaenicke Share this post Link to post
Angus Robertson 577 Posted June 14, 2023 Ultimately, if the DLLs are missing and you make an SSL request, you will get an exception sooner or later. Angus Share this post Link to post
jaenicke 13 Posted June 14, 2023 (edited) Yes, but the problem ist, that I get this: But I should get: I had to search for the error, because the error message from the log did not tell me anything. Edited June 14, 2023 by jaenicke 1 Share this post Link to post
Angus Robertson 577 Posted June 14, 2023 I'll look into improving the error handling next week. But if this happens in a real application, you should have OverbyteIcsWSocket.LoadSsl much earlier so OpenSSL only gets loaded once, and you handle error before starting requests, see any of the SSL samples. Angus Share this post Link to post
jaenicke 13 Posted June 15, 2023 Thank you! I didn't pay attention to this call as I do not make many calls, so speed does not matter. But of course I'll use this now that I am aware of it. There the error handling works correctly, though I would prefer not to get an exception, as I can configure it when calling the Get method. LibeayLoad always returns true instead. But it is not important as this is called only once. Thank you for your help! Share this post Link to post
w0wbagger 3 Posted November 11 (edited) Just FYI in case anyone else has a similar problem, My app was working fine on my development machine, but stopped when I put it on a client machine. I was having this problem (didn't load Libcrypto-1_1.dll), and put LoadLibrary into my app at startup, but it still wasn't working (although it wasn't failing on LoadLibrary) Error was *still* reported as that it couldn't load Libcrypto-1_1.dll. However, the issue was that I was missing libssl-1_1.dll, Once I copied that into the directory, it worked well. Was still getting the Application Exception error instead of a clean exception, but didn't seem to affect performance. Edited November 11 by w0wbagger Share this post Link to post
Angus Robertson 577 Posted November 12 OpenSSL loading was totally rewritten in the last year. Angus Share this post Link to post
w0wbagger 3 Posted November 12 Thanks, Angus. Until I can get the new version working with C++ Builder (Been crushed at work and haven't had time to get at it), I have to use 8.x, where someone else might have this issue. Sorry, I should have mentioned that I had this issue with 8.x, not 9.x Share this post Link to post