2

I have a weird requirement. I am trying to communicate with a server written in C#. It looks like this basically:

 SslStream sslStream = new SslStream(client.GetStream(), true,
                                   ValidateServerCertificate,
                                   SelectLocalCertificate); 
sslStream.AuthenticateAsServer(_pushCert);

I also have example code in C# that uses a X509 certificate and connects to the server. I have the password for the cert.pfx file as well.

What I would like to do is setup some kind of shell script that can connect to the socket, transmit a few bytes and receive the response. (any language really, although I was looking at Python or Ruby or Perl)

I tried using the SSL wrapper from Python, but I get an error stating their is no known algorithm for the server/client to talk.

Example of my Python code:

ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = ssl.wrap_socket(ss, ca_certs=CERT, ssl_version=ssl.PROTOCOL_SSLv23 )
#Attempt connection to our server
try:
    s.connect((HOST, PORT))
    print s
except:
    print 'ERROR Connecting'
    sys.exit(0)

For CERT I tried a few different filee: the .pfx, and some extracted from the .pfx using openssl.

I tried many different examples as well (Arguments for the ssl.wrap_socket). I am not really familiar with these connections either.

Perhaps someone here could lend a hand?

Thanks!

Chris
  • 51
  • 5
  • The server needs access to the server private key, not the client. – President James K. Polk Nov 24 '10 at 01:23
  • The Cert I used (.pfx) was from a C# client that connects to this server. The error I keep getting (Exception) is: "The client and server cannot communicate, because they do not possess a common algorithm" – Chris Nov 24 '10 at 01:26
  • AuthenticateAsServer uses SSL 3.0 or TLS 1.0 by default, and your Python code seems to use SSL 2 or 3. So they *should* agree on SSL 3.0 (which afaik specifies a set of algorithms that all implementations must support). I'd say the only possible point of failure here is the certificate. Try with a different one. (You can pretty easily create a self-signed certificate using [makecert.exe](http://msdn.microsoft.com/en-us/library/bfsktky3\(v=VS.100\).aspx).) – dtb Nov 24 '10 at 01:33
  • Thanks for the pointers! Now I am not getting an exception, but the python script freezes on s.connect . the C# Server seems to just stop doing anything as well afterwards.. Maybe some kind of handshake or something needs to be done. – Chris Nov 24 '10 at 02:15
  • When I kill the python process (using 100% cpu) the C# does: e = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."} So it seems to be waiting on some data or something. – Chris Nov 24 '10 at 02:32
  • Okay, so it is the problem with "AuthenticateAsServer" and in my python I have no similar "AuthenticateAsClient" code... Not sure how to solve this one – Chris Nov 24 '10 at 03:26

1 Answers1

0

You can simplify your SslStream constructor call:

SslStream sslStream = new SslStream(client.GetStream()); 
sslStream.AuthenticateAsServer(_pushCert);

This server sends _pushCert and does not expect the client to send a certificate back. The server needs the private key for the certificate to make the SSL connection.

The client only needs the CA root certificate that signed the server certificate (or, an option to accept an untrusted certificate.) This needs to be in the "trusted root certificate store" or otherwise identified as trusted to the client wrapper.

If the server certificate is signed by an intermediate CA certificate that is itself signed by the root CA certificate, the client needs that intermediate certificate too. That can be sent by the server, or can already be at the client. Either way, the entire chain of signing certificates has to be in hand at the client to verify all of the signatures along the chain. The intermediate CA certificate does not need to be in the trusted root store.

Neither side needs a private key for the CA root, or for an intermediate signing certificate.

However, if your server expects the client to send a client certificate, then you have to call AuthenticateAsServer with more arguments (clientCertificateRequired == true). In that case, the client needs both its own certificate and the private key for its certificate. The server needs the CA root that signs the client certificate in its trusted store. The client wrapper will take a pfx file, for example, containing the client certificate and private key. The server does not need the client's private key.

Jim Flood
  • 8,144
  • 3
  • 36
  • 48