
TLS / SSL protocol support for socket connection on AS3

We are developing a Flash client for a client-server application with a constant socket connection, and it is important for us to protect ourselves from wiretapping traffic. One way to do this is with SSL / TLS encryption. There are two ways to do this in Flash: use the native SecureSocket or TLSSocket from the as3crypto library . Below we discuss the pros and cons, performance, and the problems that we encountered when implementing both options.
Pivot Table
SSL / TLS is a socket add-on to prevent listening and performs two functions - authentication of participants (server and client) and traffic encryption. The main functionality of sockets is presented in the form of a table for clarity:

Comparison of SecureSocket and TLSSocket, “+” - no problems identified, “-” - not supported or not working, “±” - working but with errors or not working for all cases, “?” - failed to verify due to previous errors, “-?” - it is stated that it works, but could not be confirmed
Details on items
SecureSocket
Minimum version of Flash Player
To work SecureSocket required Flash Player version 11 or higher, which is set in only 75% of users , ie, for the remaining 25%, you will have to use TLSSocket anyway .
Work with certificates
SecureSocket is integrated into the system, which allows it to work with the system storage of certificates and system tools for verifying their authenticity, i.e. the server certificate will actually be verified through a certificate authority, which TLSSocket can never do . SecureSocket also allows you to add your own certificate, which will be considered trusted, but still check it for other errors (expiration date, Common Name mismatch in the certificate and server name) and if something goes wrong, it will cut off the connection, so old test certificates (I think almost every developer will have one) they most likely will not work.
SSL
SSL 3.0 (hereinafter referred to as SSL always means SSL 3.0) were tested on their servers in forced SSL mode. The client closed the connection with an unrecognized certificate verification status (serverCertificateStatus = invalid) on all certificates that we tried, including the officially signed one. I note that the socket successfully enters the 443rd port of public servers (google.com, yandex.ru), but the TLS protocol is most likely selected there, and SecureSocket does not allow forcing to use only one of the two TLS or SSL protocols , as it does not attention to the TLS / SSL settings in the browser that runs swf. I can’t pretend to say that SSL 3.0 in principle does not work, yet its support is stated in the official documentation, but we were unable to get it to work.
TLS
TLS earned immediately on both certificates. With a working socket, we were able to evaluate the speed of operation in comparison with an unprotected protocol, here we were very disappointed, more on that below.
TLSSocket
Work with certificates
TLSSocket has several weaknesses in working with certificates :
- There are various uncorrected bugs when parsing some types of certificates. The certificate of the certification authority was not parsed and the patch proposed in issue 26 did not help
- You cannot add your own certificate, which will be automatically considered trusted. Paired with the previous paragraph, we basically lost the ability to verify the server certificate. You will have to add the functionality yourself (an implementation example below), or work in trustAllCertificates mode leaving a security hole .
- There is no way to work with certificates installed on the client system. Judging by the presence of the TLSConfig :: localKeyStore property, the idea was, but, apparently, the inability of AS3 to consider such a list slowed down the implementation.
However, there is a positive point, the library provides several flags for working even with invalid certificates (mismatch of the server name in the certificate and real, self-signed certificates) openness of the code allows you to add inadequate functionality (for example, the flag of ignoring the expiration of the certificate or the addition of its own certificates)
Patch for adding your own trusted certificates
A small patch that adds support for external certificates as trusted in DER format. For implementation, we simply take the MD5 hash of the entire certificate and compare it with what came from the server, if it matches, the certificate is trusted.
Usage example:
- In the class com.hurlant.crypto.tls.TLSConfig add methods to add and verify your certificates
/** * Add own your own trusted certificate * @param cert A ByteArray object containing a DER-encoded X.509 digital certificate. */ public function addTrustedCertificate(cert:ByteArray):void { var md5:String = Hex.fromArray(new MD5().hash(cert)); trustedCertificates[md5] = true; } /** * Check whether the certificate is marked as trusted * @param cert X509Certificate object to check */ public function isTrustedCertificate(cert:X509Certificate):Boolean { var md5:String = cert.md5; return trustedCertificates[md5]; }
- In the class com.hurlant.crypto.cert.X509Certificate add a getter on the md5 hash and the _bytes property (certificate in DER encoding).
private function load():void { ... } else if (p is ByteArray) { b = p; } _bytes = b; ... } private var _bytes:ByteArray; private var _md5:String; /** * get md5 hash for certificate */ public function get md5():String { if(_md5) { return _md5; } if (_bytes) { _md5 = Hex.fromArray(new MD5().hash(_bytes)); } else { throw new Error("get md5: Invalid x509 Certificate parameter"); } return _md5; }
- in the class com.hurlant.crypto.tls.TLSEngine, add the proxy verification of the server certificate to the loadCertificates method line 810:
... } else if (_config.isTrustedCertificate(firstCert)) { certTrusted = true; } else if(_config.trustSelfSignedCertificates ) { // Self-signed certs certTrusted = firstCert.isSelfSigned(new Date); }else { ...
Usage example:
package
{
import com.hurlant.crypto.tls.TLSConfig;
import com.hurlant.crypto.tls.TLSEngine;
import com.hurlant.crypto.tls.TLSSecurityParameters;
import com.hurlant.crypto.tls.TLSSocket;
import com.hurlant.util.der.PEM;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.utils.ByteArray;
public class addcerttest extends Sprite
{
[Embed(source="cert.pem", mimeType="application/octet-stream")]
private static const cert_pem:Class;
public function addcerttest()
{
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, TLSSecurityParameters.PROTOCOL_VERSION);
config.addTrustedCertificate(cert_der);
var socket:TLSSocket = new TLSSocket(null, 0, config);
socket.addEventListener(Event.CONNECT, log);
socket.addEventListener(Event.CLOSE, log);
socket.addEventListener(IOErrorEvent.IO_ERROR, log);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, log);
socket.connect("my.app.server", 443);
}
private function log(event:Event):void
{
trace(event.type);
}
}
}
SSL / TLS
At TLSSocket , traffic encryption worked in both protocols, but packet encryption on the client breaks in SSL after several minutes of client operation. Most likely it breaks due to some kind of bugs in the library, they did not search, because TLS works without problems.
As3crypto generally has a rather large list of bugs and the problem is aggravated by the fact that the developers stopped updating the library.
Performance
SecureSocket
A new problem arose with SecureSocket - periodically (every 5-10 requests), the socket “goes into itself” for 2-8 seconds for no apparent reason. I do not presume to say that everyone will have such lags, but we had them, moreover, on the same server. on which TLSSocket worked quickly, i.e. business on the client side. Tested in a “clean” demo without binding as an application. It was not possible to establish the dependence of parsing time on the packet size, we tried packets from 30 bytes to 5 kb, freezes appeared at different times on random packets, the processor did not load during freezes, fps did not drop. The packet parsing itself is fast, if you take only packets without any hangs, the difference between Socket and SecureSocket is imperceptible, while TLSSocketstill slower than socket . I'll try to deal with this later, because I would still like to have a fast-working native option.
TLSSocket
Since the entire implementation here on as3 the time of parsing packets is linearly proportional to the size and for 2-7 kb packets (maximum in our project) on core i7 it was 40-120 ms, respectively, small packets with runtime alerts are parsed (5-20 ms for packets in 100-500 bytes) and do not cause any lags. For the user, the addition of SSL / TLS will be noticeable only on large packets.
Swf layout
All checked and debugged, now, we post the assembly on the http server, do not forget to configure the socket policy server . We start the application, we see that both sockets do not work. Each has its own reasons: TLSSocket does not work due to issue 4 - the client sends a request for a “handshake” earlier than the connection is established. With SecureSocket, it’s a little more difficult for Flash Player to allow you to open a TLS / SSL connection, you will have to send the policy file from the server via the TLS / SSL protocol, i.e. finalization of the distributor of this file will be required.
conclusions
SecureSocket is integrated into the system, which allows it to work with the system storage of certificates and system tools for verifying their authenticity, which TLSSocket cannot boast of . However, the benefits of SecureSocket end there. Of the obvious shortcomings, I note the second lags when parsing incoming data, broken SSL 3.0 and generally debugging silence if something does not work, which is characteristic of many native as3 solutions. TLSSocket is characterized by fast speed and the ability to fix (or at least figure out the reason) errors in the work, providing its source.
Thanks, who read to the end, I hope the material will be useful and save someone time. Typos and errors please send in a personal. Inaccuracies and additions will be glad to discuss in the comments.
Link to GitHub as3crypto_patched with the patches mentioned in the article and the functionality for adding external trusted certificates.