AdoNetCore.AseClient icon indicating copy to clipboard operation
AdoNetCore.AseClient copied to clipboard

SSL/TLS Certificate Validation Improvements

Open senseibaka opened this issue 5 years ago • 4 comments

The current implementation of certificate validation is generally OK, but we've noticed it doesn't work in AWS Lambda whereas the same code, but running in ECS will work (really not sure why).

In addition, the current validation is quite verbose, and a lot of it can be cut down by using .net's built-in X509Chain type. e.g.:

bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain _, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }

    var chain = new X509Chain
    {
        ChainPolicy =
        {
            RevocationMode = X509RevocationMode.NoCheck,
            VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority |
                                X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown |
                                X509VerificationFlags.IgnoreInvalidBasicConstraints,
            
        }
    };
    chain.ChainPolicy.ExtraStore.AddRange(Extra);
    
    return chain.Build(new X509Certificate2(certificate)); // .Build asserts the chain is valid, given the policy specified above
}

So, my suggestion is to do two things:

  1. Update the current validator to something using X509Builder, akin to the above (this is to maintain support for the TrustedFile connection parameter).
  2. Add something so the driver user can supply their own validator callback (more flexibility over the driver's behavior).

senseibaka avatar Jan 21 '20 05:01 senseibaka

The only reference I can find to the way TrustedFile is supposed to work comes from the ASE SDK Doco.

Most importantly

The list of known and trusted CAs is maintained in the trusted roots file. The trusted roots file is similar in format to a certificate file, except that it contains certificates for CAs known to the entity (client applications, servers, network resources, and so on). The System Security Officer adds and deletes trusted CAs using a standard ASCII-text editor.

The application program specifies the location of the trusted roots file using the TrustedFile=trusted file path property in the ConnectString. A trusted roots file with most widely used CAs (Thawte, Entrust, Baltimore, VeriSign andRSA) is installed in at: %SYBASE%\ini\trusted.txt.

From this I think it's fair to conclude that any reasonable consumer using this feature will be specifying at least the root CA cert of the expected SSL cert in this file, so the AllowUnknownerCertificateAuthority flag is unnecessary, and possibly even counter-productive.

Our experience across a few different versions of ASE has shown that it's inconsistent about how much of the certificate chain it will send, so supporting intermediate certs in the TrustedFile for chain reconstruction seems like a good idea.

formicas avatar Mar 13 '20 14:03 formicas

Indeed, it seems like X509VerificationFlags.AllowUnknownCertificateAuthority probably shouldn't be there.

senseibaka avatar Mar 13 '20 21:03 senseibaka

A few key differences between the "official" Sybase driver and this AdoNetCore driver:

  1. The Sybase driver is very forgiving of errors made to the CA cert used in the TrustedFile. I am able to make multiple character changes to the certificate without it failing to connect utilizing a self signed CA. The same changes fail with the AdoNetCore driver.

  2. The Sybase driver doesn't seem to care what the server name is somehow; Our db cert for our server s-test-04 has a CN STEST04 and the official driver works with this connection string:

     "Database=ssltest;Charset='iso_1';Server={server};Port=5000;...;Pooling=True;Encryption=ssl;TrustedFile=c:\\trusted.txt";
    

    where server can be s-test-04, STEST04, s-test-04.myinternaldomain.com, the ip address, or any other uri I put in my hosts file. The AdoNetCore driver (with the patch PR) only connects to STEST04.

  3. I don't think the Sybase driver works with a cert that validates to the OS CA but doesn't against the trusted file. In the AdoNetCore driver if the cert validates with a trusted root, it doesn't matter what the trusted file contains. It would perhaps be more "drop in replacement" compatible to require the validation against a cert in the trusted file somewhere in the chain instead of accepting certs without any chain errors?

bbarry avatar Apr 03 '20 16:04 bbarry

Do we have any doco regarding setting up SSL env for development and testing?

ngvtien avatar Feb 07 '21 03:02 ngvtien