[fpc-devel] certificate verify issue of tfphttpclient with openssl

baldzhang baldzhang at 163.com
Fri Aug 21 23:06:12 CEST 2020


certificate verify issue of tfphttpclient with openssl

from wiki page, https client as easy as:
  tfphttpclient.simpleget('https://192.168.0.1')

in TOpenSSLSocketHandler, the VerifyPeerCert is False by default
when check the TSSL.VerifyResult, will got one of following:

1) X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18;
  when https server use a self-signed cert

2) X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19;
  when server use a cert signed by internal CA

3) X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20;
  when connect to a real *signed* server, ex: https://www.kernel.org

if set TSSL.VerifyResult to True, the connect will fail and exception raised.
even set Handler.CertificateData.CertCA.FileName to a valid cert file.

finally found in opensslsockets.pas: TOpenSSLSocketHandler.Connect: Boolean
...
     if Result and VerifyPeerCert then
       Result:=(FSSL.VerifyResult<>0) or (not DoVerifyCert);
...
in first Result and VerifyPeerCert both are True
the second line, if I'm not wrong understanding, is totally reverse

FSSL.VerifyResult is 0 here, and DoVerifyCert always return True,
so the Result changed to False, and then the connect became fail.


in a real prog, we want to check the VerifyResult, and still allow the connection in some conditions.

after some modify, things changed to:

1) when VerifyPeerCert is True 
  if Handler.CertificateData.CertCA.FileName set to a valid cert,
  VerifyResult will be 0, and https request passed

2) when it's False
   assign a OnVerifyCertificate handler, check SSL infos, to allow or deny the connect.


*** tested fpc 3.2.0, openssl 1.0.2j(copied from lazarus), windows 10 64-bit, client side of https transmition.

patch file attached,
some explain:

a) sslsockets.pp
  the TVerifyCertificateEvent shall allow to modify the "Allow" param, for compatibility reason, 
  function DoVerifyCert: Boolean may change to virtual

b) fppoenssl.pp
  FingerPrint always genarate by MD5, can be SHA1 or SHA256

c) opensslsockets.pp
  export SSL: TSSL for more lower level control
  in Connect():
    Result and VerifyPeerCert check are duplicated
    alway give a chance to let user do the certificate verifing.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openssl-verify-cert.diff
Type: application/octet-stream
Size: 3035 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20200822/96927e9b/attachment.obj>


More information about the fpc-devel mailing list