Need help with http Client using https

I tried to port the HttpClient sample from the NETMF 4.2 SDK to the spider Mainboard but have problems using https.
This is my code. When the button is pressed the page from the GHI Community Dashboard shall be loaded.


using System;
using System.Collections;
using System.Threading;
using System.Security.Cryptography;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;  //System.Http, need to also add System.dll to references
using Microsoft.SPOT.Time;
using System.Net;
using Gadgeteer.Modules.GHIElectronics;
using System.Security.Cryptography.X509Certificates;

namespace HttpClient_https_Test
{
    public partial class Program
    {
        byte[] ca = Resources.GetBytes(Resources.BinaryResources.DigiCert);
        X509Certificate[] caCerts;

        private static IPAddress localIpAddress = null;
        private Microsoft.SPOT.Net.NetworkInformation.NetworkInterface settings;
        private TimeServiceSettings timeSettings;
        private bool timeServiceIsRunnig = false;
        private int timeZoneOffset = 0;
        
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            caCerts = new X509Certificate[] { new X509Certificate(ca) };
            button.ButtonPressed += button_ButtonPressed;
            ethernetJ11D.UseThisNetworkInterface();
            ethernetJ11D.NetworkSettings.EnableDhcp();
            ethernetJ11D.NetworkSettings.EnableDynamicDns();
            ethernetJ11D.NetworkUp += ethernetJ11D_NetworkUp;
            ethernetJ11D.NetworkDown += ethernetJ11D_NetworkDown;
            timeSettings = new Microsoft.SPOT.Time.TimeServiceSettings()
            {
                ForceSyncAtWakeUp = true
            };
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            MyHttpClient.PrintHttpData("https://www.ghielectronics.com/community/dashboard", caCerts);
        }
        #region initializeNetwork()
        void initializeNetwork()
        {
            try
            {
                ethernetJ11D.NetworkInterface.Open();
                ethernetJ11D.NetworkSettings.EnableDhcp();
                ethernetJ11D.NetworkSettings.EnableDynamicDns();
                ethernetJ11D.UseStaticIP("192.168.1.222", "255.255.254.0", "192.168.1.1");
                ethernetJ11D.UseDHCP();
                
                Thread.Sleep(2000);
                while (ethernetJ11D.NetworkSettings.IPAddress == "192.168.1.222")
                {
                    Debug.Print("Waiting for DHCP");
                    Thread.Sleep(250);
                }
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
        #endregion

        #region ListNetworkInterfaces()
        void ListNetworkInterfaces()
        {
            var settings = ethernetJ11D.NetworkSettings;

            Debug.Print("------------------------------------------------");
            Debug.Print("MAC: " + ByteExtensions.ToHexString(settings.PhysicalAddress));
            Debug.Print("IP Address:   " + settings.IPAddress);
            Debug.Print("DHCP Enabled: " + settings.IsDhcpEnabled);
            Debug.Print("Subnet Mask:  " + settings.SubnetMask);
            Debug.Print("Gateway:      " + settings.GatewayAddress);
            Debug.Print("------------------------------------------------");
        }
        #endregion

        #region SetTime()
        void SetTime()
        {
            timeSettings = new Microsoft.SPOT.Time.TimeServiceSettings()
            {
                ForceSyncAtWakeUp = true
            };
            IPAddress[] address = System.Net.Dns.GetHostEntry("time1.google.com").AddressList;
            try
            {
                timeSettings.PrimaryServer = address[0].GetAddressBytes();
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
            TimeService.Settings = timeSettings;
            TimeService.SetTimeZoneOffset(timeZoneOffset);
            TimeService.Start();
            timeServiceIsRunnig = true;
        }
        #endregion

        #region ethernetJ11D_NetworkUp and ethernetJ11D_NetworkDown Events
        void ethernetJ11D_NetworkUp(Gadgeteer.Modules.Module.NetworkModule sender, Gadgeteer.Modules.Module.NetworkModule.NetworkState state)
        {
            Debug.Print("Network up");
            while (ethernetJ11D.NetworkSettings.IPAddress == "0.0.0.0")
            {
                Thread.Sleep(300);
            }
            localIpAddress = IPAddress.Parse(ethernetJ11D.NetworkSettings.IPAddress);
            Debug.Print("Got IP-Address by DHCP: " + localIpAddress.ToString());

            if (!timeServiceIsRunnig)
            {
                SetTime();
            }
            settings = ethernetJ11D.NetworkSettings;
            ListNetworkInterfaces();
            //SetTime();
            Thread.Sleep(20);
            Debug.Print("Time is: " + DateTime.Now);
        }

        void ethernetJ11D_NetworkDown(Gadgeteer.Modules.Module.NetworkModule sender, Gadgeteer.Modules.Module.NetworkModule.NetworkState state)
        {
            Debug.Print("Network down");
        }
    #endregion
    }

}

This is the HttpClient Class


using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.Security;
using System.Security.Cryptography.X509Certificates;

/// This program demonstrates how to use the .NET Micro Framework HTTP classes 
/// to create a simple HTTP client that retrieves pages from several different 
/// websites, including secure sites.
namespace HttpClient_https_Test
{
    public static class MyHttpClient
    {
        public static void PrintHttpData(string url, X509Certificate[] caCerts)
        {
            HttpWebRequest request = 
                HttpWebRequest.Create(url) as HttpWebRequest;

            // Initialize the default webproxy to be used by all 
            // HttpWebRequests.
            // Change the proxy address to fit your environment.
            try
            {
                // Check networking - we need to make sure we can reach our proxy server
                //System.Net.Dns.GetHostEntry("itgproxy.dns.microsoft.com");  //this does not work
                System.Net.Dns.GetHostEntry("4.2.2.2");
            }
            catch (Exception ex)
            {
                Debug.Print("Exception " + ex.Message);
            }

            HttpWebRequest.DefaultWebProxy = new WebProxy("4.2.2.2", true);

            // Assign the certificates. The value must not be null if the connection is HTTPS.
            request.HttpsAuthentCerts = caCerts;

            // Set request.KeepAlive to use a persistent connection. 
            request.KeepAlive = true;

            // Get a response from the server.
            WebResponse resp = null;
            try
            {
                resp = request.GetResponse();
            }
            catch (Exception e)
            {
                Debug.Print("Exception in HttpWebRequest.GetResponse(): " + 
                    e.ToString());
            }

            // Get the network response stream to read the page data.
            if (resp != null)
            {
                Stream respStream = resp.GetResponseStream();
                string page = null;
                byte[] byteData = new byte[4096];
                char[] charData = new char[4096];
                int bytesRead = 0;
                Decoder UTF8decoder = System.Text.Encoding.UTF8.GetDecoder();
                int totalBytes = 0;

                // allow 5 seconds for reading the stream
                respStream.ReadTimeout = 5000; 

                // If we know the content length, read exactly that amount of 
                // data; otherwise, read until there is nothing left to read.
                if (resp.ContentLength != -1)
                {
                    for (int dataRem = (int)resp.ContentLength; dataRem > 0; )
                    {
                        Thread.Sleep(500);
                        bytesRead = 
                            respStream.Read(byteData, 0, byteData.Length);
                        if (bytesRead == 0)
                        {
                            Debug.Print("Error: Received " +
                                (resp.ContentLength - dataRem) + " Out of " +
                                resp.ContentLength);
                            break;
                        }
                        dataRem -= bytesRead;

                        // Convert from bytes to chars, and add to the page 
                        int byteUsed, charUsed;
                        bool completed = false;
                        totalBytes += bytesRead;
                        UTF8decoder.Convert(byteData, 0, bytesRead, charData, 0, 
                            bytesRead, true, out byteUsed, out charUsed, 
                            out completed);
                        page = page + new String(charData, 0, charUsed);

                        // Display the page download status.
                        Debug.Print("Bytes Read Now: " + bytesRead + 
                            " Total: " + totalBytes);
                    }

                    page = new String(
                        System.Text.Encoding.UTF8.GetChars(byteData));
                }
                else
                {
                    // Read until the end of the data is reached.
                    while (true)
                    {
                        // If the Read method times out, it throws an exception, 
                        // which is expected for Keep-Alive streams because the 
                        // connection isn't terminated.
                        try
                        {
                            Thread.Sleep(500);
                            bytesRead = 
                                respStream.Read(byteData, 0, byteData.Length);
                        }
                        catch (Exception)
                        {
                            bytesRead = 0;
                        }

                        // Zero bytes indicates the connection has been closed 
                        // by the server.
                        if (bytesRead == 0)
                        {
                            break;
                        }

                        int byteUsed, charUsed;
                        bool completed = false;
                        totalBytes += bytesRead;
                        UTF8decoder.Convert(byteData, 0, bytesRead, charData, 0, 
                            bytesRead, true, out byteUsed, out charUsed, 
                            out completed);
                        page = page + new String(charData, 0, charUsed);

                        // Display page download status.
                        Debug.Print("Bytes Read Now: " + bytesRead + 
                            " Total: " + totalBytes);
                    }

                    Debug.Print("Total bytes downloaded in message body : " 
                        + totalBytes);
                }

                // Display the page results.
                Debug.Print(page);

                // Close the response stream.  For Keep-Alive streams, the 
                // stream will remain open and will be pushed into the unused 
                // stream list.
                resp.Close();
            }
        }
    }
}

The exception is shown in the picture.
The exception is thrown in HttpClient Class in the line: resp = request.GetResponse();
What am I doing wrong?




@ RoSchmi - Did you update the ssl seed in MFDeploy?

@ John - Thanks John,
yes, I updated the SSL Seed.

In the meantime I did some more test with my listed code.

I was able to download a blob from my azure account:
https://roschmi01.blob.core.windows.net/con7/Hello_Azure_from_Gadgeteer.html
when the “DigiCert Baltimore Root” certificate, which is the root certificate of Azure, was installed
When I try to load other pages like Log In ‹ GHI Electronics — WordPress with the proper certificates installed, I get SocketException ErrorCode = -1 RTSSL_CTX_NOT_VALID or 5 RTSSL_X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE

What might be the reason?

@ RoSchmi - We’ve noticed that finding the right certificate to use can be very trick. Have you read https://www.ghielectronics.com/docs/30/networking#3370

@ John - I have read it.
Is “DigiCert” not the right certificate for the GHI page?

@ RoSchmi - I believe the certificate we last used in our tests against our own site was the “DigiCert Global Root CA” with serial number “‎08 3b e0 56 90 42 46 b1 a1 75 6a c9 59 91 c7 4a”.

@ John - thanks, I’ll try it later today