Search code examples
c#iisftpx509certificate2

C# is not trusting installed certificate


I set up a FTP server in IIS with an SSL certificate which I created my self (using Makecert.exe and Pvk2Pfx). I attributed the PFX file to my FTP server.

I have a C# script which connects to the FTP server and always gets the following error message:

System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

I installed the certificate in the "Trusted Root Certification Authorities" in the local computer and user.

As it does not authenticate, I took a look via C# on the store:

X509Store store = new X509Store(StoreName.AuthRoot, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

foreach (X509Certificate2 mCert in store.Certificates)
{
     var friendlyName = mCert.Issuer;
     Console.WriteLine(friendlyName);
}
store.Close();

But my certificate is not listed. When I open the MMC console I see my certificate.


Solution

  • Usually, C# doesn't trust certificates without a trusted root certificate - like in the case of a self-signed certificate. The ServicePointManagerallows to add a function where you can handle trusts yourself.

    // Callback used to validate the certificate in an SSL conversation
    private static bool ValidateRemoteCertificate(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors policyErrors)
    {
        if (Convert.ToBoolean(ConfigurationManager.AppSettings["IgnoreSslErrors"]))
        {
            // Allow any old dodgy certificate...
            return true;
        }
        else
        {
            return policyErrors == SslPolicyErrors.None;
        }
    }
    
    private static string MakeRequest(string uri, string method, WebProxy proxy)
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
        webRequest.AllowAutoRedirect = true;
        webRequest.Method = method;
    
        // Allows for validation of SSL conversations
    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
        ValidateRemoteCertificate);
    
        if (proxy != null)
        {
            webRequest.Proxy = proxy;
        }
    
        HttpWebResponse response = null;
        try
        {
            response = (HttpWebResponse)webRequest.GetResponse();
            using (Stream s = response.GetResponseStream())
            {
                using (StreamReader sr = new StreamReader(s))
                {
                    return sr.ReadToEnd();
                }
            }
        }
        finally
        {
            if (response != null)
                response.Close();
        }
    }
    

    From blog post How to accept an invalid SSL certificate programmatically.