Validating X509 certificates by using the EWS Managed API 2.0

Last modified: June 20, 2013

Applies to: EWS Managed API | Exchange Server 2007 Service Pack 1 (SP1) | Exchange Server 2010

Note: This content applies to the EWS Managed API 2.0 and earlier versions. For the latest information about the EWS Managed API, see Web services in Exchange.

By default, Exchange uses self-signed X509 certificates to authenticate calls to the Exchange Web Services (EWS) Managed API. Unless you create a certificate validation callback method, calls to the EWS Managed API will fail. If you are using the Autodiscover service to find the EWS Managed API endpoint, the call to the Autodiscover method will fail with an AutodiscoverLocalException exception.

The ServicePointManager class in the.NET Frameword System.Net namespace enables you to hook up a validation callback method by setting the ServerCertificateValidationCallback property. This topic provides information about how to set up your application to use a certificate validation callback method. The code example in this topic shows how to create a method that examines the certificate that is returned in a call to an EWS Managed API method.

To create an X509 certificate validation callback method

  1. Include references to the required.NET Framework namespaces.

    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    
  2. Create a certificate validation callback method that your application can call. For an example of a certificate validation callback method, see Example later in this topic.

  3. Before calling the Autodiscover service, set the ServerCertificateValidationCallback property of the ServicePointManager class to your certificate validation callback method.

    ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
    

Example

The following code example shows how to create an X509 certificate validation callback method. This method will validate an X509 certificate. This method only returns true if either of the following criteria are met:

  • The certificate is valid and signed with a valid root certificate.

  • The certificate is self-signed by the server that returned the certificate.

Security noteSecurity Note

The certificate validation callback method in this example provides sufficient security for development and testing of EWS Managed API applications. However, it may not provide sufficient security for your deployed application. You should always make sure that the certificate validation callback method that you use meets the security requirements of your organization.

      private static bool CertificateValidationCallBack(
         object sender,
         System.Security.Cryptography.X509Certificates.X509Certificate certificate,
         System.Security.Cryptography.X509Certificates.X509Chain chain,
         System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
      // If the certificate is a valid, signed certificate, return true.
      if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
      {
        return true;
      }

      // If there are errors in the certificate chain, look at each error to determine the cause.
      if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
      {
        if (chain != null && chain.ChainStatus != null)
        {
          foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
          {
            if ((certificate.Subject == certificate.Issuer) &&
               (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
            {
              // Self-signed certificates with an untrusted root are valid. 
              continue;
            }
            else
            {
              if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
              {
                // If there are any other errors in the certificate chain, the certificate is invalid,
             // so the method returns false.
                return false;
              }
            }
          }
        }

        // When processing reaches this line, the only errors in the certificate chain are 
    // untrusted root errors for self-signed certificates. These certificates are valid
    // for default Exchange server installations, so return true.
        return true;
      }
      else
      {
     // In all other cases, return false.
        return false;
      }
    }

Compiling the code

For information about compiling this code, see Getting started with the EWS Managed API 2.0.

Robust programming

  • Write appropriate error handling code for common search errors.

  • Review the client request XML that is sent to the Exchange server.

  • Review the server response XML that is sent from the Exchange server.

  • Set the service binding as shown in Setting the Exchange service URL by using the EWS Managed API 2.0. Do not hard code URLs because if mailboxes move, they might be serviced by a different Client Access server. If the client cannot connect to the service, retry setting the binding by using the AutodiscoverUrl method.

Security

  • Use HTTP with SSL for all communications between client and server.

  • Always validate the server certificate that is used to establish the SSL connections.

  • Do not include user names and passwords in trace files.

  • Verify that Autodiscover lookups that use HTTP GET to find an endpoint always prompt for user confirmation; otherwise, they should be blocked.