Connecting through TLS using ALPN

1.3k Views Asked by At

I'm attempting to connect to Amazon IoT MQTT broker using a C# net core 2.1 class library. My requirements say I must use port 443, which means per Amazon's documentation I have to use a connection that supports ALPN.

.Net Core 2.1 now has the methods to support this, so I try the following code:

(Note: I can try this same code using port 8883 instead of 443, and it connects fine and sends my MQTT data, so I know my certs and endpoint address are correct.)

    this.socket = new Socket(this.remoteIpAddress.GetAddressFamily(), SocketType.Stream, ProtocolType.Tcp);
    this.socket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
    this.netStream = new NetworkStream(this.socket);
    this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback);
    X509CertificateCollection clientCertificates = null;
    clientCertificates = new X509CertificateCollection(new X509Certificate[] { this.clientCert });
    SslApplicationProtocol amzProtocol = new SslApplicationProtocol("x-amzn-mqtt-ca");
    System.Threading.CancellationToken token = new System.Threading.CancellationToken();

    SslClientAuthenticationOptions options = new SslClientAuthenticationOptions()
    {
        AllowRenegotiation = false,
        TargetHost = this.remoteHostName,
        ClientCertificates = clientCertificates,
        EnabledSslProtocols = SslProtocols.Tls12,
        CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
        ApplicationProtocols = new List<SslApplicationProtocol>() { amzProtocol },
        LocalCertificateSelectionCallback = this.userCertificateSelectionCallback,
        RemoteCertificateValidationCallback = this.userCertificateValidationCallback,
        EncryptionPolicy = EncryptionPolicy.RequireEncryption
    };

    this.sslStream.AuthenticateAsClientAsync(options, token).Wait();

Now, from what I understand, I should see (I'm using wireshark) an extension added on to the Client Hello handshake protocol similar to this:

    Extension: Application Layer Protocol Negotiation
      Type: Application Layer Protocol Negotiation (0x0010)
      Length: ##
      ALPN Extension Length: ##
      ALPN Protocol
        ALPN string length: 14
        ALPN Next Protocol: x-amzn-mqtt-ca

But I'm not getting that extension, and the connection fails on port 443.

Am I missing something in setting up the list of protocols? I'm not getting any errors from that, but since this is a pretty new release there's not a lot of reference material out there to look for hints.

1

There are 1 best solutions below

0
On

Well, It seems that even though Net CORE 2.1 has added the functions to support this, that it won't work with Windows 7. You must be using Windows 8.1 or greater. This was not documented anywhere in the code or on the examples on GitHub, but I found out from one of the dev team that for some reason they decided to have it "fail silently", rather than throw an error.