title: Sending APNS from ASPX/C# Page, Authentication with SSL
body: <p>I have been trying to get a Windows 2008 R2 Datacenter(On Amazon) to utilize the Apple Push Notification Service - I've seen a lot of questions about some of this, but none of the existing answers have solved my problem.  I am writing this using an SslStream with TcpClient which I've wrapped together in a class called SSLClient.  I keep getting the "The certificate chain was issued by an authority that is not trusted" error on the AuthenticateAsClient line.  Here is my SSLClient(Much of it started from the MSDN example of using an SslStream with TcpClient):</p>
  
  <pre><code>public class SSLClient
  {
      public delegate void OnSSLRequestHandler(SSLRequestEvent e);
  
      private string _machineName;
      private string [] _serverCertFilenames;
      private string [] _serverCertPasswords;
  
      public event OnSSLRequestHandler OnLoaded;
  
      public SSLClient(
          string machineName,
          string [] serverCertFilenames,
          string [] serverCertPasswords )
      {
          _machineName = machineName;
          _serverCertFilenames = serverCertFilenames;
          _serverCertPasswords = serverCertPasswords;
      }
  
      public bool ValidateServerCertificate(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
      {
         if (sslPolicyErrors == SslPolicyErrors.None)
              return true;
  
          // Do not allow this client to communicate with unauthenticated servers. 
          return false;
      }
  
      public void Load(byte[] sendData, int port = 443)  
      {
          // Create a TCP/IP client socket. 
          // machineName is the host running the server application.
          TcpClient client = new TcpClient(_machineName, port);
  
          // Create an SSL stream that will close the client's stream.
          SslStream sslStream = new SslStream(
              client.GetStream(), 
              false, 
              new RemoteCertificateValidationCallback (ValidateServerCertificate), 
              null
          );
  
          // The server name must match the name on the server certificate. 
          try 
          {
              X509Certificate2Collection xc = new X509Certificate2Collection();
              for (int i = 0; i &lt; _serverCertFilenames.Length; i++)
              {
                  string certName = _serverCertFilenames[i];
                  string certPwd = _serverCertPasswords[i];
  
                  X509Certificate2 x;
                  if (certPwd != "")
                      x = new X509Certificate2(certName, certPwd);
                  else
                      x = new X509Certificate2(certName);
  
                  xc.Add(x);
              }
  
              sslStream.AuthenticateAsClient(_machineName, xc, SslProtocols.Ssl3, false);
          } 
          catch (AuthenticationException e)
          {
              string errMsg = "Exception: " + e.Message;
  
  
              if (e.InnerException != null)
                  errMsg += ("\r\nInner exception: " + e.InnerException.Message);
  
              errMsg += ("\r\nAuthentication failed - closing the connection.");
              client.Close();
  
              // Just fires an event, ctor(success, message, response, SSLClient)
              if (OnLoaded != null)
                  OnLoaded(new SSLRequestEvent(false, errMsg, null, this));
  
              return;
          }
  
          sslStream.Write(sendData);
          sslStream.Flush();
  
          // Read message from the server. 
          byte[] response = ReadMessage(sslStream);
  
          // Just fires an event, ctor(success, message, response, SSLClient)
          if (OnLoaded != null)
              OnLoaded(new SSLRequestEvent(true, "Success", response, this));
  
          // Close the client connection.
          client.Close();
      }
  
      private byte[] ReadMessage(SslStream sslStream)
      {
          MemoryStream ms = new MemoryStream();
  
          byte [] buffer = new byte[2048];
  
          int bytes = -1;
          do
          {
              bytes = sslStream.Read(buffer, 0, buffer.Length);
  
              ms.Write(buffer, 0, bytes);
  
          } while (bytes != 0);
  
          return ms.ToArray();
      }
  }
  </code></pre>
  
  <p>The certificates used are one I have followed the steps for from Apple to a test mobile application I am working on, as well as 4 entrust certificates which seems are also required.  The usage of this class is as follows:</p>
  
  <pre><code>public void DoAPNSPush()
  {
      // Build the binary data to be sent
      byte[] bin = BuildAPNSMessage();
  
      // These certs are uploaded to the server next to this ASPX
      // and are being found and read correctly.
      string[] certs = new string[] {
          Server.MapPath("certs") + "\\MyPFX.pfx",
          Server.MapPath("certs") + "\\my_cert_from_apple.cer",
          Server.MapPath("certs") + "\\entrust_2048_ca.cer"
      };
  
      string[] pwds = new string[] {
          "password",
          "",
          ""
      };
  
      SSLClient ssl = new SSLClient("gateway.sandbox.push.apple.com", certs, pwds);
      ssl.OnLoaded += new SSLClient.OnSSLRequestHandler(onSSLLoaded);
      ssl.Load(bin, 2195);
  }
  
  public void onSSLLoaded(SSLRequestEvent e)
  {
      // We never get here, but the event has the following members:
      //      bool e.Success
      //      string e.Message
      //      byte[] e.Response
      //      SSLClient e.Client
  }
  </code></pre>
  
  <p>Hopefully this isn't TLDR.  What could I be doing wrong that authentication still fails?  I have already made sure port 2195 is open on the Amazon Security Group. Additionally, I have tried other SslProtocols.Ssl3 and SslProtocols.Tls.  The CSR for apple was generated from this server and completed, the entrust certs were downloaded from their website(<a href="https://www.entrust.net/downloads/root_request.cfm#" rel="nofollow">https://www.entrust.net/downloads/root_request.cfm#</a>) and I just double-clicked them once on the server to install them.</p>
  
  <p>Any input would be helpful</p>
  
  <p>Thanks in advance.</p>