title: SSL: Error parsing the certificate: Ok
body: <blockquote>
    <p><strong>NOTE:</strong> I ended up dropping support for Android 2.2 entirely, due to other problems... this issue remains a mistery though.</p>
  </blockquote>
  
  <hr>
  
  <p>I have been experiencing a SSL exception in Android 2.2 on a Huawei U8150.</p>
  
  <pre><code>java.io.IOException: Error parsing the certificates: Ok
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeinit(Native Method)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.init(OpenSSLSocketImpl.java:125)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.&lt;init&gt;(OpenSSLSocketImpl.java:241)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImplWrapper.&lt;init&gt;(OpenSSLSocketImplWrapper.java:35)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl.createSocket(OpenSSLSocketFactoryImpl.java:83)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:739)
  </code></pre>
  
  <p>The code I'm using is fairly simple:
  <a href="https://github.com/kontalk/androidclient/blob/master/app/src/main/java/org/kontalk/client/KontalkConnection.java" rel="nofollow noreferrer">https://github.com/kontalk/androidclient/blob/master/app/src/main/java/org/kontalk/client/KontalkConnection.java</a></p>
  
  <p>The code above just sets a client certificate and a private key for authentication. The code works correctly on Android 2.3 and later.</p>
  
  <p>I've inspected Apache Harmony code to understand what's hunder the hood, and it seems to fail when parsing the certificate chain: <a href="http://www.netmite.com/android/mydroid/dalvik/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java" rel="nofollow noreferrer">http://www.netmite.com/android/mydroid/dalvik/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java</a></p>
  
  <p>In function <code>init()</code>:</p>
  
  <pre><code>ByteArrayOutputStream certificateOS = new ByteArrayOutputStream();
  PEMWriter certificateWriter = new PEMWriter(new OutputStreamWriter(certificateOS));
  
  for (int i = 0; i &lt; certificates.length; i++) {
      certificateWriter.writeObject(certificates[i]);
  }
  certificateWriter.close();
  </code></pre>
  
  <p>It just uses a <code>PEMWriter</code> to create a concatenated chain in PEM format to pass it on to OpenSSL (via <code>nativeinit</code> function).</p>
  
  <p>The certificate generated by my app is genuine, tested with <code>openssl x509</code>. I have to say it has a custom extension, but I repeat that any version newer than 2.2 just work.</p>
  
  <p>I've uploaded the certificate here: <a href="http://paste.debian.net/209823/" rel="nofollow noreferrer">http://paste.debian.net/209823/</a></p>
  
  <hr>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I've been trying to reproduce on my desktop all the steps that Android does to reach the problematic point, that is (marked with <strong>CHECK</strong> the ones I've tried successfully):</p>
  
  <ol>
  <li>store certificate into keystore</li>
  <li>load certificate from keystore (in DER format) - <strong>CHECK</strong></li>
  <li>convert certificate to PEM format - <strong>CHECK</strong></li>
  <li>parse PEM certificate by OpenSSL - <strong>CHECK</strong></li>
  </ol>
  
  <p>For step 3 I'm using Bouncy Castle 1.49 with PEMWriter, just like Android does.<br>
  For step 4 I've created a small C utility linked against OpenSSL 0.9.8m (version installed in Android 2.2) that does the same function calls to initialize a SSL context and load a certificate from a file.</p>
  
  <p>Now what I have left is:</p>
  
  <ul>
  <li>something wrong in keystore handling (I doubt that, although Android is known to have a crippled/modified version of Bouncy Castle)</li>
  <li>Android Java/Dalvik bug (unlikely, but still possible)</li>
  <li>exclude Android 2.2 completely (I'd rather not do it, especially because the issue could also be in other more recent versions that I haven't tried yet)</li>
  </ul>
  
  <p>Code is posted here: <a href="https://gist.github.com/daniele-athome/47f458d64aefed6e6c11" rel="nofollow noreferrer">https://gist.github.com/daniele-athome/47f458d64aefed6e6c11</a></p>