Ivan Markovic
Ivan Markovic

Reputation: 11

SSL accepting self signed certificate in ActionScript 3

i am trying to use SecureSocket connection to server. i am using FlashBuilder 4.6 that has SecureSocket class implemented. the problem is that after creating SecureSocket object and calling connect function i get ioError - type 2031 and "invalid" for serverCertificateStatus. certificate on the server side is self signed. is there any way for flash to work with self signed certificates?

Upvotes: 1

Views: 2981

Answers (2)

Ivan Markovic
Ivan Markovic

Reputation: 11

tlssocket.addEventListener(ProgressEvent.SOCKET_DATA, ESecureSocketData);
private function ESecureSocketData( evt:ProgressEvent ):void
{
    StartTimer();

    ReadResponse();
    ParseMessage();
}
private function ReadResponse():void
{
    var o_Bytes:ByteArray = new ByteArray();

    tlssocket.readBytes( o_Bytes, 0, tlssocket.bytesAvailable );

    for ( var i:uint = 0; i < o_Bytes.length; i ++ ) {
        o_Bytes.position    = i;
        str_Response        += String.fromCharCode( o_Bytes.readByte() );
    }
}

Upvotes: 0

fsbmain
fsbmain

Reputation: 5267

You can use as3crypto TLSSocket instead (I recommend take my patched version, it has patches for several critical issues), it also contains new method addTrustedCertificate that may be help in your case (just adds the certificate in *.der format, it will be accepted in any case (self signed, wrong domain and so)).

package
{
    import com.hurlant.crypto.tls.SSLSecurityParameters;
    import com.hurlant.crypto.tls.TLSConfig;
    import com.hurlant.crypto.tls.TLSEngine;
    import com.hurlant.crypto.tls.TLSSocket;
    import com.hurlant.util.der.PEM;
    import com.kamagames.core.util.log.Logger;
    import com.kamagames.core.util.log.TraceTarget;

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.net.SecureSocket;
    import flash.utils.ByteArray;

    public class sockettest extends Sprite
    {
        [Embed(source="cert.pem", mimeType="application/octet-stream")]
        private static const cert_pem:Class;

        private var tlssocket:TLSSocket;
        private var secsocket:SecureSocket;

        public function sockettest()
        {
            var cert_pem_bytes:ByteArray = new cert_pem();
            var cert_der:ByteArray = PEM.readCertIntoArray(cert_pem_bytes.readUTFBytes(cert_pem_bytes.bytesAvailable));

            var config:TLSConfig = new TLSConfig(TLSEngine.CLIENT, null, null, null, null, null, SSLSecurityParameters.PROTOCOL_VERSION);
            config.ignoreCommonNameMismatch = true;
            config.addTrustedCertificate(cert_der);

            var socket:Object = new TLSSocket(null, 0, config);
            socket.addEventListener(Event.CONNECT, log);
            socket.addEventListener(ProgressEvent.SOCKET_DATA, log);
            socket.addEventListener(Event.CLOSE, log);
            socket.addEventListener(IOErrorEvent.IO_ERROR, log);
            socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, log);

            socket.connect("google.com", 443);
        }

        private function log(event:Event):void
        {
            trace(event.type);
        }
    }
}

In theory the SecureSocket.addBinaryChainBuildingCertificate method may also helps you, but I don't sure about it, may be it works only for chained certificates.

In general patched TLSSocket is more suitable than SecureSocket for applications because it opensource and gain more overall control over communication process, but SecureSocket is native for system as @Reboog711 mentioned (it works with system certificate for example that TLSSocket can't)

Upvotes: 1

Related Questions