You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Усманов Азат Анварович <us...@ieml.ru> on 2019/05/22 10:28:05 UTC

OCSP with openSSL

Hi everyone! I have a web app running on tomcat and java 7 using apr for TLS related issues. I m still unable to have OCSP verification working with tomcat. I'm  NOT  talking about the client- certificate based auth here,  just the opposite. I want tomcat to present it's OCSP  status to the client(browser) when it connects to the server.  Since the options on OCSP  section tomcat docs talk about client-auth I figured I don't need to add anything on my HTTPS connector to get OCSP working.  So here is my  https connector
   <Connector  allowTrace="false" server=" " port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
      maxThreads="350" SSLEnabled="true"   enableLookups="false" disableUploadTimeout="true" acceptCount="100" scheme="https" secure="true" compression="force">
 <UpgradeProtocol  className="org.apache.coyote.http2.Http2Protocol" compression="force" />
        <SSLHostConfig sessionCacheSize="50"  honorCipherOrder= "true" protocols="TLSv1.3+TLSv1.2" ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-SHA384,ECDHE-ECDSA-AES128-SHA256">
            <Certificate certificateKeyFile="/home/idis/server.key"
                         certificateFile="/home/idis/STAR_ieml_ru.crt"
                         certificateChainFile="/home/idis/authorities.crt"
                         type="RSA"/>
</SSLHostConfig>
    </Connector>
our ocsp certificate has ocsp responder address  http://ocsp.comodoca.com
 I thought that my issues  were  caused by the fact the server in question  sits behind a proxy but I just tested ocsp stapling  manually via OpenSSL ocsp utility and it working properly  when invoked through the command line
 openssl ocsp  -no_nonce  -issuer issuer.crt -cert /home/idis/STAR_ieml_ru.crt    -url  http://ocsp.comodoca.com/ -text
OCSP Request Data:
    Version: 1 (0x0)
    Requestor List:
        Certificate ID:
          Hash Algorithm: sha1
          Issuer Name Hash: 7AE13EE8A0C42A2CB428CBE7A605461940E2A1E9
          Issuer Key Hash: 90AF6A3A945A0BD890EA125673DF43B43A28DAE7
          Serial Number: F078CB8E2F4E5A678BFB9065A9611B57
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: 90AF6A3A945A0BD890EA125673DF43B43A28DAE7
    Produced At: May 15 19:34:39 2019 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: 7AE13EE8A0C42A2CB428CBE7A605461940E2A1E9
      Issuer Key Hash: 90AF6A3A945A0BD890EA125673DF43B43A28DAE7
      Serial Number: F078CB8E2F4E5A678BFB9065A9611B57
    Cert Status: good
    This Update: May 15 19:34:39 2019 GMT
    Next Update: May 22 19:34:39 2019 GMT

    Signature Algorithm: sha256WithRSAEncryption
         37:ee:ae:ed:35:ea:2f:f5:3c:d6:4e:4b:60:fd:5b:8b:f6:24:
         90:e4:da:11:d7:57:9c:22:d6:fe:53:2f:48:a3:cb:7a:1e:c0:
         82:70:28:c9:bb:d5:07:31:c3:33:d2:0b:09:12:96:68:ed:a1:
         3f:d7:d6:46:9d:dc:9a:d8:55:27:0b:5e:c2:56:fc:47:42:de:
         f0:e6:5f:75:f1:c0:b4:42:76:f4:e6:30:b9:a8:9a:75:8f:5f:
         0c:e6:5b:1e:6b:6d:8e:66:3c:7f:73:df:22:98:4d:40:aa:e1:
         d5:fb:27:8d:9b:e6:67:ae:40:3d:1f:29:da:23:7d:74:ad:b3:
         e6:76:f9:be:18:ad:df:be:ee:7d:1a:ab:26:5b:0c:4a:3b:d3:
         7e:f4:7d:c6:6d:f4:93:90:90:ec:25:b1:d1:4a:c8:1e:47:fb:
         67:5e:50:42:97:cf:26:2e:d4:21:9f:e1:4a:a9:a1:ba:8c:0a:
         0f:f6:1e:d8:2e:f7:25:32:89:c7:af:b7:81:39:9b:57:72:9c:
         28:1b:9d:b1:58:aa:e2:47:bc:f9:5b:23:d2:f2:cb:9d:ac:72:
         cf:d9:75:12:a2:94:c3:78:d6:59:f7:96:12:18:9a:3b:b8:84:
         d2:fd:b5:54:e7:4c:51:17:01:f2:0a:0d:fa:52:e7:5e:51:6a:
         d9:14:1a:e3
Response verify OK
/home/idis/STAR_ieml_ru.crt: good
        This Update: May 15 19:34:39 2019 GMT
        Next Update: May 22 19:34:39 2019 GMT
However, then I test the server both manually and via ssllabs  server test  ocsp stapling   still shows no
openssl s_client -connect debug.ieml.ru:8443  -tls1_2 -status
CONNECTED(00000004)
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
OCSP response: no response sent
---
Certificate chain
 0 s:OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.ieml.ru
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
 1 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
   i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
 2 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
   i:C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFQzCCBCugAwIBAgIRAPB4y44vTlpni/uQZalhG1cwDQYJKoZIhvcNAQELBQAw
gZAxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTYwNAYD
VQQDEy1DT01PRE8gUlNBIERvbWFpbiBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIg
Q0EwHhcNMTcwNjI5MDAwMDAwWhcNMTkwODI5MjM1OTU5WjBWMSEwHwYDVQQLExhE
b21haW4gQ29udHJvbCBWYWxpZGF0ZWQxHTAbBgNVBAsTFFBvc2l0aXZlU1NMIFdp
bGRjYXJkMRIwEAYDVQQDDAkqLmllbWwucnUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDDPvJ/lpxUzUyI6xAI4vm+fJG76JPJ3PjVPWshE6DQ8FSOX1tz
x/77d7DHH3o73I1fZL26o8feq1tscHg5Hn/L4S+N3pPAqz3Q6Q98O3r6lzJtK5Yz
gfWCEx6tFNvuQ96G2rN6b+wwpbo42e+Ml9HejTH3F3tdgkZ9++jq2/xge/82tRfm
F7OdKpOl0HJhjyKb4ehck032lACLLzKaiVXwuvm0PFeNVMfGli6esVjvf6qUvXIe
dxfgJu5emAdFwAWSwJYQ61sUPt/o4G5SLFx4xaDaA0W5cK8Wtd2BGe12kDVstVft
hP7KKj/giXFQSIrC5JmIE4wr8c4yiHBcrwdjAgMBAAGjggHPMIIByzAfBgNVHSME
GDAWgBSQr2o6lFoL2JDqElZz30O0Oija5zAdBgNVHQ4EFgQUs+5Z8D1kBsszi2+H
fbGGs7WeS7EwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYw
FAYIKwYBBQUHAwEGCCsGAQUFBwMCME8GA1UdIARIMEYwOgYLKwYBBAGyMQECAgcw
KzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwCAYG
Z4EMAQIBMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly9jcmwuY29tb2RvY2EuY29t
L0NPTU9ET1JTQURvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYUG
CCsGAQUFBwEBBHkwdzBPBggrBgEFBQcwAoZDaHR0cDovL2NydC5jb21vZG9jYS5j
b20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk
BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMB0GA1UdEQQWMBSC
CSouaWVtbC5ydYIHaWVtbC5ydTANBgkqhkiG9w0BAQsFAAOCAQEAQTfwPlwQrEDN
Xm8cFJHnn7HhA0/fs/eaJ8SiSqZtUbPZar8V1fd0uIHElwQGTdxLBPktyAVBE7Ro
tP1QCU7Al6y0LMba1+aGIxGhVE7Ub7ntwPIPMs8Q68YZIC7oHBMtr6Qn34HF1lI0
CWHJqwWCv4UWwtwZcy4ab5tS+Nv1qd4O4fok9T/LTQCY5rbyCnhWfiRNMihLX2tk
/Cc5UvwUkS81c1A5sHgCLuqKPL7zCmJbcaFKPYTZEN2EUaKhT1jq06cmDfyXP6cq
4rmuaMxMxgsmDL4emO9LP9IfKmL3IvFngpkgAuNks/RiILFRuBv/EcF8C+FI46g5
PqY0SNxCGA==
-----END CERTIFICATE-----
subject=OU = Domain Control Validated, OU = PositiveSSL Wildcard, CN = *.ieml.ru

issuer=C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4966 bytes and written 318 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 47F268768C011706B01BA181164ADC7BE4452049E84BA24515CB4645B8717A15
    Session-ID-ctx:
    Master-Key: 87C245B1F3D8ABB69B14865AF0E650B395BFEEFB88FBC99D818439E7A60A31AADD83363D24AFFEA2A1CE14C3EDF2EA41
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 86400 (seconds)
    TLS session ticket:
    0000 - 31 da bf fc ec 56 ef 77-8c 74 d8 df 15 51 b3 e8   1....V.w.t...Q..
    0010 - 69 3d 6d ba a7 5f 9c 15-3f 8f d7 e9 07 50 2b ca   i=m.._..?....P+.
    0020 - c1 f2 fd f2 7d 31 6d 52-25 16 31 45 71 c4 ef 75   ....}1mR%.1Eq..u
    0030 - 85 59 ea 14 a2 00 4a 4e-b1 c8 d7 90 32 c7 a0 3c   .Y....JN....2..<
    0040 - b5 11 e7 53 0a cc 8b 4a-26 fc fd fd e9 8c 77 12   ...S...J&.....w.
    0050 - b5 de 85 0c f1 d4 b9 ff-67 e6 5c c7 10 98 ab 20   ........g.\....
    0060 - 37 1d 95 75 09 77 76 5d-42 8f 46 96 63 c5 fa ea   7..u.wv]B.F.c...
    0070 - 58 e1 58 52 4c 07 17 c2-0b d0 64 5c 68 ce 5d 23   X.XRL.....d\h.]#
    0080 - dd 73 2c e3 83 50 fe 8f-7b f0 89 aa ee de a2 52   .s,..P..{......R
    0090 - 14 ba 68 5c 13 d7 6a b8-cc 07 73 9a 2e 11 b3 0d   ..h\..j...s.....
    00a0 - 7f 84 45 d4 8c fc a0 3a-8d f4 d9 39 48 6d bf 9c   ..E....:...9Hm..
    00b0 - 6d 7b ef 50 bc 0b e2 89-af 4e 8b 82 60 cf 22 64   m{.P.....N..`."d

    Start Time: 1558517267
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: yes
---
read:errno=0
 I have tried running tcpdump on the server but don't' see any Comodo related IP addresses in the output when I access the server in question in the browser.
At this point I don't know what else to do, If it was java I would just put some System.out.println statements in OCSP SSL related source code and recompile the tomcat source, but since in my case tomcat uses OpenSSL and tomcat native I'm not sure how/where to do that. the only places I found in the TC-native source that mentions OCSP  is sslutils.c  source file. I'm not sure when/ if it is actually gets called in my case. Maybe be someone with more c experience c++ would help me with that.  I really want to get to the bottom of this. Any help is appreciated
 my tomcat version  is 8.5.39
 APR based Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
Openssl version is [OpenSSL 1.1.1a  20 Nov 2018
OS: Linux RHEL 6.6




Re: OCSP with openSSL

Posted by logo <lo...@kreuser.name>.
Hi Mark,

Sorry for top posting - I want to wrap this thread up.

I was bitten again by the default SSL Implementation.

While I wanted to use JSSE on Port 8443, I just noticed today that without telling the connector to do so (sslImplementationName=„org.apache.tomcat.util.net.jsse.JSSEImplementation"), it used the OpenSSLImplementation - well that does not support OCSP as we all know.

The documentation is a bit vague on the defaults
To enable it, the native library should be enabled as if intending to use the APR connector, and Tomcat will automatically enable it and the default value of this attribute becomes org.apache.tomcat.util.net.openssl.OpenSSLImplementation

My basic test case uses the tomcat docker image with openjdk11. I did not specifically install tc native and enable APR.

Now when I look at below logfile I can see all that‘s wrong…
Sorry for the noise!


PS: now waiting for the openssl fix for tc native ;-)

Am 28.06.2019 um 14:14 schrieb logo <logo@kreuser.name <ma...@kreuser.name>>:

> Mark,
> 
> Still no luck with 8.5.42/JDK11/JSSE.
> 
>> Am 17.06.2019 um 22:11 schrieb logo <logo@kreuser.name <ma...@kreuser.name>>:
>> 
>> Mark,
>> 
>> 
>>> Am 17.06.2019 um 18:00 schrieb Mark Thomas <markt@apache.org <ma...@apache.org>>:
>>> 
>>> On 17/06/2019 15:51, logo wrote:
>>>> Mark,
>>>> 
>>>> 
>>>> Am 2019-06-17 16:29, schrieb Mark Thomas:
>>>>> On 17/06/2019 15:15, logo wrote:
>>>>>> Hi Mark,
>>>>>> 
>>>>>> having been in contact with Усманов, I can confirm your summary.
>>>>>> 
>>>>>> May I add my question from February with additional info to this thread:
>>>>>> https://markmail.org/message/zvziqrhm32bctm7e <https://markmail.org/message/zvziqrhm32bctm7e>
>>>>> 
>>>>> Thanks.
>>>>> 
>>>>> Progress can be tracked here:
>>>>> https://bz.apache.org/bugzilla/show_bug.cgi?id=56148 <https://bz.apache.org/bugzilla/show_bug.cgi?id=56148>
>>>>> 
>>>>> At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
>>>>> OCSP stapling with appropriate configuration.
>>>>> 
>>>> 
>>>> Do you mean on trunk or really only configuration?
>>>> 
>>>> I just tried it on 8.5.42 and it will not send the message on my
>>>> letsencrypt cert.
>>>> 
>>>> If it should work out of the box, do you mind to share the "appropriate"
>>>> config here.
>>> 
>>> I was testing Tomcat 9.0.x (latest source from Git) but with the
>>> knowledge that we haven't made *any* changes to Tomcat to support OCSP
>>> stapling and that 9.0.x and 8.5.x have very similar TLS code.
>>> 
>>> I have just tested with 8.5.42. Both NIO+JSSE and NIO2+JSSE support OCSP
>>> stapling. My Connector configuration is:
>>> 
>>>    <Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
>>>               port="8443"
>>>               proxyPort="443"
>>>               maxThreads="150"
>>>               useAsyncIO="true"
>>>               SSLEnabled="true">
>>>        <UpgradeProtocol
>>>                 className="org.apache.coyote.http2.Http2Protocol"
>>>                 useSendfile="false"
>>>                 maxConcurrentStreamExecution="50" />
>>>        <SSLHostConfig>
>>>            <Certificate certificateKeyFile="/.../privkey.pem"
>>>                         certificateFile="/.../cert.pem"
>>>                         certificateChainFile="/.../chain.pem"
>>>                         type="RSA" />
>>>        </SSLHostConfig>
>>>    </Connector>
>>> 
>>> Mark
>>> 
>> I’m lost. My conf is pretty much similar.
>> 
> <snip>
> 
>> Any debug info I can create?
>> 
>> Thanks Peter
> 
> 
> Started from scratch, plain tc 8.5.42 with JDK 11 (Docker Hub version)
> 
> Only added my certs to server.xml,
> 
>     <Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
>                maxThreads="150" SSLEnabled="true" >
>         <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
>         <SSLHostConfig>
>             <Certificate
>               certificateKeyFile="${catalina.base}/conf/ssl/privkey.pem"
>               certificateFile="${catalina.base}/conf/ssl/cert.pem"
>               certificateChainFile="${catalina.base}/conf/ssl/chain.pem"
>               type="RSA" />           
>         </SSLHostConfig>
>     </Connector>
> 
> export JAVA_OPTS="${JAVA_OPTS} -Djdk.tls.server.enableStatusRequestExtension=true“
> alternatively
> export CATALINA_OPTS="${CATALINA_OPTS} -Djdk.tls.server.enableStatusRequestExtension=true"
> to bin/setenv.sh
> 
> That gets picked up:
> 
> 28-Jun-2019 14:05:04.509 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.42
> 28-Jun-2019 14:05:04.524 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 4 2019 20:29:04 UTC
> 28-Jun-2019 14:05:04.525 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.42.0
> 28-Jun-2019 14:05:04.526 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
> 28-Jun-2019 14:05:04.527 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            4.14.116-boot2docker
> 28-Jun-2019 14:05:04.532 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
> 28-Jun-2019 14:05:04.533 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-11
> 28-Jun-2019 14:05:04.533 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.3+7
> 28-Jun-2019 14:05:04.534 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
> 28-Jun-2019 14:05:04.534 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /opt/apache-tomcat.base
> 28-Jun-2019 14:05:04.535 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
> 28-Jun-2019 14:05:04.535 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
> 28-Jun-2019 14:05:04.536 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io <http://java.io/>=ALL-UNNAMED
> 28-Jun-2019 14:05:04.537 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
> 28-Jun-2019 14:05:04.538 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/opt/apache-tomcat.base/conf/logging.properties
> 28-Jun-2019 14:05:04.538 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
> 28-Jun-2019 14:05:04.539 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.server.enableStatusRequestExtension=true
> 28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
> 28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
> 28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
> 28-Jun-2019 14:05:04.541 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
> 28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/opt/apache-tomcat.base
> 28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
> 28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/opt/apache-tomcat.base/temp
> 28-Jun-2019 14:05:04.543 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.21] using APR version [1.5.2].
> 28-Jun-2019 14:05:04.546 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
> 28-Jun-2019 14:05:04.547 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
> 28-Jun-2019 14:05:04.554 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.0j  20 Nov 2018]
> 28-Jun-2019 14:05:04.639 INFO [main] org.apache.coyote.http11.AbstractHttp11Protocol.configureUpgradeProtocol The ["https-openssl-nio2-8443"] connector has been configured to support negotiation to [h2] via ALPN
> 28-Jun-2019 14:05:04.640 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-nio2-8443"]
> 28-Jun-2019 14:05:04.877 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1184 ms
> 28-Jun-2019 14:05:05.017 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
> 28-Jun-2019 14:05:05.018 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.42
> 28-Jun-2019 14:05:05.036 SEVERE [Catalina-startStop-1] org.apache.catalina.startup.HostConfig.beforeStart Unable to create directory for deployment: [/opt/apache-tomcat.base/conf/Catalina/localhost]
> 28-Jun-2019 14:05:05.076 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/apache-tomcat.base/webapps/ROOT]
> 28-Jun-2019 14:05:08.827 WARNING [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [3,029] milliseconds.
> 28-Jun-2019 14:05:08.876 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/apache-tomcat.base/webapps/ROOT] has finished in [3,800] ms
> 28-Jun-2019 14:05:08.881 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-nio2-8443"]
> 28-Jun-2019 14:05:08.885 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 4007 ms
> 
> 
> Still openssl says
> 
> *****OCSP response: no response sent********
> 
> And testssl.sh on my domain says:
> 
>  Testing server defaults (Server Hello) 
> 
>  TLS extensions (standard)    "renegotiation info/#65281" "server name/#0" "EC point formats/#11" "session ticket/#35"
>                               "next protocol/#13172" "encrypt-then-mac/#22" "extended master secret/#23"
>                               "application layer protocol negotiation/#16"
>  Session Ticket RFC 5077 hint 86400 seconds, session tickets keys seems to be rotated < daily
>  SSL Session ID support       yes
>  Session Resumption           Tickets: yes, ID: no
>  TLS clock skew               Random values, no fingerprinting possible 
>  Signature Algorithm          SHA256 with RSA
>  Server key size              RSA 4096 bits
>  Server key usage             Digital Signature, Key Encipherment
>  Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
>  Serial / Fingerprints        xx / SHA1 xx
>                               SHA256 xx
>  Common Name (CN)             xxx.dedyn.io <http://xxx.dedyn.io/>
>  subjectAltName (SAN)         xxx xxx xxx.dedyn.io <http://xxx.dedyn.io/> 
>  Issuer                       Let's Encrypt Authority X3 (Let's Encrypt from US)
>  Trust (hostname)             Ok via SAN and CN (same w/o SNI)
>  Chain of trust               Ok   
>  EV cert (experimental)       no 
>  ETS/"eTLS", visibility info  not present
>  Certificate Validity (UTC)   expires < 30 days (20) (2019-04-20 00:48 --> 2019-07-19 00:48)
>  # of certificates provided   2
>  Certificate Revocation List  --
>  OCSP URI                     http://ocsp.int-x3.letsencrypt.org <http://ocsp.int-x3.letsencrypt.org/>
>  OCSP stapling                ****not offered****
>  OCSP must staple extension   ****requires OCSP stapling (NOT ok)****
>  DNS CAA RR (experimental)    available - please check for match with "Issuer" above
>                               iodef=mailto:xx@xx.com <ma...@xx.com>, issue=letsencrypt.org <http://letsencrypt.org/>
>  Certificate Transparency     yes (certificate extension)
> 
> 
> 
> Anything I can do to figure that out?
> 
> Thank you for your help!
> 
>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org <ma...@tomcat.apache.org>
>>> For additional commands, e-mail: users-help@tomcat.apache.org <ma...@tomcat.apache.org>

Re: OCSP with openSSL

Posted by logo <lo...@kreuser.name>.
Mark,

Still no luck with 8.5.42/JDK11/JSSE.

> Am 17.06.2019 um 22:11 schrieb logo <lo...@kreuser.name>:
> 
> Mark,
> 
> 
>> Am 17.06.2019 um 18:00 schrieb Mark Thomas <markt@apache.org <ma...@apache.org>>:
>> 
>> On 17/06/2019 15:51, logo wrote:
>>> Mark,
>>> 
>>> 
>>> Am 2019-06-17 16:29, schrieb Mark Thomas:
>>>> On 17/06/2019 15:15, logo wrote:
>>>>> Hi Mark,
>>>>> 
>>>>> having been in contact with Усманов, I can confirm your summary.
>>>>> 
>>>>> May I add my question from February with additional info to this thread:
>>>>> https://markmail.org/message/zvziqrhm32bctm7e <https://markmail.org/message/zvziqrhm32bctm7e>
>>>> 
>>>> Thanks.
>>>> 
>>>> Progress can be tracked here:
>>>> https://bz.apache.org/bugzilla/show_bug.cgi?id=56148 <https://bz.apache.org/bugzilla/show_bug.cgi?id=56148>
>>>> 
>>>> At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
>>>> OCSP stapling with appropriate configuration.
>>>> 
>>> 
>>> Do you mean on trunk or really only configuration?
>>> 
>>> I just tried it on 8.5.42 and it will not send the message on my
>>> letsencrypt cert.
>>> 
>>> If it should work out of the box, do you mind to share the "appropriate"
>>> config here.
>> 
>> I was testing Tomcat 9.0.x (latest source from Git) but with the
>> knowledge that we haven't made *any* changes to Tomcat to support OCSP
>> stapling and that 9.0.x and 8.5.x have very similar TLS code.
>> 
>> I have just tested with 8.5.42. Both NIO+JSSE and NIO2+JSSE support OCSP
>> stapling. My Connector configuration is:
>> 
>>    <Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
>>               port="8443"
>>               proxyPort="443"
>>               maxThreads="150"
>>               useAsyncIO="true"
>>               SSLEnabled="true">
>>        <UpgradeProtocol
>>                 className="org.apache.coyote.http2.Http2Protocol"
>>                 useSendfile="false"
>>                 maxConcurrentStreamExecution="50" />
>>        <SSLHostConfig>
>>            <Certificate certificateKeyFile="/.../privkey.pem"
>>                         certificateFile="/.../cert.pem"
>>                         certificateChainFile="/.../chain.pem"
>>                         type="RSA" />
>>        </SSLHostConfig>
>>    </Connector>
>> 
>> Mark
>> 
> I’m lost. My conf is pretty much similar.
> 
<snip>

> Any debug info I can create?
> 
> Thanks Peter


Started from scratch, plain tc 8.5.42 with JDK 11 (Docker Hub version)

Only added my certs to server.xml,

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate
              certificateKeyFile="${catalina.base}/conf/ssl/privkey.pem"
              certificateFile="${catalina.base}/conf/ssl/cert.pem"
              certificateChainFile="${catalina.base}/conf/ssl/chain.pem"
              type="RSA" />           
        </SSLHostConfig>
    </Connector>

export JAVA_OPTS="${JAVA_OPTS} -Djdk.tls.server.enableStatusRequestExtension=true“
alternatively
export CATALINA_OPTS="${CATALINA_OPTS} -Djdk.tls.server.enableStatusRequestExtension=true"
to bin/setenv.sh

That gets picked up:

28-Jun-2019 14:05:04.509 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.42
28-Jun-2019 14:05:04.524 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 4 2019 20:29:04 UTC
28-Jun-2019 14:05:04.525 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.42.0
28-Jun-2019 14:05:04.526 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
28-Jun-2019 14:05:04.527 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            4.14.116-boot2docker
28-Jun-2019 14:05:04.532 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
28-Jun-2019 14:05:04.533 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-11
28-Jun-2019 14:05:04.533 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.3+7
28-Jun-2019 14:05:04.534 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
28-Jun-2019 14:05:04.534 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /opt/apache-tomcat.base
28-Jun-2019 14:05:04.535 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
28-Jun-2019 14:05:04.535 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
28-Jun-2019 14:05:04.536 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
28-Jun-2019 14:05:04.537 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
28-Jun-2019 14:05:04.538 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/opt/apache-tomcat.base/conf/logging.properties
28-Jun-2019 14:05:04.538 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
28-Jun-2019 14:05:04.539 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.server.enableStatusRequestExtension=true
28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
28-Jun-2019 14:05:04.540 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
28-Jun-2019 14:05:04.541 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/opt/apache-tomcat.base
28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
28-Jun-2019 14:05:04.542 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/opt/apache-tomcat.base/temp
28-Jun-2019 14:05:04.543 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.21] using APR version [1.5.2].
28-Jun-2019 14:05:04.546 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
28-Jun-2019 14:05:04.547 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
28-Jun-2019 14:05:04.554 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.0j  20 Nov 2018]
28-Jun-2019 14:05:04.639 INFO [main] org.apache.coyote.http11.AbstractHttp11Protocol.configureUpgradeProtocol The ["https-openssl-nio2-8443"] connector has been configured to support negotiation to [h2] via ALPN
28-Jun-2019 14:05:04.640 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-nio2-8443"]
28-Jun-2019 14:05:04.877 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 1184 ms
28-Jun-2019 14:05:05.017 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
28-Jun-2019 14:05:05.018 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.42
28-Jun-2019 14:05:05.036 SEVERE [Catalina-startStop-1] org.apache.catalina.startup.HostConfig.beforeStart Unable to create directory for deployment: [/opt/apache-tomcat.base/conf/Catalina/localhost]
28-Jun-2019 14:05:05.076 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/apache-tomcat.base/webapps/ROOT]
28-Jun-2019 14:05:08.827 WARNING [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [3,029] milliseconds.
28-Jun-2019 14:05:08.876 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/apache-tomcat.base/webapps/ROOT] has finished in [3,800] ms
28-Jun-2019 14:05:08.881 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-nio2-8443"]
28-Jun-2019 14:05:08.885 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 4007 ms


Still openssl says

*****OCSP response: no response sent********

And testssl.sh on my domain says:

 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "renegotiation info/#65281" "server name/#0" "EC point formats/#11" "session ticket/#35"
                              "next protocol/#13172" "encrypt-then-mac/#22" "extended master secret/#23"
                              "application layer protocol negotiation/#16"
 Session Ticket RFC 5077 hint 86400 seconds, session tickets keys seems to be rotated < daily
 SSL Session ID support       yes
 Session Resumption           Tickets: yes, ID: no
 TLS clock skew               Random values, no fingerprinting possible 
 Signature Algorithm          SHA256 with RSA
 Server key size              RSA 4096 bits
 Server key usage             Digital Signature, Key Encipherment
 Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
 Serial / Fingerprints        xx / SHA1 xx
                              SHA256 xx
 Common Name (CN)             xxx.dedyn.io
 subjectAltName (SAN)         xxx xxx xxx.dedyn.io 
 Issuer                       Let's Encrypt Authority X3 (Let's Encrypt from US)
 Trust (hostname)             Ok via SAN and CN (same w/o SNI)
 Chain of trust               Ok   
 EV cert (experimental)       no 
 ETS/"eTLS", visibility info  not present
 Certificate Validity (UTC)   expires < 30 days (20) (2019-04-20 00:48 --> 2019-07-19 00:48)
 # of certificates provided   2
 Certificate Revocation List  --
 OCSP URI                     http://ocsp.int-x3.letsencrypt.org
 OCSP stapling                ****not offered****
 OCSP must staple extension   ****requires OCSP stapling (NOT ok)****
 DNS CAA RR (experimental)    available - please check for match with "Issuer" above
                              iodef=mailto:xx@xx.com, issue=letsencrypt.org
 Certificate Transparency     yes (certificate extension)



Anything I can do to figure that out?

Thank you for your help!

> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org <ma...@tomcat.apache.org>
>> For additional commands, e-mail: users-help@tomcat.apache.org <ma...@tomcat.apache.org>

Re: OCSP with openSSL

Posted by logo <lo...@kreuser.name>.
Mark,


> Am 17.06.2019 um 18:00 schrieb Mark Thomas <ma...@apache.org>:
> 
> On 17/06/2019 15:51, logo wrote:
>> Mark,
>> 
>> 
>> Am 2019-06-17 16:29, schrieb Mark Thomas:
>>> On 17/06/2019 15:15, logo wrote:
>>>> Hi Mark,
>>>> 
>>>> having been in contact with Усманов, I can confirm your summary.
>>>> 
>>>> May I add my question from February with additional info to this thread:
>>>> https://markmail.org/message/zvziqrhm32bctm7e
>>> 
>>> Thanks.
>>> 
>>> Progress can be tracked here:
>>> https://bz.apache.org/bugzilla/show_bug.cgi?id=56148
>>> 
>>> At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
>>> OCSP stapling with appropriate configuration.
>>> 
>> 
>> Do you mean on trunk or really only configuration?
>> 
>> I just tried it on 8.5.42 and it will not send the message on my
>> letsencrypt cert.
>> 
>> If it should work out of the box, do you mind to share the "appropriate"
>> config here.
> 
> I was testing Tomcat 9.0.x (latest source from Git) but with the
> knowledge that we haven't made *any* changes to Tomcat to support OCSP
> stapling and that 9.0.x and 8.5.x have very similar TLS code.
> 
> I have just tested with 8.5.42. Both NIO+JSSE and NIO2+JSSE support OCSP
> stapling. My Connector configuration is:
> 
>    <Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
>               port="8443"
>               proxyPort="443"
>               maxThreads="150"
>               useAsyncIO="true"
>               SSLEnabled="true">
>        <UpgradeProtocol
>                 className="org.apache.coyote.http2.Http2Protocol"
>                 useSendfile="false"
>                 maxConcurrentStreamExecution="50" />
>        <SSLHostConfig>
>            <Certificate certificateKeyFile="/.../privkey.pem"
>                         certificateFile="/.../cert.pem"
>                         certificateChainFile="/.../chain.pem"
>                         type="RSA" />
>        </SSLHostConfig>
>    </Connector>
> 
> Mark
> 
I’m lost. My conf is pretty much similar.

<Connector port="8443"
            protocol="org.apache.coyote.http11.Http11Nio2Protocol"
            allowTrace="false"
            maxThreads="150"
            SSLEnabled="true"
            compression="off"
            scheme="https"
            server="Apache Tomcat"
            secure="true"
            defaultSSLHostConfigName="xxx" >
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" compression="on" />
    <SSLHostConfig
            hostName="x (from the LE cert)"
            honorCipherOrder="true"
            certificateVerification="none"
            protocols="TLSv1.2+TLSv1.3"
            ciphers="HIGH:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS">
     <Certificate certificateKeystoreFile="${catalina.base}/conf/ssl/jssecacerts"
                  certificateKeystorePassword="xxx"
                  certificateKeyAlias="tomcat"
                  type="RSA" />
    </SSLHostConfig>

JAVA_OPTS are set (startup logs show 17-Jun-2019 16:46:48.497 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.server.enableStatusRequestExtension=true )


I use a JSSE keystore - that contains the correct cert. Openssl syntax did not change anything.

Running openssl to the letsencrypt ocsp responder from the machine gives a positive result. Tcpdump shows data.

$ openssl ocsp -verify_other intermediate.pem -issuer intermediate.pem -cert xxx.crt  -text -url http://ocsp.int-x3.letsencrypt.org -header "Host=ocsp.int-x3.letsencrypt.org"
OCSP Request Data:
    Version: 1 (0x0)
    Requestor List:
        Certificate ID:
          Hash Algorithm: sha1
          Issuer Name Hash: 7EE66AE7729AB3FCF8A220646C16A12D6071085D
          Issuer Key Hash: A84A6A63047DDDBAE6D139B7A64565EFF3A8ECA1
          Serial Number: 041237E97D620E10AFA0442E9C1D7B588046
    Request Extensions:
        OCSP Nonce: 
            0410E8ED9179F620FD43BBCC4C81EC432CFB
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
    Produced At: Jun 15 23:48:00 2019 GMT
…
Response verify OK


But once I connect to tomcat from outside, I don’t see any tcpdump traffic.

$ openssl s_client -connect xxx.dedyn.io:8443  -servername xxx.dedyn.io  -tlsextdebug  -status
CONNECTED(00000003)
TLS server extension "renegotiation info" (id=65281), len=1
0000 - 00                                                .
TLS server extension "server name" (id=0), len=0
TLS server extension "EC point formats" (id=11), len=4
0000 - 03 00 01 02                                       ....
TLS server extension "session ticket" (id=35), len=0
*****OCSP response: no response sent*****
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = xxx.dedyn.io
verify return:1
---
Certificate chain
 0 s:/CN=xxx.dedyn.io
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE——

Any debug info I can create?

Thanks Peter

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 


Re: OCSP with openSSL

Posted by Mark Thomas <ma...@apache.org>.
On 17/06/2019 15:51, logo wrote:
> Mark,
> 
> 
> Am 2019-06-17 16:29, schrieb Mark Thomas:
>> On 17/06/2019 15:15, logo wrote:
>>> Hi Mark,
>>>
>>> having been in contact with Усманов, I can confirm your summary.
>>>
>>> May I add my question from February with additional info to this thread:
>>> https://markmail.org/message/zvziqrhm32bctm7e
>>
>> Thanks.
>>
>> Progress can be tracked here:
>> https://bz.apache.org/bugzilla/show_bug.cgi?id=56148
>>
>> At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
>> OCSP stapling with appropriate configuration.
>>
> 
> Do you mean on trunk or really only configuration?
> 
> I just tried it on 8.5.42 and it will not send the message on my
> letsencrypt cert.
> 
> If it should work out of the box, do you mind to share the "appropriate"
> config here.

I was testing Tomcat 9.0.x (latest source from Git) but with the
knowledge that we haven't made *any* changes to Tomcat to support OCSP
stapling and that 9.0.x and 8.5.x have very similar TLS code.

I have just tested with 8.5.42. Both NIO+JSSE and NIO2+JSSE support OCSP
stapling. My Connector configuration is:

    <Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               port="8443"
               proxyPort="443"
               maxThreads="150"
               useAsyncIO="true"
               SSLEnabled="true">
        <UpgradeProtocol
                 className="org.apache.coyote.http2.Http2Protocol"
                 useSendfile="false"
                 maxConcurrentStreamExecution="50" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="/.../privkey.pem"
                         certificateFile="/.../cert.pem"
                         certificateChainFile="/.../chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by logo <lo...@kreuser.name>.
Mark,


Am 2019-06-17 16:29, schrieb Mark Thomas:
> On 17/06/2019 15:15, logo wrote:
>> Hi Mark,
>> 
>> having been in contact with Усманов, I can confirm your summary.
>> 
>> May I add my question from February with additional info to this 
>> thread:
>> https://markmail.org/message/zvziqrhm32bctm7e
> 
> Thanks.
> 
> Progress can be tracked here:
> https://bz.apache.org/bugzilla/show_bug.cgi?id=56148
> 
> At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
> OCSP stapling with appropriate configuration.
> 

Do you mean on trunk or really only configuration?

I just tried it on 8.5.42 and it will not send the message on my 
letsencrypt cert.

If it should work out of the box, do you mind to share the "appropriate" 
config here.

Thanks
Peter

> The OpenSSL ones (APR/native, NIO+OpenSSL, NIO2+OpenSSL) do not.
> 
> It might be simply a configuration issue with OpenSSL. It might need
> code changes in APR/Native. I'm currently looking in to that.
> 
> Mark
> 
> 
>> 
>> Thanks.
>> 
>> Peter
>> 
>> Am 2019-06-17 15:44, schrieb Mark Thomas:
>>> Coming back to this as it has been on my TODO list for a while.
>>> 
>>> Having re-read the thread I think it would be helpful to first 
>>> clarify
>>> exactly what behaviour you are expecting and not seeing.
>>> 
>>> The issue relates to OCSP checks when Tomcat is presenting it's 
>>> server
>>> certificate to the client.
>>> 
>>> You are expecting Tomcat to use OCSP stapling to provide the OCSP
>>> information to the client so that the client does not have to request 
>>> it
>>> itself.
>>> 
>>> Tomcat is not providing the OCSP information. It appears that OCSP
>>> stapling is not working.
>>> 
>>> Is the above a fair summary? If not, please provide corrections.
>>> 
>>> Thanks,
>>> 
>>> Mark
>>> 
>>> 
>>> On 27/05/2019 12:36, Усманов Азат Анварович wrote:
>>>> Just a quick follow up , trying to get some answers, I added  
>>>> include
>>>> <stdio.h> to sslutils.c (which has alll the ocsp functions )   to
>>>> print some info.I  added printf calls to every function defined in
>>>> this file.  Interestingly enough  when I issue  the  openssl 
>>>> s_client
>>>> -connect debug.ieml.ru:8443  -tls1_2 -status -proxy 192.168.1.6:3131
>>>> both tls1_2 and tls 1_3  versions and when I access  the server from
>>>> another machine via browser none of printf  calls are displayed, 
>>>> however, when I issue ssllabs server test (which is also supposedly
>>>> capable of detecting ocsp)   some of them start to appear.  sadly
>>>> none of them are ocsp related. I did put basic  ifdef  test for
>>>> HAVE_OCSP_STAPLING, surprisingly  it  shows that ocsp support is
>>>> indeed enabled . So here are  both   the modified  sslutils.c file
>>>> and tomcat log snippet (not sure if attachments are allowed on  the
>>>> list  so posting it  here )
>>>> Not sure where to go from here
>>>> /* Licensed to the Apache Software Foundation (ASF) under one or 
>>>> more
>>>>  * contributor license agreements.  See the NOTICE file distributed 
>>>> with
>>>>  * this work for additional information regarding copyright 
>>>> ownership.
>>>>  * The ASF licenses this file to You under the Apache License,
>>>> Version 2.0
>>>>  * (the "License"); you may not use this file except in compliance 
>>>> with
>>>>  * the License.  You may obtain a copy of the License at
>>>>  *
>>>>  *     http://www.apache.org/licenses/LICENSE-2.0
>>>>  *
>>>>  * Unless required by applicable law or agreed to in writing, 
>>>> software
>>>>  * distributed under the License is distributed on an "AS IS" BASIS,
>>>>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>>> implied.
>>>>  * See the License for the specific language governing permissions 
>>>> and
>>>>  * limitations under the License.
>>>>  */
>>>> 
>>>> /** SSL Utilities
>>>>  */
>>>> 
>>>> #include "tcn.h"
>>>> #include <stdio.h>
>>>> #ifdef HAVE_OPENSSL
>>>> #include "apr_poll.h"
>>>> #include "ssl_private.h"
>>>> 
>>>> 
>>>> #ifdef WIN32
>>>> extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
>>>> #endif
>>>> 
>>>> #ifdef HAVE_OCSP_STAPLING
>>>> #include <openssl/bio.h>
>>>> #include <openssl/ocsp.h>
>>>> /* defines with the values as seen by the asn1parse -dump openssl
>>>> command */
>>>> #define ASN1_SEQUENCE 0x30
>>>> #define ASN1_OID      0x06
>>>> #define ASN1_STRING   0x86
>>>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
>>>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX
>>>> *ctx);
>>>> #endif
>>>> 
>>>> /*  
>>>> _________________________________________________________________
>>>> **
>>>> **  Additional High-Level Functions for OpenSSL
>>>> **  
>>>> _________________________________________________________________
>>>> */
>>>> 
>>>> /* we initialize this index at startup time
>>>>  * and never write to it at request time,
>>>>  * so this static is thread safe.
>>>>  * also note that OpenSSL increments at static variable when
>>>>  * SSL_get_ex_new_index() is called, so we _must_ do this at 
>>>> startup.
>>>>  */
>>>> static int SSL_app_data2_idx = -1;
>>>> static int SSL_app_data3_idx = -1;
>>>> static int SSL_app_data4_idx = -1;
>>>> 
>>>> void SSL_init_app_data_idx(void)
>>>> { printf(" SSL_init_app_data_idx\n");
>>>>    #ifdef HAVE_OCSP_STAPLING
>>>> printf("Hi OCSP \n");
>>>> #else
>>>> printf("Sorry no OCSP support\n");
>>>> #endif
>>>> 
>>>>     int i;
>>>> 
>>>>     if (SSL_app_data2_idx > -1) {
>>>>         return;
>>>>     }
>>>> 
>>>>     /* we _do_ need to call this twice */
>>>>     for (i = 0; i <= 1; i++) {
>>>>         SSL_app_data2_idx =
>>>>             SSL_get_ex_new_index(0,
>>>>                                  "Second Application Data for SSL",
>>>>                                  NULL, NULL, NULL);
>>>>     }
>>>> 
>>>>     if (SSL_app_data3_idx > -1) {
>>>>         return;
>>>>     }
>>>> 
>>>>     SSL_app_data3_idx =
>>>>             SSL_get_ex_new_index(0,
>>>>                                  "Third Application Data for SSL",
>>>>                                   NULL, NULL, NULL);
>>>> 
>>>>     if (SSL_app_data4_idx > -1) {
>>>>         return;
>>>>     }
>>>> 
>>>>     SSL_app_data4_idx =
>>>>             SSL_get_ex_new_index(0,
>>>>                                  "Fourth Application Data for SSL",
>>>>                                   NULL, NULL, NULL);
>>>> 
>>>> }
>>>> 
>>>> void *SSL_get_app_data2(SSL *ssl)
>>>> {
>>>>      printf("ssl_get_app_data2 \n");
>>>>     return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
>>>> }
>>>> 
>>>> void SSL_set_app_data2(SSL *ssl, void *arg)
>>>> {
>>>> printf("ssl_set_app_data2 \n");
>>>> 
>>>>     SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
>>>>     return;
>>>> }
>>>> 
>>>> 
>>>> void *SSL_get_app_data3(const SSL *ssl)
>>>> {
>>>> printf("ssl_get_app_data3 \n");
>>>> 
>>>>     return SSL_get_ex_data(ssl, SSL_app_data3_idx);
>>>> }
>>>> 
>>>> void SSL_set_app_data3(SSL *ssl, void *arg)
>>>> {
>>>> printf("ssl_set_app_data3 \n");
>>>>     SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
>>>> }
>>>> 
>>>> void *SSL_get_app_data4(const SSL *ssl)
>>>> {
>>>> printf("ssl_get_app_data4 \n");
>>>>     return SSL_get_ex_data(ssl, SSL_app_data4_idx);
>>>> }
>>>> 
>>>> void SSL_set_app_data4(SSL *ssl, void *arg)
>>>> {
>>>> printf("ssl_set_app_data4 \n");
>>>>     SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
>>>> }
>>>> 
>>>> /* Simple echo password prompting */
>>>> int SSL_password_prompt(tcn_pass_cb_t *data)
>>>> {
>>>> 
>>>>     printf(" SSL_password_prompt\n");
>>>> int rv = 0;
>>>>     data->password[0] = '\0';
>>>>     if (data->cb.obj) {
>>>>         JNIEnv *e;
>>>>         jobject  o;
>>>>         jstring  prompt;
>>>>         tcn_get_java_env(&e);
>>>>         prompt = AJP_TO_JSTRING(data->prompt);
>>>>         if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
>>>>                             data->cb.mid[0], prompt))) {
>>>>             TCN_ALLOC_CSTRING(o);
>>>>             if (J2S(o)) {
>>>>                 strncpy(data->password, J2S(o), 
>>>> SSL_MAX_PASSWORD_LEN);
>>>>                 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
>>>>                 rv = (int)strlen(data->password);
>>>>             }
>>>>             TCN_FREE_CSTRING(o);
>>>>         }
>>>>     }
>>>>     else {
>>>> #ifdef WIN32
>>>>         rv = WIN32_SSL_password_prompt(data);
>>>> #else
>>>>         EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
>>>>                            data->prompt, 0);
>>>> #endif
>>>>         rv = (int)strlen(data->password);
>>>>     }
>>>>     if (rv > 0) {
>>>>         /* Remove LF char if present */
>>>>         char *r = strchr(data->password, '\n');
>>>>         if (r) {
>>>>             *r = '\0';
>>>>             rv--;
>>>>         }
>>>> #ifdef WIN32
>>>>         if ((r = strchr(data->password, '\r'))) {
>>>>             *r = '\0';
>>>>             rv--;
>>>>         }
>>>> #endif
>>>>     }
>>>>     return rv;
>>>> }
>>>> 
>>>> int SSL_password_callback(char *buf, int bufsiz, int verify,
>>>>                           void *cb)
>>>> {   printf("SSL_password_callback\n");
>>>>     tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;
>>>> 
>>>>     if (buf == NULL)
>>>>         return 0;
>>>>     *buf = '\0';
>>>>     if (cb_data == NULL)
>>>>         cb_data = &tcn_password_callback;
>>>>     if (!cb_data->prompt)
>>>>         cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
>>>>     if (cb_data->password[0]) {
>>>>         /* Return already obtained password */
>>>>         strncpy(buf, cb_data->password, bufsiz);
>>>>         buf[bufsiz - 1] = '\0';
>>>>         return (int)strlen(buf);
>>>>     }
>>>>     else {
>>>>         if (SSL_password_prompt(cb_data) > 0)
>>>>             strncpy(buf, cb_data->password, bufsiz);
>>>>     }
>>>>     buf[bufsiz - 1] = '\0';
>>>>     return (int)strlen(buf);
>>>> }
>>>> 
>>>> /*  
>>>> _________________________________________________________________
>>>> **
>>>> **  Custom (EC)DH parameter support
>>>> **  
>>>> _________________________________________________________________
>>>> */
>>>> DH *SSL_dh_GetParamFromFile(const char *file)
>>>> {
>>>>    printf("SSL_dh_GetParamFromFile\n");
>>>>  DH *dh = NULL;
>>>>     BIO *bio;
>>>> 
>>>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>>>         return NULL;
>>>>     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
>>>>     BIO_free(bio);
>>>>     return dh;
>>>> }
>>>> 
>>>> #ifdef HAVE_ECC
>>>> EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
>>>> {
>>>> 
>>>>    printf("SSL_ec_GetParamFromFile\n");
>>>> EC_GROUP *group = NULL;
>>>>     BIO *bio;
>>>> 
>>>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>>>         return NULL;
>>>>     group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
>>>>     BIO_free(bio);
>>>>     return (group);
>>>> }
>>>> #endif
>>>> 
>>>> /*
>>>>  * Hand out standard DH parameters, based on the authentication 
>>>> strength
>>>>  */
>>>> DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
>>>> {
>>>> printf("SSL_callback_tmp_DH\n");
>>>> EVP_PKEY *pkey = SSL_get_privatekey(ssl);
>>>>     int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : 
>>>> EVP_PKEY_NONE;
>>>> 
>>>>     /*
>>>>      * OpenSSL will call us with either keylen == 512 or keylen == 
>>>> 1024
>>>>      * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
>>>>      * Adjust the DH parameter length according to the size of the
>>>>      * RSA/DSA private key used for the current connection, and 
>>>> always
>>>>      * use at least 1024-bit parameters.
>>>>      * Note: This may cause interoperability issues with 
>>>> implementations
>>>>      * which limit their DH support to 1024 bit - e.g. Java 7 and
>>>> earlier.
>>>>      * In this case, SSLCertificateFile can be used to specify fixed
>>>>      * 1024-bit DH parameters (with the effect that OpenSSL skips 
>>>> this
>>>>      * callback).
>>>>      */
>>>>     if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
>>>>         keylen = EVP_PKEY_bits(pkey);
>>>>     }
>>>>     return SSL_get_dh_params(keylen);
>>>> }
>>>> 
>>>> /*
>>>>  * Read a file that optionally contains the server certificate in 
>>>> PEM
>>>>  * format, possibly followed by a sequence of CA certificates that
>>>>  * should be sent to the peer in the SSL Certificate message.
>>>>  */
>>>> int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
>>>>                                   int skipfirst)
>>>> {
>>>>      printf("SSL_CTX_use_certificate_chain\n");
>>>> 
>>>>     BIO *bio;
>>>>     X509 *x509;
>>>>     unsigned long err;
>>>>     int n;
>>>> 
>>>>     if ((bio = BIO_new(BIO_s_file())) == NULL)
>>>>         return -1;
>>>>     if (BIO_read_filename(bio, file) <= 0) {
>>>>         BIO_free(bio);
>>>>         return -1;
>>>>     }
>>>>     /* optionally skip a leading server certificate */
>>>>     if (skipfirst) {
>>>>         if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == 
>>>> NULL) {
>>>>             BIO_free(bio);
>>>>             return -1;
>>>>         }
>>>>         X509_free(x509);
>>>>     }
>>>> 
>>>>     /* free a perhaps already configured extra chain */
>>>>     SSL_CTX_clear_extra_chain_certs(ctx);
>>>> 
>>>>     /* create new extra chain by loading the certs */
>>>>     n = 0;
>>>>     while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != 
>>>> NULL) {
>>>>         if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
>>>>             X509_free(x509);
>>>>             BIO_free(bio);
>>>>             return -1;
>>>>         }
>>>>         n++;
>>>>     }
>>>>     /* Make sure that only the error is just an EOF */
>>>>     if ((err = ERR_peek_error()) > 0) {
>>>>         if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
>>>>               && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
>>>>             BIO_free(bio);
>>>>             return -1;
>>>>         }
>>>>         while (SSL_ERR_get() > 0) ;
>>>>     }
>>>>     BIO_free(bio);
>>>>     return n;
>>>> }
>>>> 
>>>> /*
>>>>  * This OpenSSL callback function is called when OpenSSL
>>>>  * does client authentication and verifies the certificate chain.
>>>>  */
>>>> 
>>>> 
>>>> int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
>>>> {
>>>>      printf("SSL_callback_SSL_verify\n");
>>>> /* Get Apache context back through OpenSSL context */
>>>>     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
>>>>                                          
>>>> SSL_get_ex_data_X509_STORE_CTX_idx());
>>>>     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>>>>     /* Get verify ingredients */
>>>>     int errnum   = X509_STORE_CTX_get_error(ctx);
>>>>     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
>>>>     int verify   = con->ctx->verify_mode;
>>>>     int depth    = con->ctx->verify_depth;
>>>> 
>>>> #if defined(SSL_OP_NO_TLSv1_3)
>>>>     con->pha_state = PHA_COMPLETE;
>>>> #endif
>>>> 
>>>>     if (verify == SSL_CVERIFY_UNSET ||
>>>>         verify == SSL_CVERIFY_NONE) {
>>>>         return 1;
>>>>     }
>>>> 
>>>>     if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
>>>>         (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
>>>>         ok = 1;
>>>>         SSL_set_verify_result(ssl, X509_V_OK);
>>>>     }
>>>> 
>>>>     /*
>>>>      * Expired certificates vs. "expired" CRLs: by default, OpenSSL
>>>>      * turns X509_V_ERR_CRL_HAS_EXPIRED into a 
>>>> "certificate_expired(45)"
>>>>      * SSL alert, but that's not really the message we should convey
>>>> to the
>>>>      * peer (at the very least, it's confusing, and in many cases,
>>>> it's also
>>>>      * inaccurate, as the certificate itself may very well not have
>>>> expired
>>>>      * yet). We set the X509_STORE_CTX error to something which
>>>> OpenSSL's
>>>>      * s3_both.c:ssl_verify_alarm_type() maps to
>>>> SSL_AD_CERTIFICATE_UNKNOWN,
>>>>      * i.e. the peer will receive a "certificate_unknown(46)" alert.
>>>>      * We do not touch errnum, though, so that later on we will 
>>>> still
>>>> log
>>>>      * the "real" error, as returned by OpenSSL.
>>>>      */
>>>>     if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
>>>>         X509_STORE_CTX_set_error(ctx, -1);
>>>>     }
>>>> 
>>>> #ifdef HAVE_OCSP_STAPLING
>>>>     /* First perform OCSP validation if possible */
>>>>     if (ok) {
>>>>         /* If there was an optional verification error, it's not
>>>>          * possible to perform OCSP validation since the issuer may 
>>>> be
>>>>          * missing/untrusted.  Fail in that case.
>>>>          */
>>>>         if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
>>>>             X509_STORE_CTX_set_error(ctx,
>>>> X509_V_ERR_APPLICATION_VERIFICATION);
>>>>             errnum = X509_V_ERR_APPLICATION_VERIFICATION;
>>>>             ok = 0;
>>>>         }
>>>>         else {
>>>>             int ocsp_response = ssl_verify_OCSP(ctx);
>>>>             if (ocsp_response == OCSP_STATUS_REVOKED) {
>>>>                 ok = 0 ;
>>>>                 errnum = X509_STORE_CTX_get_error(ctx);
>>>>             }
>>>>             else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
>>>>                 /* TODO: do nothing for time being */
>>>>                 ;
>>>>             }
>>>>         }
>>>>     }
>>>> #endif
>>>>     /*
>>>>      * If we already know it's not ok, log the real reason
>>>>      */
>>>>     if (!ok) {
>>>>         /* TODO: Some logging
>>>>          * Certificate Verification: Error
>>>>          */
>>>>         if (con->peer) {
>>>>             X509_free(con->peer);
>>>>             con->peer = NULL;
>>>>         }
>>>>     }
>>>>     if (errdepth > depth) {
>>>>         /* TODO: Some logging
>>>>          * Certificate Verification: Certificate Chain too long
>>>>          */
>>>>         ok = 0;
>>>>     }
>>>>     return ok;
>>>> }
>>>> 
>>>> /*
>>>>  * This callback function is executed while OpenSSL processes the 
>>>> SSL
>>>>  * handshake and does SSL record layer stuff.  It's used to trap
>>>>  * client-initiated renegotiations, and for dumping everything to 
>>>> the
>>>>  * log.
>>>>  */
>>>> void SSL_callback_handshake(const SSL *ssl, int where, int rc)
>>>> {
>>>>          printf("SSL_callback_handshake\n");
>>>>  tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>>>> #ifdef HAVE_TLSV1_3
>>>>     const SSL_SESSION *session = SSL_get_session(ssl);
>>>> #endif
>>>> 
>>>>     /* Retrieve the conn_rec and the associated SSLConnRec. */
>>>>     if (con == NULL) {
>>>>         return;
>>>>     }
>>>> 
>>>> #ifdef HAVE_TLSV1_3
>>>>     /* TLS 1.3 does not use renegotiation so do not update the
>>>> renegotiation
>>>>      * state once we know we are using TLS 1.3. */
>>>>     if (session != NULL) {
>>>>         if (SSL_SESSION_get_protocol_version(session) ==
>>>> TLS1_3_VERSION) {
>>>>             return;
>>>>         }
>>>>     }
>>>> #endif
>>>> 
>>>>     /* If the reneg state is to reject renegotiations, check the SSL
>>>>      * state machine and move to ABORT if a Client Hello is being
>>>>      * read. */
>>>>     if ((where & SSL_CB_HANDSHAKE_START) &&
>>>>          con->reneg_state == RENEG_REJECT) {
>>>>         con->reneg_state = RENEG_ABORT;
>>>>     }
>>>>     /* If the first handshake is complete, change state to reject 
>>>> any
>>>>      * subsequent client-initated renegotiation. */
>>>>     else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state ==
>>>> RENEG_INIT) {
>>>>         con->reneg_state = RENEG_REJECT;
>>>>     }
>>>> }
>>>> 
>>>> int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
>>>>                              unsigned int *len, void *arg)
>>>> {
>>>>       printf("SSL_callback_next_protos\n");
>>>> tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>> 
>>>>     *data = ssl_ctxt->next_proto_data;
>>>>     *len = ssl_ctxt->next_proto_len;
>>>> 
>>>>     return SSL_TLSEXT_ERR_OK;
>>>> }
>>>> 
>>>> /* The code here is inspired by nghttp2
>>>>  *
>>>>  * See
>>>> https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244
>>>> */
>>>> int select_next_proto(SSL *ssl, const unsigned char **out, unsigned
>>>> char *outlen,
>>>>         const unsigned char *in, unsigned int inlen, unsigned char
>>>> *supported_protos,
>>>>         unsigned int supported_protos_len, int failure_behavior) {
>>>>    printf("select_next_proto\n");
>>>> 
>>>>     unsigned int i = 0;
>>>>     unsigned char target_proto_len;
>>>>     const unsigned char *p;
>>>>     const unsigned char *end;
>>>>     const unsigned char *proto;
>>>>     unsigned char proto_len = '\0';
>>>> 
>>>>     while (i < supported_protos_len) {
>>>>         target_proto_len = *supported_protos;
>>>>         ++supported_protos;
>>>> 
>>>>         p = in;
>>>>         end = in + inlen;
>>>> 
>>>>         while (p < end) {
>>>>             proto_len = *p;
>>>>             proto = ++p;
>>>> 
>>>>             if (proto + proto_len <= end && target_proto_len ==
>>>> proto_len &&
>>>>                     memcmp(supported_protos, proto, proto_len) == 0) 
>>>> {
>>>> 
>>>>                 // We found a match, so set the output and return
>>>> with OK!
>>>>                 *out = proto;
>>>>                 *outlen = proto_len;
>>>> 
>>>>                 return SSL_TLSEXT_ERR_OK;
>>>>             }
>>>>             // Move on to the next protocol.
>>>>             p += proto_len;
>>>>         }
>>>> 
>>>>         // increment len and pointers.
>>>>         i += target_proto_len;
>>>>         supported_protos += target_proto_len;
>>>>     }
>>>> 
>>>>     if (supported_protos_len > 0 && inlen > 0 && failure_behavior ==
>>>> SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
>>>>          // There were no match but we just select our last protocol
>>>> and hope the other peer support it.
>>>>          //
>>>>          // decrement the pointer again so the pointer points to the
>>>> start of the protocol.
>>>>          p -= proto_len;
>>>>          *out = p;
>>>>          *outlen = proto_len;
>>>>          return SSL_TLSEXT_ERR_OK;
>>>>     }
>>>>     // TODO: OpenSSL currently not support to fail with fatal error.
>>>> Once this changes we can also support it here.
>>>>     //       Issue https://github.com/openssl/openssl/issues/188 has
>>>> been created for this.
>>>>     // Nothing matched so not select anything and just accept.
>>>>     return SSL_TLSEXT_ERR_NOACK;
>>>> }
>>>> 
>>>> int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out,
>>>> unsigned char *outlen,
>>>>                          const unsigned char *in, unsigned int 
>>>> inlen,
>>>>                          void *arg) {
>>>>     printf("ssl_callback_select_next_proto\n");
>>>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>>     return select_next_proto(ssl, (const unsigned char **) out,
>>>> outlen, in, inlen, ssl_ctxt->next_proto_data,
>>>> ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
>>>> }
>>>> 
>>>> int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char
>>>> **out, unsigned char *outlen,
>>>>         const unsigned char *in, unsigned int inlen, void *arg) {
>>>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>>       printf("ssl_callback_alpn_select_proto\n");
>>>>     return select_next_proto(ssl, out, outlen, in, inlen,
>>>> ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len,
>>>> ssl_ctxt->alpn_selector_failure_behavior);
>>>> }
>>>> #ifdef HAVE_OCSP_STAPLING
>>>> 
>>>> /* Function that is used to do the OCSP verification */
>>>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
>>>> {
>>>>      printf("ssl_verify_OCSP\n");
>>>> 
>>>> X509 *cert, *issuer;
>>>>     int r = OCSP_STATUS_UNKNOWN;
>>>>      printf("Hello, OCSP\n");
>>>>     cert = X509_STORE_CTX_get_current_cert(ctx);
>>>> 
>>>>     if (!cert) {
>>>>        printf("CERT NOT OK\n");
>>>>  /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
>>>>          * may yield NULL. Return early, but leave the ctx error as
>>>> is. */
>>>>         return OCSP_STATUS_UNKNOWN;
>>>>     }
>>>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>>>     else if (cert->valid && X509_check_issued(cert,cert) == 
>>>> X509_V_OK) {
>>>> #else
>>>>     /* No need to check cert->valid, because ssl_verify_OCSP() only
>>>>      * is called if OpenSSL already successfully verified the
>>>> certificate
>>>>      * (parameter "ok" in SSL_callback_SSL_verify() must be true).
>>>>      */
>>>>     else if (X509_check_issued(cert,cert) == X509_V_OK) {
>>>> #endif
>>>>         /* don't do OCSP checking for valid self-issued certs */
>>>>         X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>>>         return OCSP_STATUS_UNKNOWN;
>>>>     }
>>>> 
>>>>     /* if we can't get the issuer, we cannot perform OCSP
>>>> verification */
>>>>     issuer = X509_STORE_CTX_get0_current_issuer(ctx);
>>>>     if (issuer != NULL) {
>>>>         r = ssl_ocsp_request(cert, issuer, ctx);
>>>>         switch (r) {
>>>>         case OCSP_STATUS_OK:
>>>>             X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>>>             break;
>>>>         case OCSP_STATUS_REVOKED:
>>>>             /* we set the error if we know that it is revoked */
>>>>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
>>>>             break;
>>>>         case OCSP_STATUS_UNKNOWN:
>>>>             /* ssl_ocsp_request() sets the error correctly already. 
>>>> */
>>>>             break;
>>>>         }
>>>>     }
>>>>     return r;
>>>> }
>>>> 
>>>> 
>>>> /* Helps with error handling or realloc */
>>>> static void *apr_xrealloc(void *buf, size_t oldlen, size_t len,
>>>> apr_pool_t *p)
>>>> {
>>>>       printf("apr_xrealloc\n");
>>>> void *newp = apr_palloc(p, len);
>>>> 
>>>>     if(newp)
>>>>         memcpy(newp, buf, oldlen);
>>>>     return newp;
>>>> }
>>>> 
>>>> /* Parses an ASN.1 length.
>>>>  * On entry, asn1 points to the current tag.
>>>>  * Updates the pointer to the ASN.1 structure to point to the start
>>>> of the data.
>>>>  * Returns 0 on success, 1 on failure.
>>>>  */
>>>> static int parse_asn1_length(unsigned char **asn1, int *len) {
>>>>   printf("parse_asn1_length\n");
>>>>     /* Length immediately follows tag so increment before reading
>>>> first (and
>>>>      * possibly only) length byte.
>>>>      */
>>>>     (*asn1)++;
>>>> 
>>>>     if (**asn1 & 0x80) {
>>>>         // MSB set. Remaining bits are number of bytes used to store
>>>> the length.
>>>>         int i, l;
>>>> 
>>>>         // How many bytes for this length?
>>>>         i = **asn1 & 0x7F;
>>>> 
>>>>         if (i == 0) {
>>>>             /* This is the indefinite form of length. Since
>>>> certificates use DER
>>>>              * this should never happen and is therefore an error.
>>>>              */
>>>>             return 1;
>>>>         }
>>>>         if (i > 3) {
>>>>             /* Three bytes for length gives a maximum of 16MB which
>>>> should be
>>>>              * far more than is required. (2 bytes is 64K which is
>>>> probably more
>>>>              * than enough but play safe.)
>>>>              */
>>>>             return 1;
>>>>         }
>>>> 
>>>>         // Most significant byte is first
>>>>         l = 0;
>>>>         while (i > 0) {
>>>>             l <<= 8;
>>>>             (*asn1)++;
>>>>             l += **asn1;
>>>>             i--;
>>>>         }
>>>>         *len = l;
>>>>     } else {
>>>>         // Single byte length
>>>>         *len = **asn1;
>>>>     }
>>>> 
>>>>     (*asn1)++;
>>>> 
>>>>     return 0;
>>>> }
>>>> 
>>>> /* parses the ocsp url and updates the ocsp_urls and nocsp_urls
>>>> variables
>>>>    returns 0 on success, 1 on failure */
>>>> static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
>>>>                           int *nocsp_urls, apr_pool_t *p)
>>>> {
>>>>   printf("parse_ocsp_url\n");
>>>>     char **new_ocsp_urls, *ocsp_url;
>>>>     int len, err = 0, new_nocsp_urls;
>>>> 
>>>>     if (*asn1 == ASN1_STRING) {
>>>>         err = parse_asn1_length(&asn1, &len);
>>>> 
>>>>         if (!err) {
>>>>             new_nocsp_urls = *nocsp_urls+1;
>>>>             if ((new_ocsp_urls = 
>>>> apr_xrealloc(*ocsp_urls,*nocsp_urls,
>>>> new_nocsp_urls, p)) == NULL)
>>>>                 err = 1;
>>>>         }
>>>>         if (!err) {
>>>>             *ocsp_urls  = new_ocsp_urls;
>>>>             *nocsp_urls = new_nocsp_urls;
>>>>             *(*ocsp_urls + *nocsp_urls) = NULL;
>>>>             if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
>>>>                 err = 1;
>>>>             }
>>>>             else {
>>>>                 memcpy(ocsp_url, asn1, len);
>>>>                 ocsp_url[len] = '\0';
>>>>                 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
>>>>             }
>>>>         }
>>>>     }
>>>>     return err;
>>>> 
>>>> }
>>>> 
>>>> /* parses the ANS1 OID and if it is an OCSP OID then calls the
>>>> parse_ocsp_url function */
>>>> static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, 
>>>> int
>>>> *nocsp_urls, apr_pool_t *p)
>>>> {
>>>>   printf("PARSE  OCSP_OID\n");
>>>>   int len, err = 0 ;
>>>>     const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
>>>> 0x07, 0x30, 0x01};
>>>> 
>>>>     err = parse_asn1_length(&asn1, &len);
>>>> 
>>>>     if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
>>>>         asn1+=len;
>>>>         err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
>>>>     }
>>>>     return err;
>>>> }
>>>> 
>>>> 
>>>> /* Parses an ASN1 Sequence. It is a recursive function, since if it
>>>> finds a  sequence
>>>>    within the sequence it calls recursively itself. This function
>>>> stops when it finds
>>>>    the end of the ASN1 sequence (marked by '\0'), so if there are
>>>> other sequences within
>>>>    the same sequence the while loop parses the sequences */
>>>> 
>>>> /* This algo was developed with AIA in mind so it was tested only
>>>> with this extension */
>>>> static int parse_ASN1_Sequence(unsigned char *asn1, char 
>>>> ***ocsp_urls,
>>>>                                int *nocsp_urls, apr_pool_t *p)
>>>> {
>>>>      printf("parse_ASN1_Sequence\n");
>>>> 
>>>>  int len = 0 , err = 0;
>>>> 
>>>>     while (!err && *asn1 != '\0') {
>>>>         switch(*asn1) {
>>>>             case ASN1_SEQUENCE:
>>>>                 err = parse_asn1_length(&asn1, &len);
>>>>                 if (!err) {
>>>>                     err = parse_ASN1_Sequence(asn1, ocsp_urls,
>>>> nocsp_urls, p);
>>>>                 }
>>>>             break;
>>>>             case ASN1_OID:
>>>>                 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
>>>>                 return err;
>>>>             break;
>>>>             default:
>>>>                 err = 1; /* we shouldn't have any errors */
>>>>             break;
>>>>         }
>>>>         asn1+=len;
>>>>     }
>>>>     return err;
>>>> }
>>>> 
>>>> /* the main function that gets the ASN1 encoding string and returns
>>>>    a pointer to a NULL terminated "array" of char *, that contains
>>>>    the ocsp_urls */
>>>> static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
>>>> {
>>>>         printf("decode_OCSP_url\n");
>>>> 
>>>> char **response = NULL;
>>>>     unsigned char *ocsp_urls;
>>>>     int len, numofresponses = 0 ;
>>>> 
>>>>     len = ASN1_STRING_length(os);
>>>> 
>>>>     ocsp_urls = apr_palloc(p,  len + 1);
>>>>     memcpy(ocsp_urls,os->data, len);
>>>>     ocsp_urls[len] = '\0';
>>>> 
>>>>     if ((response = apr_pcalloc(p, sizeof(char *))) == NULL)
>>>>         return NULL;
>>>>     if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, 
>>>> p))
>>>>         response = NULL;
>>>>     return response;
>>>> }
>>>> 
>>>> 
>>>> /* stolen from openssl ocsp command */
>>>> static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 
>>>> *issuer)
>>>> {
>>>>       printf("add_ocsp_cert\n");
>>>> OCSP_CERTID *id;
>>>> 
>>>>     if (!issuer)
>>>>         return 0;
>>>>     id = OCSP_cert_to_id(NULL, cert, issuer);
>>>>     if (!id)
>>>>         return 0;
>>>>     if (!OCSP_request_add0_id(req, id)) {
>>>>         OCSP_CERTID_free(id);
>>>>         return 0;
>>>>     } else {
>>>>         /* id will be freed by OCSP_REQUEST_free() */
>>>>         return 1;
>>>>     }
>>>> }
>>>> 
>>>> 
>>>> /* Creates the APR socket and connect to the hostname. Returns the
>>>>    socket or NULL if there is an error.
>>>> */
>>>> static apr_socket_t *make_socket(char *hostname, int port, 
>>>> apr_pool_t
>>>> *mp)
>>>> {
>>>>      printf("*make_socket\n");
>>>> apr_sockaddr_t *sa_in;
>>>>     apr_status_t status;
>>>>     apr_socket_t *sock = NULL;
>>>> 
>>>> 
>>>>     status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port,
>>>> 0, mp);
>>>> 
>>>>     if (status == APR_SUCCESS)
>>>>         status = apr_socket_create(&sock, sa_in->family, 
>>>> SOCK_STREAM,
>>>> APR_PROTO_TCP, mp);
>>>>     if (status == APR_SUCCESS)
>>>>         status = apr_socket_connect(sock, sa_in);
>>>> 
>>>>     if (status == APR_SUCCESS)
>>>>         return sock;
>>>>     return NULL;
>>>> }
>>>> 
>>>> 
>>>> /* Creates the request in a memory BIO in order to send it to the
>>>> OCSP server.
>>>>    Most parts of this function are taken from mod_ssl support for
>>>> OCSP (with some
>>>>    minor modifications
>>>> */
>>>> static BIO *serialize_request(OCSP_REQUEST *req, char *host, int
>>>> port, char *path)
>>>> {
>>>>     printf("serialize_request\n");
>>>> BIO *bio;
>>>>     int len;
>>>> 
>>>>     len = i2d_OCSP_REQUEST(req, NULL);
>>>> 
>>>>     bio = BIO_new(BIO_s_mem());
>>>> 
>>>>     BIO_printf(bio, "POST %s HTTP/1.0\r\n"
>>>>       "Host: %s:%d\r\n"
>>>>       "Content-Type: application/ocsp-request\r\n"
>>>>       "Content-Length: %d\r\n"
>>>>       "\r\n",
>>>>       path, host, port, len);
>>>> 
>>>>     if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
>>>>         BIO_free(bio);
>>>>         return NULL;
>>>>     }
>>>> 
>>>>     return bio;
>>>> }
>>>> 
>>>> 
>>>> /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP
>>>> support */
>>>> static int ocsp_send_req(apr_socket_t *sock, BIO *req)
>>>> {
>>>>     printf("ocsp_send_req\n");
>>>> int len;
>>>>     char buf[TCN_BUFFER_SZ];
>>>>     apr_status_t rv;
>>>> 
>>>>     while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
>>>>         char *wbuf = buf;
>>>>         apr_size_t remain = len;
>>>> 
>>>>         do {
>>>>             apr_size_t wlen = remain;
>>>>             rv = apr_socket_send(sock, wbuf, &wlen);
>>>>             wbuf += remain;
>>>>             remain -= wlen;
>>>>         } while (rv == APR_SUCCESS && remain > 0);
>>>> 
>>>>         if (rv != APR_SUCCESS) {
>>>>             return 0;
>>>>         }
>>>>     }
>>>> 
>>>>     return 1;
>>>> }
>>>> 
>>>> 
>>>> 
>>>> /* Parses the buffer from the response and extracts the OCSP 
>>>> response.
>>>>    Taken from openssl library */
>>>> static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
>>>> {
>>>>  printf("parse_ocsp_resp\n");
>>>>    BIO *mem = NULL;
>>>>     char tmpbuf[1024];
>>>>     OCSP_RESPONSE *resp = NULL;
>>>>     char *p, *q, *r;
>>>>     int retcode;
>>>> 
>>>>     mem = BIO_new(BIO_s_mem());
>>>>     if(mem == NULL)
>>>>         return NULL;
>>>> 
>>>>     BIO_write(mem, buf, len);  /* write the buffer to the bio */
>>>>     if (BIO_gets(mem, tmpbuf, 512) <= 0) {
>>>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>>>        
>>>> OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
>>>> #endif
>>>>         goto err;
>>>>     }
>>>>     /* Parse the HTTP response. This will look like this:
>>>>      * "HTTP/1.0 200 OK". We need to obtain the numeric code and
>>>>      * (optional) informational message.
>>>>      */
>>>> 
>>>>     /* Skip to first white space (passed protocol info) */
>>>>     for (p = tmpbuf; *p && !apr_isspace(*p); p++)
>>>>         continue;
>>>>     if (!*p) {
>>>>         goto err;
>>>>     }
>>>>     /* Skip past white space to start of response code */
>>>>     while (apr_isspace(*p))
>>>>         p++;
>>>>     if (!*p) {
>>>>         goto err;
>>>>     }
>>>>     /* Find end of response code: first whitespace after start of
>>>> code */
>>>>     for (q = p; *q && !apr_isspace(*q); q++)
>>>>         continue;
>>>>     if (!*q) {
>>>>         goto err;
>>>>     }
>>>>     /* Set end of response code and start of message */
>>>>     *q++ = 0;
>>>>     /* Attempt to parse numeric code */
>>>>     retcode = strtoul(p, &r, 10);
>>>>     if (*r)
>>>>         goto err;
>>>>     /* Skip over any leading white space in message */
>>>>     while (apr_isspace(*q))
>>>>         q++;
>>>>     if (*q) {
>>>>         /* Finally zap any trailing white space in message (include
>>>> CRLF) */
>>>>         /* We know q has a non white space character so this is OK 
>>>> */
>>>>         for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
>>>>     }
>>>>     if (retcode != 200) {
>>>>         goto err;
>>>>     }
>>>>     /* Find blank line marking beginning of content */
>>>>     while (BIO_gets(mem, tmpbuf, 512) > 0) {
>>>>         for (p = tmpbuf; apr_isspace(*p); p++)
>>>>             continue;
>>>>         if (!*p)
>>>>             break;
>>>>     }
>>>>     if (*p) {
>>>>         goto err;
>>>>     }
>>>>     if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
>>>>         goto err;
>>>>     }
>>>> err:
>>>>     /* XXX No error logging? */
>>>>     BIO_free(mem);
>>>>     return resp;
>>>> }
>>>> 
>>>> 
>>>> /* Reads the response from the APR socket to a buffer, and parses 
>>>> the
>>>> buffer to
>>>>    return the OCSP response  */
>>>> #define ADDLEN 512
>>>> static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t 
>>>> *sock)
>>>> {
>>>>      printf("ocsp_get_resp\n");
>>>> int buflen;
>>>>     apr_size_t totalread = 0;
>>>>     apr_size_t readlen;
>>>>     char *buf, tmpbuf[ADDLEN];
>>>>     apr_status_t rv = APR_SUCCESS;
>>>>     apr_pool_t *p;
>>>>     OCSP_RESPONSE *resp;
>>>> 
>>>>     apr_pool_create(&p, mp);
>>>>     buflen = ADDLEN;
>>>>     buf = apr_palloc(p, buflen);
>>>>     if (buf == NULL) {
>>>>         apr_pool_destroy(p);
>>>>         return NULL;
>>>>     }
>>>> 
>>>>     while (rv == APR_SUCCESS ) {
>>>>         readlen = sizeof(tmpbuf);
>>>>         rv = apr_socket_recv(sock, tmpbuf, &readlen);
>>>>         if (rv == APR_SUCCESS) { /* if we have read something .. we
>>>> can put it in the buffer*/
>>>>             if ((totalread + readlen) >= buflen) {
>>>>                 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
>>>>                 if (buf == NULL) {
>>>>                     apr_pool_destroy(p);
>>>>                     return NULL;
>>>>                 }
>>>>                 buflen += ADDLEN; /* if needed we enlarge the buffer 
>>>> */
>>>>             }
>>>>             memcpy(buf + totalread, tmpbuf, readlen); /* the copy to
>>>> the buffer */
>>>>             totalread += readlen; /* update the total bytes read */
>>>>         }
>>>>         else {
>>>>             if (rv == APR_EOF && readlen == 0)
>>>>                 ; /* EOF, normal situation */
>>>>             else if (readlen == 0) {
>>>>                 /* Not success, and readlen == 0 .. some error */
>>>>                 apr_pool_destroy(p);
>>>>                 return NULL;
>>>>             }
>>>>         }
>>>>     }
>>>> 
>>>>     resp = parse_ocsp_resp(buf, buflen);
>>>>     apr_pool_destroy(p);
>>>>     return resp;
>>>> }
>>>> 
>>>> /* Creates and OCSP request and returns the OCSP_RESPONSE */
>>>> static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert,
>>>> X509 *issuer, char *url)
>>>> {
>>>>        printf("get_ocsp_response\n");
>>>> OCSP_RESPONSE *ocsp_resp = NULL;
>>>>     OCSP_REQUEST *ocsp_req = NULL;
>>>>     BIO *bio_req;
>>>>     char *hostname, *path, *c_port;
>>>>     int port, use_ssl;
>>>>     int ok = 0;
>>>>     apr_socket_t *apr_sock = NULL;
>>>>     apr_pool_t *mp;
>>>> 
>>>>     if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 
>>>> )
>>>>         goto end;
>>>> 
>>>>     if (sscanf(c_port, "%d", &port) != 1)
>>>>         goto end;
>>>> 
>>>>     /* Create the OCSP request */
>>>>     ocsp_req = OCSP_REQUEST_new();
>>>>     if (ocsp_req == NULL)
>>>>         goto end;
>>>> 
>>>>     if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
>>>>         goto free_req;
>>>> 
>>>>     /* create the BIO with the request to send */
>>>>     bio_req = serialize_request(ocsp_req, hostname, port, path);
>>>>     if (bio_req == NULL) {
>>>>         goto free_req;
>>>>     }
>>>> 
>>>>     apr_pool_create(&mp, p);
>>>>     apr_sock = make_socket(hostname, port, mp);
>>>>     if (apr_sock == NULL) {
>>>>         goto free_bio;
>>>>     }
>>>> 
>>>>     ok = ocsp_send_req(apr_sock, bio_req);
>>>>     if (ok) {
>>>>         ocsp_resp = ocsp_get_resp(mp, apr_sock);
>>>>     }
>>>>     apr_socket_close(apr_sock);
>>>> 
>>>> free_bio:
>>>>     BIO_free(bio_req);
>>>>     apr_pool_destroy(mp);
>>>> 
>>>> free_req:
>>>>     OCSP_REQUEST_free(ocsp_req);
>>>> 
>>>> end:
>>>>     OPENSSL_free(hostname);
>>>>     OPENSSL_free(c_port);
>>>>     OPENSSL_free(path);
>>>> 
>>>>     return ocsp_resp;
>>>> }
>>>> 
>>>> /* Process the OCSP_RESPONSE and returns the corresponding
>>>>    answert according to the status.
>>>> */
>>>> static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509
>>>> *cert, X509 *issuer)
>>>> {
>>>>        printf("process_ocsp_response\n");
>>>> int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
>>>>     OCSP_BASICRESP *bs;
>>>>     OCSP_SINGLERESP *ss;
>>>>     OCSP_CERTID *certid;
>>>> 
>>>>     r = OCSP_response_status(ocsp_resp);
>>>> 
>>>>     if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
>>>>         return OCSP_STATUS_UNKNOWN;
>>>>     }
>>>>     bs = OCSP_response_get1_basic(ocsp_resp);
>>>> 
>>>>     certid = OCSP_cert_to_id(NULL, cert, issuer);
>>>>     if (certid == NULL) {
>>>>         return OCSP_STATUS_UNKNOWN;
>>>>     }
>>>>     ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find
>>>> by serial number and get the matching response */
>>>> 
>>>> 
>>>>     i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
>>>>     if (i == V_OCSP_CERTSTATUS_GOOD)
>>>>         o =  OCSP_STATUS_OK;
>>>>     else if (i == V_OCSP_CERTSTATUS_REVOKED)
>>>>         o = OCSP_STATUS_REVOKED;
>>>>     else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
>>>>         o = OCSP_STATUS_UNKNOWN;
>>>> 
>>>>     /* we clean up */
>>>>     OCSP_CERTID_free(certid);
>>>>     OCSP_BASICRESP_free(bs);
>>>>     return o;
>>>> }
>>>> 
>>>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX
>>>> *ctx)
>>>> {
>>>>      printf("ssl_ocsp_request\n");
>>>>    char **ocsp_urls = NULL;
>>>>     int nid;
>>>>     X509_EXTENSION *ext;
>>>>     ASN1_OCTET_STRING *os;
>>>>     apr_pool_t *p;
>>>> 
>>>>     apr_pool_create(&p, NULL);
>>>> 
>>>>     /* Get the proper extension */
>>>>     nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
>>>>     if (nid >= 0 ) {
>>>>         ext = X509_get_ext(cert,nid);
>>>>         os = X509_EXTENSION_get_data(ext);
>>>> 
>>>>         ocsp_urls = decode_OCSP_url(os, p);
>>>>     }
>>>>      printf("OCSP request\n");
>>>> 
>>>>     /* if we find the extensions and we can parse it check
>>>>        the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
>>>>     if (ocsp_urls != NULL) {
>>>>     printf("ocsp url not null\n");
>>>>         OCSP_RESPONSE *resp;
>>>>         int rv = OCSP_STATUS_UNKNOWN;
>>>>         /* for the time being just check for the fist response .. a
>>>> better
>>>>            approach is to iterate for all the possible ocsp urls */
>>>>         resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
>>>>         if (resp != NULL) {
>>>>             rv = process_ocsp_response(resp, cert, issuer);
>>>>         } else {
>>>>             /* correct error code for application errors? */
>>>>             X509_STORE_CTX_set_error(ctx,
>>>> X509_V_ERR_APPLICATION_VERIFICATION);
>>>>         }
>>>> 
>>>>         if (resp != NULL) {
>>>>             OCSP_RESPONSE_free(resp);
>>>>             apr_pool_destroy(p);
>>>>             return rv;
>>>>         }
>>>>     }
>>>>     apr_pool_destroy(p);
>>>>     return OCSP_STATUS_UNKNOWN;
>>>> }
>>>> 
>>>> #endif /* HAVE_OCSP_STAPLING */
>>>> #endif /* HAVE_OPENSSL  */
>>>> 
>>>> 
>>>> 
>>>> 
>>>> -----------------------------------------tomcat log
>>>> 27-May-2019 14:15:59.727 INFO [main]
>>>> org.apache.catalina.startup.Catalina.start Server startup in 31619 
>>>> ms
>>>>  SSL_init_app_data_idx
>>>> Hi OCSP
>>>> ssl_set_app_data3
>>>> ssl_set_app_data4
>>>> ssl_set_app_data2
>>>> ssl_get_app_data3
>>>> ssl_get_app_data4
>>>> ssl_get_app_data4
>>>> SSL_dh_GetParamFromFile
>>>> SSL_ec_GetParamFromFile
>>>> SSL_CTX_use_certificate_chain
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_next_protos
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_next_protos
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_next_protos
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_next_protos
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_next_protos
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callback_alpn_select_proto
>>>> select_next_proto
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_set_app_data2
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> SSL_callback_handshake
>>>> ssl_callbac
>>>> 
>>>> 
>>>> 
>>>> ________________________________
>>>> От: Усманов Азат Анварович <us...@ieml.ru>
>>>> Отправлено: 24 мая 2019 г. 7:21
>>>> Кому: Tomcat Users List
>>>> Тема: Re: OCSP with openSSL
>>>> 
>>>> 
>>>> 
>>>> Chris,
>>>> Yes the version is the same in
>>>> /usr/local/openssl/bin/openssl as well.
>>>> It is the same version Tomcat uses,I get this info in the logs
>>>> 
>>>> 23-May-2019 12:55:42.145 INFO [main] 
>>>> org.apache.catalina.core.AprLife
>>>> cycleListener.initializeSSL OpenSSL successfully initialized 
>>>> [OpenSSL
>>>> 1.1.1a  20 Nov 2018]
>>>> ________________________________
>>>> От: Christopher Schultz <ch...@christopherschultz.net>
>>>> Отправлено: 23 мая 2019 г. 18:04:29
>>>> Кому: Усманов Азат Анварович
>>>> Тема: Re: OCSP with openSSL
>>>> 
>>>> Азат,
>>>> 
>>>> On 5/22/19 14:02, Усманов Азат Анварович wrote:
>>>>> [root] ~# openssl version
>>>>> OpenSSL 1.1.1a  20 Nov 2018
>>>> 
>>>> Great. Is this also the same version in 
>>>> /usr/local/openssl/bin/openssl?
>>>> 
>>>>> [root] ~# openssl  ocsp -help
>>>>> Usage: ocsp [options]
>>>> 
>>>> Excellent.
>>>> 
>>>> When you launch Tomcat, are you getting a message about the version 
>>>> of
>>>> OpenSSL in use, and does it agree with above?
>>>> 
>>>> AFAIK, OCSP is enabled by default in libtcnative. There were some 
>>>> posts
>>>> a few months/years ago about someone trying to get it to work, and
>>>> having to edit the JVM's security.properties file and all kinds of 
>>>> weird
>>>> stuff. I must admit it didn't make any sense to me at the time. I'm
>>>> sorry, but I don't personally have any experience with dealing with
>>>> OCSP, but hopefully this additio0nal information will give someone 
>>>> else
>>>> some good info.
>>>> 
>>>> -chris
>>>> 
>>>>> ________________________________
>>>>> От: Christopher Schultz <ch...@christopherschultz.net>
>>>>> Отправлено: 22 мая 2019 г. 19:45
>>>>> Кому: users@tomcat.apache.org
>>>>> Тема: Re: OCSP with openSSL
>>>>> 
>>>>> Усманов,
>>>>> 
>>>>> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>>>>>> Mark,  I installed it  just   by  downloading  tcnative src  
>>>>>> tar.gz
>>>>>> file from tomcat  website and issued  ./configure
>>>>>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>>>>>> -with-ssl=/usr/local/openssl && make && make install && make clean
>>>>>> I'm not sure  how to specify any ocsp related configure options
>>>>>> when building tomcat native    from source
>>>>> 
>>>>> What is your OpenSSL version and capabilities?
>>>>> 
>>>>> $ openssl version
>>>>> 
>>>>> $ openssl -help
>>>>> 
>>>>> $ openssl ocsp -help
>>>>> 
>>>>> -chris
>>>>> 
>>>>>> ________________________________ От: Mark Thomas
>>>>>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>>>>>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>>>>> 
>>>>>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>>>>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>>>>>> apr for TLS related issues. I m still unable to have OCSP
>>>>>>> verification working with tomcat.
>>>>> 
>>>>>> <snip/>
>>>>> 
>>>>>>> I have tried running tcpdump on the server but don't' see any
>>>>>>> Comodo related IP addresses in the output when I access the
>>>>>>> server in question in the browser. At this point I don't know
>>>>>>> what else to do, If it was java I would just put some
>>>>>>> System.out.println statements in OCSP SSL related source code and
>>>>>>> recompile the tomcat source, but since in my case tomcat uses
>>>>>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>>>>>> only places I found in the TC-native source that mentions OCSP
>>>>>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>>>>>> gets called in my case. Maybe be someone with more c experience
>>>>>>> c++ would help me with that.  I really want to get to the bottom
>>>>>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>>>>>> based Apache Tomcat Native library [1.2.21] using APR version
>>>>>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>>>>>> Linux RHEL 6.6
>>>>> 
>>>>>> How did you build the Tomcat Native library? Was OCSP enabled?
>>>>> 
>>>>>> Mark
>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>> 
>>>>> 
>>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>> 
>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: users-help@tomcat.apache.org
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by Mark Thomas <ma...@apache.org>.
On 17/06/2019 15:15, logo wrote:
> Hi Mark,
> 
> having been in contact with Усманов, I can confirm your summary.
> 
> May I add my question from February with additional info to this thread:
> https://markmail.org/message/zvziqrhm32bctm7e

Thanks.

Progress can be tracked here:
https://bz.apache.org/bugzilla/show_bug.cgi?id=56148

At the moment, the pure JSSE solutions (NIO+JSSE, NIO2+JSSE) support
OCSP stapling with appropriate configuration.

The OpenSSL ones (APR/native, NIO+OpenSSL, NIO2+OpenSSL) do not.

It might be simply a configuration issue with OpenSSL. It might need
code changes in APR/Native. I'm currently looking in to that.

Mark


> 
> Thanks.
> 
> Peter
> 
> Am 2019-06-17 15:44, schrieb Mark Thomas:
>> Coming back to this as it has been on my TODO list for a while.
>>
>> Having re-read the thread I think it would be helpful to first clarify
>> exactly what behaviour you are expecting and not seeing.
>>
>> The issue relates to OCSP checks when Tomcat is presenting it's server
>> certificate to the client.
>>
>> You are expecting Tomcat to use OCSP stapling to provide the OCSP
>> information to the client so that the client does not have to request it
>> itself.
>>
>> Tomcat is not providing the OCSP information. It appears that OCSP
>> stapling is not working.
>>
>> Is the above a fair summary? If not, please provide corrections.
>>
>> Thanks,
>>
>> Mark
>>
>>
>> On 27/05/2019 12:36, Усманов Азат Анварович wrote:
>>> Just a quick follow up , trying to get some answers, I added  include
>>> <stdio.h> to sslutils.c (which has alll the ocsp functions )   to
>>> print some info.I  added printf calls to every function defined in
>>> this file.  Interestingly enough  when I issue  the  openssl s_client
>>> -connect debug.ieml.ru:8443  -tls1_2 -status -proxy 192.168.1.6:3131
>>> both tls1_2 and tls 1_3  versions and when I access  the server from
>>> another machine via browser none of printf  calls are displayed, 
>>> however, when I issue ssllabs server test (which is also supposedly
>>> capable of detecting ocsp)   some of them start to appear.  sadly
>>> none of them are ocsp related. I did put basic  ifdef  test for
>>> HAVE_OCSP_STAPLING, surprisingly  it  shows that ocsp support is
>>> indeed enabled . So here are  both   the modified  sslutils.c file
>>> and tomcat log snippet (not sure if attachments are allowed on  the
>>> list  so posting it  here )
>>> Not sure where to go from here
>>> /* Licensed to the Apache Software Foundation (ASF) under one or more
>>>  * contributor license agreements.  See the NOTICE file distributed with
>>>  * this work for additional information regarding copyright ownership.
>>>  * The ASF licenses this file to You under the Apache License,
>>> Version 2.0
>>>  * (the "License"); you may not use this file except in compliance with
>>>  * the License.  You may obtain a copy of the License at
>>>  *
>>>  *     http://www.apache.org/licenses/LICENSE-2.0
>>>  *
>>>  * Unless required by applicable law or agreed to in writing, software
>>>  * distributed under the License is distributed on an "AS IS" BASIS,
>>>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>>> implied.
>>>  * See the License for the specific language governing permissions and
>>>  * limitations under the License.
>>>  */
>>>
>>> /** SSL Utilities
>>>  */
>>>
>>> #include "tcn.h"
>>> #include <stdio.h>
>>> #ifdef HAVE_OPENSSL
>>> #include "apr_poll.h"
>>> #include "ssl_private.h"
>>>
>>>
>>> #ifdef WIN32
>>> extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
>>> #endif
>>>
>>> #ifdef HAVE_OCSP_STAPLING
>>> #include <openssl/bio.h>
>>> #include <openssl/ocsp.h>
>>> /* defines with the values as seen by the asn1parse -dump openssl
>>> command */
>>> #define ASN1_SEQUENCE 0x30
>>> #define ASN1_OID      0x06
>>> #define ASN1_STRING   0x86
>>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
>>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX
>>> *ctx);
>>> #endif
>>>
>>> /*  _________________________________________________________________
>>> **
>>> **  Additional High-Level Functions for OpenSSL
>>> **  _________________________________________________________________
>>> */
>>>
>>> /* we initialize this index at startup time
>>>  * and never write to it at request time,
>>>  * so this static is thread safe.
>>>  * also note that OpenSSL increments at static variable when
>>>  * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
>>>  */
>>> static int SSL_app_data2_idx = -1;
>>> static int SSL_app_data3_idx = -1;
>>> static int SSL_app_data4_idx = -1;
>>>
>>> void SSL_init_app_data_idx(void)
>>> { printf(" SSL_init_app_data_idx\n");
>>>    #ifdef HAVE_OCSP_STAPLING
>>> printf("Hi OCSP \n");
>>> #else
>>> printf("Sorry no OCSP support\n");
>>> #endif
>>>
>>>     int i;
>>>
>>>     if (SSL_app_data2_idx > -1) {
>>>         return;
>>>     }
>>>
>>>     /* we _do_ need to call this twice */
>>>     for (i = 0; i <= 1; i++) {
>>>         SSL_app_data2_idx =
>>>             SSL_get_ex_new_index(0,
>>>                                  "Second Application Data for SSL",
>>>                                  NULL, NULL, NULL);
>>>     }
>>>
>>>     if (SSL_app_data3_idx > -1) {
>>>         return;
>>>     }
>>>
>>>     SSL_app_data3_idx =
>>>             SSL_get_ex_new_index(0,
>>>                                  "Third Application Data for SSL",
>>>                                   NULL, NULL, NULL);
>>>
>>>     if (SSL_app_data4_idx > -1) {
>>>         return;
>>>     }
>>>
>>>     SSL_app_data4_idx =
>>>             SSL_get_ex_new_index(0,
>>>                                  "Fourth Application Data for SSL",
>>>                                   NULL, NULL, NULL);
>>>
>>> }
>>>
>>> void *SSL_get_app_data2(SSL *ssl)
>>> {
>>>      printf("ssl_get_app_data2 \n");
>>>     return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
>>> }
>>>
>>> void SSL_set_app_data2(SSL *ssl, void *arg)
>>> {
>>> printf("ssl_set_app_data2 \n");
>>>
>>>     SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
>>>     return;
>>> }
>>>
>>>
>>> void *SSL_get_app_data3(const SSL *ssl)
>>> {
>>> printf("ssl_get_app_data3 \n");
>>>
>>>     return SSL_get_ex_data(ssl, SSL_app_data3_idx);
>>> }
>>>
>>> void SSL_set_app_data3(SSL *ssl, void *arg)
>>> {
>>> printf("ssl_set_app_data3 \n");
>>>     SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
>>> }
>>>
>>> void *SSL_get_app_data4(const SSL *ssl)
>>> {
>>> printf("ssl_get_app_data4 \n");
>>>     return SSL_get_ex_data(ssl, SSL_app_data4_idx);
>>> }
>>>
>>> void SSL_set_app_data4(SSL *ssl, void *arg)
>>> {
>>> printf("ssl_set_app_data4 \n");
>>>     SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
>>> }
>>>
>>> /* Simple echo password prompting */
>>> int SSL_password_prompt(tcn_pass_cb_t *data)
>>> {
>>>
>>>     printf(" SSL_password_prompt\n");
>>> int rv = 0;
>>>     data->password[0] = '\0';
>>>     if (data->cb.obj) {
>>>         JNIEnv *e;
>>>         jobject  o;
>>>         jstring  prompt;
>>>         tcn_get_java_env(&e);
>>>         prompt = AJP_TO_JSTRING(data->prompt);
>>>         if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
>>>                             data->cb.mid[0], prompt))) {
>>>             TCN_ALLOC_CSTRING(o);
>>>             if (J2S(o)) {
>>>                 strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN);
>>>                 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
>>>                 rv = (int)strlen(data->password);
>>>             }
>>>             TCN_FREE_CSTRING(o);
>>>         }
>>>     }
>>>     else {
>>> #ifdef WIN32
>>>         rv = WIN32_SSL_password_prompt(data);
>>> #else
>>>         EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
>>>                            data->prompt, 0);
>>> #endif
>>>         rv = (int)strlen(data->password);
>>>     }
>>>     if (rv > 0) {
>>>         /* Remove LF char if present */
>>>         char *r = strchr(data->password, '\n');
>>>         if (r) {
>>>             *r = '\0';
>>>             rv--;
>>>         }
>>> #ifdef WIN32
>>>         if ((r = strchr(data->password, '\r'))) {
>>>             *r = '\0';
>>>             rv--;
>>>         }
>>> #endif
>>>     }
>>>     return rv;
>>> }
>>>
>>> int SSL_password_callback(char *buf, int bufsiz, int verify,
>>>                           void *cb)
>>> {   printf("SSL_password_callback\n");
>>>     tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;
>>>
>>>     if (buf == NULL)
>>>         return 0;
>>>     *buf = '\0';
>>>     if (cb_data == NULL)
>>>         cb_data = &tcn_password_callback;
>>>     if (!cb_data->prompt)
>>>         cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
>>>     if (cb_data->password[0]) {
>>>         /* Return already obtained password */
>>>         strncpy(buf, cb_data->password, bufsiz);
>>>         buf[bufsiz - 1] = '\0';
>>>         return (int)strlen(buf);
>>>     }
>>>     else {
>>>         if (SSL_password_prompt(cb_data) > 0)
>>>             strncpy(buf, cb_data->password, bufsiz);
>>>     }
>>>     buf[bufsiz - 1] = '\0';
>>>     return (int)strlen(buf);
>>> }
>>>
>>> /*  _________________________________________________________________
>>> **
>>> **  Custom (EC)DH parameter support
>>> **  _________________________________________________________________
>>> */
>>> DH *SSL_dh_GetParamFromFile(const char *file)
>>> {
>>>    printf("SSL_dh_GetParamFromFile\n");
>>>  DH *dh = NULL;
>>>     BIO *bio;
>>>
>>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>>         return NULL;
>>>     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
>>>     BIO_free(bio);
>>>     return dh;
>>> }
>>>
>>> #ifdef HAVE_ECC
>>> EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
>>> {
>>>
>>>    printf("SSL_ec_GetParamFromFile\n");
>>> EC_GROUP *group = NULL;
>>>     BIO *bio;
>>>
>>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>>         return NULL;
>>>     group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
>>>     BIO_free(bio);
>>>     return (group);
>>> }
>>> #endif
>>>
>>> /*
>>>  * Hand out standard DH parameters, based on the authentication strength
>>>  */
>>> DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
>>> {
>>> printf("SSL_callback_tmp_DH\n");
>>> EVP_PKEY *pkey = SSL_get_privatekey(ssl);
>>>     int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
>>>
>>>     /*
>>>      * OpenSSL will call us with either keylen == 512 or keylen == 1024
>>>      * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
>>>      * Adjust the DH parameter length according to the size of the
>>>      * RSA/DSA private key used for the current connection, and always
>>>      * use at least 1024-bit parameters.
>>>      * Note: This may cause interoperability issues with implementations
>>>      * which limit their DH support to 1024 bit - e.g. Java 7 and
>>> earlier.
>>>      * In this case, SSLCertificateFile can be used to specify fixed
>>>      * 1024-bit DH parameters (with the effect that OpenSSL skips this
>>>      * callback).
>>>      */
>>>     if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
>>>         keylen = EVP_PKEY_bits(pkey);
>>>     }
>>>     return SSL_get_dh_params(keylen);
>>> }
>>>
>>> /*
>>>  * Read a file that optionally contains the server certificate in PEM
>>>  * format, possibly followed by a sequence of CA certificates that
>>>  * should be sent to the peer in the SSL Certificate message.
>>>  */
>>> int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
>>>                                   int skipfirst)
>>> {
>>>      printf("SSL_CTX_use_certificate_chain\n");
>>>
>>>     BIO *bio;
>>>     X509 *x509;
>>>     unsigned long err;
>>>     int n;
>>>
>>>     if ((bio = BIO_new(BIO_s_file())) == NULL)
>>>         return -1;
>>>     if (BIO_read_filename(bio, file) <= 0) {
>>>         BIO_free(bio);
>>>         return -1;
>>>     }
>>>     /* optionally skip a leading server certificate */
>>>     if (skipfirst) {
>>>         if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
>>>             BIO_free(bio);
>>>             return -1;
>>>         }
>>>         X509_free(x509);
>>>     }
>>>
>>>     /* free a perhaps already configured extra chain */
>>>     SSL_CTX_clear_extra_chain_certs(ctx);
>>>
>>>     /* create new extra chain by loading the certs */
>>>     n = 0;
>>>     while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
>>>         if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
>>>             X509_free(x509);
>>>             BIO_free(bio);
>>>             return -1;
>>>         }
>>>         n++;
>>>     }
>>>     /* Make sure that only the error is just an EOF */
>>>     if ((err = ERR_peek_error()) > 0) {
>>>         if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
>>>               && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
>>>             BIO_free(bio);
>>>             return -1;
>>>         }
>>>         while (SSL_ERR_get() > 0) ;
>>>     }
>>>     BIO_free(bio);
>>>     return n;
>>> }
>>>
>>> /*
>>>  * This OpenSSL callback function is called when OpenSSL
>>>  * does client authentication and verifies the certificate chain.
>>>  */
>>>
>>>
>>> int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
>>> {
>>>      printf("SSL_callback_SSL_verify\n");
>>> /* Get Apache context back through OpenSSL context */
>>>     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
>>>                                          
>>> SSL_get_ex_data_X509_STORE_CTX_idx());
>>>     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>>>     /* Get verify ingredients */
>>>     int errnum   = X509_STORE_CTX_get_error(ctx);
>>>     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
>>>     int verify   = con->ctx->verify_mode;
>>>     int depth    = con->ctx->verify_depth;
>>>
>>> #if defined(SSL_OP_NO_TLSv1_3)
>>>     con->pha_state = PHA_COMPLETE;
>>> #endif
>>>
>>>     if (verify == SSL_CVERIFY_UNSET ||
>>>         verify == SSL_CVERIFY_NONE) {
>>>         return 1;
>>>     }
>>>
>>>     if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
>>>         (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
>>>         ok = 1;
>>>         SSL_set_verify_result(ssl, X509_V_OK);
>>>     }
>>>
>>>     /*
>>>      * Expired certificates vs. "expired" CRLs: by default, OpenSSL
>>>      * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
>>>      * SSL alert, but that's not really the message we should convey
>>> to the
>>>      * peer (at the very least, it's confusing, and in many cases,
>>> it's also
>>>      * inaccurate, as the certificate itself may very well not have
>>> expired
>>>      * yet). We set the X509_STORE_CTX error to something which
>>> OpenSSL's
>>>      * s3_both.c:ssl_verify_alarm_type() maps to
>>> SSL_AD_CERTIFICATE_UNKNOWN,
>>>      * i.e. the peer will receive a "certificate_unknown(46)" alert.
>>>      * We do not touch errnum, though, so that later on we will still
>>> log
>>>      * the "real" error, as returned by OpenSSL.
>>>      */
>>>     if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
>>>         X509_STORE_CTX_set_error(ctx, -1);
>>>     }
>>>
>>> #ifdef HAVE_OCSP_STAPLING
>>>     /* First perform OCSP validation if possible */
>>>     if (ok) {
>>>         /* If there was an optional verification error, it's not
>>>          * possible to perform OCSP validation since the issuer may be
>>>          * missing/untrusted.  Fail in that case.
>>>          */
>>>         if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
>>>             X509_STORE_CTX_set_error(ctx,
>>> X509_V_ERR_APPLICATION_VERIFICATION);
>>>             errnum = X509_V_ERR_APPLICATION_VERIFICATION;
>>>             ok = 0;
>>>         }
>>>         else {
>>>             int ocsp_response = ssl_verify_OCSP(ctx);
>>>             if (ocsp_response == OCSP_STATUS_REVOKED) {
>>>                 ok = 0 ;
>>>                 errnum = X509_STORE_CTX_get_error(ctx);
>>>             }
>>>             else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
>>>                 /* TODO: do nothing for time being */
>>>                 ;
>>>             }
>>>         }
>>>     }
>>> #endif
>>>     /*
>>>      * If we already know it's not ok, log the real reason
>>>      */
>>>     if (!ok) {
>>>         /* TODO: Some logging
>>>          * Certificate Verification: Error
>>>          */
>>>         if (con->peer) {
>>>             X509_free(con->peer);
>>>             con->peer = NULL;
>>>         }
>>>     }
>>>     if (errdepth > depth) {
>>>         /* TODO: Some logging
>>>          * Certificate Verification: Certificate Chain too long
>>>          */
>>>         ok = 0;
>>>     }
>>>     return ok;
>>> }
>>>
>>> /*
>>>  * This callback function is executed while OpenSSL processes the SSL
>>>  * handshake and does SSL record layer stuff.  It's used to trap
>>>  * client-initiated renegotiations, and for dumping everything to the
>>>  * log.
>>>  */
>>> void SSL_callback_handshake(const SSL *ssl, int where, int rc)
>>> {
>>>          printf("SSL_callback_handshake\n");
>>>  tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>>> #ifdef HAVE_TLSV1_3
>>>     const SSL_SESSION *session = SSL_get_session(ssl);
>>> #endif
>>>
>>>     /* Retrieve the conn_rec and the associated SSLConnRec. */
>>>     if (con == NULL) {
>>>         return;
>>>     }
>>>
>>> #ifdef HAVE_TLSV1_3
>>>     /* TLS 1.3 does not use renegotiation so do not update the
>>> renegotiation
>>>      * state once we know we are using TLS 1.3. */
>>>     if (session != NULL) {
>>>         if (SSL_SESSION_get_protocol_version(session) ==
>>> TLS1_3_VERSION) {
>>>             return;
>>>         }
>>>     }
>>> #endif
>>>
>>>     /* If the reneg state is to reject renegotiations, check the SSL
>>>      * state machine and move to ABORT if a Client Hello is being
>>>      * read. */
>>>     if ((where & SSL_CB_HANDSHAKE_START) &&
>>>          con->reneg_state == RENEG_REJECT) {
>>>         con->reneg_state = RENEG_ABORT;
>>>     }
>>>     /* If the first handshake is complete, change state to reject any
>>>      * subsequent client-initated renegotiation. */
>>>     else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state ==
>>> RENEG_INIT) {
>>>         con->reneg_state = RENEG_REJECT;
>>>     }
>>> }
>>>
>>> int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
>>>                              unsigned int *len, void *arg)
>>> {
>>>       printf("SSL_callback_next_protos\n");
>>> tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>
>>>     *data = ssl_ctxt->next_proto_data;
>>>     *len = ssl_ctxt->next_proto_len;
>>>
>>>     return SSL_TLSEXT_ERR_OK;
>>> }
>>>
>>> /* The code here is inspired by nghttp2
>>>  *
>>>  * See
>>> https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244
>>> */
>>> int select_next_proto(SSL *ssl, const unsigned char **out, unsigned
>>> char *outlen,
>>>         const unsigned char *in, unsigned int inlen, unsigned char
>>> *supported_protos,
>>>         unsigned int supported_protos_len, int failure_behavior) {
>>>    printf("select_next_proto\n");
>>>
>>>     unsigned int i = 0;
>>>     unsigned char target_proto_len;
>>>     const unsigned char *p;
>>>     const unsigned char *end;
>>>     const unsigned char *proto;
>>>     unsigned char proto_len = '\0';
>>>
>>>     while (i < supported_protos_len) {
>>>         target_proto_len = *supported_protos;
>>>         ++supported_protos;
>>>
>>>         p = in;
>>>         end = in + inlen;
>>>
>>>         while (p < end) {
>>>             proto_len = *p;
>>>             proto = ++p;
>>>
>>>             if (proto + proto_len <= end && target_proto_len ==
>>> proto_len &&
>>>                     memcmp(supported_protos, proto, proto_len) == 0) {
>>>
>>>                 // We found a match, so set the output and return
>>> with OK!
>>>                 *out = proto;
>>>                 *outlen = proto_len;
>>>
>>>                 return SSL_TLSEXT_ERR_OK;
>>>             }
>>>             // Move on to the next protocol.
>>>             p += proto_len;
>>>         }
>>>
>>>         // increment len and pointers.
>>>         i += target_proto_len;
>>>         supported_protos += target_proto_len;
>>>     }
>>>
>>>     if (supported_protos_len > 0 && inlen > 0 && failure_behavior ==
>>> SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
>>>          // There were no match but we just select our last protocol
>>> and hope the other peer support it.
>>>          //
>>>          // decrement the pointer again so the pointer points to the
>>> start of the protocol.
>>>          p -= proto_len;
>>>          *out = p;
>>>          *outlen = proto_len;
>>>          return SSL_TLSEXT_ERR_OK;
>>>     }
>>>     // TODO: OpenSSL currently not support to fail with fatal error.
>>> Once this changes we can also support it here.
>>>     //       Issue https://github.com/openssl/openssl/issues/188 has
>>> been created for this.
>>>     // Nothing matched so not select anything and just accept.
>>>     return SSL_TLSEXT_ERR_NOACK;
>>> }
>>>
>>> int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out,
>>> unsigned char *outlen,
>>>                          const unsigned char *in, unsigned int inlen,
>>>                          void *arg) {
>>>     printf("ssl_callback_select_next_proto\n");
>>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>     return select_next_proto(ssl, (const unsigned char **) out,
>>> outlen, in, inlen, ssl_ctxt->next_proto_data,
>>> ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
>>> }
>>>
>>> int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char
>>> **out, unsigned char *outlen,
>>>         const unsigned char *in, unsigned int inlen, void *arg) {
>>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>>       printf("ssl_callback_alpn_select_proto\n");
>>>     return select_next_proto(ssl, out, outlen, in, inlen,
>>> ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len,
>>> ssl_ctxt->alpn_selector_failure_behavior);
>>> }
>>> #ifdef HAVE_OCSP_STAPLING
>>>
>>> /* Function that is used to do the OCSP verification */
>>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
>>> {
>>>      printf("ssl_verify_OCSP\n");
>>>
>>> X509 *cert, *issuer;
>>>     int r = OCSP_STATUS_UNKNOWN;
>>>      printf("Hello, OCSP\n");
>>>     cert = X509_STORE_CTX_get_current_cert(ctx);
>>>
>>>     if (!cert) {
>>>        printf("CERT NOT OK\n");
>>>  /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
>>>          * may yield NULL. Return early, but leave the ctx error as
>>> is. */
>>>         return OCSP_STATUS_UNKNOWN;
>>>     }
>>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>>     else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
>>> #else
>>>     /* No need to check cert->valid, because ssl_verify_OCSP() only
>>>      * is called if OpenSSL already successfully verified the
>>> certificate
>>>      * (parameter "ok" in SSL_callback_SSL_verify() must be true).
>>>      */
>>>     else if (X509_check_issued(cert,cert) == X509_V_OK) {
>>> #endif
>>>         /* don't do OCSP checking for valid self-issued certs */
>>>         X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>>         return OCSP_STATUS_UNKNOWN;
>>>     }
>>>
>>>     /* if we can't get the issuer, we cannot perform OCSP
>>> verification */
>>>     issuer = X509_STORE_CTX_get0_current_issuer(ctx);
>>>     if (issuer != NULL) {
>>>         r = ssl_ocsp_request(cert, issuer, ctx);
>>>         switch (r) {
>>>         case OCSP_STATUS_OK:
>>>             X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>>             break;
>>>         case OCSP_STATUS_REVOKED:
>>>             /* we set the error if we know that it is revoked */
>>>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
>>>             break;
>>>         case OCSP_STATUS_UNKNOWN:
>>>             /* ssl_ocsp_request() sets the error correctly already. */
>>>             break;
>>>         }
>>>     }
>>>     return r;
>>> }
>>>
>>>
>>> /* Helps with error handling or realloc */
>>> static void *apr_xrealloc(void *buf, size_t oldlen, size_t len,
>>> apr_pool_t *p)
>>> {
>>>       printf("apr_xrealloc\n");
>>> void *newp = apr_palloc(p, len);
>>>
>>>     if(newp)
>>>         memcpy(newp, buf, oldlen);
>>>     return newp;
>>> }
>>>
>>> /* Parses an ASN.1 length.
>>>  * On entry, asn1 points to the current tag.
>>>  * Updates the pointer to the ASN.1 structure to point to the start
>>> of the data.
>>>  * Returns 0 on success, 1 on failure.
>>>  */
>>> static int parse_asn1_length(unsigned char **asn1, int *len) {
>>>   printf("parse_asn1_length\n");
>>>     /* Length immediately follows tag so increment before reading
>>> first (and
>>>      * possibly only) length byte.
>>>      */
>>>     (*asn1)++;
>>>
>>>     if (**asn1 & 0x80) {
>>>         // MSB set. Remaining bits are number of bytes used to store
>>> the length.
>>>         int i, l;
>>>
>>>         // How many bytes for this length?
>>>         i = **asn1 & 0x7F;
>>>
>>>         if (i == 0) {
>>>             /* This is the indefinite form of length. Since
>>> certificates use DER
>>>              * this should never happen and is therefore an error.
>>>              */
>>>             return 1;
>>>         }
>>>         if (i > 3) {
>>>             /* Three bytes for length gives a maximum of 16MB which
>>> should be
>>>              * far more than is required. (2 bytes is 64K which is
>>> probably more
>>>              * than enough but play safe.)
>>>              */
>>>             return 1;
>>>         }
>>>
>>>         // Most significant byte is first
>>>         l = 0;
>>>         while (i > 0) {
>>>             l <<= 8;
>>>             (*asn1)++;
>>>             l += **asn1;
>>>             i--;
>>>         }
>>>         *len = l;
>>>     } else {
>>>         // Single byte length
>>>         *len = **asn1;
>>>     }
>>>
>>>     (*asn1)++;
>>>
>>>     return 0;
>>> }
>>>
>>> /* parses the ocsp url and updates the ocsp_urls and nocsp_urls
>>> variables
>>>    returns 0 on success, 1 on failure */
>>> static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
>>>                           int *nocsp_urls, apr_pool_t *p)
>>> {
>>>   printf("parse_ocsp_url\n");
>>>     char **new_ocsp_urls, *ocsp_url;
>>>     int len, err = 0, new_nocsp_urls;
>>>
>>>     if (*asn1 == ASN1_STRING) {
>>>         err = parse_asn1_length(&asn1, &len);
>>>
>>>         if (!err) {
>>>             new_nocsp_urls = *nocsp_urls+1;
>>>             if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls,
>>> new_nocsp_urls, p)) == NULL)
>>>                 err = 1;
>>>         }
>>>         if (!err) {
>>>             *ocsp_urls  = new_ocsp_urls;
>>>             *nocsp_urls = new_nocsp_urls;
>>>             *(*ocsp_urls + *nocsp_urls) = NULL;
>>>             if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
>>>                 err = 1;
>>>             }
>>>             else {
>>>                 memcpy(ocsp_url, asn1, len);
>>>                 ocsp_url[len] = '\0';
>>>                 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
>>>             }
>>>         }
>>>     }
>>>     return err;
>>>
>>> }
>>>
>>> /* parses the ANS1 OID and if it is an OCSP OID then calls the
>>> parse_ocsp_url function */
>>> static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int
>>> *nocsp_urls, apr_pool_t *p)
>>> {
>>>   printf("PARSE  OCSP_OID\n");
>>>   int len, err = 0 ;
>>>     const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
>>> 0x07, 0x30, 0x01};
>>>
>>>     err = parse_asn1_length(&asn1, &len);
>>>
>>>     if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
>>>         asn1+=len;
>>>         err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
>>>     }
>>>     return err;
>>> }
>>>
>>>
>>> /* Parses an ASN1 Sequence. It is a recursive function, since if it
>>> finds a  sequence
>>>    within the sequence it calls recursively itself. This function
>>> stops when it finds
>>>    the end of the ASN1 sequence (marked by '\0'), so if there are
>>> other sequences within
>>>    the same sequence the while loop parses the sequences */
>>>
>>> /* This algo was developed with AIA in mind so it was tested only
>>> with this extension */
>>> static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
>>>                                int *nocsp_urls, apr_pool_t *p)
>>> {
>>>      printf("parse_ASN1_Sequence\n");
>>>
>>>  int len = 0 , err = 0;
>>>
>>>     while (!err && *asn1 != '\0') {
>>>         switch(*asn1) {
>>>             case ASN1_SEQUENCE:
>>>                 err = parse_asn1_length(&asn1, &len);
>>>                 if (!err) {
>>>                     err = parse_ASN1_Sequence(asn1, ocsp_urls,
>>> nocsp_urls, p);
>>>                 }
>>>             break;
>>>             case ASN1_OID:
>>>                 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
>>>                 return err;
>>>             break;
>>>             default:
>>>                 err = 1; /* we shouldn't have any errors */
>>>             break;
>>>         }
>>>         asn1+=len;
>>>     }
>>>     return err;
>>> }
>>>
>>> /* the main function that gets the ASN1 encoding string and returns
>>>    a pointer to a NULL terminated "array" of char *, that contains
>>>    the ocsp_urls */
>>> static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
>>> {
>>>         printf("decode_OCSP_url\n");
>>>
>>> char **response = NULL;
>>>     unsigned char *ocsp_urls;
>>>     int len, numofresponses = 0 ;
>>>
>>>     len = ASN1_STRING_length(os);
>>>
>>>     ocsp_urls = apr_palloc(p,  len + 1);
>>>     memcpy(ocsp_urls,os->data, len);
>>>     ocsp_urls[len] = '\0';
>>>
>>>     if ((response = apr_pcalloc(p, sizeof(char *))) == NULL)
>>>         return NULL;
>>>     if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p))
>>>         response = NULL;
>>>     return response;
>>> }
>>>
>>>
>>> /* stolen from openssl ocsp command */
>>> static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 *issuer)
>>> {
>>>       printf("add_ocsp_cert\n");
>>> OCSP_CERTID *id;
>>>
>>>     if (!issuer)
>>>         return 0;
>>>     id = OCSP_cert_to_id(NULL, cert, issuer);
>>>     if (!id)
>>>         return 0;
>>>     if (!OCSP_request_add0_id(req, id)) {
>>>         OCSP_CERTID_free(id);
>>>         return 0;
>>>     } else {
>>>         /* id will be freed by OCSP_REQUEST_free() */
>>>         return 1;
>>>     }
>>> }
>>>
>>>
>>> /* Creates the APR socket and connect to the hostname. Returns the
>>>    socket or NULL if there is an error.
>>> */
>>> static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t
>>> *mp)
>>> {
>>>      printf("*make_socket\n");
>>> apr_sockaddr_t *sa_in;
>>>     apr_status_t status;
>>>     apr_socket_t *sock = NULL;
>>>
>>>
>>>     status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port,
>>> 0, mp);
>>>
>>>     if (status == APR_SUCCESS)
>>>         status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM,
>>> APR_PROTO_TCP, mp);
>>>     if (status == APR_SUCCESS)
>>>         status = apr_socket_connect(sock, sa_in);
>>>
>>>     if (status == APR_SUCCESS)
>>>         return sock;
>>>     return NULL;
>>> }
>>>
>>>
>>> /* Creates the request in a memory BIO in order to send it to the
>>> OCSP server.
>>>    Most parts of this function are taken from mod_ssl support for
>>> OCSP (with some
>>>    minor modifications
>>> */
>>> static BIO *serialize_request(OCSP_REQUEST *req, char *host, int
>>> port, char *path)
>>> {
>>>     printf("serialize_request\n");
>>> BIO *bio;
>>>     int len;
>>>
>>>     len = i2d_OCSP_REQUEST(req, NULL);
>>>
>>>     bio = BIO_new(BIO_s_mem());
>>>
>>>     BIO_printf(bio, "POST %s HTTP/1.0\r\n"
>>>       "Host: %s:%d\r\n"
>>>       "Content-Type: application/ocsp-request\r\n"
>>>       "Content-Length: %d\r\n"
>>>       "\r\n",
>>>       path, host, port, len);
>>>
>>>     if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
>>>         BIO_free(bio);
>>>         return NULL;
>>>     }
>>>
>>>     return bio;
>>> }
>>>
>>>
>>> /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP
>>> support */
>>> static int ocsp_send_req(apr_socket_t *sock, BIO *req)
>>> {
>>>     printf("ocsp_send_req\n");
>>> int len;
>>>     char buf[TCN_BUFFER_SZ];
>>>     apr_status_t rv;
>>>
>>>     while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
>>>         char *wbuf = buf;
>>>         apr_size_t remain = len;
>>>
>>>         do {
>>>             apr_size_t wlen = remain;
>>>             rv = apr_socket_send(sock, wbuf, &wlen);
>>>             wbuf += remain;
>>>             remain -= wlen;
>>>         } while (rv == APR_SUCCESS && remain > 0);
>>>
>>>         if (rv != APR_SUCCESS) {
>>>             return 0;
>>>         }
>>>     }
>>>
>>>     return 1;
>>> }
>>>
>>>
>>>
>>> /* Parses the buffer from the response and extracts the OCSP response.
>>>    Taken from openssl library */
>>> static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
>>> {
>>>  printf("parse_ocsp_resp\n");
>>>    BIO *mem = NULL;
>>>     char tmpbuf[1024];
>>>     OCSP_RESPONSE *resp = NULL;
>>>     char *p, *q, *r;
>>>     int retcode;
>>>
>>>     mem = BIO_new(BIO_s_mem());
>>>     if(mem == NULL)
>>>         return NULL;
>>>
>>>     BIO_write(mem, buf, len);  /* write the buffer to the bio */
>>>     if (BIO_gets(mem, tmpbuf, 512) <= 0) {
>>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>>        
>>> OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
>>> #endif
>>>         goto err;
>>>     }
>>>     /* Parse the HTTP response. This will look like this:
>>>      * "HTTP/1.0 200 OK". We need to obtain the numeric code and
>>>      * (optional) informational message.
>>>      */
>>>
>>>     /* Skip to first white space (passed protocol info) */
>>>     for (p = tmpbuf; *p && !apr_isspace(*p); p++)
>>>         continue;
>>>     if (!*p) {
>>>         goto err;
>>>     }
>>>     /* Skip past white space to start of response code */
>>>     while (apr_isspace(*p))
>>>         p++;
>>>     if (!*p) {
>>>         goto err;
>>>     }
>>>     /* Find end of response code: first whitespace after start of
>>> code */
>>>     for (q = p; *q && !apr_isspace(*q); q++)
>>>         continue;
>>>     if (!*q) {
>>>         goto err;
>>>     }
>>>     /* Set end of response code and start of message */
>>>     *q++ = 0;
>>>     /* Attempt to parse numeric code */
>>>     retcode = strtoul(p, &r, 10);
>>>     if (*r)
>>>         goto err;
>>>     /* Skip over any leading white space in message */
>>>     while (apr_isspace(*q))
>>>         q++;
>>>     if (*q) {
>>>         /* Finally zap any trailing white space in message (include
>>> CRLF) */
>>>         /* We know q has a non white space character so this is OK */
>>>         for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
>>>     }
>>>     if (retcode != 200) {
>>>         goto err;
>>>     }
>>>     /* Find blank line marking beginning of content */
>>>     while (BIO_gets(mem, tmpbuf, 512) > 0) {
>>>         for (p = tmpbuf; apr_isspace(*p); p++)
>>>             continue;
>>>         if (!*p)
>>>             break;
>>>     }
>>>     if (*p) {
>>>         goto err;
>>>     }
>>>     if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
>>>         goto err;
>>>     }
>>> err:
>>>     /* XXX No error logging? */
>>>     BIO_free(mem);
>>>     return resp;
>>> }
>>>
>>>
>>> /* Reads the response from the APR socket to a buffer, and parses the
>>> buffer to
>>>    return the OCSP response  */
>>> #define ADDLEN 512
>>> static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t *sock)
>>> {
>>>      printf("ocsp_get_resp\n");
>>> int buflen;
>>>     apr_size_t totalread = 0;
>>>     apr_size_t readlen;
>>>     char *buf, tmpbuf[ADDLEN];
>>>     apr_status_t rv = APR_SUCCESS;
>>>     apr_pool_t *p;
>>>     OCSP_RESPONSE *resp;
>>>
>>>     apr_pool_create(&p, mp);
>>>     buflen = ADDLEN;
>>>     buf = apr_palloc(p, buflen);
>>>     if (buf == NULL) {
>>>         apr_pool_destroy(p);
>>>         return NULL;
>>>     }
>>>
>>>     while (rv == APR_SUCCESS ) {
>>>         readlen = sizeof(tmpbuf);
>>>         rv = apr_socket_recv(sock, tmpbuf, &readlen);
>>>         if (rv == APR_SUCCESS) { /* if we have read something .. we
>>> can put it in the buffer*/
>>>             if ((totalread + readlen) >= buflen) {
>>>                 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
>>>                 if (buf == NULL) {
>>>                     apr_pool_destroy(p);
>>>                     return NULL;
>>>                 }
>>>                 buflen += ADDLEN; /* if needed we enlarge the buffer */
>>>             }
>>>             memcpy(buf + totalread, tmpbuf, readlen); /* the copy to
>>> the buffer */
>>>             totalread += readlen; /* update the total bytes read */
>>>         }
>>>         else {
>>>             if (rv == APR_EOF && readlen == 0)
>>>                 ; /* EOF, normal situation */
>>>             else if (readlen == 0) {
>>>                 /* Not success, and readlen == 0 .. some error */
>>>                 apr_pool_destroy(p);
>>>                 return NULL;
>>>             }
>>>         }
>>>     }
>>>
>>>     resp = parse_ocsp_resp(buf, buflen);
>>>     apr_pool_destroy(p);
>>>     return resp;
>>> }
>>>
>>> /* Creates and OCSP request and returns the OCSP_RESPONSE */
>>> static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert,
>>> X509 *issuer, char *url)
>>> {
>>>        printf("get_ocsp_response\n");
>>> OCSP_RESPONSE *ocsp_resp = NULL;
>>>     OCSP_REQUEST *ocsp_req = NULL;
>>>     BIO *bio_req;
>>>     char *hostname, *path, *c_port;
>>>     int port, use_ssl;
>>>     int ok = 0;
>>>     apr_socket_t *apr_sock = NULL;
>>>     apr_pool_t *mp;
>>>
>>>     if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 )
>>>         goto end;
>>>
>>>     if (sscanf(c_port, "%d", &port) != 1)
>>>         goto end;
>>>
>>>     /* Create the OCSP request */
>>>     ocsp_req = OCSP_REQUEST_new();
>>>     if (ocsp_req == NULL)
>>>         goto end;
>>>
>>>     if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
>>>         goto free_req;
>>>
>>>     /* create the BIO with the request to send */
>>>     bio_req = serialize_request(ocsp_req, hostname, port, path);
>>>     if (bio_req == NULL) {
>>>         goto free_req;
>>>     }
>>>
>>>     apr_pool_create(&mp, p);
>>>     apr_sock = make_socket(hostname, port, mp);
>>>     if (apr_sock == NULL) {
>>>         goto free_bio;
>>>     }
>>>
>>>     ok = ocsp_send_req(apr_sock, bio_req);
>>>     if (ok) {
>>>         ocsp_resp = ocsp_get_resp(mp, apr_sock);
>>>     }
>>>     apr_socket_close(apr_sock);
>>>
>>> free_bio:
>>>     BIO_free(bio_req);
>>>     apr_pool_destroy(mp);
>>>
>>> free_req:
>>>     OCSP_REQUEST_free(ocsp_req);
>>>
>>> end:
>>>     OPENSSL_free(hostname);
>>>     OPENSSL_free(c_port);
>>>     OPENSSL_free(path);
>>>
>>>     return ocsp_resp;
>>> }
>>>
>>> /* Process the OCSP_RESPONSE and returns the corresponding
>>>    answert according to the status.
>>> */
>>> static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509
>>> *cert, X509 *issuer)
>>> {
>>>        printf("process_ocsp_response\n");
>>> int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
>>>     OCSP_BASICRESP *bs;
>>>     OCSP_SINGLERESP *ss;
>>>     OCSP_CERTID *certid;
>>>
>>>     r = OCSP_response_status(ocsp_resp);
>>>
>>>     if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
>>>         return OCSP_STATUS_UNKNOWN;
>>>     }
>>>     bs = OCSP_response_get1_basic(ocsp_resp);
>>>
>>>     certid = OCSP_cert_to_id(NULL, cert, issuer);
>>>     if (certid == NULL) {
>>>         return OCSP_STATUS_UNKNOWN;
>>>     }
>>>     ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find
>>> by serial number and get the matching response */
>>>
>>>
>>>     i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
>>>     if (i == V_OCSP_CERTSTATUS_GOOD)
>>>         o =  OCSP_STATUS_OK;
>>>     else if (i == V_OCSP_CERTSTATUS_REVOKED)
>>>         o = OCSP_STATUS_REVOKED;
>>>     else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
>>>         o = OCSP_STATUS_UNKNOWN;
>>>
>>>     /* we clean up */
>>>     OCSP_CERTID_free(certid);
>>>     OCSP_BASICRESP_free(bs);
>>>     return o;
>>> }
>>>
>>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX
>>> *ctx)
>>> {
>>>      printf("ssl_ocsp_request\n");
>>>    char **ocsp_urls = NULL;
>>>     int nid;
>>>     X509_EXTENSION *ext;
>>>     ASN1_OCTET_STRING *os;
>>>     apr_pool_t *p;
>>>
>>>     apr_pool_create(&p, NULL);
>>>
>>>     /* Get the proper extension */
>>>     nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
>>>     if (nid >= 0 ) {
>>>         ext = X509_get_ext(cert,nid);
>>>         os = X509_EXTENSION_get_data(ext);
>>>
>>>         ocsp_urls = decode_OCSP_url(os, p);
>>>     }
>>>      printf("OCSP request\n");
>>>
>>>     /* if we find the extensions and we can parse it check
>>>        the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
>>>     if (ocsp_urls != NULL) {
>>>     printf("ocsp url not null\n");
>>>         OCSP_RESPONSE *resp;
>>>         int rv = OCSP_STATUS_UNKNOWN;
>>>         /* for the time being just check for the fist response .. a
>>> better
>>>            approach is to iterate for all the possible ocsp urls */
>>>         resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
>>>         if (resp != NULL) {
>>>             rv = process_ocsp_response(resp, cert, issuer);
>>>         } else {
>>>             /* correct error code for application errors? */
>>>             X509_STORE_CTX_set_error(ctx,
>>> X509_V_ERR_APPLICATION_VERIFICATION);
>>>         }
>>>
>>>         if (resp != NULL) {
>>>             OCSP_RESPONSE_free(resp);
>>>             apr_pool_destroy(p);
>>>             return rv;
>>>         }
>>>     }
>>>     apr_pool_destroy(p);
>>>     return OCSP_STATUS_UNKNOWN;
>>> }
>>>
>>> #endif /* HAVE_OCSP_STAPLING */
>>> #endif /* HAVE_OPENSSL  */
>>>
>>>
>>>
>>>
>>> -----------------------------------------tomcat log
>>> 27-May-2019 14:15:59.727 INFO [main]
>>> org.apache.catalina.startup.Catalina.start Server startup in 31619 ms
>>>  SSL_init_app_data_idx
>>> Hi OCSP
>>> ssl_set_app_data3
>>> ssl_set_app_data4
>>> ssl_set_app_data2
>>> ssl_get_app_data3
>>> ssl_get_app_data4
>>> ssl_get_app_data4
>>> SSL_dh_GetParamFromFile
>>> SSL_ec_GetParamFromFile
>>> SSL_CTX_use_certificate_chain
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_next_protos
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_next_protos
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_next_protos
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_next_protos
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_next_protos
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callback_alpn_select_proto
>>> select_next_proto
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_set_app_data2
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> SSL_callback_handshake
>>> ssl_callbac
>>>
>>>
>>>
>>> ________________________________
>>> От: Усманов Азат Анварович <us...@ieml.ru>
>>> Отправлено: 24 мая 2019 г. 7:21
>>> Кому: Tomcat Users List
>>> Тема: Re: OCSP with openSSL
>>>
>>>
>>>
>>> Chris,
>>> Yes the version is the same in
>>> /usr/local/openssl/bin/openssl as well.
>>> It is the same version Tomcat uses,I get this info in the logs
>>>
>>> 23-May-2019 12:55:42.145 INFO [main] org.apache.catalina.core.AprLife
>>> cycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL
>>> 1.1.1a  20 Nov 2018]
>>> ________________________________
>>> От: Christopher Schultz <ch...@christopherschultz.net>
>>> Отправлено: 23 мая 2019 г. 18:04:29
>>> Кому: Усманов Азат Анварович
>>> Тема: Re: OCSP with openSSL
>>>
>>> Азат,
>>>
>>> On 5/22/19 14:02, Усманов Азат Анварович wrote:
>>>> [root] ~# openssl version
>>>> OpenSSL 1.1.1a  20 Nov 2018
>>>
>>> Great. Is this also the same version in /usr/local/openssl/bin/openssl?
>>>
>>>> [root] ~# openssl  ocsp -help
>>>> Usage: ocsp [options]
>>>
>>> Excellent.
>>>
>>> When you launch Tomcat, are you getting a message about the version of
>>> OpenSSL in use, and does it agree with above?
>>>
>>> AFAIK, OCSP is enabled by default in libtcnative. There were some posts
>>> a few months/years ago about someone trying to get it to work, and
>>> having to edit the JVM's security.properties file and all kinds of weird
>>> stuff. I must admit it didn't make any sense to me at the time. I'm
>>> sorry, but I don't personally have any experience with dealing with
>>> OCSP, but hopefully this additio0nal information will give someone else
>>> some good info.
>>>
>>> -chris
>>>
>>>> ________________________________
>>>> От: Christopher Schultz <ch...@christopherschultz.net>
>>>> Отправлено: 22 мая 2019 г. 19:45
>>>> Кому: users@tomcat.apache.org
>>>> Тема: Re: OCSP with openSSL
>>>>
>>>> Усманов,
>>>>
>>>> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>>>>> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
>>>>> file from tomcat  website and issued  ./configure
>>>>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>>>>> -with-ssl=/usr/local/openssl && make && make install && make clean
>>>>> I'm not sure  how to specify any ocsp related configure options
>>>>> when building tomcat native    from source
>>>>
>>>> What is your OpenSSL version and capabilities?
>>>>
>>>> $ openssl version
>>>>
>>>> $ openssl -help
>>>>
>>>> $ openssl ocsp -help
>>>>
>>>> -chris
>>>>
>>>>> ________________________________ От: Mark Thomas
>>>>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>>>>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>>>>
>>>>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>>>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>>>>> apr for TLS related issues. I m still unable to have OCSP
>>>>>> verification working with tomcat.
>>>>
>>>>> <snip/>
>>>>
>>>>>> I have tried running tcpdump on the server but don't' see any
>>>>>> Comodo related IP addresses in the output when I access the
>>>>>> server in question in the browser. At this point I don't know
>>>>>> what else to do, If it was java I would just put some
>>>>>> System.out.println statements in OCSP SSL related source code and
>>>>>> recompile the tomcat source, but since in my case tomcat uses
>>>>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>>>>> only places I found in the TC-native source that mentions OCSP
>>>>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>>>>> gets called in my case. Maybe be someone with more c experience
>>>>>> c++ would help me with that.  I really want to get to the bottom
>>>>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>>>>> based Apache Tomcat Native library [1.2.21] using APR version
>>>>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>>>>> Linux RHEL 6.6
>>>>
>>>>> How did you build the Tomcat Native library? Was OCSP enabled?
>>>>
>>>>> Mark
>>>>
>>>>> ---------------------------------------------------------------------
>>>>
>>>>
>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>>>
>>>>
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by logo <lo...@kreuser.name>.
Hi Mark,

having been in contact with Усманов, I can confirm your summary.

May I add my question from February with additional info to this thread:
https://markmail.org/message/zvziqrhm32bctm7e

Thanks.

Peter

Am 2019-06-17 15:44, schrieb Mark Thomas:
> Coming back to this as it has been on my TODO list for a while.
> 
> Having re-read the thread I think it would be helpful to first clarify
> exactly what behaviour you are expecting and not seeing.
> 
> The issue relates to OCSP checks when Tomcat is presenting it's server
> certificate to the client.
> 
> You are expecting Tomcat to use OCSP stapling to provide the OCSP
> information to the client so that the client does not have to request 
> it
> itself.
> 
> Tomcat is not providing the OCSP information. It appears that OCSP
> stapling is not working.
> 
> Is the above a fair summary? If not, please provide corrections.
> 
> Thanks,
> 
> Mark
> 
> 
> On 27/05/2019 12:36, Усманов Азат Анварович wrote:
>> Just a quick follow up , trying to get some answers, I added  include 
>> <stdio.h> to sslutils.c (which has alll the ocsp functions )   to 
>> print some info.I  added printf calls to every function defined in 
>> this file.  Interestingly enough  when I issue  the  openssl s_client 
>> -connect debug.ieml.ru:8443  -tls1_2 -status -proxy 192.168.1.6:3131
>> both tls1_2 and tls 1_3  versions and when I access  the server from 
>> another machine via browser none of printf  calls are displayed,  
>> however, when I issue ssllabs server test (which is also supposedly 
>> capable of detecting ocsp)   some of them start to appear.  sadly none 
>> of them are ocsp related. I did put basic  ifdef  test for 
>> HAVE_OCSP_STAPLING, surprisingly  it  shows that ocsp support is 
>> indeed enabled . So here are  both   the modified  sslutils.c file and 
>> tomcat log snippet (not sure if attachments are allowed on  the list  
>> so posting it  here )
>> Not sure where to go from here
>> /* Licensed to the Apache Software Foundation (ASF) under one or more
>>  * contributor license agreements.  See the NOTICE file distributed 
>> with
>>  * this work for additional information regarding copyright ownership.
>>  * The ASF licenses this file to You under the Apache License, Version 
>> 2.0
>>  * (the "License"); you may not use this file except in compliance 
>> with
>>  * the License.  You may obtain a copy of the License at
>>  *
>>  *     http://www.apache.org/licenses/LICENSE-2.0
>>  *
>>  * Unless required by applicable law or agreed to in writing, software
>>  * distributed under the License is distributed on an "AS IS" BASIS,
>>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>>  * See the License for the specific language governing permissions and
>>  * limitations under the License.
>>  */
>> 
>> /** SSL Utilities
>>  */
>> 
>> #include "tcn.h"
>> #include <stdio.h>
>> #ifdef HAVE_OPENSSL
>> #include "apr_poll.h"
>> #include "ssl_private.h"
>> 
>> 
>> #ifdef WIN32
>> extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
>> #endif
>> 
>> #ifdef HAVE_OCSP_STAPLING
>> #include <openssl/bio.h>
>> #include <openssl/ocsp.h>
>> /* defines with the values as seen by the asn1parse -dump openssl 
>> command */
>> #define ASN1_SEQUENCE 0x30
>> #define ASN1_OID      0x06
>> #define ASN1_STRING   0x86
>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX 
>> *ctx);
>> #endif
>> 
>> /*  _________________________________________________________________
>> **
>> **  Additional High-Level Functions for OpenSSL
>> **  _________________________________________________________________
>> */
>> 
>> /* we initialize this index at startup time
>>  * and never write to it at request time,
>>  * so this static is thread safe.
>>  * also note that OpenSSL increments at static variable when
>>  * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
>>  */
>> static int SSL_app_data2_idx = -1;
>> static int SSL_app_data3_idx = -1;
>> static int SSL_app_data4_idx = -1;
>> 
>> void SSL_init_app_data_idx(void)
>> { printf(" SSL_init_app_data_idx\n");
>>    #ifdef HAVE_OCSP_STAPLING
>> printf("Hi OCSP \n");
>> #else
>> printf("Sorry no OCSP support\n");
>> #endif
>> 
>>     int i;
>> 
>>     if (SSL_app_data2_idx > -1) {
>>         return;
>>     }
>> 
>>     /* we _do_ need to call this twice */
>>     for (i = 0; i <= 1; i++) {
>>         SSL_app_data2_idx =
>>             SSL_get_ex_new_index(0,
>>                                  "Second Application Data for SSL",
>>                                  NULL, NULL, NULL);
>>     }
>> 
>>     if (SSL_app_data3_idx > -1) {
>>         return;
>>     }
>> 
>>     SSL_app_data3_idx =
>>             SSL_get_ex_new_index(0,
>>                                  "Third Application Data for SSL",
>>                                   NULL, NULL, NULL);
>> 
>>     if (SSL_app_data4_idx > -1) {
>>         return;
>>     }
>> 
>>     SSL_app_data4_idx =
>>             SSL_get_ex_new_index(0,
>>                                  "Fourth Application Data for SSL",
>>                                   NULL, NULL, NULL);
>> 
>> }
>> 
>> void *SSL_get_app_data2(SSL *ssl)
>> {
>>      printf("ssl_get_app_data2 \n");
>>     return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
>> }
>> 
>> void SSL_set_app_data2(SSL *ssl, void *arg)
>> {
>> printf("ssl_set_app_data2 \n");
>> 
>>     SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
>>     return;
>> }
>> 
>> 
>> void *SSL_get_app_data3(const SSL *ssl)
>> {
>> printf("ssl_get_app_data3 \n");
>> 
>>     return SSL_get_ex_data(ssl, SSL_app_data3_idx);
>> }
>> 
>> void SSL_set_app_data3(SSL *ssl, void *arg)
>> {
>> printf("ssl_set_app_data3 \n");
>>     SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
>> }
>> 
>> void *SSL_get_app_data4(const SSL *ssl)
>> {
>> printf("ssl_get_app_data4 \n");
>>     return SSL_get_ex_data(ssl, SSL_app_data4_idx);
>> }
>> 
>> void SSL_set_app_data4(SSL *ssl, void *arg)
>> {
>> printf("ssl_set_app_data4 \n");
>>     SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
>> }
>> 
>> /* Simple echo password prompting */
>> int SSL_password_prompt(tcn_pass_cb_t *data)
>> {
>> 
>>     printf(" SSL_password_prompt\n");
>> int rv = 0;
>>     data->password[0] = '\0';
>>     if (data->cb.obj) {
>>         JNIEnv *e;
>>         jobject  o;
>>         jstring  prompt;
>>         tcn_get_java_env(&e);
>>         prompt = AJP_TO_JSTRING(data->prompt);
>>         if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
>>                             data->cb.mid[0], prompt))) {
>>             TCN_ALLOC_CSTRING(o);
>>             if (J2S(o)) {
>>                 strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN);
>>                 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
>>                 rv = (int)strlen(data->password);
>>             }
>>             TCN_FREE_CSTRING(o);
>>         }
>>     }
>>     else {
>> #ifdef WIN32
>>         rv = WIN32_SSL_password_prompt(data);
>> #else
>>         EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
>>                            data->prompt, 0);
>> #endif
>>         rv = (int)strlen(data->password);
>>     }
>>     if (rv > 0) {
>>         /* Remove LF char if present */
>>         char *r = strchr(data->password, '\n');
>>         if (r) {
>>             *r = '\0';
>>             rv--;
>>         }
>> #ifdef WIN32
>>         if ((r = strchr(data->password, '\r'))) {
>>             *r = '\0';
>>             rv--;
>>         }
>> #endif
>>     }
>>     return rv;
>> }
>> 
>> int SSL_password_callback(char *buf, int bufsiz, int verify,
>>                           void *cb)
>> {   printf("SSL_password_callback\n");
>>     tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;
>> 
>>     if (buf == NULL)
>>         return 0;
>>     *buf = '\0';
>>     if (cb_data == NULL)
>>         cb_data = &tcn_password_callback;
>>     if (!cb_data->prompt)
>>         cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
>>     if (cb_data->password[0]) {
>>         /* Return already obtained password */
>>         strncpy(buf, cb_data->password, bufsiz);
>>         buf[bufsiz - 1] = '\0';
>>         return (int)strlen(buf);
>>     }
>>     else {
>>         if (SSL_password_prompt(cb_data) > 0)
>>             strncpy(buf, cb_data->password, bufsiz);
>>     }
>>     buf[bufsiz - 1] = '\0';
>>     return (int)strlen(buf);
>> }
>> 
>> /*  _________________________________________________________________
>> **
>> **  Custom (EC)DH parameter support
>> **  _________________________________________________________________
>> */
>> DH *SSL_dh_GetParamFromFile(const char *file)
>> {
>>    printf("SSL_dh_GetParamFromFile\n");
>>  DH *dh = NULL;
>>     BIO *bio;
>> 
>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>         return NULL;
>>     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
>>     BIO_free(bio);
>>     return dh;
>> }
>> 
>> #ifdef HAVE_ECC
>> EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
>> {
>> 
>>    printf("SSL_ec_GetParamFromFile\n");
>> EC_GROUP *group = NULL;
>>     BIO *bio;
>> 
>>     if ((bio = BIO_new_file(file, "r")) == NULL)
>>         return NULL;
>>     group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
>>     BIO_free(bio);
>>     return (group);
>> }
>> #endif
>> 
>> /*
>>  * Hand out standard DH parameters, based on the authentication 
>> strength
>>  */
>> DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
>> {
>> printf("SSL_callback_tmp_DH\n");
>> EVP_PKEY *pkey = SSL_get_privatekey(ssl);
>>     int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
>> 
>>     /*
>>      * OpenSSL will call us with either keylen == 512 or keylen == 
>> 1024
>>      * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
>>      * Adjust the DH parameter length according to the size of the
>>      * RSA/DSA private key used for the current connection, and always
>>      * use at least 1024-bit parameters.
>>      * Note: This may cause interoperability issues with 
>> implementations
>>      * which limit their DH support to 1024 bit - e.g. Java 7 and 
>> earlier.
>>      * In this case, SSLCertificateFile can be used to specify fixed
>>      * 1024-bit DH parameters (with the effect that OpenSSL skips this
>>      * callback).
>>      */
>>     if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
>>         keylen = EVP_PKEY_bits(pkey);
>>     }
>>     return SSL_get_dh_params(keylen);
>> }
>> 
>> /*
>>  * Read a file that optionally contains the server certificate in PEM
>>  * format, possibly followed by a sequence of CA certificates that
>>  * should be sent to the peer in the SSL Certificate message.
>>  */
>> int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
>>                                   int skipfirst)
>> {
>>      printf("SSL_CTX_use_certificate_chain\n");
>> 
>>     BIO *bio;
>>     X509 *x509;
>>     unsigned long err;
>>     int n;
>> 
>>     if ((bio = BIO_new(BIO_s_file())) == NULL)
>>         return -1;
>>     if (BIO_read_filename(bio, file) <= 0) {
>>         BIO_free(bio);
>>         return -1;
>>     }
>>     /* optionally skip a leading server certificate */
>>     if (skipfirst) {
>>         if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) 
>> {
>>             BIO_free(bio);
>>             return -1;
>>         }
>>         X509_free(x509);
>>     }
>> 
>>     /* free a perhaps already configured extra chain */
>>     SSL_CTX_clear_extra_chain_certs(ctx);
>> 
>>     /* create new extra chain by loading the certs */
>>     n = 0;
>>     while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) 
>> {
>>         if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
>>             X509_free(x509);
>>             BIO_free(bio);
>>             return -1;
>>         }
>>         n++;
>>     }
>>     /* Make sure that only the error is just an EOF */
>>     if ((err = ERR_peek_error()) > 0) {
>>         if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
>>               && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
>>             BIO_free(bio);
>>             return -1;
>>         }
>>         while (SSL_ERR_get() > 0) ;
>>     }
>>     BIO_free(bio);
>>     return n;
>> }
>> 
>> /*
>>  * This OpenSSL callback function is called when OpenSSL
>>  * does client authentication and verifies the certificate chain.
>>  */
>> 
>> 
>> int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
>> {
>>      printf("SSL_callback_SSL_verify\n");
>> /* Get Apache context back through OpenSSL context */
>>     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
>>                                           
>> SSL_get_ex_data_X509_STORE_CTX_idx());
>>     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>>     /* Get verify ingredients */
>>     int errnum   = X509_STORE_CTX_get_error(ctx);
>>     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
>>     int verify   = con->ctx->verify_mode;
>>     int depth    = con->ctx->verify_depth;
>> 
>> #if defined(SSL_OP_NO_TLSv1_3)
>>     con->pha_state = PHA_COMPLETE;
>> #endif
>> 
>>     if (verify == SSL_CVERIFY_UNSET ||
>>         verify == SSL_CVERIFY_NONE) {
>>         return 1;
>>     }
>> 
>>     if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
>>         (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
>>         ok = 1;
>>         SSL_set_verify_result(ssl, X509_V_OK);
>>     }
>> 
>>     /*
>>      * Expired certificates vs. "expired" CRLs: by default, OpenSSL
>>      * turns X509_V_ERR_CRL_HAS_EXPIRED into a 
>> "certificate_expired(45)"
>>      * SSL alert, but that's not really the message we should convey 
>> to the
>>      * peer (at the very least, it's confusing, and in many cases, 
>> it's also
>>      * inaccurate, as the certificate itself may very well not have 
>> expired
>>      * yet). We set the X509_STORE_CTX error to something which 
>> OpenSSL's
>>      * s3_both.c:ssl_verify_alarm_type() maps to 
>> SSL_AD_CERTIFICATE_UNKNOWN,
>>      * i.e. the peer will receive a "certificate_unknown(46)" alert.
>>      * We do not touch errnum, though, so that later on we will still 
>> log
>>      * the "real" error, as returned by OpenSSL.
>>      */
>>     if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
>>         X509_STORE_CTX_set_error(ctx, -1);
>>     }
>> 
>> #ifdef HAVE_OCSP_STAPLING
>>     /* First perform OCSP validation if possible */
>>     if (ok) {
>>         /* If there was an optional verification error, it's not
>>          * possible to perform OCSP validation since the issuer may be
>>          * missing/untrusted.  Fail in that case.
>>          */
>>         if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
>>             X509_STORE_CTX_set_error(ctx, 
>> X509_V_ERR_APPLICATION_VERIFICATION);
>>             errnum = X509_V_ERR_APPLICATION_VERIFICATION;
>>             ok = 0;
>>         }
>>         else {
>>             int ocsp_response = ssl_verify_OCSP(ctx);
>>             if (ocsp_response == OCSP_STATUS_REVOKED) {
>>                 ok = 0 ;
>>                 errnum = X509_STORE_CTX_get_error(ctx);
>>             }
>>             else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
>>                 /* TODO: do nothing for time being */
>>                 ;
>>             }
>>         }
>>     }
>> #endif
>>     /*
>>      * If we already know it's not ok, log the real reason
>>      */
>>     if (!ok) {
>>         /* TODO: Some logging
>>          * Certificate Verification: Error
>>          */
>>         if (con->peer) {
>>             X509_free(con->peer);
>>             con->peer = NULL;
>>         }
>>     }
>>     if (errdepth > depth) {
>>         /* TODO: Some logging
>>          * Certificate Verification: Certificate Chain too long
>>          */
>>         ok = 0;
>>     }
>>     return ok;
>> }
>> 
>> /*
>>  * This callback function is executed while OpenSSL processes the SSL
>>  * handshake and does SSL record layer stuff.  It's used to trap
>>  * client-initiated renegotiations, and for dumping everything to the
>>  * log.
>>  */
>> void SSL_callback_handshake(const SSL *ssl, int where, int rc)
>> {
>>          printf("SSL_callback_handshake\n");
>>  tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>> #ifdef HAVE_TLSV1_3
>>     const SSL_SESSION *session = SSL_get_session(ssl);
>> #endif
>> 
>>     /* Retrieve the conn_rec and the associated SSLConnRec. */
>>     if (con == NULL) {
>>         return;
>>     }
>> 
>> #ifdef HAVE_TLSV1_3
>>     /* TLS 1.3 does not use renegotiation so do not update the 
>> renegotiation
>>      * state once we know we are using TLS 1.3. */
>>     if (session != NULL) {
>>         if (SSL_SESSION_get_protocol_version(session) == 
>> TLS1_3_VERSION) {
>>             return;
>>         }
>>     }
>> #endif
>> 
>>     /* If the reneg state is to reject renegotiations, check the SSL
>>      * state machine and move to ABORT if a Client Hello is being
>>      * read. */
>>     if ((where & SSL_CB_HANDSHAKE_START) &&
>>          con->reneg_state == RENEG_REJECT) {
>>         con->reneg_state = RENEG_ABORT;
>>     }
>>     /* If the first handshake is complete, change state to reject any
>>      * subsequent client-initated renegotiation. */
>>     else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == 
>> RENEG_INIT) {
>>         con->reneg_state = RENEG_REJECT;
>>     }
>> }
>> 
>> int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
>>                              unsigned int *len, void *arg)
>> {
>>       printf("SSL_callback_next_protos\n");
>> tcn_ssl_ctxt_t *ssl_ctxt = arg;
>> 
>>     *data = ssl_ctxt->next_proto_data;
>>     *len = ssl_ctxt->next_proto_len;
>> 
>>     return SSL_TLSEXT_ERR_OK;
>> }
>> 
>> /* The code here is inspired by nghttp2
>>  *
>>  * See 
>> https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244 
>> */
>> int select_next_proto(SSL *ssl, const unsigned char **out, unsigned 
>> char *outlen,
>>         const unsigned char *in, unsigned int inlen, unsigned char 
>> *supported_protos,
>>         unsigned int supported_protos_len, int failure_behavior) {
>>    printf("select_next_proto\n");
>> 
>>     unsigned int i = 0;
>>     unsigned char target_proto_len;
>>     const unsigned char *p;
>>     const unsigned char *end;
>>     const unsigned char *proto;
>>     unsigned char proto_len = '\0';
>> 
>>     while (i < supported_protos_len) {
>>         target_proto_len = *supported_protos;
>>         ++supported_protos;
>> 
>>         p = in;
>>         end = in + inlen;
>> 
>>         while (p < end) {
>>             proto_len = *p;
>>             proto = ++p;
>> 
>>             if (proto + proto_len <= end && target_proto_len == 
>> proto_len &&
>>                     memcmp(supported_protos, proto, proto_len) == 0) {
>> 
>>                 // We found a match, so set the output and return with 
>> OK!
>>                 *out = proto;
>>                 *outlen = proto_len;
>> 
>>                 return SSL_TLSEXT_ERR_OK;
>>             }
>>             // Move on to the next protocol.
>>             p += proto_len;
>>         }
>> 
>>         // increment len and pointers.
>>         i += target_proto_len;
>>         supported_protos += target_proto_len;
>>     }
>> 
>>     if (supported_protos_len > 0 && inlen > 0 && failure_behavior == 
>> SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
>>          // There were no match but we just select our last protocol 
>> and hope the other peer support it.
>>          //
>>          // decrement the pointer again so the pointer points to the 
>> start of the protocol.
>>          p -= proto_len;
>>          *out = p;
>>          *outlen = proto_len;
>>          return SSL_TLSEXT_ERR_OK;
>>     }
>>     // TODO: OpenSSL currently not support to fail with fatal error. 
>> Once this changes we can also support it here.
>>     //       Issue https://github.com/openssl/openssl/issues/188 has 
>> been created for this.
>>     // Nothing matched so not select anything and just accept.
>>     return SSL_TLSEXT_ERR_NOACK;
>> }
>> 
>> int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out, 
>> unsigned char *outlen,
>>                          const unsigned char *in, unsigned int inlen,
>>                          void *arg) {
>>     printf("ssl_callback_select_next_proto\n");
>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>     return select_next_proto(ssl, (const unsigned char **) out, 
>> outlen, in, inlen, ssl_ctxt->next_proto_data, 
>> ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
>> }
>> 
>> int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char 
>> **out, unsigned char *outlen,
>>         const unsigned char *in, unsigned int inlen, void *arg) {
>>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>>       printf("ssl_callback_alpn_select_proto\n");
>>     return select_next_proto(ssl, out, outlen, in, inlen, 
>> ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len, 
>> ssl_ctxt->alpn_selector_failure_behavior);
>> }
>> #ifdef HAVE_OCSP_STAPLING
>> 
>> /* Function that is used to do the OCSP verification */
>> static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
>> {
>>      printf("ssl_verify_OCSP\n");
>> 
>> X509 *cert, *issuer;
>>     int r = OCSP_STATUS_UNKNOWN;
>>      printf("Hello, OCSP\n");
>>     cert = X509_STORE_CTX_get_current_cert(ctx);
>> 
>>     if (!cert) {
>>        printf("CERT NOT OK\n");
>>  /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
>>          * may yield NULL. Return early, but leave the ctx error as 
>> is. */
>>         return OCSP_STATUS_UNKNOWN;
>>     }
>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>     else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) 
>> {
>> #else
>>     /* No need to check cert->valid, because ssl_verify_OCSP() only
>>      * is called if OpenSSL already successfully verified the 
>> certificate
>>      * (parameter "ok" in SSL_callback_SSL_verify() must be true).
>>      */
>>     else if (X509_check_issued(cert,cert) == X509_V_OK) {
>> #endif
>>         /* don't do OCSP checking for valid self-issued certs */
>>         X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>         return OCSP_STATUS_UNKNOWN;
>>     }
>> 
>>     /* if we can't get the issuer, we cannot perform OCSP verification 
>> */
>>     issuer = X509_STORE_CTX_get0_current_issuer(ctx);
>>     if (issuer != NULL) {
>>         r = ssl_ocsp_request(cert, issuer, ctx);
>>         switch (r) {
>>         case OCSP_STATUS_OK:
>>             X509_STORE_CTX_set_error(ctx, X509_V_OK);
>>             break;
>>         case OCSP_STATUS_REVOKED:
>>             /* we set the error if we know that it is revoked */
>>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
>>             break;
>>         case OCSP_STATUS_UNKNOWN:
>>             /* ssl_ocsp_request() sets the error correctly already. */
>>             break;
>>         }
>>     }
>>     return r;
>> }
>> 
>> 
>> /* Helps with error handling or realloc */
>> static void *apr_xrealloc(void *buf, size_t oldlen, size_t len, 
>> apr_pool_t *p)
>> {
>>       printf("apr_xrealloc\n");
>> void *newp = apr_palloc(p, len);
>> 
>>     if(newp)
>>         memcpy(newp, buf, oldlen);
>>     return newp;
>> }
>> 
>> /* Parses an ASN.1 length.
>>  * On entry, asn1 points to the current tag.
>>  * Updates the pointer to the ASN.1 structure to point to the start of 
>> the data.
>>  * Returns 0 on success, 1 on failure.
>>  */
>> static int parse_asn1_length(unsigned char **asn1, int *len) {
>>   printf("parse_asn1_length\n");
>>     /* Length immediately follows tag so increment before reading 
>> first (and
>>      * possibly only) length byte.
>>      */
>>     (*asn1)++;
>> 
>>     if (**asn1 & 0x80) {
>>         // MSB set. Remaining bits are number of bytes used to store 
>> the length.
>>         int i, l;
>> 
>>         // How many bytes for this length?
>>         i = **asn1 & 0x7F;
>> 
>>         if (i == 0) {
>>             /* This is the indefinite form of length. Since 
>> certificates use DER
>>              * this should never happen and is therefore an error.
>>              */
>>             return 1;
>>         }
>>         if (i > 3) {
>>             /* Three bytes for length gives a maximum of 16MB which 
>> should be
>>              * far more than is required. (2 bytes is 64K which is 
>> probably more
>>              * than enough but play safe.)
>>              */
>>             return 1;
>>         }
>> 
>>         // Most significant byte is first
>>         l = 0;
>>         while (i > 0) {
>>             l <<= 8;
>>             (*asn1)++;
>>             l += **asn1;
>>             i--;
>>         }
>>         *len = l;
>>     } else {
>>         // Single byte length
>>         *len = **asn1;
>>     }
>> 
>>     (*asn1)++;
>> 
>>     return 0;
>> }
>> 
>> /* parses the ocsp url and updates the ocsp_urls and nocsp_urls 
>> variables
>>    returns 0 on success, 1 on failure */
>> static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
>>                           int *nocsp_urls, apr_pool_t *p)
>> {
>>   printf("parse_ocsp_url\n");
>>     char **new_ocsp_urls, *ocsp_url;
>>     int len, err = 0, new_nocsp_urls;
>> 
>>     if (*asn1 == ASN1_STRING) {
>>         err = parse_asn1_length(&asn1, &len);
>> 
>>         if (!err) {
>>             new_nocsp_urls = *nocsp_urls+1;
>>             if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls, 
>> new_nocsp_urls, p)) == NULL)
>>                 err = 1;
>>         }
>>         if (!err) {
>>             *ocsp_urls  = new_ocsp_urls;
>>             *nocsp_urls = new_nocsp_urls;
>>             *(*ocsp_urls + *nocsp_urls) = NULL;
>>             if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
>>                 err = 1;
>>             }
>>             else {
>>                 memcpy(ocsp_url, asn1, len);
>>                 ocsp_url[len] = '\0';
>>                 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
>>             }
>>         }
>>     }
>>     return err;
>> 
>> }
>> 
>> /* parses the ANS1 OID and if it is an OCSP OID then calls the 
>> parse_ocsp_url function */
>> static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int 
>> *nocsp_urls, apr_pool_t *p)
>> {
>>   printf("PARSE  OCSP_OID\n");
>>   int len, err = 0 ;
>>     const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 
>> 0x07, 0x30, 0x01};
>> 
>>     err = parse_asn1_length(&asn1, &len);
>> 
>>     if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
>>         asn1+=len;
>>         err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
>>     }
>>     return err;
>> }
>> 
>> 
>> /* Parses an ASN1 Sequence. It is a recursive function, since if it 
>> finds a  sequence
>>    within the sequence it calls recursively itself. This function 
>> stops when it finds
>>    the end of the ASN1 sequence (marked by '\0'), so if there are 
>> other sequences within
>>    the same sequence the while loop parses the sequences */
>> 
>> /* This algo was developed with AIA in mind so it was tested only with 
>> this extension */
>> static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
>>                                int *nocsp_urls, apr_pool_t *p)
>> {
>>      printf("parse_ASN1_Sequence\n");
>> 
>>  int len = 0 , err = 0;
>> 
>>     while (!err && *asn1 != '\0') {
>>         switch(*asn1) {
>>             case ASN1_SEQUENCE:
>>                 err = parse_asn1_length(&asn1, &len);
>>                 if (!err) {
>>                     err = parse_ASN1_Sequence(asn1, ocsp_urls, 
>> nocsp_urls, p);
>>                 }
>>             break;
>>             case ASN1_OID:
>>                 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
>>                 return err;
>>             break;
>>             default:
>>                 err = 1; /* we shouldn't have any errors */
>>             break;
>>         }
>>         asn1+=len;
>>     }
>>     return err;
>> }
>> 
>> /* the main function that gets the ASN1 encoding string and returns
>>    a pointer to a NULL terminated "array" of char *, that contains
>>    the ocsp_urls */
>> static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
>> {
>>         printf("decode_OCSP_url\n");
>> 
>> char **response = NULL;
>>     unsigned char *ocsp_urls;
>>     int len, numofresponses = 0 ;
>> 
>>     len = ASN1_STRING_length(os);
>> 
>>     ocsp_urls = apr_palloc(p,  len + 1);
>>     memcpy(ocsp_urls,os->data, len);
>>     ocsp_urls[len] = '\0';
>> 
>>     if ((response = apr_pcalloc(p, sizeof(char *))) == NULL)
>>         return NULL;
>>     if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p))
>>         response = NULL;
>>     return response;
>> }
>> 
>> 
>> /* stolen from openssl ocsp command */
>> static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 *issuer)
>> {
>>       printf("add_ocsp_cert\n");
>> OCSP_CERTID *id;
>> 
>>     if (!issuer)
>>         return 0;
>>     id = OCSP_cert_to_id(NULL, cert, issuer);
>>     if (!id)
>>         return 0;
>>     if (!OCSP_request_add0_id(req, id)) {
>>         OCSP_CERTID_free(id);
>>         return 0;
>>     } else {
>>         /* id will be freed by OCSP_REQUEST_free() */
>>         return 1;
>>     }
>> }
>> 
>> 
>> /* Creates the APR socket and connect to the hostname. Returns the
>>    socket or NULL if there is an error.
>> */
>> static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t 
>> *mp)
>> {
>>      printf("*make_socket\n");
>> apr_sockaddr_t *sa_in;
>>     apr_status_t status;
>>     apr_socket_t *sock = NULL;
>> 
>> 
>>     status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 
>> 0, mp);
>> 
>>     if (status == APR_SUCCESS)
>>         status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, 
>> APR_PROTO_TCP, mp);
>>     if (status == APR_SUCCESS)
>>         status = apr_socket_connect(sock, sa_in);
>> 
>>     if (status == APR_SUCCESS)
>>         return sock;
>>     return NULL;
>> }
>> 
>> 
>> /* Creates the request in a memory BIO in order to send it to the OCSP 
>> server.
>>    Most parts of this function are taken from mod_ssl support for OCSP 
>> (with some
>>    minor modifications
>> */
>> static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, 
>> char *path)
>> {
>>     printf("serialize_request\n");
>> BIO *bio;
>>     int len;
>> 
>>     len = i2d_OCSP_REQUEST(req, NULL);
>> 
>>     bio = BIO_new(BIO_s_mem());
>> 
>>     BIO_printf(bio, "POST %s HTTP/1.0\r\n"
>>       "Host: %s:%d\r\n"
>>       "Content-Type: application/ocsp-request\r\n"
>>       "Content-Length: %d\r\n"
>>       "\r\n",
>>       path, host, port, len);
>> 
>>     if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
>>         BIO_free(bio);
>>         return NULL;
>>     }
>> 
>>     return bio;
>> }
>> 
>> 
>> /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP 
>> support */
>> static int ocsp_send_req(apr_socket_t *sock, BIO *req)
>> {
>>     printf("ocsp_send_req\n");
>> int len;
>>     char buf[TCN_BUFFER_SZ];
>>     apr_status_t rv;
>> 
>>     while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
>>         char *wbuf = buf;
>>         apr_size_t remain = len;
>> 
>>         do {
>>             apr_size_t wlen = remain;
>>             rv = apr_socket_send(sock, wbuf, &wlen);
>>             wbuf += remain;
>>             remain -= wlen;
>>         } while (rv == APR_SUCCESS && remain > 0);
>> 
>>         if (rv != APR_SUCCESS) {
>>             return 0;
>>         }
>>     }
>> 
>>     return 1;
>> }
>> 
>> 
>> 
>> /* Parses the buffer from the response and extracts the OCSP response.
>>    Taken from openssl library */
>> static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
>> {
>>  printf("parse_ocsp_resp\n");
>>    BIO *mem = NULL;
>>     char tmpbuf[1024];
>>     OCSP_RESPONSE *resp = NULL;
>>     char *p, *q, *r;
>>     int retcode;
>> 
>>     mem = BIO_new(BIO_s_mem());
>>     if(mem == NULL)
>>         return NULL;
>> 
>>     BIO_write(mem, buf, len);  /* write the buffer to the bio */
>>     if (BIO_gets(mem, tmpbuf, 512) <= 0) {
>> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>>         
>> OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
>> #endif
>>         goto err;
>>     }
>>     /* Parse the HTTP response. This will look like this:
>>      * "HTTP/1.0 200 OK". We need to obtain the numeric code and
>>      * (optional) informational message.
>>      */
>> 
>>     /* Skip to first white space (passed protocol info) */
>>     for (p = tmpbuf; *p && !apr_isspace(*p); p++)
>>         continue;
>>     if (!*p) {
>>         goto err;
>>     }
>>     /* Skip past white space to start of response code */
>>     while (apr_isspace(*p))
>>         p++;
>>     if (!*p) {
>>         goto err;
>>     }
>>     /* Find end of response code: first whitespace after start of code 
>> */
>>     for (q = p; *q && !apr_isspace(*q); q++)
>>         continue;
>>     if (!*q) {
>>         goto err;
>>     }
>>     /* Set end of response code and start of message */
>>     *q++ = 0;
>>     /* Attempt to parse numeric code */
>>     retcode = strtoul(p, &r, 10);
>>     if (*r)
>>         goto err;
>>     /* Skip over any leading white space in message */
>>     while (apr_isspace(*q))
>>         q++;
>>     if (*q) {
>>         /* Finally zap any trailing white space in message (include 
>> CRLF) */
>>         /* We know q has a non white space character so this is OK */
>>         for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
>>     }
>>     if (retcode != 200) {
>>         goto err;
>>     }
>>     /* Find blank line marking beginning of content */
>>     while (BIO_gets(mem, tmpbuf, 512) > 0) {
>>         for (p = tmpbuf; apr_isspace(*p); p++)
>>             continue;
>>         if (!*p)
>>             break;
>>     }
>>     if (*p) {
>>         goto err;
>>     }
>>     if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
>>         goto err;
>>     }
>> err:
>>     /* XXX No error logging? */
>>     BIO_free(mem);
>>     return resp;
>> }
>> 
>> 
>> /* Reads the response from the APR socket to a buffer, and parses the 
>> buffer to
>>    return the OCSP response  */
>> #define ADDLEN 512
>> static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t 
>> *sock)
>> {
>>      printf("ocsp_get_resp\n");
>> int buflen;
>>     apr_size_t totalread = 0;
>>     apr_size_t readlen;
>>     char *buf, tmpbuf[ADDLEN];
>>     apr_status_t rv = APR_SUCCESS;
>>     apr_pool_t *p;
>>     OCSP_RESPONSE *resp;
>> 
>>     apr_pool_create(&p, mp);
>>     buflen = ADDLEN;
>>     buf = apr_palloc(p, buflen);
>>     if (buf == NULL) {
>>         apr_pool_destroy(p);
>>         return NULL;
>>     }
>> 
>>     while (rv == APR_SUCCESS ) {
>>         readlen = sizeof(tmpbuf);
>>         rv = apr_socket_recv(sock, tmpbuf, &readlen);
>>         if (rv == APR_SUCCESS) { /* if we have read something .. we 
>> can put it in the buffer*/
>>             if ((totalread + readlen) >= buflen) {
>>                 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
>>                 if (buf == NULL) {
>>                     apr_pool_destroy(p);
>>                     return NULL;
>>                 }
>>                 buflen += ADDLEN; /* if needed we enlarge the buffer 
>> */
>>             }
>>             memcpy(buf + totalread, tmpbuf, readlen); /* the copy to 
>> the buffer */
>>             totalread += readlen; /* update the total bytes read */
>>         }
>>         else {
>>             if (rv == APR_EOF && readlen == 0)
>>                 ; /* EOF, normal situation */
>>             else if (readlen == 0) {
>>                 /* Not success, and readlen == 0 .. some error */
>>                 apr_pool_destroy(p);
>>                 return NULL;
>>             }
>>         }
>>     }
>> 
>>     resp = parse_ocsp_resp(buf, buflen);
>>     apr_pool_destroy(p);
>>     return resp;
>> }
>> 
>> /* Creates and OCSP request and returns the OCSP_RESPONSE */
>> static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert, 
>> X509 *issuer, char *url)
>> {
>>        printf("get_ocsp_response\n");
>> OCSP_RESPONSE *ocsp_resp = NULL;
>>     OCSP_REQUEST *ocsp_req = NULL;
>>     BIO *bio_req;
>>     char *hostname, *path, *c_port;
>>     int port, use_ssl;
>>     int ok = 0;
>>     apr_socket_t *apr_sock = NULL;
>>     apr_pool_t *mp;
>> 
>>     if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 )
>>         goto end;
>> 
>>     if (sscanf(c_port, "%d", &port) != 1)
>>         goto end;
>> 
>>     /* Create the OCSP request */
>>     ocsp_req = OCSP_REQUEST_new();
>>     if (ocsp_req == NULL)
>>         goto end;
>> 
>>     if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
>>         goto free_req;
>> 
>>     /* create the BIO with the request to send */
>>     bio_req = serialize_request(ocsp_req, hostname, port, path);
>>     if (bio_req == NULL) {
>>         goto free_req;
>>     }
>> 
>>     apr_pool_create(&mp, p);
>>     apr_sock = make_socket(hostname, port, mp);
>>     if (apr_sock == NULL) {
>>         goto free_bio;
>>     }
>> 
>>     ok = ocsp_send_req(apr_sock, bio_req);
>>     if (ok) {
>>         ocsp_resp = ocsp_get_resp(mp, apr_sock);
>>     }
>>     apr_socket_close(apr_sock);
>> 
>> free_bio:
>>     BIO_free(bio_req);
>>     apr_pool_destroy(mp);
>> 
>> free_req:
>>     OCSP_REQUEST_free(ocsp_req);
>> 
>> end:
>>     OPENSSL_free(hostname);
>>     OPENSSL_free(c_port);
>>     OPENSSL_free(path);
>> 
>>     return ocsp_resp;
>> }
>> 
>> /* Process the OCSP_RESPONSE and returns the corresponding
>>    answert according to the status.
>> */
>> static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509 *cert, 
>> X509 *issuer)
>> {
>>        printf("process_ocsp_response\n");
>> int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
>>     OCSP_BASICRESP *bs;
>>     OCSP_SINGLERESP *ss;
>>     OCSP_CERTID *certid;
>> 
>>     r = OCSP_response_status(ocsp_resp);
>> 
>>     if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
>>         return OCSP_STATUS_UNKNOWN;
>>     }
>>     bs = OCSP_response_get1_basic(ocsp_resp);
>> 
>>     certid = OCSP_cert_to_id(NULL, cert, issuer);
>>     if (certid == NULL) {
>>         return OCSP_STATUS_UNKNOWN;
>>     }
>>     ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find 
>> by serial number and get the matching response */
>> 
>> 
>>     i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
>>     if (i == V_OCSP_CERTSTATUS_GOOD)
>>         o =  OCSP_STATUS_OK;
>>     else if (i == V_OCSP_CERTSTATUS_REVOKED)
>>         o = OCSP_STATUS_REVOKED;
>>     else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
>>         o = OCSP_STATUS_UNKNOWN;
>> 
>>     /* we clean up */
>>     OCSP_CERTID_free(certid);
>>     OCSP_BASICRESP_free(bs);
>>     return o;
>> }
>> 
>> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX 
>> *ctx)
>> {
>>      printf("ssl_ocsp_request\n");
>>    char **ocsp_urls = NULL;
>>     int nid;
>>     X509_EXTENSION *ext;
>>     ASN1_OCTET_STRING *os;
>>     apr_pool_t *p;
>> 
>>     apr_pool_create(&p, NULL);
>> 
>>     /* Get the proper extension */
>>     nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
>>     if (nid >= 0 ) {
>>         ext = X509_get_ext(cert,nid);
>>         os = X509_EXTENSION_get_data(ext);
>> 
>>         ocsp_urls = decode_OCSP_url(os, p);
>>     }
>>      printf("OCSP request\n");
>> 
>>     /* if we find the extensions and we can parse it check
>>        the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
>>     if (ocsp_urls != NULL) {
>>     printf("ocsp url not null\n");
>>         OCSP_RESPONSE *resp;
>>         int rv = OCSP_STATUS_UNKNOWN;
>>         /* for the time being just check for the fist response .. a 
>> better
>>            approach is to iterate for all the possible ocsp urls */
>>         resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
>>         if (resp != NULL) {
>>             rv = process_ocsp_response(resp, cert, issuer);
>>         } else {
>>             /* correct error code for application errors? */
>>             X509_STORE_CTX_set_error(ctx, 
>> X509_V_ERR_APPLICATION_VERIFICATION);
>>         }
>> 
>>         if (resp != NULL) {
>>             OCSP_RESPONSE_free(resp);
>>             apr_pool_destroy(p);
>>             return rv;
>>         }
>>     }
>>     apr_pool_destroy(p);
>>     return OCSP_STATUS_UNKNOWN;
>> }
>> 
>> #endif /* HAVE_OCSP_STAPLING */
>> #endif /* HAVE_OPENSSL  */
>> 
>> 
>> 
>> 
>> -----------------------------------------tomcat log
>> 27-May-2019 14:15:59.727 INFO [main] 
>> org.apache.catalina.startup.Catalina.start Server startup in 31619 ms
>>  SSL_init_app_data_idx
>> Hi OCSP
>> ssl_set_app_data3
>> ssl_set_app_data4
>> ssl_set_app_data2
>> ssl_get_app_data3
>> ssl_get_app_data4
>> ssl_get_app_data4
>> SSL_dh_GetParamFromFile
>> SSL_ec_GetParamFromFile
>> SSL_CTX_use_certificate_chain
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_next_protos
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_next_protos
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_next_protos
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_next_protos
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_next_protos
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callback_alpn_select_proto
>> select_next_proto
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_set_app_data2
>> SSL_callback_handshake
>> SSL_callback_handshake
>> SSL_callback_handshake
>> ssl_callbac
>> 
>> 
>> 
>> ________________________________
>> От: Усманов Азат Анварович <us...@ieml.ru>
>> Отправлено: 24 мая 2019 г. 7:21
>> Кому: Tomcat Users List
>> Тема: Re: OCSP with openSSL
>> 
>> 
>> 
>> Chris,
>> Yes the version is the same in
>> /usr/local/openssl/bin/openssl as well.
>> It is the same version Tomcat uses,I get this info in the logs
>> 
>> 23-May-2019 12:55:42.145 INFO [main] org.apache.catalina.core.AprLife
>> cycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL
>> 1.1.1a  20 Nov 2018]
>> ________________________________
>> От: Christopher Schultz <ch...@christopherschultz.net>
>> Отправлено: 23 мая 2019 г. 18:04:29
>> Кому: Усманов Азат Анварович
>> Тема: Re: OCSP with openSSL
>> 
>> Азат,
>> 
>> On 5/22/19 14:02, Усманов Азат Анварович wrote:
>>> [root] ~# openssl version
>>> OpenSSL 1.1.1a  20 Nov 2018
>> 
>> Great. Is this also the same version in 
>> /usr/local/openssl/bin/openssl?
>> 
>>> [root] ~# openssl  ocsp -help
>>> Usage: ocsp [options]
>> 
>> Excellent.
>> 
>> When you launch Tomcat, are you getting a message about the version of
>> OpenSSL in use, and does it agree with above?
>> 
>> AFAIK, OCSP is enabled by default in libtcnative. There were some 
>> posts
>> a few months/years ago about someone trying to get it to work, and
>> having to edit the JVM's security.properties file and all kinds of 
>> weird
>> stuff. I must admit it didn't make any sense to me at the time. I'm
>> sorry, but I don't personally have any experience with dealing with
>> OCSP, but hopefully this additio0nal information will give someone 
>> else
>> some good info.
>> 
>> -chris
>> 
>>> ________________________________
>>> От: Christopher Schultz <ch...@christopherschultz.net>
>>> Отправлено: 22 мая 2019 г. 19:45
>>> Кому: users@tomcat.apache.org
>>> Тема: Re: OCSP with openSSL
>>> 
>>> Усманов,
>>> 
>>> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>>>> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
>>>> file from tomcat  website and issued  ./configure
>>>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>>>> -with-ssl=/usr/local/openssl && make && make install && make clean
>>>> I'm not sure  how to specify any ocsp related configure options
>>>> when building tomcat native    from source
>>> 
>>> What is your OpenSSL version and capabilities?
>>> 
>>> $ openssl version
>>> 
>>> $ openssl -help
>>> 
>>> $ openssl ocsp -help
>>> 
>>> -chris
>>> 
>>>> ________________________________ От: Mark Thomas
>>>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>>>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>>> 
>>>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>>>> apr for TLS related issues. I m still unable to have OCSP
>>>>> verification working with tomcat.
>>> 
>>>> <snip/>
>>> 
>>>>> I have tried running tcpdump on the server but don't' see any
>>>>> Comodo related IP addresses in the output when I access the
>>>>> server in question in the browser. At this point I don't know
>>>>> what else to do, If it was java I would just put some
>>>>> System.out.println statements in OCSP SSL related source code and
>>>>> recompile the tomcat source, but since in my case tomcat uses
>>>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>>>> only places I found in the TC-native source that mentions OCSP
>>>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>>>> gets called in my case. Maybe be someone with more c experience
>>>>> c++ would help me with that.  I really want to get to the bottom
>>>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>>>> based Apache Tomcat Native library [1.2.21] using APR version
>>>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>>>> Linux RHEL 6.6
>>> 
>>>> How did you build the Tomcat Native library? Was OCSP enabled?
>>> 
>>>> Mark
>>> 
>>>> ---------------------------------------------------------------------
>>> 
>>> 
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>> 
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>> 
>>> 
>> 
>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by Mark Thomas <ma...@apache.org>.
Coming back to this as it has been on my TODO list for a while.

Having re-read the thread I think it would be helpful to first clarify
exactly what behaviour you are expecting and not seeing.

The issue relates to OCSP checks when Tomcat is presenting it's server
certificate to the client.

You are expecting Tomcat to use OCSP stapling to provide the OCSP
information to the client so that the client does not have to request it
itself.

Tomcat is not providing the OCSP information. It appears that OCSP
stapling is not working.

Is the above a fair summary? If not, please provide corrections.

Thanks,

Mark


On 27/05/2019 12:36, Усманов Азат Анварович wrote:
> Just a quick follow up , trying to get some answers, I added  include <stdio.h> to sslutils.c (which has alll the ocsp functions )   to print some info.I  added printf calls to every function defined in this file.  Interestingly enough  when I issue  the  openssl s_client -connect debug.ieml.ru:8443  -tls1_2 -status -proxy 192.168.1.6:3131
> both tls1_2 and tls 1_3  versions and when I access  the server from another machine via browser none of printf  calls are displayed,  however, when I issue ssllabs server test (which is also supposedly capable of detecting ocsp)   some of them start to appear.  sadly none of them are ocsp related. I did put basic  ifdef  test for HAVE_OCSP_STAPLING, surprisingly  it  shows that ocsp support is indeed enabled . So here are  both   the modified  sslutils.c file and tomcat log snippet (not sure if attachments are allowed on  the list  so posting it  here )
> Not sure where to go from here
> /* Licensed to the Apache Software Foundation (ASF) under one or more
>  * contributor license agreements.  See the NOTICE file distributed with
>  * this work for additional information regarding copyright ownership.
>  * The ASF licenses this file to You under the Apache License, Version 2.0
>  * (the "License"); you may not use this file except in compliance with
>  * the License.  You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> /** SSL Utilities
>  */
> 
> #include "tcn.h"
> #include <stdio.h>
> #ifdef HAVE_OPENSSL
> #include "apr_poll.h"
> #include "ssl_private.h"
> 
> 
> #ifdef WIN32
> extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
> #endif
> 
> #ifdef HAVE_OCSP_STAPLING
> #include <openssl/bio.h>
> #include <openssl/ocsp.h>
> /* defines with the values as seen by the asn1parse -dump openssl command */
> #define ASN1_SEQUENCE 0x30
> #define ASN1_OID      0x06
> #define ASN1_STRING   0x86
> static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx);
> #endif
> 
> /*  _________________________________________________________________
> **
> **  Additional High-Level Functions for OpenSSL
> **  _________________________________________________________________
> */
> 
> /* we initialize this index at startup time
>  * and never write to it at request time,
>  * so this static is thread safe.
>  * also note that OpenSSL increments at static variable when
>  * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
>  */
> static int SSL_app_data2_idx = -1;
> static int SSL_app_data3_idx = -1;
> static int SSL_app_data4_idx = -1;
> 
> void SSL_init_app_data_idx(void)
> { printf(" SSL_init_app_data_idx\n");
>    #ifdef HAVE_OCSP_STAPLING
> printf("Hi OCSP \n");
> #else
> printf("Sorry no OCSP support\n");
> #endif
> 
>     int i;
> 
>     if (SSL_app_data2_idx > -1) {
>         return;
>     }
> 
>     /* we _do_ need to call this twice */
>     for (i = 0; i <= 1; i++) {
>         SSL_app_data2_idx =
>             SSL_get_ex_new_index(0,
>                                  "Second Application Data for SSL",
>                                  NULL, NULL, NULL);
>     }
> 
>     if (SSL_app_data3_idx > -1) {
>         return;
>     }
> 
>     SSL_app_data3_idx =
>             SSL_get_ex_new_index(0,
>                                  "Third Application Data for SSL",
>                                   NULL, NULL, NULL);
> 
>     if (SSL_app_data4_idx > -1) {
>         return;
>     }
> 
>     SSL_app_data4_idx =
>             SSL_get_ex_new_index(0,
>                                  "Fourth Application Data for SSL",
>                                   NULL, NULL, NULL);
> 
> }
> 
> void *SSL_get_app_data2(SSL *ssl)
> {
>      printf("ssl_get_app_data2 \n");
>     return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
> }
> 
> void SSL_set_app_data2(SSL *ssl, void *arg)
> {
> printf("ssl_set_app_data2 \n");
> 
>     SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
>     return;
> }
> 
> 
> void *SSL_get_app_data3(const SSL *ssl)
> {
> printf("ssl_get_app_data3 \n");
> 
>     return SSL_get_ex_data(ssl, SSL_app_data3_idx);
> }
> 
> void SSL_set_app_data3(SSL *ssl, void *arg)
> {
> printf("ssl_set_app_data3 \n");
>     SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
> }
> 
> void *SSL_get_app_data4(const SSL *ssl)
> {
> printf("ssl_get_app_data4 \n");
>     return SSL_get_ex_data(ssl, SSL_app_data4_idx);
> }
> 
> void SSL_set_app_data4(SSL *ssl, void *arg)
> {
> printf("ssl_set_app_data4 \n");
>     SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
> }
> 
> /* Simple echo password prompting */
> int SSL_password_prompt(tcn_pass_cb_t *data)
> {
> 
>     printf(" SSL_password_prompt\n");
> int rv = 0;
>     data->password[0] = '\0';
>     if (data->cb.obj) {
>         JNIEnv *e;
>         jobject  o;
>         jstring  prompt;
>         tcn_get_java_env(&e);
>         prompt = AJP_TO_JSTRING(data->prompt);
>         if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
>                             data->cb.mid[0], prompt))) {
>             TCN_ALLOC_CSTRING(o);
>             if (J2S(o)) {
>                 strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN);
>                 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
>                 rv = (int)strlen(data->password);
>             }
>             TCN_FREE_CSTRING(o);
>         }
>     }
>     else {
> #ifdef WIN32
>         rv = WIN32_SSL_password_prompt(data);
> #else
>         EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
>                            data->prompt, 0);
> #endif
>         rv = (int)strlen(data->password);
>     }
>     if (rv > 0) {
>         /* Remove LF char if present */
>         char *r = strchr(data->password, '\n');
>         if (r) {
>             *r = '\0';
>             rv--;
>         }
> #ifdef WIN32
>         if ((r = strchr(data->password, '\r'))) {
>             *r = '\0';
>             rv--;
>         }
> #endif
>     }
>     return rv;
> }
> 
> int SSL_password_callback(char *buf, int bufsiz, int verify,
>                           void *cb)
> {   printf("SSL_password_callback\n");
>     tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;
> 
>     if (buf == NULL)
>         return 0;
>     *buf = '\0';
>     if (cb_data == NULL)
>         cb_data = &tcn_password_callback;
>     if (!cb_data->prompt)
>         cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
>     if (cb_data->password[0]) {
>         /* Return already obtained password */
>         strncpy(buf, cb_data->password, bufsiz);
>         buf[bufsiz - 1] = '\0';
>         return (int)strlen(buf);
>     }
>     else {
>         if (SSL_password_prompt(cb_data) > 0)
>             strncpy(buf, cb_data->password, bufsiz);
>     }
>     buf[bufsiz - 1] = '\0';
>     return (int)strlen(buf);
> }
> 
> /*  _________________________________________________________________
> **
> **  Custom (EC)DH parameter support
> **  _________________________________________________________________
> */
> DH *SSL_dh_GetParamFromFile(const char *file)
> {
>    printf("SSL_dh_GetParamFromFile\n");
>  DH *dh = NULL;
>     BIO *bio;
> 
>     if ((bio = BIO_new_file(file, "r")) == NULL)
>         return NULL;
>     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
>     BIO_free(bio);
>     return dh;
> }
> 
> #ifdef HAVE_ECC
> EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
> {
> 
>    printf("SSL_ec_GetParamFromFile\n");
> EC_GROUP *group = NULL;
>     BIO *bio;
> 
>     if ((bio = BIO_new_file(file, "r")) == NULL)
>         return NULL;
>     group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
>     BIO_free(bio);
>     return (group);
> }
> #endif
> 
> /*
>  * Hand out standard DH parameters, based on the authentication strength
>  */
> DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
> {
> printf("SSL_callback_tmp_DH\n");
> EVP_PKEY *pkey = SSL_get_privatekey(ssl);
>     int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
> 
>     /*
>      * OpenSSL will call us with either keylen == 512 or keylen == 1024
>      * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
>      * Adjust the DH parameter length according to the size of the
>      * RSA/DSA private key used for the current connection, and always
>      * use at least 1024-bit parameters.
>      * Note: This may cause interoperability issues with implementations
>      * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
>      * In this case, SSLCertificateFile can be used to specify fixed
>      * 1024-bit DH parameters (with the effect that OpenSSL skips this
>      * callback).
>      */
>     if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
>         keylen = EVP_PKEY_bits(pkey);
>     }
>     return SSL_get_dh_params(keylen);
> }
> 
> /*
>  * Read a file that optionally contains the server certificate in PEM
>  * format, possibly followed by a sequence of CA certificates that
>  * should be sent to the peer in the SSL Certificate message.
>  */
> int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
>                                   int skipfirst)
> {
>      printf("SSL_CTX_use_certificate_chain\n");
> 
>     BIO *bio;
>     X509 *x509;
>     unsigned long err;
>     int n;
> 
>     if ((bio = BIO_new(BIO_s_file())) == NULL)
>         return -1;
>     if (BIO_read_filename(bio, file) <= 0) {
>         BIO_free(bio);
>         return -1;
>     }
>     /* optionally skip a leading server certificate */
>     if (skipfirst) {
>         if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
>             BIO_free(bio);
>             return -1;
>         }
>         X509_free(x509);
>     }
> 
>     /* free a perhaps already configured extra chain */
>     SSL_CTX_clear_extra_chain_certs(ctx);
> 
>     /* create new extra chain by loading the certs */
>     n = 0;
>     while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
>         if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
>             X509_free(x509);
>             BIO_free(bio);
>             return -1;
>         }
>         n++;
>     }
>     /* Make sure that only the error is just an EOF */
>     if ((err = ERR_peek_error()) > 0) {
>         if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
>               && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
>             BIO_free(bio);
>             return -1;
>         }
>         while (SSL_ERR_get() > 0) ;
>     }
>     BIO_free(bio);
>     return n;
> }
> 
> /*
>  * This OpenSSL callback function is called when OpenSSL
>  * does client authentication and verifies the certificate chain.
>  */
> 
> 
> int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
> {
>      printf("SSL_callback_SSL_verify\n");
> /* Get Apache context back through OpenSSL context */
>     SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
>                                           SSL_get_ex_data_X509_STORE_CTX_idx());
>     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
>     /* Get verify ingredients */
>     int errnum   = X509_STORE_CTX_get_error(ctx);
>     int errdepth = X509_STORE_CTX_get_error_depth(ctx);
>     int verify   = con->ctx->verify_mode;
>     int depth    = con->ctx->verify_depth;
> 
> #if defined(SSL_OP_NO_TLSv1_3)
>     con->pha_state = PHA_COMPLETE;
> #endif
> 
>     if (verify == SSL_CVERIFY_UNSET ||
>         verify == SSL_CVERIFY_NONE) {
>         return 1;
>     }
> 
>     if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
>         (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
>         ok = 1;
>         SSL_set_verify_result(ssl, X509_V_OK);
>     }
> 
>     /*
>      * Expired certificates vs. "expired" CRLs: by default, OpenSSL
>      * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
>      * SSL alert, but that's not really the message we should convey to the
>      * peer (at the very least, it's confusing, and in many cases, it's also
>      * inaccurate, as the certificate itself may very well not have expired
>      * yet). We set the X509_STORE_CTX error to something which OpenSSL's
>      * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
>      * i.e. the peer will receive a "certificate_unknown(46)" alert.
>      * We do not touch errnum, though, so that later on we will still log
>      * the "real" error, as returned by OpenSSL.
>      */
>     if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
>         X509_STORE_CTX_set_error(ctx, -1);
>     }
> 
> #ifdef HAVE_OCSP_STAPLING
>     /* First perform OCSP validation if possible */
>     if (ok) {
>         /* If there was an optional verification error, it's not
>          * possible to perform OCSP validation since the issuer may be
>          * missing/untrusted.  Fail in that case.
>          */
>         if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
>             errnum = X509_V_ERR_APPLICATION_VERIFICATION;
>             ok = 0;
>         }
>         else {
>             int ocsp_response = ssl_verify_OCSP(ctx);
>             if (ocsp_response == OCSP_STATUS_REVOKED) {
>                 ok = 0 ;
>                 errnum = X509_STORE_CTX_get_error(ctx);
>             }
>             else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
>                 /* TODO: do nothing for time being */
>                 ;
>             }
>         }
>     }
> #endif
>     /*
>      * If we already know it's not ok, log the real reason
>      */
>     if (!ok) {
>         /* TODO: Some logging
>          * Certificate Verification: Error
>          */
>         if (con->peer) {
>             X509_free(con->peer);
>             con->peer = NULL;
>         }
>     }
>     if (errdepth > depth) {
>         /* TODO: Some logging
>          * Certificate Verification: Certificate Chain too long
>          */
>         ok = 0;
>     }
>     return ok;
> }
> 
> /*
>  * This callback function is executed while OpenSSL processes the SSL
>  * handshake and does SSL record layer stuff.  It's used to trap
>  * client-initiated renegotiations, and for dumping everything to the
>  * log.
>  */
> void SSL_callback_handshake(const SSL *ssl, int where, int rc)
> {
>          printf("SSL_callback_handshake\n");
>  tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
> #ifdef HAVE_TLSV1_3
>     const SSL_SESSION *session = SSL_get_session(ssl);
> #endif
> 
>     /* Retrieve the conn_rec and the associated SSLConnRec. */
>     if (con == NULL) {
>         return;
>     }
> 
> #ifdef HAVE_TLSV1_3
>     /* TLS 1.3 does not use renegotiation so do not update the renegotiation
>      * state once we know we are using TLS 1.3. */
>     if (session != NULL) {
>         if (SSL_SESSION_get_protocol_version(session) == TLS1_3_VERSION) {
>             return;
>         }
>     }
> #endif
> 
>     /* If the reneg state is to reject renegotiations, check the SSL
>      * state machine and move to ABORT if a Client Hello is being
>      * read. */
>     if ((where & SSL_CB_HANDSHAKE_START) &&
>          con->reneg_state == RENEG_REJECT) {
>         con->reneg_state = RENEG_ABORT;
>     }
>     /* If the first handshake is complete, change state to reject any
>      * subsequent client-initated renegotiation. */
>     else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == RENEG_INIT) {
>         con->reneg_state = RENEG_REJECT;
>     }
> }
> 
> int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
>                              unsigned int *len, void *arg)
> {
>       printf("SSL_callback_next_protos\n");
> tcn_ssl_ctxt_t *ssl_ctxt = arg;
> 
>     *data = ssl_ctxt->next_proto_data;
>     *len = ssl_ctxt->next_proto_len;
> 
>     return SSL_TLSEXT_ERR_OK;
> }
> 
> /* The code here is inspired by nghttp2
>  *
>  * See https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244 */
> int select_next_proto(SSL *ssl, const unsigned char **out, unsigned char *outlen,
>         const unsigned char *in, unsigned int inlen, unsigned char *supported_protos,
>         unsigned int supported_protos_len, int failure_behavior) {
>    printf("select_next_proto\n");
> 
>     unsigned int i = 0;
>     unsigned char target_proto_len;
>     const unsigned char *p;
>     const unsigned char *end;
>     const unsigned char *proto;
>     unsigned char proto_len = '\0';
> 
>     while (i < supported_protos_len) {
>         target_proto_len = *supported_protos;
>         ++supported_protos;
> 
>         p = in;
>         end = in + inlen;
> 
>         while (p < end) {
>             proto_len = *p;
>             proto = ++p;
> 
>             if (proto + proto_len <= end && target_proto_len == proto_len &&
>                     memcmp(supported_protos, proto, proto_len) == 0) {
> 
>                 // We found a match, so set the output and return with OK!
>                 *out = proto;
>                 *outlen = proto_len;
> 
>                 return SSL_TLSEXT_ERR_OK;
>             }
>             // Move on to the next protocol.
>             p += proto_len;
>         }
> 
>         // increment len and pointers.
>         i += target_proto_len;
>         supported_protos += target_proto_len;
>     }
> 
>     if (supported_protos_len > 0 && inlen > 0 && failure_behavior == SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
>          // There were no match but we just select our last protocol and hope the other peer support it.
>          //
>          // decrement the pointer again so the pointer points to the start of the protocol.
>          p -= proto_len;
>          *out = p;
>          *outlen = proto_len;
>          return SSL_TLSEXT_ERR_OK;
>     }
>     // TODO: OpenSSL currently not support to fail with fatal error. Once this changes we can also support it here.
>     //       Issue https://github.com/openssl/openssl/issues/188 has been created for this.
>     // Nothing matched so not select anything and just accept.
>     return SSL_TLSEXT_ERR_NOACK;
> }
> 
> int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out, unsigned char *outlen,
>                          const unsigned char *in, unsigned int inlen,
>                          void *arg) {
>     printf("ssl_callback_select_next_proto\n");
>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>     return select_next_proto(ssl, (const unsigned char **) out, outlen, in, inlen, ssl_ctxt->next_proto_data, ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
> }
> 
> int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
>         const unsigned char *in, unsigned int inlen, void *arg) {
>     tcn_ssl_ctxt_t *ssl_ctxt = arg;
>       printf("ssl_callback_alpn_select_proto\n");
>     return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior);
> }
> #ifdef HAVE_OCSP_STAPLING
> 
> /* Function that is used to do the OCSP verification */
> static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
> {
>      printf("ssl_verify_OCSP\n");
> 
> X509 *cert, *issuer;
>     int r = OCSP_STATUS_UNKNOWN;
>      printf("Hello, OCSP\n");
>     cert = X509_STORE_CTX_get_current_cert(ctx);
> 
>     if (!cert) {
>        printf("CERT NOT OK\n");
>  /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
>          * may yield NULL. Return early, but leave the ctx error as is. */
>         return OCSP_STATUS_UNKNOWN;
>     }
> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>     else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
> #else
>     /* No need to check cert->valid, because ssl_verify_OCSP() only
>      * is called if OpenSSL already successfully verified the certificate
>      * (parameter "ok" in SSL_callback_SSL_verify() must be true).
>      */
>     else if (X509_check_issued(cert,cert) == X509_V_OK) {
> #endif
>         /* don't do OCSP checking for valid self-issued certs */
>         X509_STORE_CTX_set_error(ctx, X509_V_OK);
>         return OCSP_STATUS_UNKNOWN;
>     }
> 
>     /* if we can't get the issuer, we cannot perform OCSP verification */
>     issuer = X509_STORE_CTX_get0_current_issuer(ctx);
>     if (issuer != NULL) {
>         r = ssl_ocsp_request(cert, issuer, ctx);
>         switch (r) {
>         case OCSP_STATUS_OK:
>             X509_STORE_CTX_set_error(ctx, X509_V_OK);
>             break;
>         case OCSP_STATUS_REVOKED:
>             /* we set the error if we know that it is revoked */
>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
>             break;
>         case OCSP_STATUS_UNKNOWN:
>             /* ssl_ocsp_request() sets the error correctly already. */
>             break;
>         }
>     }
>     return r;
> }
> 
> 
> /* Helps with error handling or realloc */
> static void *apr_xrealloc(void *buf, size_t oldlen, size_t len, apr_pool_t *p)
> {
>       printf("apr_xrealloc\n");
> void *newp = apr_palloc(p, len);
> 
>     if(newp)
>         memcpy(newp, buf, oldlen);
>     return newp;
> }
> 
> /* Parses an ASN.1 length.
>  * On entry, asn1 points to the current tag.
>  * Updates the pointer to the ASN.1 structure to point to the start of the data.
>  * Returns 0 on success, 1 on failure.
>  */
> static int parse_asn1_length(unsigned char **asn1, int *len) {
>   printf("parse_asn1_length\n");
>     /* Length immediately follows tag so increment before reading first (and
>      * possibly only) length byte.
>      */
>     (*asn1)++;
> 
>     if (**asn1 & 0x80) {
>         // MSB set. Remaining bits are number of bytes used to store the length.
>         int i, l;
> 
>         // How many bytes for this length?
>         i = **asn1 & 0x7F;
> 
>         if (i == 0) {
>             /* This is the indefinite form of length. Since certificates use DER
>              * this should never happen and is therefore an error.
>              */
>             return 1;
>         }
>         if (i > 3) {
>             /* Three bytes for length gives a maximum of 16MB which should be
>              * far more than is required. (2 bytes is 64K which is probably more
>              * than enough but play safe.)
>              */
>             return 1;
>         }
> 
>         // Most significant byte is first
>         l = 0;
>         while (i > 0) {
>             l <<= 8;
>             (*asn1)++;
>             l += **asn1;
>             i--;
>         }
>         *len = l;
>     } else {
>         // Single byte length
>         *len = **asn1;
>     }
> 
>     (*asn1)++;
> 
>     return 0;
> }
> 
> /* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables
>    returns 0 on success, 1 on failure */
> static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
>                           int *nocsp_urls, apr_pool_t *p)
> {
>   printf("parse_ocsp_url\n");
>     char **new_ocsp_urls, *ocsp_url;
>     int len, err = 0, new_nocsp_urls;
> 
>     if (*asn1 == ASN1_STRING) {
>         err = parse_asn1_length(&asn1, &len);
> 
>         if (!err) {
>             new_nocsp_urls = *nocsp_urls+1;
>             if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls, new_nocsp_urls, p)) == NULL)
>                 err = 1;
>         }
>         if (!err) {
>             *ocsp_urls  = new_ocsp_urls;
>             *nocsp_urls = new_nocsp_urls;
>             *(*ocsp_urls + *nocsp_urls) = NULL;
>             if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
>                 err = 1;
>             }
>             else {
>                 memcpy(ocsp_url, asn1, len);
>                 ocsp_url[len] = '\0';
>                 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
>             }
>         }
>     }
>     return err;
> 
> }
> 
> /* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url function */
> static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls, apr_pool_t *p)
> {
>   printf("PARSE  OCSP_OID\n");
>   int len, err = 0 ;
>     const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01};
> 
>     err = parse_asn1_length(&asn1, &len);
> 
>     if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
>         asn1+=len;
>         err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
>     }
>     return err;
> }
> 
> 
> /* Parses an ASN1 Sequence. It is a recursive function, since if it finds a  sequence
>    within the sequence it calls recursively itself. This function stops when it finds
>    the end of the ASN1 sequence (marked by '\0'), so if there are other sequences within
>    the same sequence the while loop parses the sequences */
> 
> /* This algo was developed with AIA in mind so it was tested only with this extension */
> static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
>                                int *nocsp_urls, apr_pool_t *p)
> {
>      printf("parse_ASN1_Sequence\n");
> 
>  int len = 0 , err = 0;
> 
>     while (!err && *asn1 != '\0') {
>         switch(*asn1) {
>             case ASN1_SEQUENCE:
>                 err = parse_asn1_length(&asn1, &len);
>                 if (!err) {
>                     err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls, p);
>                 }
>             break;
>             case ASN1_OID:
>                 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
>                 return err;
>             break;
>             default:
>                 err = 1; /* we shouldn't have any errors */
>             break;
>         }
>         asn1+=len;
>     }
>     return err;
> }
> 
> /* the main function that gets the ASN1 encoding string and returns
>    a pointer to a NULL terminated "array" of char *, that contains
>    the ocsp_urls */
> static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
> {
>         printf("decode_OCSP_url\n");
> 
> char **response = NULL;
>     unsigned char *ocsp_urls;
>     int len, numofresponses = 0 ;
> 
>     len = ASN1_STRING_length(os);
> 
>     ocsp_urls = apr_palloc(p,  len + 1);
>     memcpy(ocsp_urls,os->data, len);
>     ocsp_urls[len] = '\0';
> 
>     if ((response = apr_pcalloc(p, sizeof(char *))) == NULL)
>         return NULL;
>     if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p))
>         response = NULL;
>     return response;
> }
> 
> 
> /* stolen from openssl ocsp command */
> static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 *issuer)
> {
>       printf("add_ocsp_cert\n");
> OCSP_CERTID *id;
> 
>     if (!issuer)
>         return 0;
>     id = OCSP_cert_to_id(NULL, cert, issuer);
>     if (!id)
>         return 0;
>     if (!OCSP_request_add0_id(req, id)) {
>         OCSP_CERTID_free(id);
>         return 0;
>     } else {
>         /* id will be freed by OCSP_REQUEST_free() */
>         return 1;
>     }
> }
> 
> 
> /* Creates the APR socket and connect to the hostname. Returns the
>    socket or NULL if there is an error.
> */
> static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp)
> {
>      printf("*make_socket\n");
> apr_sockaddr_t *sa_in;
>     apr_status_t status;
>     apr_socket_t *sock = NULL;
> 
> 
>     status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp);
> 
>     if (status == APR_SUCCESS)
>         status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_TCP, mp);
>     if (status == APR_SUCCESS)
>         status = apr_socket_connect(sock, sa_in);
> 
>     if (status == APR_SUCCESS)
>         return sock;
>     return NULL;
> }
> 
> 
> /* Creates the request in a memory BIO in order to send it to the OCSP server.
>    Most parts of this function are taken from mod_ssl support for OCSP (with some
>    minor modifications
> */
> static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *path)
> {
>     printf("serialize_request\n");
> BIO *bio;
>     int len;
> 
>     len = i2d_OCSP_REQUEST(req, NULL);
> 
>     bio = BIO_new(BIO_s_mem());
> 
>     BIO_printf(bio, "POST %s HTTP/1.0\r\n"
>       "Host: %s:%d\r\n"
>       "Content-Type: application/ocsp-request\r\n"
>       "Content-Length: %d\r\n"
>       "\r\n",
>       path, host, port, len);
> 
>     if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
>         BIO_free(bio);
>         return NULL;
>     }
> 
>     return bio;
> }
> 
> 
> /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */
> static int ocsp_send_req(apr_socket_t *sock, BIO *req)
> {
>     printf("ocsp_send_req\n");
> int len;
>     char buf[TCN_BUFFER_SZ];
>     apr_status_t rv;
> 
>     while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
>         char *wbuf = buf;
>         apr_size_t remain = len;
> 
>         do {
>             apr_size_t wlen = remain;
>             rv = apr_socket_send(sock, wbuf, &wlen);
>             wbuf += remain;
>             remain -= wlen;
>         } while (rv == APR_SUCCESS && remain > 0);
> 
>         if (rv != APR_SUCCESS) {
>             return 0;
>         }
>     }
> 
>     return 1;
> }
> 
> 
> 
> /* Parses the buffer from the response and extracts the OCSP response.
>    Taken from openssl library */
> static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
> {
>  printf("parse_ocsp_resp\n");
>    BIO *mem = NULL;
>     char tmpbuf[1024];
>     OCSP_RESPONSE *resp = NULL;
>     char *p, *q, *r;
>     int retcode;
> 
>     mem = BIO_new(BIO_s_mem());
>     if(mem == NULL)
>         return NULL;
> 
>     BIO_write(mem, buf, len);  /* write the buffer to the bio */
>     if (BIO_gets(mem, tmpbuf, 512) <= 0) {
> #if OPENSSL_VERSION_NUMBER < 0x10100000L
>         OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
> #endif
>         goto err;
>     }
>     /* Parse the HTTP response. This will look like this:
>      * "HTTP/1.0 200 OK". We need to obtain the numeric code and
>      * (optional) informational message.
>      */
> 
>     /* Skip to first white space (passed protocol info) */
>     for (p = tmpbuf; *p && !apr_isspace(*p); p++)
>         continue;
>     if (!*p) {
>         goto err;
>     }
>     /* Skip past white space to start of response code */
>     while (apr_isspace(*p))
>         p++;
>     if (!*p) {
>         goto err;
>     }
>     /* Find end of response code: first whitespace after start of code */
>     for (q = p; *q && !apr_isspace(*q); q++)
>         continue;
>     if (!*q) {
>         goto err;
>     }
>     /* Set end of response code and start of message */
>     *q++ = 0;
>     /* Attempt to parse numeric code */
>     retcode = strtoul(p, &r, 10);
>     if (*r)
>         goto err;
>     /* Skip over any leading white space in message */
>     while (apr_isspace(*q))
>         q++;
>     if (*q) {
>         /* Finally zap any trailing white space in message (include CRLF) */
>         /* We know q has a non white space character so this is OK */
>         for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
>     }
>     if (retcode != 200) {
>         goto err;
>     }
>     /* Find blank line marking beginning of content */
>     while (BIO_gets(mem, tmpbuf, 512) > 0) {
>         for (p = tmpbuf; apr_isspace(*p); p++)
>             continue;
>         if (!*p)
>             break;
>     }
>     if (*p) {
>         goto err;
>     }
>     if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
>         goto err;
>     }
> err:
>     /* XXX No error logging? */
>     BIO_free(mem);
>     return resp;
> }
> 
> 
> /* Reads the response from the APR socket to a buffer, and parses the buffer to
>    return the OCSP response  */
> #define ADDLEN 512
> static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t *sock)
> {
>      printf("ocsp_get_resp\n");
> int buflen;
>     apr_size_t totalread = 0;
>     apr_size_t readlen;
>     char *buf, tmpbuf[ADDLEN];
>     apr_status_t rv = APR_SUCCESS;
>     apr_pool_t *p;
>     OCSP_RESPONSE *resp;
> 
>     apr_pool_create(&p, mp);
>     buflen = ADDLEN;
>     buf = apr_palloc(p, buflen);
>     if (buf == NULL) {
>         apr_pool_destroy(p);
>         return NULL;
>     }
> 
>     while (rv == APR_SUCCESS ) {
>         readlen = sizeof(tmpbuf);
>         rv = apr_socket_recv(sock, tmpbuf, &readlen);
>         if (rv == APR_SUCCESS) { /* if we have read something .. we can put it in the buffer*/
>             if ((totalread + readlen) >= buflen) {
>                 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
>                 if (buf == NULL) {
>                     apr_pool_destroy(p);
>                     return NULL;
>                 }
>                 buflen += ADDLEN; /* if needed we enlarge the buffer */
>             }
>             memcpy(buf + totalread, tmpbuf, readlen); /* the copy to the buffer */
>             totalread += readlen; /* update the total bytes read */
>         }
>         else {
>             if (rv == APR_EOF && readlen == 0)
>                 ; /* EOF, normal situation */
>             else if (readlen == 0) {
>                 /* Not success, and readlen == 0 .. some error */
>                 apr_pool_destroy(p);
>                 return NULL;
>             }
>         }
>     }
> 
>     resp = parse_ocsp_resp(buf, buflen);
>     apr_pool_destroy(p);
>     return resp;
> }
> 
> /* Creates and OCSP request and returns the OCSP_RESPONSE */
> static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert, X509 *issuer, char *url)
> {
>        printf("get_ocsp_response\n");
> OCSP_RESPONSE *ocsp_resp = NULL;
>     OCSP_REQUEST *ocsp_req = NULL;
>     BIO *bio_req;
>     char *hostname, *path, *c_port;
>     int port, use_ssl;
>     int ok = 0;
>     apr_socket_t *apr_sock = NULL;
>     apr_pool_t *mp;
> 
>     if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 )
>         goto end;
> 
>     if (sscanf(c_port, "%d", &port) != 1)
>         goto end;
> 
>     /* Create the OCSP request */
>     ocsp_req = OCSP_REQUEST_new();
>     if (ocsp_req == NULL)
>         goto end;
> 
>     if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
>         goto free_req;
> 
>     /* create the BIO with the request to send */
>     bio_req = serialize_request(ocsp_req, hostname, port, path);
>     if (bio_req == NULL) {
>         goto free_req;
>     }
> 
>     apr_pool_create(&mp, p);
>     apr_sock = make_socket(hostname, port, mp);
>     if (apr_sock == NULL) {
>         goto free_bio;
>     }
> 
>     ok = ocsp_send_req(apr_sock, bio_req);
>     if (ok) {
>         ocsp_resp = ocsp_get_resp(mp, apr_sock);
>     }
>     apr_socket_close(apr_sock);
> 
> free_bio:
>     BIO_free(bio_req);
>     apr_pool_destroy(mp);
> 
> free_req:
>     OCSP_REQUEST_free(ocsp_req);
> 
> end:
>     OPENSSL_free(hostname);
>     OPENSSL_free(c_port);
>     OPENSSL_free(path);
> 
>     return ocsp_resp;
> }
> 
> /* Process the OCSP_RESPONSE and returns the corresponding
>    answert according to the status.
> */
> static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509 *cert, X509 *issuer)
> {
>        printf("process_ocsp_response\n");
> int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
>     OCSP_BASICRESP *bs;
>     OCSP_SINGLERESP *ss;
>     OCSP_CERTID *certid;
> 
>     r = OCSP_response_status(ocsp_resp);
> 
>     if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
>         return OCSP_STATUS_UNKNOWN;
>     }
>     bs = OCSP_response_get1_basic(ocsp_resp);
> 
>     certid = OCSP_cert_to_id(NULL, cert, issuer);
>     if (certid == NULL) {
>         return OCSP_STATUS_UNKNOWN;
>     }
>     ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find by serial number and get the matching response */
> 
> 
>     i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
>     if (i == V_OCSP_CERTSTATUS_GOOD)
>         o =  OCSP_STATUS_OK;
>     else if (i == V_OCSP_CERTSTATUS_REVOKED)
>         o = OCSP_STATUS_REVOKED;
>     else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
>         o = OCSP_STATUS_UNKNOWN;
> 
>     /* we clean up */
>     OCSP_CERTID_free(certid);
>     OCSP_BASICRESP_free(bs);
>     return o;
> }
> 
> static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx)
> {
>      printf("ssl_ocsp_request\n");
>    char **ocsp_urls = NULL;
>     int nid;
>     X509_EXTENSION *ext;
>     ASN1_OCTET_STRING *os;
>     apr_pool_t *p;
> 
>     apr_pool_create(&p, NULL);
> 
>     /* Get the proper extension */
>     nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
>     if (nid >= 0 ) {
>         ext = X509_get_ext(cert,nid);
>         os = X509_EXTENSION_get_data(ext);
> 
>         ocsp_urls = decode_OCSP_url(os, p);
>     }
>      printf("OCSP request\n");
> 
>     /* if we find the extensions and we can parse it check
>        the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
>     if (ocsp_urls != NULL) {
>     printf("ocsp url not null\n");
>         OCSP_RESPONSE *resp;
>         int rv = OCSP_STATUS_UNKNOWN;
>         /* for the time being just check for the fist response .. a better
>            approach is to iterate for all the possible ocsp urls */
>         resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
>         if (resp != NULL) {
>             rv = process_ocsp_response(resp, cert, issuer);
>         } else {
>             /* correct error code for application errors? */
>             X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
>         }
> 
>         if (resp != NULL) {
>             OCSP_RESPONSE_free(resp);
>             apr_pool_destroy(p);
>             return rv;
>         }
>     }
>     apr_pool_destroy(p);
>     return OCSP_STATUS_UNKNOWN;
> }
> 
> #endif /* HAVE_OCSP_STAPLING */
> #endif /* HAVE_OPENSSL  */
> 
> 
> 
> 
> -----------------------------------------tomcat log
> 27-May-2019 14:15:59.727 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 31619 ms
>  SSL_init_app_data_idx
> Hi OCSP
> ssl_set_app_data3
> ssl_set_app_data4
> ssl_set_app_data2
> ssl_get_app_data3
> ssl_get_app_data4
> ssl_get_app_data4
> SSL_dh_GetParamFromFile
> SSL_ec_GetParamFromFile
> SSL_CTX_use_certificate_chain
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_next_protos
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_next_protos
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_next_protos
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_next_protos
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_next_protos
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callback_alpn_select_proto
> select_next_proto
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_set_app_data2
> SSL_callback_handshake
> SSL_callback_handshake
> SSL_callback_handshake
> ssl_callbac
> 
> 
> 
> ________________________________
> От: Усманов Азат Анварович <us...@ieml.ru>
> Отправлено: 24 мая 2019 г. 7:21
> Кому: Tomcat Users List
> Тема: Re: OCSP with openSSL
> 
> 
> 
> Chris,
> Yes the version is the same in
> /usr/local/openssl/bin/openssl as well.
> It is the same version Tomcat uses,I get this info in the logs
> 
> 23-May-2019 12:55:42.145 INFO [main] org.apache.catalina.core.AprLife
> cycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL
> 1.1.1a  20 Nov 2018]
> ________________________________
> От: Christopher Schultz <ch...@christopherschultz.net>
> Отправлено: 23 мая 2019 г. 18:04:29
> Кому: Усманов Азат Анварович
> Тема: Re: OCSP with openSSL
> 
> Азат,
> 
> On 5/22/19 14:02, Усманов Азат Анварович wrote:
>> [root] ~# openssl version
>> OpenSSL 1.1.1a  20 Nov 2018
> 
> Great. Is this also the same version in /usr/local/openssl/bin/openssl?
> 
>> [root] ~# openssl  ocsp -help
>> Usage: ocsp [options]
> 
> Excellent.
> 
> When you launch Tomcat, are you getting a message about the version of
> OpenSSL in use, and does it agree with above?
> 
> AFAIK, OCSP is enabled by default in libtcnative. There were some posts
> a few months/years ago about someone trying to get it to work, and
> having to edit the JVM's security.properties file and all kinds of weird
> stuff. I must admit it didn't make any sense to me at the time. I'm
> sorry, but I don't personally have any experience with dealing with
> OCSP, but hopefully this additio0nal information will give someone else
> some good info.
> 
> -chris
> 
>> ________________________________
>> От: Christopher Schultz <ch...@christopherschultz.net>
>> Отправлено: 22 мая 2019 г. 19:45
>> Кому: users@tomcat.apache.org
>> Тема: Re: OCSP with openSSL
>>
>> Усманов,
>>
>> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>>> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
>>> file from tomcat  website and issued  ./configure
>>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>>> -with-ssl=/usr/local/openssl && make && make install && make clean
>>> I'm not sure  how to specify any ocsp related configure options
>>> when building tomcat native    from source
>>
>> What is your OpenSSL version and capabilities?
>>
>> $ openssl version
>>
>> $ openssl -help
>>
>> $ openssl ocsp -help
>>
>> -chris
>>
>>> ________________________________ От: Mark Thomas
>>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>>
>>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>>> apr for TLS related issues. I m still unable to have OCSP
>>>> verification working with tomcat.
>>
>>> <snip/>
>>
>>>> I have tried running tcpdump on the server but don't' see any
>>>> Comodo related IP addresses in the output when I access the
>>>> server in question in the browser. At this point I don't know
>>>> what else to do, If it was java I would just put some
>>>> System.out.println statements in OCSP SSL related source code and
>>>> recompile the tomcat source, but since in my case tomcat uses
>>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>>> only places I found in the TC-native source that mentions OCSP
>>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>>> gets called in my case. Maybe be someone with more c experience
>>>> c++ would help me with that.  I really want to get to the bottom
>>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>>> based Apache Tomcat Native library [1.2.21] using APR version
>>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>>> Linux RHEL 6.6
>>
>>> How did you build the Tomcat Native library? Was OCSP enabled?
>>
>>> Mark
>>
>>> ---------------------------------------------------------------------
>>
>>
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>>
>>
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: OCSP with openSSL

Posted by Усманов Азат Анварович <us...@ieml.ru>.
Just a quick follow up , trying to get some answers, I added  include <stdio.h> to sslutils.c (which has alll the ocsp functions )   to print some info.I  added printf calls to every function defined in this file.  Interestingly enough  when I issue  the  openssl s_client -connect debug.ieml.ru:8443  -tls1_2 -status -proxy 192.168.1.6:3131
both tls1_2 and tls 1_3  versions and when I access  the server from another machine via browser none of printf  calls are displayed,  however, when I issue ssllabs server test (which is also supposedly capable of detecting ocsp)   some of them start to appear.  sadly none of them are ocsp related. I did put basic  ifdef  test for HAVE_OCSP_STAPLING, surprisingly  it  shows that ocsp support is indeed enabled . So here are  both   the modified  sslutils.c file and tomcat log snippet (not sure if attachments are allowed on  the list  so posting it  here )
Not sure where to go from here
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** SSL Utilities
 */

#include "tcn.h"
#include <stdio.h>
#ifdef HAVE_OPENSSL
#include "apr_poll.h"
#include "ssl_private.h"


#ifdef WIN32
extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
#endif

#ifdef HAVE_OCSP_STAPLING
#include <openssl/bio.h>
#include <openssl/ocsp.h>
/* defines with the values as seen by the asn1parse -dump openssl command */
#define ASN1_SEQUENCE 0x30
#define ASN1_OID      0x06
#define ASN1_STRING   0x86
static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx);
#endif

/*  _________________________________________________________________
**
**  Additional High-Level Functions for OpenSSL
**  _________________________________________________________________
*/

/* we initialize this index at startup time
 * and never write to it at request time,
 * so this static is thread safe.
 * also note that OpenSSL increments at static variable when
 * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
 */
static int SSL_app_data2_idx = -1;
static int SSL_app_data3_idx = -1;
static int SSL_app_data4_idx = -1;

void SSL_init_app_data_idx(void)
{ printf(" SSL_init_app_data_idx\n");
   #ifdef HAVE_OCSP_STAPLING
printf("Hi OCSP \n");
#else
printf("Sorry no OCSP support\n");
#endif

    int i;

    if (SSL_app_data2_idx > -1) {
        return;
    }

    /* we _do_ need to call this twice */
    for (i = 0; i <= 1; i++) {
        SSL_app_data2_idx =
            SSL_get_ex_new_index(0,
                                 "Second Application Data for SSL",
                                 NULL, NULL, NULL);
    }

    if (SSL_app_data3_idx > -1) {
        return;
    }

    SSL_app_data3_idx =
            SSL_get_ex_new_index(0,
                                 "Third Application Data for SSL",
                                  NULL, NULL, NULL);

    if (SSL_app_data4_idx > -1) {
        return;
    }

    SSL_app_data4_idx =
            SSL_get_ex_new_index(0,
                                 "Fourth Application Data for SSL",
                                  NULL, NULL, NULL);

}

void *SSL_get_app_data2(SSL *ssl)
{
     printf("ssl_get_app_data2 \n");
    return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
}

void SSL_set_app_data2(SSL *ssl, void *arg)
{
printf("ssl_set_app_data2 \n");

    SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
    return;
}


void *SSL_get_app_data3(const SSL *ssl)
{
printf("ssl_get_app_data3 \n");

    return SSL_get_ex_data(ssl, SSL_app_data3_idx);
}

void SSL_set_app_data3(SSL *ssl, void *arg)
{
printf("ssl_set_app_data3 \n");
    SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
}

void *SSL_get_app_data4(const SSL *ssl)
{
printf("ssl_get_app_data4 \n");
    return SSL_get_ex_data(ssl, SSL_app_data4_idx);
}

void SSL_set_app_data4(SSL *ssl, void *arg)
{
printf("ssl_set_app_data4 \n");
    SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
}

/* Simple echo password prompting */
int SSL_password_prompt(tcn_pass_cb_t *data)
{

    printf(" SSL_password_prompt\n");
int rv = 0;
    data->password[0] = '\0';
    if (data->cb.obj) {
        JNIEnv *e;
        jobject  o;
        jstring  prompt;
        tcn_get_java_env(&e);
        prompt = AJP_TO_JSTRING(data->prompt);
        if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
                            data->cb.mid[0], prompt))) {
            TCN_ALLOC_CSTRING(o);
            if (J2S(o)) {
                strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN);
                data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
                rv = (int)strlen(data->password);
            }
            TCN_FREE_CSTRING(o);
        }
    }
    else {
#ifdef WIN32
        rv = WIN32_SSL_password_prompt(data);
#else
        EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
                           data->prompt, 0);
#endif
        rv = (int)strlen(data->password);
    }
    if (rv > 0) {
        /* Remove LF char if present */
        char *r = strchr(data->password, '\n');
        if (r) {
            *r = '\0';
            rv--;
        }
#ifdef WIN32
        if ((r = strchr(data->password, '\r'))) {
            *r = '\0';
            rv--;
        }
#endif
    }
    return rv;
}

int SSL_password_callback(char *buf, int bufsiz, int verify,
                          void *cb)
{   printf("SSL_password_callback\n");
    tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;

    if (buf == NULL)
        return 0;
    *buf = '\0';
    if (cb_data == NULL)
        cb_data = &tcn_password_callback;
    if (!cb_data->prompt)
        cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
    if (cb_data->password[0]) {
        /* Return already obtained password */
        strncpy(buf, cb_data->password, bufsiz);
        buf[bufsiz - 1] = '\0';
        return (int)strlen(buf);
    }
    else {
        if (SSL_password_prompt(cb_data) > 0)
            strncpy(buf, cb_data->password, bufsiz);
    }
    buf[bufsiz - 1] = '\0';
    return (int)strlen(buf);
}

/*  _________________________________________________________________
**
**  Custom (EC)DH parameter support
**  _________________________________________________________________
*/
DH *SSL_dh_GetParamFromFile(const char *file)
{
   printf("SSL_dh_GetParamFromFile\n");
 DH *dh = NULL;
    BIO *bio;

    if ((bio = BIO_new_file(file, "r")) == NULL)
        return NULL;
    dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return dh;
}

#ifdef HAVE_ECC
EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
{

   printf("SSL_ec_GetParamFromFile\n");
EC_GROUP *group = NULL;
    BIO *bio;

    if ((bio = BIO_new_file(file, "r")) == NULL)
        return NULL;
    group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
    BIO_free(bio);
    return (group);
}
#endif

/*
 * Hand out standard DH parameters, based on the authentication strength
 */
DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
{
printf("SSL_callback_tmp_DH\n");
EVP_PKEY *pkey = SSL_get_privatekey(ssl);
    int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;

    /*
     * OpenSSL will call us with either keylen == 512 or keylen == 1024
     * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
     * Adjust the DH parameter length according to the size of the
     * RSA/DSA private key used for the current connection, and always
     * use at least 1024-bit parameters.
     * Note: This may cause interoperability issues with implementations
     * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
     * In this case, SSLCertificateFile can be used to specify fixed
     * 1024-bit DH parameters (with the effect that OpenSSL skips this
     * callback).
     */
    if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
        keylen = EVP_PKEY_bits(pkey);
    }
    return SSL_get_dh_params(keylen);
}

/*
 * Read a file that optionally contains the server certificate in PEM
 * format, possibly followed by a sequence of CA certificates that
 * should be sent to the peer in the SSL Certificate message.
 */
int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
                                  int skipfirst)
{
     printf("SSL_CTX_use_certificate_chain\n");

    BIO *bio;
    X509 *x509;
    unsigned long err;
    int n;

    if ((bio = BIO_new(BIO_s_file())) == NULL)
        return -1;
    if (BIO_read_filename(bio, file) <= 0) {
        BIO_free(bio);
        return -1;
    }
    /* optionally skip a leading server certificate */
    if (skipfirst) {
        if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
            BIO_free(bio);
            return -1;
        }
        X509_free(x509);
    }

    /* free a perhaps already configured extra chain */
    SSL_CTX_clear_extra_chain_certs(ctx);

    /* create new extra chain by loading the certs */
    n = 0;
    while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
        if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
            X509_free(x509);
            BIO_free(bio);
            return -1;
        }
        n++;
    }
    /* Make sure that only the error is just an EOF */
    if ((err = ERR_peek_error()) > 0) {
        if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
              && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
            BIO_free(bio);
            return -1;
        }
        while (SSL_ERR_get() > 0) ;
    }
    BIO_free(bio);
    return n;
}

/*
 * This OpenSSL callback function is called when OpenSSL
 * does client authentication and verifies the certificate chain.
 */


int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
{
     printf("SSL_callback_SSL_verify\n");
/* Get Apache context back through OpenSSL context */
    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
                                          SSL_get_ex_data_X509_STORE_CTX_idx());
    tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
    /* Get verify ingredients */
    int errnum   = X509_STORE_CTX_get_error(ctx);
    int errdepth = X509_STORE_CTX_get_error_depth(ctx);
    int verify   = con->ctx->verify_mode;
    int depth    = con->ctx->verify_depth;

#if defined(SSL_OP_NO_TLSv1_3)
    con->pha_state = PHA_COMPLETE;
#endif

    if (verify == SSL_CVERIFY_UNSET ||
        verify == SSL_CVERIFY_NONE) {
        return 1;
    }

    if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
        (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
        ok = 1;
        SSL_set_verify_result(ssl, X509_V_OK);
    }

    /*
     * Expired certificates vs. "expired" CRLs: by default, OpenSSL
     * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
     * SSL alert, but that's not really the message we should convey to the
     * peer (at the very least, it's confusing, and in many cases, it's also
     * inaccurate, as the certificate itself may very well not have expired
     * yet). We set the X509_STORE_CTX error to something which OpenSSL's
     * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
     * i.e. the peer will receive a "certificate_unknown(46)" alert.
     * We do not touch errnum, though, so that later on we will still log
     * the "real" error, as returned by OpenSSL.
     */
    if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
        X509_STORE_CTX_set_error(ctx, -1);
    }

#ifdef HAVE_OCSP_STAPLING
    /* First perform OCSP validation if possible */
    if (ok) {
        /* If there was an optional verification error, it's not
         * possible to perform OCSP validation since the issuer may be
         * missing/untrusted.  Fail in that case.
         */
        if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
            errnum = X509_V_ERR_APPLICATION_VERIFICATION;
            ok = 0;
        }
        else {
            int ocsp_response = ssl_verify_OCSP(ctx);
            if (ocsp_response == OCSP_STATUS_REVOKED) {
                ok = 0 ;
                errnum = X509_STORE_CTX_get_error(ctx);
            }
            else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
                /* TODO: do nothing for time being */
                ;
            }
        }
    }
#endif
    /*
     * If we already know it's not ok, log the real reason
     */
    if (!ok) {
        /* TODO: Some logging
         * Certificate Verification: Error
         */
        if (con->peer) {
            X509_free(con->peer);
            con->peer = NULL;
        }
    }
    if (errdepth > depth) {
        /* TODO: Some logging
         * Certificate Verification: Certificate Chain too long
         */
        ok = 0;
    }
    return ok;
}

/*
 * This callback function is executed while OpenSSL processes the SSL
 * handshake and does SSL record layer stuff.  It's used to trap
 * client-initiated renegotiations, and for dumping everything to the
 * log.
 */
void SSL_callback_handshake(const SSL *ssl, int where, int rc)
{
         printf("SSL_callback_handshake\n");
 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
#ifdef HAVE_TLSV1_3
    const SSL_SESSION *session = SSL_get_session(ssl);
#endif

    /* Retrieve the conn_rec and the associated SSLConnRec. */
    if (con == NULL) {
        return;
    }

#ifdef HAVE_TLSV1_3
    /* TLS 1.3 does not use renegotiation so do not update the renegotiation
     * state once we know we are using TLS 1.3. */
    if (session != NULL) {
        if (SSL_SESSION_get_protocol_version(session) == TLS1_3_VERSION) {
            return;
        }
    }
#endif

    /* If the reneg state is to reject renegotiations, check the SSL
     * state machine and move to ABORT if a Client Hello is being
     * read. */
    if ((where & SSL_CB_HANDSHAKE_START) &&
         con->reneg_state == RENEG_REJECT) {
        con->reneg_state = RENEG_ABORT;
    }
    /* If the first handshake is complete, change state to reject any
     * subsequent client-initated renegotiation. */
    else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == RENEG_INIT) {
        con->reneg_state = RENEG_REJECT;
    }
}

int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
                             unsigned int *len, void *arg)
{
      printf("SSL_callback_next_protos\n");
tcn_ssl_ctxt_t *ssl_ctxt = arg;

    *data = ssl_ctxt->next_proto_data;
    *len = ssl_ctxt->next_proto_len;

    return SSL_TLSEXT_ERR_OK;
}

/* The code here is inspired by nghttp2
 *
 * See https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244 */
int select_next_proto(SSL *ssl, const unsigned char **out, unsigned char *outlen,
        const unsigned char *in, unsigned int inlen, unsigned char *supported_protos,
        unsigned int supported_protos_len, int failure_behavior) {
   printf("select_next_proto\n");

    unsigned int i = 0;
    unsigned char target_proto_len;
    const unsigned char *p;
    const unsigned char *end;
    const unsigned char *proto;
    unsigned char proto_len = '\0';

    while (i < supported_protos_len) {
        target_proto_len = *supported_protos;
        ++supported_protos;

        p = in;
        end = in + inlen;

        while (p < end) {
            proto_len = *p;
            proto = ++p;

            if (proto + proto_len <= end && target_proto_len == proto_len &&
                    memcmp(supported_protos, proto, proto_len) == 0) {

                // We found a match, so set the output and return with OK!
                *out = proto;
                *outlen = proto_len;

                return SSL_TLSEXT_ERR_OK;
            }
            // Move on to the next protocol.
            p += proto_len;
        }

        // increment len and pointers.
        i += target_proto_len;
        supported_protos += target_proto_len;
    }

    if (supported_protos_len > 0 && inlen > 0 && failure_behavior == SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
         // There were no match but we just select our last protocol and hope the other peer support it.
         //
         // decrement the pointer again so the pointer points to the start of the protocol.
         p -= proto_len;
         *out = p;
         *outlen = proto_len;
         return SSL_TLSEXT_ERR_OK;
    }
    // TODO: OpenSSL currently not support to fail with fatal error. Once this changes we can also support it here.
    //       Issue https://github.com/openssl/openssl/issues/188 has been created for this.
    // Nothing matched so not select anything and just accept.
    return SSL_TLSEXT_ERR_NOACK;
}

int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out, unsigned char *outlen,
                         const unsigned char *in, unsigned int inlen,
                         void *arg) {
    printf("ssl_callback_select_next_proto\n");
    tcn_ssl_ctxt_t *ssl_ctxt = arg;
    return select_next_proto(ssl, (const unsigned char **) out, outlen, in, inlen, ssl_ctxt->next_proto_data, ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
}

int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
        const unsigned char *in, unsigned int inlen, void *arg) {
    tcn_ssl_ctxt_t *ssl_ctxt = arg;
      printf("ssl_callback_alpn_select_proto\n");
    return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior);
}
#ifdef HAVE_OCSP_STAPLING

/* Function that is used to do the OCSP verification */
static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
{
     printf("ssl_verify_OCSP\n");

X509 *cert, *issuer;
    int r = OCSP_STATUS_UNKNOWN;
     printf("Hello, OCSP\n");
    cert = X509_STORE_CTX_get_current_cert(ctx);

    if (!cert) {
       printf("CERT NOT OK\n");
 /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
         * may yield NULL. Return early, but leave the ctx error as is. */
        return OCSP_STATUS_UNKNOWN;
    }
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
#else
    /* No need to check cert->valid, because ssl_verify_OCSP() only
     * is called if OpenSSL already successfully verified the certificate
     * (parameter "ok" in SSL_callback_SSL_verify() must be true).
     */
    else if (X509_check_issued(cert,cert) == X509_V_OK) {
#endif
        /* don't do OCSP checking for valid self-issued certs */
        X509_STORE_CTX_set_error(ctx, X509_V_OK);
        return OCSP_STATUS_UNKNOWN;
    }

    /* if we can't get the issuer, we cannot perform OCSP verification */
    issuer = X509_STORE_CTX_get0_current_issuer(ctx);
    if (issuer != NULL) {
        r = ssl_ocsp_request(cert, issuer, ctx);
        switch (r) {
        case OCSP_STATUS_OK:
            X509_STORE_CTX_set_error(ctx, X509_V_OK);
            break;
        case OCSP_STATUS_REVOKED:
            /* we set the error if we know that it is revoked */
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
            break;
        case OCSP_STATUS_UNKNOWN:
            /* ssl_ocsp_request() sets the error correctly already. */
            break;
        }
    }
    return r;
}


/* Helps with error handling or realloc */
static void *apr_xrealloc(void *buf, size_t oldlen, size_t len, apr_pool_t *p)
{
      printf("apr_xrealloc\n");
void *newp = apr_palloc(p, len);

    if(newp)
        memcpy(newp, buf, oldlen);
    return newp;
}

/* Parses an ASN.1 length.
 * On entry, asn1 points to the current tag.
 * Updates the pointer to the ASN.1 structure to point to the start of the data.
 * Returns 0 on success, 1 on failure.
 */
static int parse_asn1_length(unsigned char **asn1, int *len) {
  printf("parse_asn1_length\n");
    /* Length immediately follows tag so increment before reading first (and
     * possibly only) length byte.
     */
    (*asn1)++;

    if (**asn1 & 0x80) {
        // MSB set. Remaining bits are number of bytes used to store the length.
        int i, l;

        // How many bytes for this length?
        i = **asn1 & 0x7F;

        if (i == 0) {
            /* This is the indefinite form of length. Since certificates use DER
             * this should never happen and is therefore an error.
             */
            return 1;
        }
        if (i > 3) {
            /* Three bytes for length gives a maximum of 16MB which should be
             * far more than is required. (2 bytes is 64K which is probably more
             * than enough but play safe.)
             */
            return 1;
        }

        // Most significant byte is first
        l = 0;
        while (i > 0) {
            l <<= 8;
            (*asn1)++;
            l += **asn1;
            i--;
        }
        *len = l;
    } else {
        // Single byte length
        *len = **asn1;
    }

    (*asn1)++;

    return 0;
}

/* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables
   returns 0 on success, 1 on failure */
static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
                          int *nocsp_urls, apr_pool_t *p)
{
  printf("parse_ocsp_url\n");
    char **new_ocsp_urls, *ocsp_url;
    int len, err = 0, new_nocsp_urls;

    if (*asn1 == ASN1_STRING) {
        err = parse_asn1_length(&asn1, &len);

        if (!err) {
            new_nocsp_urls = *nocsp_urls+1;
            if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls, new_nocsp_urls, p)) == NULL)
                err = 1;
        }
        if (!err) {
            *ocsp_urls  = new_ocsp_urls;
            *nocsp_urls = new_nocsp_urls;
            *(*ocsp_urls + *nocsp_urls) = NULL;
            if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
                err = 1;
            }
            else {
                memcpy(ocsp_url, asn1, len);
                ocsp_url[len] = '\0';
                *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
            }
        }
    }
    return err;

}

/* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url function */
static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls, apr_pool_t *p)
{
  printf("PARSE  OCSP_OID\n");
  int len, err = 0 ;
    const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01};

    err = parse_asn1_length(&asn1, &len);

    if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
        asn1+=len;
        err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
    }
    return err;
}


/* Parses an ASN1 Sequence. It is a recursive function, since if it finds a  sequence
   within the sequence it calls recursively itself. This function stops when it finds
   the end of the ASN1 sequence (marked by '\0'), so if there are other sequences within
   the same sequence the while loop parses the sequences */

/* This algo was developed with AIA in mind so it was tested only with this extension */
static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
                               int *nocsp_urls, apr_pool_t *p)
{
     printf("parse_ASN1_Sequence\n");

 int len = 0 , err = 0;

    while (!err && *asn1 != '\0') {
        switch(*asn1) {
            case ASN1_SEQUENCE:
                err = parse_asn1_length(&asn1, &len);
                if (!err) {
                    err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls, p);
                }
            break;
            case ASN1_OID:
                err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
                return err;
            break;
            default:
                err = 1; /* we shouldn't have any errors */
            break;
        }
        asn1+=len;
    }
    return err;
}

/* the main function that gets the ASN1 encoding string and returns
   a pointer to a NULL terminated "array" of char *, that contains
   the ocsp_urls */
static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
{
        printf("decode_OCSP_url\n");

char **response = NULL;
    unsigned char *ocsp_urls;
    int len, numofresponses = 0 ;

    len = ASN1_STRING_length(os);

    ocsp_urls = apr_palloc(p,  len + 1);
    memcpy(ocsp_urls,os->data, len);
    ocsp_urls[len] = '\0';

    if ((response = apr_pcalloc(p, sizeof(char *))) == NULL)
        return NULL;
    if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p))
        response = NULL;
    return response;
}


/* stolen from openssl ocsp command */
static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 *issuer)
{
      printf("add_ocsp_cert\n");
OCSP_CERTID *id;

    if (!issuer)
        return 0;
    id = OCSP_cert_to_id(NULL, cert, issuer);
    if (!id)
        return 0;
    if (!OCSP_request_add0_id(req, id)) {
        OCSP_CERTID_free(id);
        return 0;
    } else {
        /* id will be freed by OCSP_REQUEST_free() */
        return 1;
    }
}


/* Creates the APR socket and connect to the hostname. Returns the
   socket or NULL if there is an error.
*/
static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp)
{
     printf("*make_socket\n");
apr_sockaddr_t *sa_in;
    apr_status_t status;
    apr_socket_t *sock = NULL;


    status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp);

    if (status == APR_SUCCESS)
        status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_TCP, mp);
    if (status == APR_SUCCESS)
        status = apr_socket_connect(sock, sa_in);

    if (status == APR_SUCCESS)
        return sock;
    return NULL;
}


/* Creates the request in a memory BIO in order to send it to the OCSP server.
   Most parts of this function are taken from mod_ssl support for OCSP (with some
   minor modifications
*/
static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *path)
{
    printf("serialize_request\n");
BIO *bio;
    int len;

    len = i2d_OCSP_REQUEST(req, NULL);

    bio = BIO_new(BIO_s_mem());

    BIO_printf(bio, "POST %s HTTP/1.0\r\n"
      "Host: %s:%d\r\n"
      "Content-Type: application/ocsp-request\r\n"
      "Content-Length: %d\r\n"
      "\r\n",
      path, host, port, len);

    if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
        BIO_free(bio);
        return NULL;
    }

    return bio;
}


/* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */
static int ocsp_send_req(apr_socket_t *sock, BIO *req)
{
    printf("ocsp_send_req\n");
int len;
    char buf[TCN_BUFFER_SZ];
    apr_status_t rv;

    while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
        char *wbuf = buf;
        apr_size_t remain = len;

        do {
            apr_size_t wlen = remain;
            rv = apr_socket_send(sock, wbuf, &wlen);
            wbuf += remain;
            remain -= wlen;
        } while (rv == APR_SUCCESS && remain > 0);

        if (rv != APR_SUCCESS) {
            return 0;
        }
    }

    return 1;
}



/* Parses the buffer from the response and extracts the OCSP response.
   Taken from openssl library */
static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
{
 printf("parse_ocsp_resp\n");
   BIO *mem = NULL;
    char tmpbuf[1024];
    OCSP_RESPONSE *resp = NULL;
    char *p, *q, *r;
    int retcode;

    mem = BIO_new(BIO_s_mem());
    if(mem == NULL)
        return NULL;

    BIO_write(mem, buf, len);  /* write the buffer to the bio */
    if (BIO_gets(mem, tmpbuf, 512) <= 0) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
#endif
        goto err;
    }
    /* Parse the HTTP response. This will look like this:
     * "HTTP/1.0 200 OK". We need to obtain the numeric code and
     * (optional) informational message.
     */

    /* Skip to first white space (passed protocol info) */
    for (p = tmpbuf; *p && !apr_isspace(*p); p++)
        continue;
    if (!*p) {
        goto err;
    }
    /* Skip past white space to start of response code */
    while (apr_isspace(*p))
        p++;
    if (!*p) {
        goto err;
    }
    /* Find end of response code: first whitespace after start of code */
    for (q = p; *q && !apr_isspace(*q); q++)
        continue;
    if (!*q) {
        goto err;
    }
    /* Set end of response code and start of message */
    *q++ = 0;
    /* Attempt to parse numeric code */
    retcode = strtoul(p, &r, 10);
    if (*r)
        goto err;
    /* Skip over any leading white space in message */
    while (apr_isspace(*q))
        q++;
    if (*q) {
        /* Finally zap any trailing white space in message (include CRLF) */
        /* We know q has a non white space character so this is OK */
        for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
    }
    if (retcode != 200) {
        goto err;
    }
    /* Find blank line marking beginning of content */
    while (BIO_gets(mem, tmpbuf, 512) > 0) {
        for (p = tmpbuf; apr_isspace(*p); p++)
            continue;
        if (!*p)
            break;
    }
    if (*p) {
        goto err;
    }
    if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
        goto err;
    }
err:
    /* XXX No error logging? */
    BIO_free(mem);
    return resp;
}


/* Reads the response from the APR socket to a buffer, and parses the buffer to
   return the OCSP response  */
#define ADDLEN 512
static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t *sock)
{
     printf("ocsp_get_resp\n");
int buflen;
    apr_size_t totalread = 0;
    apr_size_t readlen;
    char *buf, tmpbuf[ADDLEN];
    apr_status_t rv = APR_SUCCESS;
    apr_pool_t *p;
    OCSP_RESPONSE *resp;

    apr_pool_create(&p, mp);
    buflen = ADDLEN;
    buf = apr_palloc(p, buflen);
    if (buf == NULL) {
        apr_pool_destroy(p);
        return NULL;
    }

    while (rv == APR_SUCCESS ) {
        readlen = sizeof(tmpbuf);
        rv = apr_socket_recv(sock, tmpbuf, &readlen);
        if (rv == APR_SUCCESS) { /* if we have read something .. we can put it in the buffer*/
            if ((totalread + readlen) >= buflen) {
                buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
                if (buf == NULL) {
                    apr_pool_destroy(p);
                    return NULL;
                }
                buflen += ADDLEN; /* if needed we enlarge the buffer */
            }
            memcpy(buf + totalread, tmpbuf, readlen); /* the copy to the buffer */
            totalread += readlen; /* update the total bytes read */
        }
        else {
            if (rv == APR_EOF && readlen == 0)
                ; /* EOF, normal situation */
            else if (readlen == 0) {
                /* Not success, and readlen == 0 .. some error */
                apr_pool_destroy(p);
                return NULL;
            }
        }
    }

    resp = parse_ocsp_resp(buf, buflen);
    apr_pool_destroy(p);
    return resp;
}

/* Creates and OCSP request and returns the OCSP_RESPONSE */
static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert, X509 *issuer, char *url)
{
       printf("get_ocsp_response\n");
OCSP_RESPONSE *ocsp_resp = NULL;
    OCSP_REQUEST *ocsp_req = NULL;
    BIO *bio_req;
    char *hostname, *path, *c_port;
    int port, use_ssl;
    int ok = 0;
    apr_socket_t *apr_sock = NULL;
    apr_pool_t *mp;

    if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 )
        goto end;

    if (sscanf(c_port, "%d", &port) != 1)
        goto end;

    /* Create the OCSP request */
    ocsp_req = OCSP_REQUEST_new();
    if (ocsp_req == NULL)
        goto end;

    if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
        goto free_req;

    /* create the BIO with the request to send */
    bio_req = serialize_request(ocsp_req, hostname, port, path);
    if (bio_req == NULL) {
        goto free_req;
    }

    apr_pool_create(&mp, p);
    apr_sock = make_socket(hostname, port, mp);
    if (apr_sock == NULL) {
        goto free_bio;
    }

    ok = ocsp_send_req(apr_sock, bio_req);
    if (ok) {
        ocsp_resp = ocsp_get_resp(mp, apr_sock);
    }
    apr_socket_close(apr_sock);

free_bio:
    BIO_free(bio_req);
    apr_pool_destroy(mp);

free_req:
    OCSP_REQUEST_free(ocsp_req);

end:
    OPENSSL_free(hostname);
    OPENSSL_free(c_port);
    OPENSSL_free(path);

    return ocsp_resp;
}

/* Process the OCSP_RESPONSE and returns the corresponding
   answert according to the status.
*/
static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509 *cert, X509 *issuer)
{
       printf("process_ocsp_response\n");
int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
    OCSP_BASICRESP *bs;
    OCSP_SINGLERESP *ss;
    OCSP_CERTID *certid;

    r = OCSP_response_status(ocsp_resp);

    if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        return OCSP_STATUS_UNKNOWN;
    }
    bs = OCSP_response_get1_basic(ocsp_resp);

    certid = OCSP_cert_to_id(NULL, cert, issuer);
    if (certid == NULL) {
        return OCSP_STATUS_UNKNOWN;
    }
    ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find by serial number and get the matching response */


    i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
    if (i == V_OCSP_CERTSTATUS_GOOD)
        o =  OCSP_STATUS_OK;
    else if (i == V_OCSP_CERTSTATUS_REVOKED)
        o = OCSP_STATUS_REVOKED;
    else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
        o = OCSP_STATUS_UNKNOWN;

    /* we clean up */
    OCSP_CERTID_free(certid);
    OCSP_BASICRESP_free(bs);
    return o;
}

static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx)
{
     printf("ssl_ocsp_request\n");
   char **ocsp_urls = NULL;
    int nid;
    X509_EXTENSION *ext;
    ASN1_OCTET_STRING *os;
    apr_pool_t *p;

    apr_pool_create(&p, NULL);

    /* Get the proper extension */
    nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
    if (nid >= 0 ) {
        ext = X509_get_ext(cert,nid);
        os = X509_EXTENSION_get_data(ext);

        ocsp_urls = decode_OCSP_url(os, p);
    }
     printf("OCSP request\n");

    /* if we find the extensions and we can parse it check
       the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
    if (ocsp_urls != NULL) {
    printf("ocsp url not null\n");
        OCSP_RESPONSE *resp;
        int rv = OCSP_STATUS_UNKNOWN;
        /* for the time being just check for the fist response .. a better
           approach is to iterate for all the possible ocsp urls */
        resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
        if (resp != NULL) {
            rv = process_ocsp_response(resp, cert, issuer);
        } else {
            /* correct error code for application errors? */
            X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
        }

        if (resp != NULL) {
            OCSP_RESPONSE_free(resp);
            apr_pool_destroy(p);
            return rv;
        }
    }
    apr_pool_destroy(p);
    return OCSP_STATUS_UNKNOWN;
}

#endif /* HAVE_OCSP_STAPLING */
#endif /* HAVE_OPENSSL  */




-----------------------------------------tomcat log
27-May-2019 14:15:59.727 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 31619 ms
 SSL_init_app_data_idx
Hi OCSP
ssl_set_app_data3
ssl_set_app_data4
ssl_set_app_data2
ssl_get_app_data3
ssl_get_app_data4
ssl_get_app_data4
SSL_dh_GetParamFromFile
SSL_ec_GetParamFromFile
SSL_CTX_use_certificate_chain
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_next_protos
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_next_protos
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_next_protos
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_next_protos
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_next_protos
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callback_alpn_select_proto
select_next_proto
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_set_app_data2
SSL_callback_handshake
SSL_callback_handshake
SSL_callback_handshake
ssl_callbac



________________________________
От: Усманов Азат Анварович <us...@ieml.ru>
Отправлено: 24 мая 2019 г. 7:21
Кому: Tomcat Users List
Тема: Re: OCSP with openSSL



Chris,
Yes the version is the same in
/usr/local/openssl/bin/openssl as well.
It is the same version Tomcat uses,I get this info in the logs

23-May-2019 12:55:42.145 INFO [main] org.apache.catalina.core.AprLife
cycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL
1.1.1a  20 Nov 2018]
________________________________
От: Christopher Schultz <ch...@christopherschultz.net>
Отправлено: 23 мая 2019 г. 18:04:29
Кому: Усманов Азат Анварович
Тема: Re: OCSP with openSSL

Азат,

On 5/22/19 14:02, Усманов Азат Анварович wrote:
> [root] ~# openssl version
> OpenSSL 1.1.1a  20 Nov 2018

Great. Is this also the same version in /usr/local/openssl/bin/openssl?

> [root] ~# openssl  ocsp -help
> Usage: ocsp [options]

Excellent.

When you launch Tomcat, are you getting a message about the version of
OpenSSL in use, and does it agree with above?

AFAIK, OCSP is enabled by default in libtcnative. There were some posts
a few months/years ago about someone trying to get it to work, and
having to edit the JVM's security.properties file and all kinds of weird
stuff. I must admit it didn't make any sense to me at the time. I'm
sorry, but I don't personally have any experience with dealing with
OCSP, but hopefully this additio0nal information will give someone else
some good info.

-chris

> ________________________________
> От: Christopher Schultz <ch...@christopherschultz.net>
> Отправлено: 22 мая 2019 г. 19:45
> Кому: users@tomcat.apache.org
> Тема: Re: OCSP with openSSL
>
> Усманов,
>
> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
>> file from tomcat  website and issued  ./configure
>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>> -with-ssl=/usr/local/openssl && make && make install && make clean
>> I'm not sure  how to specify any ocsp related configure options
>> when building tomcat native    from source
>
> What is your OpenSSL version and capabilities?
>
> $ openssl version
>
> $ openssl -help
>
> $ openssl ocsp -help
>
> -chris
>
>> ________________________________ От: Mark Thomas
>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>
>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>> apr for TLS related issues. I m still unable to have OCSP
>>> verification working with tomcat.
>
>> <snip/>
>
>>> I have tried running tcpdump on the server but don't' see any
>>> Comodo related IP addresses in the output when I access the
>>> server in question in the browser. At this point I don't know
>>> what else to do, If it was java I would just put some
>>> System.out.println statements in OCSP SSL related source code and
>>> recompile the tomcat source, but since in my case tomcat uses
>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>> only places I found in the TC-native source that mentions OCSP
>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>> gets called in my case. Maybe be someone with more c experience
>>> c++ would help me with that.  I really want to get to the bottom
>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>> based Apache Tomcat Native library [1.2.21] using APR version
>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>> Linux RHEL 6.6
>
>> How did you build the Tomcat Native library? Was OCSP enabled?
>
>> Mark
>
>> ---------------------------------------------------------------------
>
>
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>


Re: OCSP with openSSL

Posted by Усманов Азат Анварович <us...@ieml.ru>.

Chris,
Yes the version is the same in
/usr/local/openssl/bin/openssl as well.
It is the same version Tomcat uses,I get this info in the logs

23-May-2019 12:55:42.145 INFO [main] org.apache.catalina.core.AprLife
cycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL
1.1.1a  20 Nov 2018]
________________________________
От: Christopher Schultz <ch...@christopherschultz.net>
Отправлено: 23 мая 2019 г. 18:04:29
Кому: Усманов Азат Анварович
Тема: Re: OCSP with openSSL

Азат,

On 5/22/19 14:02, Усманов Азат Анварович wrote:
> [root] ~# openssl version
> OpenSSL 1.1.1a  20 Nov 2018

Great. Is this also the same version in /usr/local/openssl/bin/openssl?

> [root] ~# openssl  ocsp -help
> Usage: ocsp [options]

Excellent.

When you launch Tomcat, are you getting a message about the version of
OpenSSL in use, and does it agree with above?

AFAIK, OCSP is enabled by default in libtcnative. There were some posts
a few months/years ago about someone trying to get it to work, and
having to edit the JVM's security.properties file and all kinds of weird
stuff. I must admit it didn't make any sense to me at the time. I'm
sorry, but I don't personally have any experience with dealing with
OCSP, but hopefully this additio0nal information will give someone else
some good info.

-chris

> ________________________________
> От: Christopher Schultz <ch...@christopherschultz.net>
> Отправлено: 22 мая 2019 г. 19:45
> Кому: users@tomcat.apache.org
> Тема: Re: OCSP with openSSL
>
> Усманов,
>
> On 5/22/19 07:28, Усманов Азат Анварович wrote:
>> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
>> file from tomcat  website and issued  ./configure
>> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
>> -with-ssl=/usr/local/openssl && make && make install && make clean
>> I'm not sure  how to specify any ocsp related configure options
>> when building tomcat native    from source
>
> What is your OpenSSL version and capabilities?
>
> $ openssl version
>
> $ openssl -help
>
> $ openssl ocsp -help
>
> -chris
>
>> ________________________________ От: Mark Thomas
>> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
>> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>
>> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>>> Hi everyone! I have a web app running on tomcat and java 7 using
>>> apr for TLS related issues. I m still unable to have OCSP
>>> verification working with tomcat.
>
>> <snip/>
>
>>> I have tried running tcpdump on the server but don't' see any
>>> Comodo related IP addresses in the output when I access the
>>> server in question in the browser. At this point I don't know
>>> what else to do, If it was java I would just put some
>>> System.out.println statements in OCSP SSL related source code and
>>> recompile the tomcat source, but since in my case tomcat uses
>>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>>> only places I found in the TC-native source that mentions OCSP
>>> is sslutils.c  source file. I'm not sure when/ if it is actually
>>> gets called in my case. Maybe be someone with more c experience
>>> c++ would help me with that.  I really want to get to the bottom
>>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>>> based Apache Tomcat Native library [1.2.21] using APR version
>>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>>> Linux RHEL 6.6
>
>> How did you build the Tomcat Native library? Was OCSP enabled?
>
>> Mark
>
>> ---------------------------------------------------------------------
>
>
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>


RE: OCSP with openSSL

Posted by Усманов Азат Анварович <us...@ieml.ru>.
Chris,
[root] ~# openssl version
OpenSSL 1.1.1a  20 Nov 2018
[root] ~# openssl help
Standard commands
asn1parse         ca                ciphers           cms
crl               crl2pkcs7         dgst              dhparam
dsa               dsaparam          ec                ecparam
enc               engine            errstr            gendsa
genpkey           genrsa            help              list
nseq              ocsp              passwd            pkcs12
pkcs7             pkcs8             pkey              pkeyparam
pkeyutl           prime             rand              rehash
req               rsa               rsautl            s_client
s_server          s_time            sess_id           smime
speed             spkac             srp               storeutl
ts                verify            version           x509

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md4
md5               mdc2              rmd160            sha1
sha224            sha256            sha3-224          sha3-256
sha3-384          sha3-512          sha384            sha512
sha512-224        sha512-256        shake128          shake256
sm3

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8
aria-256-ctr      aria-256-ecb      aria-256-ofb      base64
bf                bf-cbc            bf-cfb            bf-ecb
bf-ofb            camellia-128-cbc  camellia-128-ecb  camellia-192-cbc
camellia-192-ecb  camellia-256-cbc  camellia-256-ecb  cast
cast-cbc          cast5-cbc         cast5-cfb         cast5-ecb
cast5-ofb         des               des-cbc           des-cfb
des-ecb           des-ede           des-ede-cbc       des-ede-cfb
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb
des-ede3-ofb      des-ofb           des3              desx
idea              idea-cbc          idea-cfb          idea-ecb
idea-ofb          rc2               rc2-40-cbc        rc2-64-cbc
rc2-cbc           rc2-cfb           rc2-ecb           rc2-ofb
rc4               rc4-40            seed              seed-cbc
seed-cfb          seed-ecb          seed-ofb          sm4-cbc
sm4-cfb           sm4-ctr           sm4-ecb           sm4-ofb
zlib

[root] ~# openssl  ocsp -help
Usage: ocsp [options]
Valid options are:
 -help                   Display this summary
 -out outfile            Output filename
 -timeout +int           Connection timeout (in seconds) to the OCSP responder
 -url val                Responder URL
 -host val               TCP/IP hostname:port to connect to
 -port +int              Port to run responder on
 -ignore_err             Ignore error on OCSP request or response and continue running
 -noverify               Don't verify response at all
 -nonce                  Add OCSP nonce to request
 -no_nonce               Don't add OCSP nonce to request
 -resp_no_certs          Don't include any certificates in response
 -resp_key_id            Identify response by signing certificate key ID
 -multi +int             run multiple responder processes
 -no_certs               Don't include any certificates in signed request
 -no_signature_verify    Don't check signature on response
 -no_cert_verify         Don't check signing certificate
 -no_chain               Don't chain verify response
 -no_cert_checks         Don't do additional checks on signing certificate
 -no_explicit            Do not explicitly check the chain, just verify the root
 -trust_other            Don't verify additional certificates
 -no_intern              Don't search certificates contained in response for signer
 -badsig                 Corrupt last byte of loaded OSCP response signature (for test)
 -text                   Print text form of request and response
 -req_text               Print text form of request
 -resp_text              Print text form of response
 -reqin val              File with the DER-encoded request
 -respin val             File with the DER-encoded response
 -signer infile          Certificate to sign OCSP request with
 -VAfile infile          Validator certificates file
 -sign_other infile      Additional certificates to include in signed request
 -verify_other infile    Additional certificates to search for signer
 -CAfile infile          Trusted certificates file
 -CApath infile          Trusted certificates directory
 -no-CAfile              Do not load the default certificates file
 -no-CApath              Do not load certificates from the default certificates directory
 -validity_period ulong  Maximum validity discrepancy in seconds
 -status_age +int        Maximum status age in seconds
 -signkey val            Private key to sign OCSP request with
 -reqout val             Output file for the DER-encoded request
 -respout val            Output file for the DER-encoded response
 -path val               Path to use in OCSP request
 -issuer infile          Issuer certificate
 -cert infile            Certificate to check
 -serial val             Serial number to check
 -index infile           Certificate status index file
 -CA infile              CA certificate
 -nmin +int              Number of minutes before next update
 -nrequest +int          Number of requests to accept (default unlimited)
 -ndays +int             Number of days before next update
 -rsigner infile         Responder certificate to sign responses with
 -rkey infile            Responder key to sign responses with
 -rother infile          Other certificates to include in response
 -rmd val                Digest Algorithm to use in signature of OCSP response
 -rsigopt val            OCSP response signature parameter in n:v form
 -header val             key=value header to add
 -*                      Any supported digest algorithm (sha1,sha256, ... )
 -policy val             adds policy to the acceptable policy set
 -purpose val            certificate chain purpose
 -verify_name val        verification policy name
 -verify_depth int       chain depth limit
 -auth_level int         chain authentication security level
 -attime intmax          verification epoch time
 -verify_hostname val    expected peer hostname
 -verify_email val       expected peer email
 -verify_ip val          expected peer IP address
 -ignore_critical        permit unhandled critical extensions
 -issuer_checks          (deprecated)
 -crl_check              check leaf certificate revocation
 -crl_check_all          check full chain revocation
 -policy_check           perform rfc5280 policy checks
 -explicit_policy        set policy variable require-explicit-policy
 -inhibit_any            set policy variable inhibit-any-policy
 -inhibit_map            set policy variable inhibit-policy-mapping
 -x509_strict            disable certificate compatibility work-arounds
 -extended_crl           enable extended CRL features
 -use_deltas             use delta CRLs
 -policy_print           print policy processing diagnostics
 -check_ss_sig           check root CA self-signatures
 -trusted_first          search trust store first (default)
 -suiteB_128_only        Suite B 128-bit-only mode
 -suiteB_128             Suite B 128-bit mode allowing 192-bit algorithms
 -suiteB_192             Suite B 192-bit-only mode
 -partial_chain          accept chains anchored by intermediate trust-store CAs
 -no_alt_chains          (deprecated)
 -no_check_time          ignore certificate validity time
 -allow_proxy_certs      allow the use of proxy certificates

________________________________
От: Christopher Schultz <ch...@christopherschultz.net>
Отправлено: 22 мая 2019 г. 19:45
Кому: users@tomcat.apache.org
Тема: Re: OCSP with openSSL

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Усманов,

On 5/22/19 07:28, Усманов Азат Анварович wrote:
> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
> file from tomcat  website and issued  ./configure
> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
> -with-ssl=/usr/local/openssl && make && make install && make clean
> I'm not sure  how to specify any ocsp related configure options
> when building tomcat native    from source

What is your OpenSSL version and capabilities?

$ openssl version

$ openssl -help

$ openssl ocsp -help

- -chris

> ________________________________ От: Mark Thomas
> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
> users@tomcat.apache.org Тема: Re: OCSP with openSSL
>
> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>> Hi everyone! I have a web app running on tomcat and java 7 using
>> apr for TLS related issues. I m still unable to have OCSP
>> verification working with tomcat.
>
> <snip/>
>
>> I have tried running tcpdump on the server but don't' see any
>> Comodo related IP addresses in the output when I access the
>> server in question in the browser. At this point I don't know
>> what else to do, If it was java I would just put some
>> System.out.println statements in OCSP SSL related source code and
>> recompile the tomcat source, but since in my case tomcat uses
>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>> only places I found in the TC-native source that mentions OCSP
>> is sslutils.c  source file. I'm not sure when/ if it is actually
>> gets called in my case. Maybe be someone with more c experience
>> c++ would help me with that.  I really want to get to the bottom
>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>> based Apache Tomcat Native library [1.2.21] using APR version
>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>> Linux RHEL 6.6
>
> How did you build the Tomcat Native library? Was OCSP enabled?
>
> Mark
>
> ---------------------------------------------------------------------
>
>
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlzlfKEACgkQHPApP6U8
pFjWvBAAhHnL9esNEDViUB6nBIzQtcgsn0FxKWVTlrM+mv1JMlZWeD1zpKAPGuOr
ip3Dl/HlHANR8poi8l3NpIUUNq74UqXRHu0ETdjl2vyCl96pYHrmXWLwYuyDeFN4
cN4bm6dm1MkpNyxIv4ig9gJ1/GfAhZW22wcJTKaxu/QyKPVJwejGf3Xbtb4lEjoS
FxEbcE+IJENXME/5+KYyVJdpuRlrbY4P4DXPeZjVcw0yOCB33jNxY9SJtImuXTtl
wiWDPW/8/NM5FUIdbZGUCXx76k2g71iYPZdAcZ94R86pOoFjbAmu6LxSddDeQDZ7
cswpq1wNeTql7aLYCVBG0/I6FgmRBEQvSeS9StuWhjwogdSzK2CmyJuct+y1UBLm
uY4SH5+DvbM57HZdQZ2WHHyjp+VEMI2qQypmVsZf7MqoCYypegOFNwtXqjgRzvmd
PReFjxz6orHlczJ4psjbpKA+BrSNWyeFJu8wBxjfhFuIzsAQyWL3nDwoxSJFQeuq
d1TIDuq5yHRnUWqqf6Tn33qOZvbjKwaeA4XPLCcfZOGWtgIaEYPLfiPSHZujmo7q
jM8EBQGraOChT+P35aNtzxiDac09Ow1wT3hnpDnMdOgWdwwWGR7lLvLUHp/JC+Vn
eUt1mv+bzq0JOpfPpRpCDa5/5LoMh1YJnRw/3JnqhyQ5lpUrB40=
=Bl8+
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Усманов,

On 5/22/19 07:28, Усманов Азат Анварович wrote:
> Mark,  I installed it  just   by  downloading  tcnative src  tar.gz
> file from tomcat  website and issued  ./configure
> --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79
> -with-ssl=/usr/local/openssl && make && make install && make clean 
> I'm not sure  how to specify any ocsp related configure options
> when building tomcat native    from source

What is your OpenSSL version and capabilities?

$ openssl version

$ openssl -help

$ openssl ocsp -help

- -chris

> ________________________________ От: Mark Thomas
> <ma...@apache.org> Отправлено: 22 мая 2019 г. 13:41 Кому:
> users@tomcat.apache.org Тема: Re: OCSP with openSSL
> 
> On 22/05/2019 11:28, Усманов Азат Анварович wrote:
>> Hi everyone! I have a web app running on tomcat and java 7 using
>> apr for TLS related issues. I m still unable to have OCSP
>> verification working with tomcat.
> 
> <snip/>
> 
>> I have tried running tcpdump on the server but don't' see any
>> Comodo related IP addresses in the output when I access the
>> server in question in the browser. At this point I don't know
>> what else to do, If it was java I would just put some
>> System.out.println statements in OCSP SSL related source code and
>> recompile the tomcat source, but since in my case tomcat uses
>> OpenSSL and tomcat native I'm not sure how/where to do that. the
>> only places I found in the TC-native source that mentions OCSP
>> is sslutils.c  source file. I'm not sure when/ if it is actually
>> gets called in my case. Maybe be someone with more c experience
>> c++ would help me with that.  I really want to get to the bottom
>> of this. Any help is appreciated my tomcat version  is 8.5.39 APR
>> based Apache Tomcat Native library [1.2.21] using APR version
>> [1.6.5]. Openssl version is [OpenSSL 1.1.1a  20 Nov 2018 OS:
>> Linux RHEL 6.6
> 
> How did you build the Tomcat Native library? Was OCSP enabled?
> 
> Mark
> 
> ---------------------------------------------------------------------
>
> 
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlzlfKEACgkQHPApP6U8
pFjWvBAAhHnL9esNEDViUB6nBIzQtcgsn0FxKWVTlrM+mv1JMlZWeD1zpKAPGuOr
ip3Dl/HlHANR8poi8l3NpIUUNq74UqXRHu0ETdjl2vyCl96pYHrmXWLwYuyDeFN4
cN4bm6dm1MkpNyxIv4ig9gJ1/GfAhZW22wcJTKaxu/QyKPVJwejGf3Xbtb4lEjoS
FxEbcE+IJENXME/5+KYyVJdpuRlrbY4P4DXPeZjVcw0yOCB33jNxY9SJtImuXTtl
wiWDPW/8/NM5FUIdbZGUCXx76k2g71iYPZdAcZ94R86pOoFjbAmu6LxSddDeQDZ7
cswpq1wNeTql7aLYCVBG0/I6FgmRBEQvSeS9StuWhjwogdSzK2CmyJuct+y1UBLm
uY4SH5+DvbM57HZdQZ2WHHyjp+VEMI2qQypmVsZf7MqoCYypegOFNwtXqjgRzvmd
PReFjxz6orHlczJ4psjbpKA+BrSNWyeFJu8wBxjfhFuIzsAQyWL3nDwoxSJFQeuq
d1TIDuq5yHRnUWqqf6Tn33qOZvbjKwaeA4XPLCcfZOGWtgIaEYPLfiPSHZujmo7q
jM8EBQGraOChT+P35aNtzxiDac09Ow1wT3hnpDnMdOgWdwwWGR7lLvLUHp/JC+Vn
eUt1mv+bzq0JOpfPpRpCDa5/5LoMh1YJnRw/3JnqhyQ5lpUrB40=
=Bl8+
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: OCSP with openSSL

Posted by Усманов Азат Анварович <us...@ieml.ru>.
Mark,  I installed it  just   by  downloading  tcnative src  tar.gz file from tomcat  website
and issued  ./configure --with-apr=/usr/local/apr --with-java-home=/usr/java/jdk1.7.0_79 -with-ssl=/usr/local/openssl && make && make install && make clean
I'm not sure  how to specify any ocsp related configure options  when building tomcat native    from source

________________________________
От: Mark Thomas <ma...@apache.org>
Отправлено: 22 мая 2019 г. 13:41
Кому: users@tomcat.apache.org
Тема: Re: OCSP with openSSL

On 22/05/2019 11:28, Усманов Азат Анварович wrote:
> Hi everyone! I have a web app running on tomcat and java 7 using apr for TLS related issues. I m still unable to have OCSP verification working with tomcat.

<snip/>

>  I have tried running tcpdump on the server but don't' see any Comodo related IP addresses in the output when I access the server in question in the browser.
> At this point I don't know what else to do, If it was java I would just put some System.out.println statements in OCSP SSL related source code and recompile the tomcat source, but since in my case tomcat uses OpenSSL and tomcat native I'm not sure how/where to do that. the only places I found in the TC-native source that mentions OCSP  is sslutils.c  source file. I'm not sure when/ if it is actually gets called in my case. Maybe be someone with more c experience c++ would help me with that.  I really want to get to the bottom of this. Any help is appreciated
>  my tomcat version  is 8.5.39
>  APR based Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
> Openssl version is [OpenSSL 1.1.1a  20 Nov 2018
> OS: Linux RHEL 6.6

How did you build the Tomcat Native library? Was OCSP enabled?

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: OCSP with openSSL

Posted by Mark Thomas <ma...@apache.org>.
On 22/05/2019 11:28, Усманов Азат Анварович wrote:
> Hi everyone! I have a web app running on tomcat and java 7 using apr for TLS related issues. I m still unable to have OCSP verification working with tomcat.

<snip/>

>  I have tried running tcpdump on the server but don't' see any Comodo related IP addresses in the output when I access the server in question in the browser.
> At this point I don't know what else to do, If it was java I would just put some System.out.println statements in OCSP SSL related source code and recompile the tomcat source, but since in my case tomcat uses OpenSSL and tomcat native I'm not sure how/where to do that. the only places I found in the TC-native source that mentions OCSP  is sslutils.c  source file. I'm not sure when/ if it is actually gets called in my case. Maybe be someone with more c experience c++ would help me with that.  I really want to get to the bottom of this. Any help is appreciated
>  my tomcat version  is 8.5.39
>  APR based Apache Tomcat Native library [1.2.21] using APR version [1.6.5].
> Openssl version is [OpenSSL 1.1.1a  20 Nov 2018
> OS: Linux RHEL 6.6

How did you build the Tomcat Native library? Was OCSP enabled?

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org