At first... This program is only just-4-fun and wont be published ever. It's only for testing Sockets, so don't care about the security of this connection. I coded a little messenger where you can type in a message in a textbox and it will be send to the server and from the server to all clients. So far, so good. Just for fun I wanted to use SSL for this connection. But when I'm trying to connect to the server socket it returns RemoteCertificateNameMismatch at ValidateServerCertificate. After I added some debug-messages I discovered that Sslstream.LocalCertificate is null. How can I fix this missing certificate? I am using a self-signed certificate.
Please help, here's my code... and yes... sorry for my bad english :/ :
C# Client
[...]
public bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
//sslPolicyErrors returns RemoteCertificateNameMismatch
return true; //Code shortened
}
public X509CertificateCollection getCertificates()
{
X509CertificateCollection cCollection = new X509CertificateCollection();
cCollection.Add(getCertificate());
return cCollection;
}
private X509Certificate getCertificate()
{
string Certificate = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.crt";
string ClientCertificatePassword = "...";
return new X509Certificate(Certificate, ClientCertificatePassword);
}
public X509Certificate SelectLocalCertificate(
object sender,
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
{
foreach(X509Certificate cer in localCertificates) {
return cer;
}
return getCertificate();
}
public void connect(String username)
{
XMLConfigManager xml = XMLConfigManager.getInstance();
String ip = xml.get("ip");
tc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ;
tc.Connect(ip, int.Parse(xml.get("port")));
networdstream = new NetworkStream(tc);
using(sslstream = new SslStream(networdstream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), new LocalCertificateSelectionCallback(SelectLocalCertificate)))
{
sslstream.AuthenticateAsClient(ip, getCertificates(), SslProtocols.Default, true);
}
sendMessage(username);
t = new Thread(new ThreadStart(checkInput));
t.Start();
tm.addThread(t);
th = new Thread(new ThreadStart(userTimer));
th.Start();
tm.addThread(th);
}
public void disconnect()
{
if(sslstream != null) {
sslstream.Close();
}
if(tc != null) {
tc.Close();
}
}
[...]
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
public void sendMessage(String s)
{
try
{
if ((s != null) && (s.Length > 0))
{
try
{
sslstream.Write(GetBytes(s));
}
catch (Exception)
{
}
}
}
catch (Exception ex)
{
endError(ex);
return;
}
}
public void userTimer()
{
Thread.Sleep(2000);
sendCommand("usercount");
th = new Thread(new ThreadStart(userTimer));
th.Start();
tm.addThread(th);
}
[...]
static String ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
} while (bytes != 0);
return messageData.ToString();
}
public void checkInput()
{
try
{
Form2 f2 = f1.f;
if(!isConnected()) {
t.Abort();
return;
}
String s = ReadMessage(sslstream);
if(s == null) {
t.Abort();
return;
}
CommandHandler ch = new CommandHandler();
Boolean handle = ch.handle(s, f1.f);
if (!handle) {
if (s == "Der Benutzername ist schon vergeben.")
{
endDuplicatename();
return;
}
f2.Invoke(new Action(() => f2.chat.Items.Add(s)));
f2.Invoke(new Action(() => f2.select_newest()));
}
}
finally
{
t = new Thread(new ThreadStart(checkInput));
t.Start();
tm.addThread(t);
}
}
Java Server Socket
package de.wladhd.server;
import java.net.Socket;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import de.wladhd.client.Client;
import de.wladhd.client.ClientManager;
import de.wladhd.logs.Log;
import de.wladhd.logs.LogType;
public class DateServer {
private SSLServerSocket server;
private boolean running = true;
private String keyStore = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.pfx";
private String keyStorePassword = "...";
private String keyStoreType = "PKCS12";
private String trustStore = "D:/Wlad/Programmierung/Zertifikat/CA/CertificateAuthority.pfx";
private String trustStorePassword = "...";
private String trustStoreType = "PKCS12";
public void execute() throws Exception {
//System.setProperty("javax.net.debug","all");
System.setProperty("javax.net.ssl.keyStoreType", keyStoreType);
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
System.setProperty("javax.net.ssl.trustStoreType", trustStoreType);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
//System.setProperty("javax.net.ssl.trustStore", "de.wladhd.server.Trusting");
SSLServerSocketFactory serverFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
if(serverFactory == null) {
new Log("Error occured... Server Factory == null!", LogType.ERROR);
return;
}
server = (SSLServerSocket) serverFactory.createServerSocket(9090);
running = true;
new Log("Server now running on query: " + server.getInetAddress().getHostAddress() + ":" + server.getLocalPort(), LogType.INFO);
while (running) {
try {
if(server.isClosed()) {
return;
}
new Log("Client connecting...", LogType.DEBUG);
final Socket rawsocket = server.accept();
if(!(rawsocket instanceof SSLSocket)) {
new Log("Client isnt an instance of SSLSocket!", LogType.DEBUG);
return;
}
final SSLSocket socket = (SSLSocket) rawsocket;
try {
socket.startHandshake();
} catch (Exception ex) {
}
new Log("Client - Connected: " + socket.isConnected(), LogType.DEBUG);
new Log("Client - Protocol: " + socket.getSession().getProtocol(), LogType.DEBUG);
new Log("Client - Session valid: " + socket.getSession().isValid(), LogType.DEBUG);
new Log("Client - CipherSuite: " + socket.getSession().getCipherSuite(), LogType.DEBUG);
new Log("Client - NeedClientAuth: " + socket.getNeedClientAuth(), LogType.DEBUG);
new Log("Client - WantClientAuth: " + socket.getWantClientAuth(), LogType.DEBUG);
Client c = new Client(socket);
//socket.getHandshakeSession() returns null and peer not authenticated exception...
} catch (Exception ex) {
ex.printStackTrace();
continue;
}
}
}
public void disconnect() throws Exception {
new Log("Server disconnecting...", LogType.INFO);
setRunning(false);
ClientManager.getInstance().disconnectClients();
if(server != null) {
server.close();
}
new Log("Server successfully disconnected!", LogType.INFO);
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean state) {
running = state;
}
}
If you need something please tell me...