ssl

SSL can refer to: read more at WikiPedia

  • How many times have you seen an alert similar to one of the below while trying to connect to the café or airport WiFi to check email or login to a secure website?

    1507221

  • Downloading resources on Android devices returns unknown file in Google Chrome, or internal browser but not in Firefox for Android!

    Short version

    • Do not rely on self signed certificate for android when downloading resources: android download manager wont work (below Android 4.1.4 SSL was even not supported in download manager)
    • Android do not support all kind of SSL Cipher, check the compatibility table below

    Long Story

    On some Android devices clicking the download link return back an error and show an 'Unknown file'. The file of an initial size of 790kb get partially and randomly downloaded: sometimes you get 140kb, sometimes 224kb or more.

    There is a workaround: if one lets the cursor on the link and clicks 'Save' then the saved document is correct and can be opened.

    This issue appear on some Android phone, not on Android tablet (???) and never on iOS (sic)

    Looking  at the logs, we have found that In Apache access log the resource-size returned is not the same as in Tomcat access log (only when client is Android). Using Desktop class browser (Google Chrome, Firefox, Opera, Safari) the sizes returned by Tomcat and Apache is the same!

    After  a lot of try and error we found out that Android is able to download properly the resource when connecting directly to tomcat (e.g. without SSL), however in this case there is a VERY strange behaviour:

    So, when we try to download the resource via HTTP, android needs to connect twice! The first connection seems to abort and only the second connection (Android download manager) is able to fetch everything. 

    After that, we enabled the debug logging in Apache and had look at the output.

    [Tue Jan 26 16:06:29 2016] [info] Initial (No.1) HTTPS request received for child 0 (server skye3.innoveo.com:443)
    [Tue Jan 26 16:06:29 2016] [debug] mod_proxy_http.c(56): proxy: HTTP: canonicalising URL //localhost:8443/xx.pdf
    [Tue Jan 26 16:06:29 2016] [debug] proxy_util.c(1525): [client 172.16.2.176] proxy: http: found worker http://localhost:8443/ for http://localhost:8443/xx.pdf
    [Tue Jan 26 16:06:29 2016] [debug] mod_proxy.c(1026): Running scheme http handler (attempt 0) [Tue Jan 26 16:06:29 2016] [debug] mod_proxy_http.c(1982): proxy: HTTP: serving URL http://localhost:8443/xx.pdf [Tue Jan 26 16:06:29 2016] [debug] proxy_util.c(2102): proxy: HTTP: has acquired connection for (localhost) [Tue Jan 26 16:06:29 2016] [debug] proxy_util.c(2158): proxy: connecting http://localhost:8443/xx.pdf to localhost:8443 [Tue Jan 26 16:06:29 2016] [debug] proxy_util.c(2285): proxy: connected /xxxxx.pdf to localhost:8443 [Tue Jan 26 16:06:29 2016] [debug] mod_proxy_http.c(1741): proxy: start body send [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] (104)Connection reset by peer: core_output_filter: writing data to the network [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] (103)Software caused connection abort: SSL output filter write failed. [Tue Jan 26 16:06:29 2016] [debug] mod_proxy_http.c(1851): proxy: end body send [Tue Jan 26 16:06:29 2016] [debug] proxy_util.c(2120): proxy: HTTP: has released connection for (localhost) [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] Connection to child 3 established (server skye3.innoveo.com:443) ... ~removed useless debug output~ [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1966): [client 172.16.2.176] SSL virtual host for servername skye3.innoveo.com found [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 read client hello A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write server hello A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write certificate A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write key exchange A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write server done A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 flush data Tue Jan 26 16:06:29 2016] [debug] ssl_engine_io.c(1929): OpenSSL: read 5/5 bytes from BIO7f1a4c1230d0 [mem: 7f1a4c17a493] (BIO dump follows) ... ~removed useless debug output~ [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 read client key exchange A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_io.c(1929): OpenSSL: read 5/5 bytes from BIO7f1a4c1230d0 [mem: 7f1a4c17a493] (BIO dump follows) ... ~removed useless debug output~ [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 read finished A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write session ticket A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write change cipher spec A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 write finished A [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1853): OpenSSL: Loop: SSLv3 flush data [Tue Jan 26 16:06:29 2016] [debug] ssl_engine_kernel.c(1849): OpenSSL: Handshake: done [Tue Jan 26 16:06:29 2016] [info] Connection: Client IP: 172.16.2.176, Protocol: TLSv1.2, Cipher: ECDHE-RSA-AES256-SHA (256/256 bits) [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] (70014)End of file found: SSL input filter read failed. [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] Connection closed to child 2 with standard shutdown (server skye3.innoveo.com:443) [Tue Jan 26 16:06:29 2016] [info] [client 172.16.2.176] Connection to child 0 established (server skye3.innoveo.com:443) ...

    So we see, the intial SSL connect works, we can see the request issued and the proxy request. Body is written and then "connection reset by peer"

    After careful search it is pretty sure that we are running into this problem: https://code.google.com/p/chromium/issues/detail?id=440951
    Summary: 
    when you try to download stuff with chromium it works (even from unsecure sources), this is why the first connect is okay. however chromium interrupts the download to hand it over to android download manager (this is why actually displaying pictures works, despite the fact that they are delivered though the same pipeline, e.g. skye code, tomcat version, apache and ssl). this is also why we see two downloads per click in the log files. Problem is however that android download manager does NOT NEVER EVER download stuff from unsecure sources (e.g. selfsigned certs) and thus the final download fails. this is also true for the default andoid browser, because they also use the android download manager.

    Solution: the only solution was be to upgrade to valid SSL  certificates (Verizon, Verisign or any other) instead of self signed. This increase the number of Android device working but unfortunately  some Android devices were still NOT able to download resources with a valid SSL cert...

    By using the Android SDK debug console (adb.exe logcat > file.txt) of android, we saw the following:

    	Line 7487: D/DownloadManager( 3054): [1] Starting
    	Line 7489: W/DownloadManager( 3054): [1] Stop requested with status HTTP_DATA_ERROR: Handshake failed
    	Line 7491: D/DownloadManager( 3054): [1] Finished with status WAITING_TO_RETRY

    This show again that the initial connect to our server happen correctly but return partial content but is then forwarded to the download manager that try to build another connection that is still fail

    Solution: change Apache cipher suite according to the table below.

    Android compatibility table

    http://developer.android.com/reference/javax/net/ssl/SSLEngine.html

    Depending on which version of android you would like to support you'll  have to find a cipher suite that is supported by iOS, Android while not sacrificing too much security. 

    Android Version Released API Level Name Build Version Code
    Android 6.0 August 2015 23 Marshmallow Android.OS.BuildVersionCodes.Marshmallow
    Android 5.1 March 2015 22 Lollipop Android.OS.BuildVersionCodes.LollipopMr1
    Android 5.0 November 2014 21 Lollipop Android.OS.BuildVersionCodes.Lollipop
    Android 4.4W June 2014 20 Kitkat Watch Android.OS.BuildVersionCodes.KitKatWatch
    Android 4.4 October 2013 19 Kitkat Android.OS.BuildVersionCodes.KitKat
    Android 4.3 July 2013 18 Jelly Bean Android.OS.BuildVersionCodes.JellyBeanMr2
    Android 4.2-4.2.2 November 2012 17 Jelly Bean Android.OS.BuildVersionCodes.JellyBeanMr1
    Android 4.1-4.1.1 June 2012 16 Jelly Bean Android.OS.BuildVersionCodes.JellyBean
    Android 4.0.3-4.0.4 December 2011 15 Ice Cream Sandwich Android.OS.BuildVersionCodes.IceCreamSandwichMr1
    Android 4.0-4.0.2 October 2011 14 Ice Cream Sandwich Android.OS.BuildVersionCodes.IceCreamSandwich
    Android 3.2 June 2011 13 Honeycomb Android.OS.BuildVersionCodes.HoneyCombMr2
    Android 3.1.x May 2011 12 Honeycomb Android.OS.BuildVersionCodes.HoneyCombMr1
    Android 3.0.x February 2011 11 Honeycomb Android.OS.BuildVersionCodes.HoneyComb
    Android 2.3.3-2.3.4 February 2011 10 Gingerbread Android.OS.BuildVersionCodes.GingerBreadMr1
    Android 2.3-2.3.2 November 2010 9 Gingerbread Android.OS.BuildVersionCodes.GingerBread
    Android 2.2.x June 2010 8 Froyo Android.OS.BuildVersionCodes.Froyo
    Android 2.1.x January 2010 7 Eclair Android.OS.BuildVersionCodes.EclairMr1
    Android 2.0.1 December 2009 6 Eclair Android.OS.BuildVersionCodes.Eclair01
    Android 2.0 November 2009 5 Eclair Android.OS.BuildVersionCodes.Eclair
    Android 1.6 September 2009 4 Donut Android.OS.BuildVersionCodes.Donut
    Android 1.5 May 2009 3 Cupcake Android.OS.BuildVersionCodes.Cupcake
    Android 1.1 February 2009 2 Base Android.OS.BuildVersionCodes.Base11
    Android 1.0 October 2008 1 Base Android.OS.BuildVersionCodes.Base

    It is always a good idea to validate your SSL settings by using one the these online services (In no particular order). Some even report if you are vulnerable to some common SSL attacks ()

  • Google increase security by using only HSTS and it is a good idea to do the same for your server. HTTP Strict Transport Security (HSTS) instructs browsers to communicate with your site only over HTTPS.

    For many years, we’ve worked to increase the use of encryption between our users and Google. Today, the vast majority of these connections are encrypted, and our work continues on this effort.

    To further protect users, we've taken another step to strengthen how we use encryption for data in transit by implementing HTTP Strict Transport Security—HSTS for short—on the www.google.com domain. HSTS prevents people from accidentally navigating to HTTP URLs by automatically converting insecure HTTP URLs into secure HTTPS URLs. Users might navigate to these HTTP URLs by manually typing a protocol-less or HTTP URL in the address bar, or by following HTTP links from other websites.

    see Bringing HSTS to www.google.com

    Quoting the Mozilla Developer Network:

    If a web site accepts a connection through HTTP and redirects to HTTPS, the user in this case may initially talk to the non-encrypted version of the site before being redirected, if, for example, the user types http://www.foo.com/ or even just foo.com. This opens up the potential for a man-in-the-middle attack, where the redirect could be exploited to direct a user to a malicious site instead of the secure version of the original page. The HTTP Strict Transport Security feature lets a web site inform the browser that it should never load the site using HTTP, and should automatically convert all attempts to access the site using HTTP to HTTPS requests instead. see https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security

    An example scenario:

    You log into a free WiFi access point at an airport and start surfing the web, visiting your online banking service to check your balance and pay a couple of bills. Unfortunately, the access point you're using is actually a hacker's laptop, and they're intercepting your original HTTP request and redirecting you to a clone of your bank's site instead of the real thing. Now your private data is exposed to the hacker. Strict Transport Security resolves this problem; as long as you've accessed your bank's web site once using HTTPS, and the bank's web site uses Strict Transport Security, your browser will know to automatically use only HTTPS, which prevents hackers from performing this sort of man-in-the-middle attack.

    For NGINX add this in the server block for your HTTPS configuration:

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; ";

    I would also add the X-Frame-Options header to your HTTPS website to make sure it is not embedded in a frame or iframe. This avoids clickjacking, and might be helpfull for HTTPS websites.

    The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a `<frame>` or `<iframe>`. Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites. see https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options

    For NGINX add this in the server block for your HTTPS configuration:

    add_header X-Frame-Options "DENY";

    Don't forget to restart NGINX.

  • How to create a rogue CA certificate...

    We(note Alexander Sotirov, Marc Stevens, Jacob Appelbaum, Arjen Lenstra, David Molnar, Dag Arne Osvik, Benne de Weger) have identified a vulnerability in the Internet Public Key Infrastructure (PKI) used to issue digital certificates for secure websites. As a proof of concept we executed a practical attack scenario and successfully created a rogue Certification Authority (CA) certificate trusted by all common web browsers. This certificate allows us to impersonate any website on the Internet, including banking and e-commerce sites secured using the HTTPS protocol.

    ps3cluster

    [..]

    "A single attempt for constructing a chosen-prefix collision costs about a little more than a day. The first stage consisting of the birthday search is computationally the most expensive. Luckily it is also very suited for the special SPU cores of the Cell Processor that the Sony PlayStation 3 uses. We had about 200 PS3s at our disposal, located at the"PlayStation Lab" of Arjen Lenstra at EPFL, Lausanne, Switzerland (see the picture). The birthdaying takes about 18 hours on the 200 PS3s using 30GB of memory that was equally divided over the PS3s. The second stage computes the 3 collision blocks that eliminate the IHV differences left after the first stage and costs in total about 3 to 10 hours on a high-end quadcore pc."

    from http://www.win.tue.nl/hashclash/rogue-ca/

    Note: only certificate signed with MD5 are forgeable, and it required a lot of knowledge and money at the moment... unfortunately these are things that spammer, thief and zombies network have at disposal. By luck as soon as Verisign switch to a more secure hashing function, the problem will be solved (Verisign will phase MD5 by January out)

    Note2: even a geek need 1 week to understand the explanations ;-)

    Read more at http://www.win.tue.nl/hashclash/rogue-ca/