Showing posts with label ssl. Show all posts
Showing posts with label ssl. Show all posts

2021/11/25

Lighttpd vs Let's Encrypt

If you are getting SSL_ERROR_NO_CYPHER_OVERLAP error with lighttpd and an SSL certificate issued by Let's Encrypt, make sure you are using the latest version of lighttpd, openssl and have your root certs up-to-date.
yum --enable-repo=epel update lighttpd openssl openssl-devel openssl-libs openssl-static ca-certificates

2019/04/04

Using a custom CA root in C#

Over the last year or so, I've been using C#. I'm surprised at how good a language it is. Yes, it suffers from MuchToMuchCamelCaseSyndrome(tm). Maybe Microsoft learned from all the mistakes of Java and avoided them. Maybe Microsoft Studio is just better then whatever that Java crap was. I did however find one problem : it's not easy to use a custom certificate authority file when using SSL. The following is the best I've put together.

using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;

namespace NS
{
    public class Cls
    {
        static private X509Certificate2 CustomCA = null;
        static public Boolean ssl_verification(Object sender, X509Certificate certificate, 
                    X509Chain chain, SslPolicyErrors sslPolicyErrors) {

            custom_ca_create();
                    
            // remove this line if commercial CAs are not allowed to issue certificate for your service.
            if ((sslPolicyErrors & (SslPolicyErrors.None)) > 0) { return true; }

            // Upgrade the server cert 
            X509Certificate2 cert2 = new X509Certificate2( certificate );

            // Build a chain we'll check ourselves.
            X509Chain p_chain = new X509Chain();
            p_chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            p_chain.ChainPolicy.ExtraStore.Add( CustomCA );

            // Maybe no errors occur during this check?
            if ( p_chain.Build( cert2 ) )
                return true;

            bool OK = true;
            foreach ( X509ChainStatus sts in p_chain.ChainStatus ) {
                if( sts.Status == X509ChainStatusFlags.UntrustedRoot ) {
                    // We already know that the custom root CA isn't trusted by .Net
                    // So we make sure the root in our custom chain is the custom root CA
                    X509Certificate2 root = p_chain.ChainElements[p_chain.ChainElements.Count - 1].Certificate;
                    if( root.Thumbprint != CustomCA.Thumbprint ) {
                        OK = false;
                        break;
                    }
                }
                else if ( sts.Status != X509ChainStatusFlags.NoError ) {
                    OK = false;
                    break;
                }
            }

            return OK;
        }

        static public void quaero_ca_create()
        {
            if ( CustomCA == null ) {
                // You must include your certificate.pem fil in your resources.
                Byte[] raw = NS.Properties.Resources.Custom_CA;
                CustomCA = ca_create( raw );
            }
        }
        static public X509Certificate2 ca_create( Byte[] raw)
        { 
            X509Certificate2 cert = new X509Certificate2();
            cert.Import( raw );
            return cert;
        }
    }
}

The above code is used with the following:

    System.Net.ServicePointManager.ServerCertificateValidationCallback = NS.Cls.ssl_verification;

As a comparison, this is how I did the same thing in Perl:

    my $ua = LWP::UserAgent->new;

    $ua->ssl_opts( SSL_ca_file => "/home/dw/prive/dw-app/SSL/Custom.CA.pem" );
    $ua->ssl_opts( verify_hostname => 1 );

The following posts helped me figure this out : https://stackoverflow.com/questions/33627593/c-sharp-net-how-to-allow-a-custom-root-ca-for-https-in-my-application-on, https://stackoverflow.com/questions/9508388/how-to-add-a-trusted-ca-certificate-not-a-client-certificate-to-httpwebrequest and https://social.msdn.microsoft.com/Forums/vstudio/en-US/1966a6e8-b6f4-44d1-9102-ec3a26426789/how-can-i-verify-a-certificate-manually-without-installing-its-parents?forum=clr.

2010/11/26

lighttpd and Thawte

Thawte have done it again: mucked about with their root cert. This did this once, years ago. You'd think they'd learn.

So, after much grief I found out how to set up a new SSL certificate in lighttpd:

domain.key is the key you signed your CSR with.
domain.cert is what you have just "Picked up" from Thawte. You want the X.509 one.
cat domain.key domain.cert >domain.pem

wget https://search.thawte.com/library/VERISIGN/ALL_OTHER/thawte%20ca/SSL123_CA_Bundle.pem
Note, please change domain to whatever the FQDN your certificate is for.

You then need to following two lines in your lighttpd config file
ssl.pemfile     = "/etc/lighttpd/domain.pem"

ssl.ca-file = "/etc/lighttpd/SSL123_CA_Bundle.pem"
The CA Bundle is a chain of certificates. Normaly, an SSL cert is signed directly by a root certificate installed with the browser. But Thawte likes doing things the hard way. So they signed a certificate with their root and now sign all new SSL certs with that intermediate certificate. So the web server has supply both the SSL cert and the intermediate certificate to the browser. That's what SSL123_CA_Bundle.pem is. If you bought one of the more expensive options, you should download another bundle.