{"id":173,"date":"2016-04-04T15:41:54","date_gmt":"2016-04-04T05:41:54","guid":{"rendered":"https:\/\/icicimov.com\/blog\/?p=173"},"modified":"2017-01-02T15:45:24","modified_gmt":"2017-01-02T04:45:24","slug":"tomcat9-ecdsaecc-elliptic-curve-certificates-and-http2","status":"publish","type":"post","link":"https:\/\/icicimov.com\/blog\/?p=173","title":{"rendered":"Tomcat9, ECDSA\/ECC (Elliptic Curve) Certificates and HTTP\/2"},"content":{"rendered":"<p>Tomcat9 brings bunch of new features of which support for HTTP\/2 and multiple certificates per Virtual Host via SNI extension are most important ones. This needs Java 1.8, the latest APR\/TC (Tomcat Native) release 1.2.x, since SNI support in current Java 1.8 is useless, which in turn requires OpenSSL version 1.0.2g installed. Early users of HTTP\/2, according to one of the main Tomcat developers Mark Thomas, reported improvement of up to 20% in page speed due to its benefits like multiplexing, header compression and server push (servlet 4.0 API needed). By default HTTP\/2 (h2) protocol is SSL, as expected the whole internet to be over https only in near future, but there is a clear-text version as well called h2c.<\/p>\n<p>The ECDSA certificates are smaller, meaning faster processing time on the server and less CPU usage which in term means less latency and more security. It&#8217;s in the early day of adoption by the clients though so for some time we will need to support both certificate types, ECDSA and RSA.<\/p>\n<p>Nice things to have so I setup a test Tomcat9 server on Ubunut 14.04.<\/p>\n<h2>Setup<\/h2>\n<p>We start by installing and setup of the prerequisites mentioned in the Introduction.<\/p>\n<h3>OpenSSL<\/h3>\n<p>Standard compile procedure, we start by installing some needed packages:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo aptitude install zlib1g-dev zlibc libcrypto++-dev\n<\/code><\/pre>\n<p>and then downloading and extracting the source:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo wget http:\/\/www.openssl.org\/source\/openssl-1.0.2g.tar.gz\nigorc@sl01:\/opt$ sudo tar -xzf openssl-1.0.2g.tar.gz\nigorc@sl01:\/opt$ sudo chown -R igorc\\: openssl-1.0.2g\n<\/code><\/pre>\n<p>Next we change to the source directory and create the openssl.ld file:<\/p>\n<pre><code>igorc@sl01:\/opt$ cd openssl-1.0.2g\/\nigorc@sl01:~\/openssl-1.0.2g$ vi openssl.ld\nOPENSSL_1.0.0 {\n    global:\n    *;\n};\n<\/code><\/pre>\n<p>and finally compile and install the software:<\/p>\n<pre><code>igorc@sl01:\/opt\/openssl-1.0.2g$ .\/config --prefix=\/opt\/openssl zlib-dynamic shared -Wl,--version-script=\/home\/igorc\/openssl-1.0.2g\/openssl.ld -Wl,-Bsymbolic-functions\nigorc@sl01:\/opt\/openssl-1.0.2g$ make depend\nigorc@sl01:\/opt\/openssl-1.0.2g$ make all\nigorc@sl01:\/opt\/openssl-1.0.2g$ sudo make install\n<\/code><\/pre>\n<p>This will set OpenSSL 1.0.2g under \/opt\/openssl directory:<\/p>\n<pre><code>igorc@sl01:\/opt\/openssl-1.0.2g$ ls -l \/opt\/openssl\ntotal 16\ndrwxr-xr-x 2 root root 4096 Apr  2 19:18 bin\ndrwxr-xr-x 3 root root 4096 Apr  2 19:18 include\ndrwxr-xr-x 4 root root 4096 Apr  2 19:18 lib\ndrwxr-xr-x 6 root root 4096 Apr  2 19:18 ssl\n<\/code><\/pre>\n<h3>Java8<\/h3>\n<p>One liner installation:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo echo oracle-java8-installer shared\/accepted-oracle-license-v1-1 select true | sudo \/usr\/bin\/debconf-set-selections &amp;&amp; echo \"deb http:\/\/ppa.launchpad.net\/webupd8team\/java\/ubuntu trusty main\" | sudo tee -a \/etc\/apt\/sources.list &amp;&amp; echo \"deb-src http:\/\/ppa.launchpad.net\/webupd8team\/java\/ubuntu trusty main\" | sudo tee -a \/etc\/apt\/sources.list &amp;&amp; sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 &amp;&amp; sudo aptitude update &amp;&amp; sudo aptitude install -y oracle-java8-installer &amp;&amp; sudo aptitude install -y oracle-java8-set-default\n<\/code><\/pre>\n<p>This will add the needed Ubuntu ppa, install the latest Oracle 1.8 JDK and set it as default Java environment.<\/p>\n<h3>Tomcat9<\/h3>\n<h4>Installation<\/h4>\n<p>Get and unpack the latest Tomcat9 release, alfa version v9.0.0.M4 at the moment of this writing, and setup tomcat user:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo groupadd -r -g 501 tomcat9\nigorc@sl01:\/opt$ sudo useradd -r -c \"Tomcat9 user\" -s \/bin\/false -M -d \/usr\/share\/tomcat9 -g 501 -u 501 -G www-data tomcat9\nigorc@sl01:\/opt$ sudo wget http:\/\/apache.uberglobalmirror.com\/tomcat\/tomcat-9\/v9.0.0.M4\/bin\/apache-tomcat-9.0.0.M4.tar.gz\nigorc@sl01:\/opt$ sudo tar -xzf apache-tomcat-9.0.0.M4.tar.gz\nigorc@sl01:\/opt$ sudo mv apache-tomcat-9.0.0.M4 \/usr\/share\/tomcat9\nigorc@sl01:\/opt$ sudo ln -sf \/usr\/share\/tomcat9\/logs \/var\/log\/tomcat9\nigorc@sl01:\/opt$ sudo ln -sf \/usr\/share\/tomcat9\/work \/var\/cache\/tomcat9\nigorc@sl01:\/opt$ sudo ln -sf \/usr\/share\/tomcat9\/conf \/etc\/tomcat9\n<\/code><\/pre>\n<h4>TC-Native<\/h4>\n<p>We install the needed packages first:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo aptitude install libapr1-dev libssl-dev\n<\/code><\/pre>\n<p>and then we download and etract the tcnative source, xtract and build it against oopenssl-1.0.2g we installed previously:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo wget http:\/\/apache.mirror.digitalpacific.com.au\/tomcat\/tomcat-connectors\/native\/1.2.5\/source\/tomcat-native-1.2.5-src.tar.gz\nigorc@sl01:\/opt$ sudo tar -xzf tomcat-native-1.2.5-src.tar.gz\nigorc@sl01:\/opt$ cd tomcat-native-1.2.5-src\/native\nigorc@sl01:\/opt\/tomcat-native-1.2.5-src\/native$ .\/configure --prefix=\/usr --libdir=\/usr\/lib --with-apr=\/usr\/bin\/apr-1-config --with-java-home=\/usr\/lib\/jvm\/java-8-oracle --with-ssl=\/opt\/openssl\nigorc@sl01:\/opt\/tomcat-native-1.2.5-src\/native$ make\nigorc@sl01:\/opt\/tomcat-native-1.2.5-src\/native$ sudo make install\n<\/code><\/pre>\n<p>We check that tcnative is properly linked to the right openssl version (in case you have more than one installed):<\/p>\n<pre><code>igorc@sl01:\/opt\/tomcat-native-1.2.5-src\/native$ ldd \/usr\/lib\/libtcnative-1.so.0.2.5\nlinux-vdso.so.1 =&gt;  (0x00007ffcd2ba5000)\nlibssl.so.1.0.0 =&gt; \/opt\/openssl\/lib\/libssl.so.1.0.0 (0x00007f67d06a1000)\nlibcrypto.so.1.0.0 =&gt; \/opt\/openssl\/lib\/libcrypto.so.1.0.0 (0x00007f67d0251000)\nlibapr-1.so.0 =&gt; \/usr\/lib\/x86_64-linux-gnu\/libapr-1.so.0 (0x00007f67d0020000)\nlibpthread.so.0 =&gt; \/lib\/x86_64-linux-gnu\/libpthread.so.0 (0x00007f67cfe02000)\nlibc.so.6 =&gt; \/lib\/x86_64-linux-gnu\/libc.so.6 (0x00007f67cfa3d000)\nlibdl.so.2 =&gt; \/lib\/x86_64-linux-gnu\/libdl.so.2 (0x00007f67cf839000)\nlibz.so.1 =&gt; \/lib\/x86_64-linux-gnu\/libz.so.1 (0x00007f67cf620000)\nlibuuid.so.1 =&gt; \/lib\/x86_64-linux-gnu\/libuuid.so.1 (0x00007f67cf41b000)\n\/lib64\/ld-linux-x86-64.so.2 (0x00007f67d0b3e000)\n<\/code><\/pre>\n<h4>Config and SSL setup<\/h4>\n<p>I wanted to test the ECDSA certificate type and multi-certificate support in tomcat9. First create ECC cert and install it so tomcat can find it:<\/p>\n<pre><code>igorc@sl01:~$ openssl req -new -x509 -nodes -newkey ec:&lt; (openssl ecparam -name secp384r1) -keyout cert_ecdsa.key -out cert_ecdsa.crt -days 7200 -subj '\/C=AU\/ST=New South Wales\/L=Sydney\/O=My Corporation Ltd.\/OU=DevOps\/CN=tomcat9.mydomain.com'\nigorc@sl01:~$ sudo mkdir \/etc\/tomcat9\/ssl\nigorc@sl01:~$ sudo cp cert_ecdsa.key cert_ecdsa.crt \/etc\/tomcat9\/ssl\/\n<\/code><\/pre>\n<p>Then created a standard RSA one too:<\/p>\n<pre><code>igorc@sl01:~$ openssl genrsa -des3 -passout pass:x -out server.pass.key 2048\nigorc@sl01:~$ openssl rsa -passin pass:x -in server.pass.key -out server.key\nigorc@sl01:~$ rm server.pass.key\nigorc@sl01:~$ openssl req -new -key server.key -out server.csr -subj '\/C=AU\/ST=New South Wales\/L=Sydney\/O=My Corporation Ltd.\/OU=DevOps\/CN=tomcat9.mydomain.com'\nigorc@sl01:~$ openssl x509 -req -days 7200 -in server.csr -signkey server.key -out server.crt\nSignature ok\nsubject=\/C=AU\/ST=New South Wales\/L=Sydney\/O=My Corporation Ltd.\/OU=DevOps\/CN=tomcat9.mydomain.com\nGetting Private key\nigorc@sl01:~$ sudo cp server.key server.crt \/etc\/tomcat9\/ssl\/\n<\/code><\/pre>\n<p>Now we can configure tomcat9&#8217;s SSL\/TLS connector with HTTP\/2 support. Replace the default <code>&lt;Connector&gt;<\/code> section in the tomcat&#8217;s server.xml file, in our case <code>\/etc\/tomcat9\/server.xml<\/code>, with the one below:<\/p>\n<pre>\n    <connector port=\"8443\" protocol=\"org.apache.coyote.http11.Http11AprProtocol\"\n               maxThreads=\"150\" SSLEnabled=\"true\" scheme=\"https\" secure=\"true\" >\n        <upgradeprotocol className=\"org.apache.coyote.http2.Http2Protocol\"><\/upgradeprotocol>\n        <sslhostconfig honorCipherOrder=\"true\" disableCompression=\"true\" protocols=\"all\"\n                       ciphers=\"EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384\n                       EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4\n                       EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4\" >\n            <certificate certificateKeyFile=\"conf\/ssl\/cert_ecdsa.key\"\n                         certificateFile=\"conf\/ssl\/cert_ecdsa.crt\"\n                         type=\"EC\"><\/certificate>\n            <certificate certificateKeyFile=\"conf\/ssl\/server.key\"\n                         certificateFile=\"conf\/ssl\/server.crt\"\n                         type=\"RSA\"><\/certificate>\n        <\/sslhostconfig>\n    <\/connector>\n<\/pre>\n<p>Now we can start the server:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo \/usr\/share\/tomcat9\/bin\/startup.sh\nUsing CATALINA_BASE:   \/usr\/share\/tomcat9\nUsing CATALINA_HOME:   \/usr\/share\/tomcat9\nUsing CATALINA_TMPDIR: \/usr\/share\/tomcat9\/temp\nUsing JRE_HOME:        \/usr\nUsing CLASSPATH:       \/usr\/share\/tomcat9\/bin\/bootstrap.jar:\/usr\/share\/tomcat9\/bin\/tomcat-juli.jar\nTomcat started.\n<\/code><\/pre>\n<p>and check for the features we need in the log file:<\/p>\n<pre><code>igorc@sl01:\/opt$ sudo grep -E \"AprLifecycleListener|h2\" \/var\/log\/tomcat9\/catalina.out\n02-Apr-2016 20:29:05.875 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library 1.2.5 using APR version 1.5.1.\n02-Apr-2016 20:29:05.875 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].\n02-Apr-2016 20:29:05.881 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized (OpenSSL 1.0.2g  1 Mar 2016)\n02-Apr-2016 20:29:05.883 INFO [main] org.apache.coyote.http11.AbstractHttp11Protocol.configureUpgradeProtocol The [\"https-apr-8443\"] connector has been configured to support negotiation to [h2] via ALPN\n<\/code><\/pre>\n<p>We can see the APR connector, the correct OpenSSL version and the h2 protocol available via ALPN (Application-Layer Protocol Negotiation).<\/p>\n<h2>Testing<\/h2>\n<h3>CuRL<\/h3>\n<p>To test the server I used the trusted curl. It came up it was little bit painful to set it up due to lot of prerequisites but since I&#8217;ve done it I might show it here as well. There are some other HTTP\/2 testing tools available that you can use in case you have domain name registered with proper DNS resolution setup.<\/p>\n<p>First the SPDY (Google extension which is now becoming obsolete with http2) support:<\/p>\n<pre><code>igorc@sl01:~$ git clone https:\/\/github.com\/tatsuhiro-t\/spdylay.git\nigorc@sl01:~$ cd spdylay\/\nigorc@sl01:~$ autoreconf -i\nigorc@sl01:~$ automake\nigorc@sl01:~$ autoconf\nigorc@sl01:~$ .\/configure\nigorc@sl01:~$ make -I\/opt\/openssl\/include\/\nigorc@sl01:~$ sudo make install\nigorc@sl01:~$ locate libspdylay.so.7\n\/opt\/spdylay\/lib\/.libs\/libspdylay.so.7\n\/opt\/spdylay\/lib\/.libs\/libspdylay.so.7.2.0\n\/usr\/local\/lib\/libspdylay.so.7\n\/usr\/local\/lib\/libspdylay.so.7.2.0\nigorc@sl01:~$ sudo ln -s \/usr\/local\/lib\/libspdylay.so.7 \/lib\/x86_64-linux-gnu\/libspdylay.so.7\nigorc@sl01:~$ sudo ln -s \/usr\/local\/lib\/libspdylay.so.7.2.0 \/lib\/x86_64-linux-gnu\/libspdylay.so.7.2.0\nigorc@sl01:~$ sudo ldconfig\n<\/code><\/pre>\n<p>Next is nghhtp2:<\/p>\n<pre><code>igorc@sl01:~$ git clone https:\/\/github.com\/nghttp2\/nghttp2.git\nigorc@sl01:~$ cd nghttp2\nigorc@sl01:~$ autoreconf -i\nigorc@sl01:~$ automake\nigorc@sl01:~$ autoconf\nigorc@sl01:~$ OPENSSL_CFLAGS=\"-I\/opt\/openssl\/include\" OPENSSL_LIBS=\"-L\/opt\/openssl\/lib -lssl -lcrypto -ldl\" .\/configure PYTHON=\/usr\/bin\/python3\nigorc@sl01:~$ make\nigorc@sl01:~$ sudo make install\nigorc@sl01:~$ sudo updatedb\nigorc@sl01:~$ locate libnghttp2.so.14\n\/opt\/nghttp2\/lib\/.libs\/libnghttp2.so.14\n\/opt\/nghttp2\/lib\/.libs\/libnghttp2.so.14.6.0\n\/opt\/nghttp2-1.9.1\/lib\/.libs\/libnghttp2.so.14\n\/opt\/nghttp2-1.9.1\/lib\/.libs\/libnghttp2.so.14.6.0\n\/usr\/local\/lib\/libnghttp2.so.14\n\/usr\/local\/lib\/libnghttp2.so.14.6.0\nigorc@sl01:~$ sudo ln -s \/usr\/local\/lib\/libnghttp2.so.14 \/lib\/x86_64-linux-gnu\/libnghttp2.so.14\nigorc@sl01:~$ sudo ln -s \/usr\/local\/lib\/libnghttp2.so.14.0.2 \/lib\/x86_64-linux-gnu\/libnghttp2.so.14.0.2\nigorc@sl01:~$ sudo ldconfig\n<\/code><\/pre>\n<p>Finally checking the versions installed:<\/p>\n<pre><code>igorc@sl01:~$ nghttp --version\nnghttp nghttp2\/1.10.0-DEV\nigorc@sl01:~$ nghttpx --version\nnghttpx nghttp2\/1.10.0-DEV\nigorc@sl01:~$ nghttpd --version\nnghttpd nghttp2\/1.10.0-DEV\nigorc@sl01:~$ h2load --version\nh2load nghttp2\/1.10.0-DEV\n<\/code><\/pre>\n<p>We can use this tool as SSL proxy if needed (nothing to do with the test, just mentioning):<\/p>\n<pre><code>$ sudo nghttpx \\\n    --frontend=*,443 \\\n    --backend=localhost,8080 \\\n    --private-key-file=\/path\/to\/key.key \\\n    --certificate-file=\/path\/to\/cert.crt\n<\/code><\/pre>\n<p>Or turn it into service:<\/p>\n<pre><code>$ sudo cp ~\/nghttp2\/contrib\/nghttpx-init \/etc\/init.d\/nghttpx\n$ sudo service nghttpx restart\n<\/code><\/pre>\n<p>And finally CuRL:<\/p>\n<pre><code>igorc@sl01:~$ wget https:\/\/curl.haxx.se\/download\/curl-7.48.0.tar.gz\nigorc@sl01:~$ tar -xzf curl-7.48.0.tar.gz\nigorc@sl01:~$ cd curl-7.48.0\/\nigorc@sl01:~$ PKG_CONFIG_LIBDIR=\/opt\/openssl\/lib\/pkgconfig\/ .\/configure --with-ssl=\/opt\/openssl --with-nghttp2=\/usr\/local\nigorc@sl01:~$ make &amp;&amp; sudo make install\n<\/code><\/pre>\n<p>Now we set the correct binary and library paths so curl can find them:<\/p>\n<pre><code>igorc@sl01:~$ export PATH=\/opt\/openssl\/bin:\/usr\/local\/bin:igorc@sl01:~$PATH\nigorc@sl01:~$ export LD_LIBRARY_PATH=\/opt\/openssl\/lib:igorc@sl01:~$LD_LIBRARY_PATH\n<\/code><\/pre>\n<p>Check the openssl and curl binaries and their features:<\/p>\n<pre><code>igorc@sl01:~$ openssl version\nOpenSSL 1.0.2g  1 Mar 2016\n\nigorc@sl01:~$ curl --version\ncurl 7.48.0 (x86_64-pc-linux-gnu) libcurl\/7.48.0 OpenSSL\/1.0.2g zlib\/1.2.8 nghttp2\/1.10.0-DEV\nProtocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp\nFeatures: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets\n<\/code><\/pre>\n<p>From the above output we can confirm that curl has http2 support.<\/p>\n<p>With all this done we can run the test. I tested for both when we have only ECDSA\/ECC certificate configured in tomcat, since I wanted to see this cert in action:<\/p>\n<pre>\nigorc@sl01:~$ curl --http2 -v -k -s -S -I https:\/\/localhost:8443\/ -o \/dev\/null\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8443 (#0)\n* ALPN, offering h2\n* ALPN, offering http\/1.1\n* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH\n* successfully set certificate verify locations:\n*   CAfile: \/etc\/ssl\/certs\/ca-certificates.crt\n  CApath: none\n* TLSv1.2 (OUT), TLS header, Certificate Status (22):\n} [5 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Client hello (1):\n} [512 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server hello (2):\n{ [75 bytes data]\n* TLSv1.2 (IN), TLS handshake, Certificate (11):\n{ [710 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server key exchange (12):\n{ [181 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server finished (14):\n{ [4 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):\n} [70 bytes data]\n* TLSv1.2 (OUT), TLS change cipher, Client hello (1):\n} [1 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Finished (20):\n} [16 bytes data]\n* TLSv1.2 (IN), TLS change cipher, Client hello (1):\n{ [1 bytes data]\n* TLSv1.2 (IN), TLS handshake, Finished (20):\n{ [16 bytes data]\n* SSL connection using TLSv1.2 \/ ECDHE-ECDSA-AES256-GCM-SHA384\n* ALPN, server accepted to use h2\n* Server certificate:\n*  subject: C=AU; ST=New South Wales; L=Sydney; O=My Corporation Ltd.; OU=DevOps; CN=tomcat9.mydomain.com\n*  start date: Apr  4 02:41:03 2016 GMT\n*  expire date: Dec 21 02:41:03 2035 GMT\n*  issuer: C=AU; ST=New South Wales; L=Sydney; O=My Corporation Ltd.; OU=DevOps; CN=tomcat9.mydomain.com\n*  SSL certificate verify result: self signed certificate (18), continuing anyway.\n* Using HTTP2, server supports multi-use\n* Connection state changed (HTTP\/2 confirmed)\n* TCP_NODELAY set\n* Copying HTTP\/2 data in stream buffer to connection buffer after upgrade: len=0\n} [5 bytes data]\n* Using Stream ID: 1 (easy handle 0x22dc050)\n} [5 bytes data]\n> HEAD \/ HTTP\/1.1\n> Host: localhost:8443\n> User-Agent: curl\/7.48.0\n> Accept: *\/*\n>\n{ [5 bytes data]\n* Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n} [5 bytes data]\n< HTTP\/2.0 200\n< content-type:text\/html;charset=UTF-8\n< date:Mon, 04 Apr 2016 02:45:38 GMT\n<\n* Connection #0 to host localhost left intact\nigorc@sl01:~$\n<\/pre>\n<p>and when both cert types are configured as per our example above:<\/p>\n<pre>\nigorc@sl01:~$ curl --http2 -v -k -s -S -I https:\/\/localhost:8443\/ -o \/dev\/null\n*   Trying 127.0.0.1...\n* Connected to localhost (127.0.0.1) port 8443 (#0)\n* ALPN, offering h2\n* ALPN, offering http\/1.1\n* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH\n* successfully set certificate verify locations:\n*   CAfile: \/etc\/ssl\/certs\/ca-certificates.crt\n  CApath: none\n* TLSv1.2 (OUT), TLS header, Certificate Status (22):\n} [5 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Client hello (1):\n} [512 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server hello (2):\n{ [75 bytes data]\n* TLSv1.2 (IN), TLS handshake, Certificate (11):\n{ [958 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server key exchange (12):\n{ [333 bytes data]\n* TLSv1.2 (IN), TLS handshake, Server finished (14):\n{ [4 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):\n} [70 bytes data]\n* TLSv1.2 (OUT), TLS change cipher, Client hello (1):\n} [1 bytes data]\n* TLSv1.2 (OUT), TLS handshake, Finished (20):\n} [16 bytes data]\n* TLSv1.2 (IN), TLS change cipher, Client hello (1):\n{ [1 bytes data]\n* TLSv1.2 (IN), TLS handshake, Finished (20):\n{ [16 bytes data]\n* SSL connection using TLSv1.2 \/ ECDHE-RSA-AES256-GCM-SHA384\n* ALPN, server accepted to use h2\n* Server certificate:\n*  subject: C=AU; ST=New South Wales; L=Sydney; O=My Corporation Ltd.; OU=DevOps; CN=tomcat9.mydomain.com\n*  start date: Apr  4 02:07:04 2016 GMT\n*  expire date: Dec 21 02:07:04 2035 GMT\n*  issuer: C=AU; ST=New South Wales; L=Sydney; O=My Corporation Ltd.; OU=DevOps; CN=tomcat9.mydomain.com\n*  SSL certificate verify result: self signed certificate (18), continuing anyway.\n* Using HTTP2, server supports multi-use\n* Connection state changed (HTTP\/2 confirmed)\n* TCP_NODELAY set\n* Copying HTTP\/2 data in stream buffer to connection buffer after upgrade: len=0\n} [5 bytes data]\n* Using Stream ID: 1 (easy handle 0x1387050)\n} [5 bytes data]\n> HEAD \/ HTTP\/1.1\n> Host: localhost:8443\n> User-Agent: curl\/7.48.0\n> Accept: *\/*\n>\n{ [5 bytes data]\n* Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n} [5 bytes data]\n< HTTP\/2.0 200\n< content-type:text\/html;charset=UTF-8\n< date:Mon, 04 Apr 2016 02:21:07 GMT\n<\n* Connection #0 to host localhost left intact\nigorc@sl01:~$\n<\/pre>\n<p>in which case the server sends the RSA type (notice the different start and expire dates) and agrees on RSA cipher instead of ECDSA, changes the cipher from <code>ECDHE-ECDSA-AES256-GCM-SHA384<\/code> to <code>ECDHE-RSA-AES256-GCM-SHA384<\/code>. In both cases we can see HTTP\/2 connection being established.<\/p>\n<h2>External_resources:<\/h2>\n<ul>\n<li><a href=\"https:\/\/tomcat.apache.org\/tomcat-9.0-doc\/index.html\">Tomcat9 documentation<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/channel\/UCpqpJ0-G1lYfUBQ6_36Au_g\">Tomcat Youtube channel<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/jfclere\/h2_demos\">Tomcat HTTP\/2 demo app<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/http2\/http2-spec\/wiki\/Implementations\">HTTP\/2 implementation tracking<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/fstab\/h2c\">H2C simple HTTP\/2 command line test tool<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Tomcat9 brings bunch of new features of which support for HTTP\/2 and multiple certificates per Virtual Host via SNI extension are most important ones. This needs Java 1.8, the latest APR\/TC (Tomcat Native) release 1.2.x, since SNI support in current&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-173","post","type-post","status-publish","format-standard","hentry","category-server"],"_links":{"self":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=173"}],"version-history":[{"count":2,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/173\/revisions"}],"predecessor-version":[{"id":175,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/173\/revisions\/175"}],"wp:attachment":[{"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/icicimov.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}