I’m developing an AIR (Flex) mobile application for Android and it needs to communicate with an http server using SSL or TSL. I got the CA Certificate Chain using Firefox (checked it also with other tools) and got the following chain:
The one scratched is my companies SSL/TSL server. For security reasons I prefer not to post its address. So, after finding out which certificates I needed (just two in the chain), I searched on my Android tablet which certificates where installed. As you can see in the next picture, the Root certificate, “VeriSign Class 3 Public Primary Certification Authority - G5” was already installed on the system:
The only one that I needed to download was “VeriSign Class 3 Secure Server CA - G3”, which I already did:
Now, I try to enter to the HTTP server with two different browsers and I’m no longer required to accept any certificates. The problem comes when AIR enters the scene. I’ve tried two approaches to communicate with the server, using HTTPService and SecureSocket. For the first one I use the following code:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Declarations>
<s:HTTPService id="bookingservice"
resultFormat="text"
url="https://www.myserver.com/"
result="bookingservice_resultHandler(event)"
fault="bookingservice_faultHandler(event)"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function button1_clickHandler(event:MouseEvent):void
{
resultado.text = "llamando...";
bookingservice.send();
}
protected function bookingservice_resultHandler(event:ResultEvent):void
{
resultado.text = event.result as String;
}
protected function bookingservice_faultHandler(event:FaultEvent):void
{
resultado.text = "satus code: " + event.statusCode + " mensaje: " + event.message.toString();
}
]]>
</fx:Script>
<s:Button top="10" right="10" click="button1_clickHandler(event)" label="Extra" />
<s:TextArea id="resultado"
width="80%" height="80%"
horizontalCenter="0" verticalCenter="0" />
</s:View>
This incredibly simple approach ends with a message box asking for user to accept the unverified server even though all its chain certificates are installed on the Android’s system certificate store. For the second approach I use the following code:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
private var secureSocket:SecureSocket = new SecureSocket;
protected function button1_clickHandler(event:MouseEvent):void
{
secureSocket.addEventListener( Event.CONNECT, onConnect )
secureSocket.addEventListener( IOErrorEvent.IO_ERROR, onError );
resultado.text = "llamando...";
try
{
secureSocket.connect( "https://www.myserver.com/",443);
}
catch ( error:Error )
{
trace ( error.toString() );
}
resultado.text = "llamando...";
}
private function onConnect( event:Event ):void
{
resultado.text = "Connected.";
}
private function onError( error:IOErrorEvent ):void
{
resultado.text = error.text + ", Server Certificate Status: " + secureSocket.serverCertificateStatus;
}
]]>
</fx:Script>
<s:Button top="10" right="10" click="button1_clickHandler(event)" label="Extra" />
<s:TextArea id="resultado"
width="80%" height="80%"
horizontalCenter="0" verticalCenter="0" />
</s:View>
For this last approach, I don’t even get a message box asking for certificate authorization, I only get an error which says: “Error #2031: Socket Error. URL: https://www.myserver.com/, Server Certificate Status: invalid”. I would like to know why the AIR (Flex) mobile runtime is not considering the certificates that are already installed on Android certificate store and it’s still asking for user authorization or, even worst, giving errors and saying that the server certificate is invalid. Does anyone know why this is happening? Am I missing something?
Every bit of help will be appreciated.