I'm attempting to push notifications to my iPhone, which I've successfully done using PHP. However, I'm unable to open a socket connection to Apple's push servers using C#. I don't think there's a problem with the certificate itself, since I'm able to successfully push notifications using this code in PHP:
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'cert.pem');
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
fwrite($fp, $msg);
When I try to authenticate in C# using the code below, Apple closes the connection right away. I get this exception: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Default, false);
I basically took all my code from this question: C# iPhone push server?
I thought it might be a problem with the certificate since I don't think C# allows you to just load .PEM files programmatically. I used OpenSSL to convert it to a .PFX file, but I still have the same problem.
Any idea how I can troubleshoot this (possible certificate) problem?
This actually turned out to be a problem with .NET 2.0. Not sure exactly what it is, but I compiled in Visual Studio 2008 and everything worked great.
Related
I have some trouble with my HttpListener. I already searched and read some dicussions.
For example: Httplistener with HTTPS support
Firstly I try to describe my scenario:
I want to create a HTTP-Listener with SSL/HTTPS Support. Thats the main target.
I used OpenSSL to create my own CA and I created my own server cert.
Now I have:
myCa.key
myCa.pem
myCa.srl
myServer.key
myServer.csr
myServer.crt
I installed the myCa.pem and the myServer.crt certificate to my local computer. I moved the CA in the trusted store and the server certificate in "own certificates"
Then I took the fingerprint (certHash) of my server certificate.
I created the netsh entry with admin-rights
netsh http add sslcert ipport=0.0.0.0:9649 appid= '{0a5ce-569a-4dc6-8ed7-9ef91241dec3}' certhash=4F556BDC3F97B31D555266DA74F573777FCCAA55
My C# implementation is relativly simple:
this.Listener = new HttpListener();
this.Listener.Prefixes.Add("https://*:9649");
this.Listener.Start();
this.Listener.BeginGetContext(new AsyncCallback(ProcessClient), this.Listener);
//Process an incoming connection
private void ProcessClient(IAsyncResult result)
{
var listener = (HttpListener)result.AsyncState;
var clientContext = listener.EndGetContext(result);
}
When I implemented SSL in my TcpStack I used a SSL-Stream and there I can validate a certificate with a ValidationCallback. Im not sure if this is possible here. I tried
ServicePointManager.ServerCertificateValidationCallback += ValidateCert; But I never hit my breakpoint there.
Now to the problems:
When I try to connect with my own HttpClient (.NET HttpClient Class) I get always a RemoteNameMismatch Error on the SSL-Layer. I dont hit the breakpoint in the ProcessClient method. I tried without specific certificate (auto detection) and I tried also to advise the same certificate (with the same hash) to the client. In both cases I got the same error. I dont understand why I get any erros when I use the same certificate on the client and the server side. I always thought the netsh will compare the certhashes.
When I try a connect with Postman I hit the ProcessClient function. But Postman gets an error that he cant check the certificate. But I think the problem is that my certificate isnt a official certifcate . But the data exchange is working.
Another point is: I want to roll out my app also in containers with a unix os. .NET60 is designed for crossplatform. But whats the unix pendant to netsh? Is it possible to run my listener with https on unix? How works the mapping here between app and certificate?
Maybe I have to change my technology? Alternative to HttpListener? Mainly I dont want to use thridparty stuff.
UPDATE Solution:
See my answer below
Thanks for reading and for help.
Greetings
Like the guys said in the in comments. The FDQN was the problem. In easy words: I created my own CA and then I created a server cert signing request against the CA. Inside the server cert the CN is matching to my DNS of my personal computer. The connection with my HTTP-Listener is working now. Thank you for your help!
Here is the project:
I'm creating a TcpListener in C#, that will host on a Linux box using Mono.
Then I will have a TcpClient (also Mono on Linux) that will connect to it, and because I can't have a username/password auth, I would like it that clients connect with a "client certificate", that I will generate with my Root CA (also self-generated)
I can't only have the client connect securely to the server, I need my TcpListener to trust my client connection too.
What i have done so far:
I have exported my server certificate as PFX:
And loaded this into the code:
sslCertificate = new X509Certificate2("myCert.pfx", "password");
Now, if I run the code as below:
bool requireClientCertificate = false; // <== turn on/off
SslStream sslStream = new SslStream(netStream, false, new RemoteCertificateValidationCallback(AcceptRemoteCertificate));
sslStream.AuthenticateAsServer(sslCertificate, requireClientCertificate, SslProtocols.Tls, false);
With requireClientCertificate = false, then I can use a browser to view this page perfectly fine. Of course, I would have already imported my Root CA, in order to see this page, otherwise Chrome gives me a certificate warning.
Right, so there is no problem with this so far... and SSL is established, but technically anyone could connect to this TcpListner.
Now I set requireClientCertificate = true, and this is where things fall apart.
I realize I need to generate a client certificate, so I did that, exported that, and imported it into my PC. I can see it under the certificate list in Chrome, and I am prompted to use it when I first attempt to connect the TcpListner.
However, doing all that, still does not solve things.
I have also installed the Root CA onto the server using:
copy to /usr/share/ca-certificates/mozilla/MyRootCA.crt
editing /etc/ca-certificates.conf
update-ca-certificates
(This showed 1 new certificate installed.. but still did'nt help)
Then I tried:
certmgr -add -c -v -m Trust /home/Certs/MyRootCA.crt
Still not working, so i tried:
certmgr -add -c -v -m CA /home/Certs/MyRootCA.crt
So from what I can see the RootCA is installed.
If I try connect with Chrome I'm getting:
RemoteCertificateChainErrors in the RemoteCertificateValidationCallback
And if I loop thought the chain, I get : PartialChain in the Status Information.
And if I test with OpenSSL, I get:
RemoteCertificateChainErrors with: UntrustedRoot in the Status Information
The totally confusing part on this, is that, my RemoteCertificate of the TcpListner is not null - it is in fact a the certificate that I installed on the browser, and can see the RootCA that singed it too (Issuer).
If I actually do a: wget https://api.myserver.com --certificate=/my.crt --private-key=/my.key --ca-certificate=/MyRootCA.crt, it connects and downloaded my expedited results.
So, questions:
Is this connection actually mutually secure?
What are those errors about? UntrustedRoot and PartialChain
If it has these errors, but still can present a RemoteCertificate, does that mean its a mutually secure connection or not?
In the past I have done this on Windows Server with a commercial CA certificates (DigiCert E.V.), and other (out of my control) CPE's, and they worked without errors. This is the only difference I have noticed. Is this the reason? Does Linux / Mono, have some sort of additional knowledge about certificates, that if you generate your own Root CA... it can't trust it completely?
EDIT:
I have not got a full answer, but I have discovered a few things. Would really appreciate some assistance from someone who has this working.
So what I discovered that you can check the stream (ssl) properties of .IsMutuallyAuthenticated and .IsSigned and .IsEncrypted. This is vital to this, and especially .IsMutuallyAuthenticated.
As it turned out, by manipulating the RemoteCertificateValidationCallback response true/false, you can handle the errors that you "don't mind", and reject the others. In that case the connection disconnects and an error is raised. However, in my RemoteCertificateChainErrors I was able to return true... and when doing that stream.IsMutuallyAuthenticated, was returning True! Yay
Ok, now I build the client with :
HttpWebRequest requestObj = (HttpWebRequest)WebRequest.Create(strURL);
requestObj.ClientCertificates = certs;
This presents the certificates to my server code, and now this is where its interesting... After getting the response object:
HttpWebResponse responseObj = (HttpWebResponse)requestObj.GetResponse();
Debug.WriteLine("IsMutuallyAuthenticated: " + responseObj.IsMutuallyAuthenticated);
Even though I'm getting my expected results back, and responseObj.StatusCode == HttpStatusCode.OK, IsMutuallyAuthenticated is false. So clearly this is an issue with the certificate that i'm presenting client side.
It seems that the client side code can NOT trust the certificate it is presenting, but I have installed the Root CA locally on the PC. Both Local Machine, and User. If I open the store - and list the certs, its there.
This seems like its more difficult than it should be. Any assistance would help.
I have an instance of OpenFIre up and running and all is pretty smooth. I can connect to it via Spark as well as a variety of app.
When I wrote my app using the trial version of the Matrix SDK, the client connected perfectly. I am trying to move over to Sharp.XMPP and yet, whenever I try to connect to the server, I get the following error message :
The XML stream could not be negotiated.
When I drill down, I get to the folllwoing inner exception
{"'�', hexadecimal value 0x15, is an invalid character. Line 1,
position 1."}
There seems to be some issue with the response encoding that Sharp.XMPP is expecting.
Does anyone have any idea how to fix this?
Are you trying to connect to an old-style SSL port (usually 5223) with a client that expects to do StartTLS (usually on 5222)?
(0x15 is the TLS content type for "alert", which is likely the response when parsing something that is not TLS.)
I have been facing the following error intermittently.
Authentication to host '127.0.0.1' for user 'root' using method 'mysql_native_password' failed with message: Reading from the stream has failed.
It shots up any time and I am at my wits end. I also posted a bug on MySQL bugs and solutions are not proving to be effective in any way.I hope you guys can help me out.
Here is the link to MySQL Bug for details: Never seems to go away!
Some more detail: I have a client-server system but this bug occurs on the server system(where MySQL database is installed) when a local running app on the server system tries to run a query.
I had already opened a question here but since has been dead. Just a caveat I thought that skip-name-resolve solved the issue but it seems to just have lowered the frequency. Hope someone would help me out this time around.
EDIT: The MySQL guys say that in a client server setup server may close a connection if it is unused for a long time. However, this is not what I am facing as I create a new connection everytime I want to execute a query. I made this point clear in the last comment on the MySQL Bugs.
Guys I tried this: "SslMode=None" in the connection string, but if you need SSL then read this:
http://www.voidcn.com/article/p-phfoefri-bpr.html
here is a sample connection string that works:
connectionString="Server=192.168.10.5;Database=mydata;Uid=root;Pwd=****;SslMode=None"
Hope this helps
I've been getting this error, quite frequently with Amazon's MySQL RDS instances. And most multi-AZ instances.
It would be interesting to compare notes to see if others mostly get this issue with RDS also?
Amazon is known to rely heavily on "fast" DNS changes to switch over stuff with things like ELBs. I wonder if the same thing is happening with RDS? Or some other internal AWS switching is messing up the idle connections in the pool.
This would explain why the Oracle devs can't reproduce it and don't see it as much of an issue.
Anyway I've had to just deal with it and add retry logic when opening a connection.
This issue is caused by Ssl.
Solution 1: SSL is not required. Since it is caused by SSL, we can turn off SSL by appending "SslMode=None" to the connection string.
Solution 2: SSL is required, server identity is important and needs to be verified. The server needs a internet connection to do the cert verification. Please note the crypto API doesn't update CTL for every process. The CTL is maintained at operating system level. Once you connect the server to connect and make an SSL database connection to the server, the CTL will be updated automatically. Then you may disconnect the internet connection. Note again the CTL has its expiration date and after that the Windows needs to update it again. This will occur probably after several months.
Solution 3: SSL is required but the server identity is not important. Typically SSL is only used to encrypt the network transport in this case. We can turn off CTL update:
Press Win+R to open the "Run" dialog
Type "gpedit.msc" (without quotes) and press Enter
In the "Local Group Policy Editor", expand "Computer Configuration", expand "Administrative Templates", expand "System", expand "Internet Communication Management", and then click "Internet Communication settings".
In the details panel, double-click "Turn off Automatic Root Certificates Update", clickEnabled, then click OK. This change will be effective immediatelly without restart.
http://www.voidcn.com/article/p-phfoefri-bpr.html
unfortunately, this error occurs if the application and mysql are on the same computer, if you move it to a different computer it is fine.
I tried many ways but for now there is no other solution. bug has been reported many times by others https://bugs.mysql.com/bug.php?id=76597
I had the exact same problem performing the upgrade on a windows form application. The solution I found was to change the server, because that one was in trouble. On the server that was presenting the similar situation you described had installed WordPress with MYSQL 5.6.34, on the other I did a clean install with MYSQL version 5.6.26.
I don't know if it has to do with the environment variables used. I believe it has nothing to do with Connection Timeout, if it is a property that is used only with the open connection. This error occurred in a shared environment as well as in a local installation with Maria DB. Another problem I found was that one of the selection commands that retrieved the data was having a problem in its formation not respecting the blanks:
SELECT COLUNA1, COLUNA2 FROM TABLE;
I made the change to SELECT COLUMN1, COLUMN2 FROM TABLE;
I am still testing on this solution I presented, and as of the time of posting there were no more errors.
I was getting the error
Authentication to host 'localhost' for user 'root' using method 'mysql_native_password' failed with message: Reading from the stream
I solved it when I put SslMode=None in my connection string.
However, I checked that the message is different from you
Check my connection
connection.ConnectionString = "server=myadressserver;userid=myuser;password=mypassword;database=test;SslMode=None";
I am currentry writing a C# client (with Mono using SSLStream) for an already existing OpenSSL server written in C++. I know that in theory, they should be able to communicate, but I always get an Exception:
Authentication or decryption has failed.
Which takes place in Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback when I invoke sslStream.AuthenticateAsClient(ServerName);
I do not need client authentication, so i don't use any client certificate, and i can't load my server certificate into a client's trust store, as I can't use the command line on the client side.
On the server, I seem to receive some random data, which should not happen, as I never invoke sslStream.Write() in the client code. Maybe I don't completely understand how the handshake happens. I have an OpenSSL C++ client that works perfectly though.
Does someone know How I could get this working?
I am using, on the server side, a self-signed certificate generated by OpenSSL, which i converted to DER format.
How I proceed:
Server side
Initialize OpenSSL
Load server certificate (DER) and private key (PEM)
Open a non-SSL listening socket
As a client connects, I open a new socket which I connect to an SSL_Bio and accept the connection
Read the SSL socket for incoming data.
Client side
I am trying to connect using a temporary client adapted from the one in this topic.
Open a new TCPClient
Link a new SSLStream to it with the same validation callback as in the thread above;
Calling AuthenticateAsClient(ServerName) which brings this exception.
Invoke sslStream.Write but the execution never gets here.
Any help would be greatly appreciated as I am not sure to understand how sslStream internally works.
Ok, got it. In fact, I was setting up the BIO and the SSL variables in the wrong order. You have to create and attach your BIO to your SSL BEFORE you actually call SSL_Accept in OpenSSL, otherwise the authentication cannot complete, which seems logical.
Also, I was using SSLStream in C# on client side to send my messages, while I was using BIO_read and BIO_write on the server Side with OpenSSL.
This could not work, because BIO_read and BIO_write are no equivalent to SSL_read and SSL_write. These two functions only read and write on the underlying socket, without any encryption or decryption, making the SSL handshake almost useless (aside from checking the identity of the other end of the line).
This explains why I was not able to engage communication as the two ends did not speak the same language: one sent unencrypted messages while the other expected SSL-wrapped messages and the other way round.
The SSL_read and SSL_Write functions take care of the encryption and decryption, so they are the ones to use here. Now it works perfectly.
If you need any further details about how I did that, please comment this answer.