Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

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.

2014/04/30

Furthermore.

A corollary to my previous dictum that a method may make a decisions OR do something is that you want to cut a larger into smaller pieces. And each piece generally looks like the following:

sub doing_something {
    my( $self ) = @_;
    $self->prepare_something;
    if( $self->is_it_time_to_do_something ) {
        $self->before_something;
        $self->something;
        $self->after_something;
   }
   $self->unprepare_something;
}

In the above, something is just the name of the particular small piece of the larger task. The prepare_something/unprepare_something calls are there to avoid all possible side-effects in is_it_time_to_do_something. I would use before_something/after_something are there for things logging, timing, transactions and other "admin" actions that aren't related to something.

I feel like I've been infected by all the Java I did last spring.

2013/03/11

Affordance, discoverability and death to the scroll bar!

There has been a lot of drama lately about major changes to the UI of some popular OSes. A lot of this drama can be boiled down to It's different! It takes me out of my comfort zone! But of course nobody is honest enough to say that straight out. Instead they will claim the UI is not intuitive.

Claiming an interface is intuitive (or not) is a red flag for me. It is unlikely that anyone using the word knows much about UI (and UX and IX), for the simple reason that there is no such thing as an intuitive interface. All interfaces must be learned, including how to suckle a mother's breast.

Features of an interface that can be quantified are discoverability (how easy it is to learn) and affordance (how easy it is to use).

We will start with affordance; it basically measures how easy one element of the UI is to use (eg, click) relative to surrounding elements. Concretely, bigger things are easier to click on then smaller things; things at the edge of the screen are easier to mouse over then things towards the center.

One example of affordance nightmares are the up and down (left/right) arrows of scroll bars, compared to using the gutters for (pretty much) the same purpose. (Visual guide to the scroll bar to your right, my left) The arrow buttons are small, on the order of 12x12 = 144 pixels on a screen that is 1920x1080=2073600 pixels. It is hard to get your mouse over them to click. And all that effort is rewarded by moving the text by a mere 30-40 pixels. (On a side note, a sure way to drive me nuts is to scroll through a page by repeatedly clicking on the down arrow.)

Compare the uselessness of these arrows to the gutters that are right below (or beside or above) the arrows. First, by being long (if narrow) and on the edge of the screen, they are relatively easy to hit (unless the content nearly fits in the window, in which case they are useless). And they reward you by moving the content of the window by roughly the height of the window; what was at the bottom of the window should now be at the top.

But of course scroll bars are pretty much obsolete. The page up/down keys, the space bar (in browsers) and most importantly the mouse wheel are all have much higher affordance. The scroll bar can be reduced to a line within a line, representing the current position within the full content of the window. This is the case in Android on my Nexus 7, even though the screen is a whopping 1280 x 800 pixels. Compare this to the VGA 640x480 pixel screens that used to be wide spread. We ran Windows 3.11 on those computers, and had massive 8-pixel scrollbars (1.25% of the screen width). 16-bit windows also had a bug in that if the content was large enough, the slider would be reduced to just a few pixels high (or wide), dropping its affordance close to zero.

On to discoverability; this is a measure of easy it to find out how to do something. Common things should be easy to discover but it should still be easy to discover rare things. Android 4.2 on my Nexus is a joy in this regard. I assume the other phone/tablet OSes are similarly as good.

You can poke at anything on the screen. "Hey look, a little bluetooth logo, I want to turn that off. [poke] [poke] Hey look! I just drew down a window that contains the 3 pieces of commonly used information (user, WiFi SSID, battery charge), 4 of the commonly adjusted settings (airplane mode, bluetooth, auto rotate, brightness) and a button to get to the settings app.

And because pretty much nothing looks like a traditional button everything could be a button. Poke it and find out!

The traditional menu bar is something of a discoverability nightmare. Pretty much every function of the application gets stuffed in a menu or sub menu. There are so many that people never explore what they do. They've learned to locate the 5 functions they need to get their work done and ignore the rest.