7

I'm new to .net and doing apn server side in C#. I'm using below code to push the messages to apple server.

    private void pushMessage()
    {
        int port = 2195;
        String deviceID = "4564c705 63b371aa 3811699e 1e4ac3d2 ba592b27 f2a5a613 d25cd035 xx213e54";
        String hostname = "gateway.sandbox.push.apple.com";     // TEST
        //String hostname = "gateway.push.apple.com";           // REAL

        //        @"cert.p12";
        String certificatePath = HttpContext.Current.Server.MapPath("Certi.p12");
        //X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, "");

        X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

        X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
        TcpClient client = new TcpClient(hostname, port);

        // _apnsStream = new SslStream(_apnsClient.GetStream(), false, validateServerCertificate, SelectLocalCertificate);
        //SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate),null);

        SslStream sslStream = new SslStream(client.GetStream(), false, validateServerCertificate, SelectLocalCertificate);
        try
        {
            sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Default, false);
        }
        catch (Exception e)
        {
            throw (e);
            client.Close();
            return;
        }

        MemoryStream memoryStream = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(memoryStream);
        writer.Write((byte)0);  //The command
        writer.Write((byte)0);  //The first byte of the deviceId length (big-endian first byte)
        writer.Write((byte)32); //The deviceId length (big-endian second byte)

        writer.Write(HexStringToByteArray(deviceID.ToUpper()));
        String payload = "{\"aps\":{\"alert\":\"hello\",\"badge\":0,\"sound\":\"default\"}}";
        writer.Write((byte)0);
        writer.Write((byte)payload.Length);
        byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
        writer.Write(b1);
        writer.Flush();
        byte[] array = memoryStream.ToArray();
        sslStream.Write(array);
        sslStream.Flush();
        client.Close();
    }

    private string HexStringToByteArray(string p)
    {
        throw new NotImplementedException();
    }

In execution, getting error like "A call to SSPI failed, see inner exception".

enter image description here

enter image description here

I'm doing any wrong or missed here. Any certificate installation is required in windows? Please help me.

Eran
  • 387,369
  • 54
  • 702
  • 768
user1842744
  • 218
  • 1
  • 6
  • 12
  • 1
    You need to click on `View Detail...` and tell us what the inner exception details are. You also have a few issues with your code - such as your `catch` is useless - all it will do is lose your stack trace and any code after `throw(e)` will not be executed (to name a couple). – Daniel Kelley Jan 28 '13 at 08:50
  • 1
    Take a look at http://stackoverflow.com/questions/1884959/exception-on-sslstream-authenticateasclient-the-message-was-badly-formatted. The OP provides an answer for how they fixed the same issue. – Daniel Kelley Jan 28 '13 at 09:12
  • 7
    I would strongly suggest to use [**PushSharp**](https://github.com/Redth/PushSharp) as they have working examples that you can simply take and use... – balexandre Jan 28 '13 at 14:17
  • 2
    You know that your exception handler is faulty, right? The client will never be closed, as `throw(e);` performs an immediated exit from the exception handler, thus the following two lines will never be called and the exception will be bubbled up. – Thorsten Dittmar Feb 10 '14 at 12:09

2 Answers2

2

I changed my code in PushNotification.class file

_certificate = string.IsNullOrEmpty(p12FilePassword)? new X509Certificate2(File.ReadAllBytes(p12File)): new X509Certificate2(File.ReadAllBytes(p12File), p12FilePassword);

with

_certificate = string.IsNullOrEmpty(p12FilePassword) ? new X509Certificate2(File.ReadAllBytes(p12File)) : new X509Certificate2(File.ReadAllBytes(p12File), p12FilePassword, X509KeyStorageFlags.MachineKeySet);
user1842744
  • 218
  • 1
  • 6
  • 12
-2

so try....

SslStream sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

....

public static bool ValidateServerCertificate(object sender,
                                             X509Certificate certificate,
                                             X509Chain chain,
                                             SslPolicyErrors sslPolicyErrors)
{
  if (sslPolicyErrors == SslPolicyErrors.None)
    return true;

  gerarLog("Certificate error: " + sslPolicyErrors);

  // Do not allow this client to communicate with unauthenticated servers.
  return false;
}

public static byte[] HexStringToByteArray(string hexString)
{
  byte[] HexAsBytes = new byte[hexString.Length / 2];
  for (int index = 0; index < HexAsBytes.Length; index++)
  {
    string byteValue = hexString.Substring(index * 2, 2);
    HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
  }
  return HexAsBytes;
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225