secureSocket w/ some light verification methods (not fully safe yet)

First off, I’m providing it and the source for free… so feel free to modify, enhance, distribute, etc. Secondly, it hasn’t been thoroughly tested (just roughly). Thirdly, don’t judge on the way I code (hahaha…). I’m sure there are many optimizations and other things that could be done different.

I’m currently in the works of creating a complete ASN.1 encoder/decoder that will work within Xojo. Until then, the way I get the information out of the certificate binary information that is passed is pretty rough (ie. using inStr, etc.); however, it works. Once I’m complete with the ASN.1 encoder/decoder, I will update the source and re-share; however, it’s a HUGE project and will be sometime before I’m done (only doing it on a part of my free time).

Anyhow, I’ve left some source comments, but it’s very limited (I quickly created this in a couple of hours today). I constructed this mainly because I have a few hundred devices that connect to a server. All the data it transmits is IP and very sensitive (meters for utility billing). The way Xojo currently handles SSL, you can’t verify the certificate. This increases the chances of a man-in-the-middle attack (or somebody simply putting any invalid (even self-generated) SSL on their server, running the traffic through a proxy, and process the information on their server) which would completely bypass ours. I found that to be a huge security concern. This solution I provided should only be used as a temporary solution until Xojo incorporates something that works into their solution. Using the socket is pretty simple:

// - secureSocket.connect() function
// -
// - isSecured
// - true - attempts to establish a secured connection w/ verified SSL
// - false - attempts to establish a standard non-secured connection
// - remoteAddress
// - remote address of the connection; must be a DNS name for certificate verification purposes
// - remotePort (optional)
// - remote port of the connection
// - NOTE: defaults to 443 for secured, and 80 for non-secured connections if ‘0’ or not provided
// - unverifiedHandler (optional)
// - secureSocket.SSL_ON_INVALID - attempts to establish a ‘secured’ connection even if the SSL certificate is invalid
// - secureSocket.NOSSL_ON_INVALID - attempts to fall-back to a standard non-secured connection if the SSL certificate is invalid
// - secureSocket.DISCONNECT_ON_INVALID - will disconnect the connection if the SSL certificate is invalid
// - NOTE: defaults to coreTcp.DISCONNECT_ON_INVALID if not provided
// - connectBypass (optional)
// used by the verification process to re-establish a secure connection using the super.construct of connect (shouldn’t be used manually)

// - secureSocket.verificationStatus property
// -
// - secureSocket.VERIFYING_SSL
// - ssl verification process is still pending
// - secureSocket.UNABLE_TO_VERIFY
// - unable to verify an ssl certificate for the connection (address may not contain one)
// - secureSocket.VALID_SSL
// - connection has a valid ssl certificate
// - NOTE: currently only validates based on domain verification, issued date, and expiration date
// - secureSocket.INVALID_SSL
// - connection has an invalid ssl certificate
// - NOTE: currently only validates based on domain verification, issued date, and expiration date

here is the .connect function:

secureSocket.connect(isSecured as boolean, remoteAddress as memoryBlock, optional remotePort as uInt16, optional unverifiedHandler as memoryBlock, optional connectBypass as boolean)

So, if you use something like:

secureSocket.connect(true, "tv.eurosport.com", 0, secureSocket.NOSSL_ON_INVALID)

it will attempt to make a secure connection and fall back to a standard non-secured (http, port 80) connection if the ssl certificate is invalid

secureSocket.connect(true, "tv.eurosport.com", 0, secureSocket.SSL_ON_INVALID)

it will attempt to make a secure connection; however, is the ssl certificate is invalid it will still use the invalid certificate to secure the connection

secureSocket.connect(true, "tv.eurosport.com", 0, secureSocket.DISCONNECT_ON_INVALID)

it will attempt to make a secure connection and disconnect if the ssl certificate is invalid

download link:
https://dl.dropboxusercontent.com/u/13574877/sslVerification.xojo_binary_project

Hey, since this class is claiming to be “SSL Verification”, I have a couple of questions:

  1. What does it report for a self-signed certificate? Because they’re not verified by a 3rd party, anyone could create one and use it behind the scenes. They’re used all the time in attacks against other systems. Your code should be able to detect a self-signed certificate and report that fact.
  2. Certificates are issued in “chains” these days so that if one piece of the chain is compromised, it (and all of its dependents) can be quickly reissued. Does your code verify the “chain of trust” for a certificate?

[quote=129218:@Greg O’Lone]Hey, since this class is claiming to be “SSL Verification”, I have a couple of questions:

  1. What does it report for a self-signed certificate? Because they’re not verified by a 3rd party, anyone could create one and use it behind the scenes. They’re used all the time in attacks against other systems. Your code should be able to detect a self-signed certificate and report that fact.[/quote]

Currently it just reports back the issued by, issued to, expiration date, and issued date. To check for self-signed certificate, you’d simply need to validate if the subject and issuer are the same; if so, it is self-signed; if they are different, then it was signed by a CA. I will update this to do that in the next day or two.

Funny you should mention this… any update on this?
<https://xojo.com/issue/34263>

Right. I wanted to bring these things up though because an uninformed user of your code might think that this is all they need to do.

I’m not convinced that the subject and issuer will always be the same for a self-signed certificate though. If a hacker created their own chain of trust (let’s say, on their computer), the issuer could be “foo” with the subject being “bar”. That should not be considered a valid issuer either.

This is why most browsers have a repository of ‘safe & verified’ CA Authorities, and validate against that. Unless we create a similar repository and keep it updated, you will always run into this.

Also, if you use sslSocket to connect your own client created with Xojo, to your own server (so you know the certificate is valid), then verifying the connection with what is already presented with this is probably enough. Again, once I get the ANS.1 portion completed then we’ll be able to do a lot more. This solution is only a temporary one to begin with. A solid verification system will not validate a certificate, break the connection, then immediately re-establish the connection if the certificate is valid… which is what this solution does. I needed a way to better insure my client devices were, infact, connecting not just to any server with an ssl… but to one on my domain. This solution helps with that (though not a perfect solution). The alternative is to cypher the packets before transmitting, and deciphering them again using my own system before sending them via ssl. This seemed redundant, and hitting on resources since I have upwards of 500 devices on a single server constantly dumping data at any one time.

As I said, I’m making sure that anyone using your code understands that there are still risks.

Don’t get me wrong, it’s good work, I just know that most users will read the subject and then go download the code without ever reading your blurb or the code itself without understanding what it does and does not do for them. I’m hoping that a few constructive questions with answers from you will make people actually read a little first since SSL security is so important to do right.

[quote=129378:@Greg O’Lone]As I said, I’m making sure that anyone using your code understands that there are still risks.

Don’t get me wrong, it’s good work, I just know that most users will read the subject and then go download the code without ever reading your blurb or the code itself without understanding what it does and does not do for them. I’m hoping that a few constructive questions with answers from you will make people actually read a little first since SSL security is so important to do right.[/quote]

Understand, and have changed the title to reflect this.

with our CURL Plugin you are able to verify the peer/host to make sure certificate chain is correct.

@Eric Brown and @Greg O’Lone , this is a very good discussion and helps understand security risks even with signed certificates.
Maybe a subject for a more comprehensive blog or videopresentation?

Thanks guys, pls go on!

Thats really not relevant to what Eric’s doing though