views:

37

answers:

1

Hi

I have WCF REST web service hosted by IIS, it works on HTTPS, I generate Certificate on IIS and assign Https to a port

I generate cer through IE browser. I create a test application and regardless Add a client certificate or not or even add a wrong certificate the connection take place and a I get correct response. I am wondering how the message was decrypted if there is no certificate sent.

Either the destination is not secured or I misunderstand the whole thing. also

The error I have from the callback "CheckValidationResult()" is either CertCN_NO_MATCH = 0x800B010F or "Unknown Certificate Problem" , the certificateProblem (parameter of CheckValidationResult) is 0 for this case

What is CertCN_NO_MATCH eror, what is CN?

See code below.

 ServicePointManager.CertificatePolicy = new CertPolicy();

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(String.Format("https://{0}/uri", ip));
            //request.ClientCertificates.Add(new X509Certificate("D:\\ThePubKey.cer"));


            request.ContentType = "application/x-www-form-urlencoded";

            request.Method = "POST";

            using (StreamWriter stream = new StreamWriter(request.GetRequestStream()))
            {
                stream.Write("RequestType=CheckStatus&ReportType=Fulfillment&ReportID=5");
            }

            using (StreamReader stream = new StreamReader(request.GetResponse().GetResponseStream()))
            {
                Response.ContentType = "text/xml";

                Response.Output.Write(stream.ReadToEnd());
                Response.End();
            } 

    class CertPolicy : ICertificatePolicy
        {
            public enum CertificateProblem : uint
            {
                CertEXPIRED = 0x800B0101,
                CertVALIDITYPERIODNESTING = 0x800B0102,
                CertROLE = 0x800B0103,
                CertPATHLENCONST = 0x800B0104,
                CertCRITICAL = 0x800B0105,
                CertPURPOSE = 0x800B0106,
                CertISSUERCHAINING = 0x800B0107,
                CertMALFORMED = 0x800B0108,
                CertUNTRUSTEDROOT = 0x800B0109,
                CertCHAINING = 0x800B010A,
                CertREVOKED = 0x800B010C,
                CertUNTRUSTEDTESTROOT = 0x800B010D,
                CertREVOCATION_FAILURE = 0x800B010E,
                CertCN_NO_MATCH = 0x800B010F,
                CertWRONG_USAGE = 0x800B0110,
                CertUNTRUSTEDCA = 0x800B0112
            }


            public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
            {
                // You can do your own certificate checking.
                // You can obtain the error values from WinError.h.

                // Return true so that any certificate will work with this sample.

                String error = "";

                using (StringWriter writer = new StringWriter())
                {

                    writer.WriteLine("Certificate Problem with accessing " + request.RequestUri);
                    writer.Write("Problem code 0x{0:X8},", (int)certificateProblem);
                    writer.WriteLine(GetProblemMessage((CertificateProblem)certificateProblem));

                    error = writer.ToString();
                }

                return true;
            }

            private String GetProblemMessage(CertificateProblem Problem)
            {
                String ProblemMessage = "";
                CertificateProblem problemList = new CertificateProblem();
                String ProblemCodeName = Enum.GetName(problemList.GetType(), Problem);
                if (ProblemCodeName != null)
                    ProblemMessage = ProblemMessage + "-Certificateproblem:" +
                       ProblemCodeName;
                else
                    ProblemMessage = "Unknown Certificate Problem";
                return ProblemMessage;
            }

        }
+1  A: 

I've just replied to this similar question (in Java).

CN is the "Common Name". It ought to be the hostname of the server to which you're connecting (unless it's in the subject alternative name). I guess from your code sample that you're using the IP address directly. In this case, the CN should be that IP address (it tends to be better to use a hostname rather than an IP address). See RFC 2818 (sec 3.1) for the specifications.

Note that the CN or subject alternative name is from the point of view of the client, so if you connect to https://some.example.com/, then the name in the cert should be some.example.com, if you connect to https://localhost/, then the name in the cert should be localhost, even if some.example.com and localhost may be the same server effectively. (I guess that by default, IIS might generate a certificate for the external name, but you'd have to look at the certificate to know; this should be visible in the certificate properties somewhere.)

Bruno
There is something I don't understand, When I put no certificate at all, the SSL connection is established successfully, I wonder how the server decrypt the message without client certificate
Costa
The client cert is only used for auth. It's the server cert that's used for encrypting the shared keys (depending on the cipher suites, though).When using optional client certs, not providing a cert is OK, but providing a invalid cert tends to make the handshake fail.I suspect the server isn't configured to trust your client cert (is it this client cert from a CA trusted by your server?), or perhaps there's no mapping of that cert to a user known by the system. (Not sure how this works with IIS.) It might be worth looking at http://msdn.microsoft.com/en-us/library/aa376545%28VS.85%29.aspx
Bruno