Validate SSL Certificate - c#

I am trying to connect my c# client to a node.js server via tls/ssl. The Server is working and I have created my certs. But If I want to connect via TcpClient to the Server, it says, that the Certificate is invalid. Could you make your own validation for that cert? Do you guys have any ideas?
namespace Client
{
class Program
{
private static TcpClient _TcpClient = new TcpClient("localhost", 8000);
private static SslStream stream;
static void Main(string[] args)
{
stream = new SslStream(_TcpClient.GetStream());
stream.AuthenticateAsClient("localhost");
byte[] buffer = new byte[2048];
StringBuilder data = new StringBuilder();
int bytes = -1;
do
{
bytes = stream.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
data.Append(chars);
if (data.ToString().IndexOf("<EOF>") != -1)
{
break;
}
}
while (bytes != 0);
Console.WriteLine(data.ToString());
Console.ReadKey();
}
}
}
The Certificate is self signed so I have to send it with the client, but I dont know how. Even if I disable the validation via ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
, it does not work (I just put it in the first line of the main method).

So, I just didn't change the code, I just installed the certificate on my server with this guide: https://technet.microsoft.com/en-us/library/ff730672.aspx

Related

C# Client halted while connecting with C++ Server, but works fine when connecting with C# Server

I have C# Client and C# Server Programs that connected with each other successfully and works fine. But when i want to connect C# Client with C++ server then C# client gets halted while C++ Server produces success messages of "winsock initialization success " and "creating socket success".
C++ Server Code
WSADATA wsaData;
struct sockaddr_in address_of_server;
struct sockaddr_in address_of_client;
int socket_of_client;
int size_of_address_of_client = sizeof(address_of_client);
if (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0) {
printf("winsock initialization success\n");
}
else {
printf("winsock initialization failure\n");
}
SOCKET socket_of_server = socket(AF_INET, SOCK_STREAM, 0);
if (socket_of_server == -1) {
printf("creating socket failure\n");
}
else {
printf("creating socket success\n");
}
memset(&address_of_server, 0, sizeof(address_of_server));
address_of_server.sin_family = AF_INET;
//address_of_server.sin_family = PF_INET;
address_of_server.sin_addr.s_addr = htonl(INADDR_ANY);
address_of_server.sin_port = htons(8888);
bind(socket_of_server, (struct sockaddr*)&address_of_server, sizeof(address_of_server));
listen(socket_of_server, 5);
ClientSocket = accept(socket_of_server, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(socket_of_server);
WSACleanup();
return 1;
}
socket_of_client = accept(socket_of_server, (struct sockaddr*)&address_of_client, &size_of_address_of_client);
WSACleanup();
C# Client Code
public CCRMain()
{
InitializeComponent();
clientSocket.Connect("127.0.0.1", 8888);
}
void Data()
{
MainWindow mw = (MainWindow)Application.Current.MainWindow;
NetworkStream serverStream = mw.clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(A1G1.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, (int)mw.clientSocket.ReceiveBufferSize);
System.IO.MemoryStream ms = new System.IO.MemoryStream(inStream);
System.IO.BinaryReader br = new System.IO.BinaryReader(ms);
int[] inComingData = new int[5];
for (int i = 0; i < 5; i++)
{
inComingData[i] = br.ReadInt32();
Debug.WriteLine(inComingData[i].ToString());
A1G1Text.Text = inComingData[0].ToString();
}
}
NetworkStream.Read() is blocking. So as long as the server does not close the connection, this will not return until 10025 bytes have been read.
You should directly read from the network stream, not copy it over twice (or even four times in your case: From network to inStream and then to a MemoryStream and then to inCommingData and then to your text variable).
Use the NetworkStream.ReadTimeout property to indicate that you want Read() to return even if not the entire buffer was filed within some time.

c# TCP NetworkStream is not receiving data

I'm trying to send files after sending their's information via TCP connection. At the end of receiver host, the data packets are received. I used Wireshark to confirm it. However the data couldn't be received in NetworkStream.
public class FileTransporter
{
public void ReceiveFiles(IPAddress IP, int port)
{
TcpListener tcpListener = new TcpListener(IP, port);
tcpListener.Start();
using (TcpClient tcpClient = tcpListener.AcceptTcpClient())
{
if (tcpClient.Connected)
{
using (NetworkStream networkStream = tcpClient.GetStream())
{
int pointer = 0;
byte[] fileNameLengthBytes = new byte[sizeof(int)];
networkStream.Read(fileNameLengthBytes, pointer, fileNameLengthBytes.Length);
int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes, pointer);
// code to read fileName and it's size
networkStream.Close();
}
}
tcpClient.Close();
}
tcpListener.Stop();
}
public void SendFiles(IPAddress IP, int port, string[] paths)
{
for(int i=0; i<paths.Length; i++)
{
FilePackage filePackage = new FilePackage(paths[i]);
byte[] infoBytes = filePackage.EncodeInfoToByte();
using (TcpClient tcpClient = new TcpClient())
{
tcpClient.Connect(IP, port);
using (NetworkStream networkStream = tcpClient.GetStream())
{
networkStream.Write(infoBytes, 0, infoBytes.Length);
networkStream.Close();
}
tcpClient.Close();
}
}
}
}
public class FilePackage
{
public FilePackage(string fileName)
{
this.Info = new FileInfo(fileName);
}
public byte[] EncodeInfoToByte()
{
List<byte> infoByte = new List<byte>();
infoByte.AddRange(BitConverter.GetBytes(this.Info.Name.Length));
infoByte.AddRange(Encoding.UTF8.GetBytes(this.Info.Name));
infoByte.AddRange(BitConverter.GetBytes(this.Info.Length));
return infoByte.ToArray();
}
I am going to Assume that ReadFiles is invoked somehow / somewhere else.
I have a very similar implementation, however my "Read" of the stream is much smaller:
// Read the first batch of the TcpServer response bytes.
var bytes = new byte[512];
// Loop to receive all the data sent by the Server.
var sb = new StringBuilder();
do
{
var i = stream.Read(bytes, 0, bytes.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(bytes, 0, i));
} while (stream.DataAvailable);
Perhaps using "stream.DataAvailable" will allow you to test for data existence and that way you can make sure that you only process when data is available.
Also I don't see where "pointer" is being initialized in your code.
If it is not set to 0 each time, you will not be processing from the beginning of the data packet.
Your problem is probably being caused by the nagle algorithm, prevent small amounts of data being sent to reduce congestion. You could try disabling it by setting the following properties on your tcpClient
tcpClient.NoDelay = true;
tcpClient.Client.NoDelay = true

C# sockets: can't read after writing to socket

In my client/server application my client wiil communicate with the server for 2 functions: the client will either request data from the server or it will send data so the server will save it. I'm using one socket for both methods, and the method to be used is defined by the first byte sent. If the first byte is "1" it is requesting data. If it is "2", it will send data (data bytes are sent after the "2" byte). It works perfectly for sending data. But when I'm requesting data it works, as long as I don't read the socket stream in the client. It's like if I make the client read data after sending data, the server will have no data to read, and it just crashes when trying to read the data.
Here is my server code:
private const int BufferSize = 1024;
NetworkStream netstream = null;
byte[] RecData = new byte[BufferSize];
int RecBytes;
try {
netstream = clientSocket.GetStream();
int totalrecbytes = 0;
using (MemoryStream ms = new MemoryStream()) {
//When I get here, there is no data to read
while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) {
ms.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
byte[] bytes = ms.ToArray();
byte b = bytes[0];
switch (b) {
case 1:
//Here I gather data and put it in "stream" variable
byte[] SendingBuffer = null;
int NoOfPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(stream.Length) / Convert.ToDouble(BufferSize)));
int TotalLength = (int)stream.Length, CurrentPacketLength, counter = 0;
for (int i = 0; i < NoOfPackets; i++) {
if (TotalLength > BufferSize) {
CurrentPacketLength = BufferSize;
TotalLength = TotalLength - CurrentPacketLength;
}
else
CurrentPacketLength = TotalLength;
SendingBuffer = new byte[CurrentPacketLength];
stream.Read(SendingBuffer, 0, CurrentPacketLength);
netstream.Write(SendingBuffer, 0, (int)SendingBuffer.Length);
}
netstream.Flush();
}
catch (Exception e) {
Console.WriteLine("EXCEPTION:\n" + e.ToString());
}
break;
case 2:
//Code to read data
break;
}
}
netstream.Close()
clientSocket.Close();
And here is my client code:
using (System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient()) {
string returnData = "";
IAsyncResult ar = clientSocket.BeginConnect("127.0.0.1", 8080, null, null);
System.Threading.WaitHandle wh = ar.AsyncWaitHandle;
try {
if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false)) {
clientSocket.Close();
Console.WriteLine("Timeout");
return;
}
System.Net.Sockets.NetworkStream serverStream = clientSocket.GetStream();
byte b = 1;
byte[] outStream = { b };
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
//If I comment following lines, the server can read sent data, but server can't otherwise
byte[] RecData = new byte[1024];
int RecBytes;
int totalrecbytes = 0;
MemoryStream MS = new MemoryStream();
while ((RecBytes = serverStream.Read(RecData, 0, RecData.Length)) > 0) {
MS.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
serverStream.Close();
clientSocket.Close();
clientSocket.EndConnect(ar);
}
catch (Exception ex) {
Console.WriteLine("Exceção: " + ex.ToString());
}
finally {
wh.Close();
}
}
So, how can I send data to server and read the response? (I tried even putting the thread to sleep after sending data, with no luck.)
Thanks in advance.
EDIT:
With some debug messages I discovered that the server do read the "1" byte that was sent, but somehow it gets stuck inside the while loop, like, the server just stops there, no more loops and it does not leave the while loop. I saw that after writing "loop" in console inside the while loop, and writing read bytes also in console. It wrote "loop" once, and the read byte.
This code worries me:
//When I get here, there is no data to read
while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) {
ms.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
You are reading until the client closes the connection (or shuts down sending, which you don't do). But the client only closes when the server has replied. The server reply will never come. It is a deadlock.
Solution: Read a single byte to determine the requests command (b).
Unrelated to the question, your "packetised" sending (NoOfPackets, ...) does not seem to serve any purpose. Just use Stream.Copy to write. TCP does not have packets.
An even better solution would be to abandon your custom TCP protocol and use an HTTP library. All these concerns just go away. There are various smaller problems with your code that are very typical to see in TCP code.

C# Socket connection doesn't work

I'm Trying to create a code to send a TCP message to a server.
When I use AutoIT Script Language with this code:
Example()
Func Example()
Local $ConnectedSocket, $szData
Local $szIPADDRESS = "10.200.0.104"
Local $nPORT = 1040
; Start The TCP Services
TCPStartup()
; Initialize a variable to represent a connection
$ConnectedSocket = -1
;Attempt to connect to SERVER at its IP and PORT 1040
$ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
; If there is an error... show it
If #error Then
MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & #error)
Else
$szData="0x0021601FA10706052B0C00815ABE14281206072B0C00821D8148A007A0050303000800000DA20B0201013006020200D30500"
TCPSend($ConnectedSocket, $szData)
EndIf
EndFunc;==>Example
Works fine but I need to write the same code in C#. I try to do this:
private static byte[] MessageToByteArray(string message, Encoding encoding)
{
var byteCount = encoding.GetByteCount(message);
if (byteCount > byte.MaxValue)
throw new ArgumentException("Message size is greater than 255 bytes in the provided encoding");
var byteArray = new byte[byteCount + 1];
byteArray[0] = (byte)byteCount;
encoding.GetBytes(message, 0, message.Length, byteArray, 1);
return byteArray;
}
public static void Main(string[] args)
{
const string message = "0x0021601FA10706052B0C00815ABE14281206072B0C00821D8148A007A0050303000800000DA20B0201013006020200D30500";
var byteArray = MessageToByteArray(message, Encoding.ASCII);
Socket m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse("10.200.0.104");
System.Net.IPEndPoint remoteEP = new IPEndPoint(ipAdd, 1040);
m_socClient.Connect(remoteEP);
try
{
m_socClient.Send(byteArray);
}
catch (SocketException se)
{
Console.WriteLine(se.Message.ToString());
}
}
But this code doesn't work. The server shows when he receives the command. With C# code, the server shows that have connected but the command doesn't execute.
Are you sure you have to prefix the length?
byteArray[0] = (byte)byteCount;
encoding.GetBytes(message, 0, message.Length, byteArray, 1);
Often you have a null-terminated string:
encoding.GetBytes(message, 0, message.Length, byteArray, 0);
byteArray[byteArray.Length - 1] = (byte)'\0';

Android retrieve bytes from inputstream

I am trying to retrieve the byte that transferred by the server that has been programmed in c# as follow:
static void Main(String[] args){
Socket sListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress IP = IPAddress.Parse("10.0.0.92");
IPEndPoint IPE = new IPEndPoint(IP, 4321);
sListen.Bind(IPE);
Console.WriteLine("Service is listening ...");
sListen.Listen(2);
while (true){
Socket clientSocket;
try{
clientSocket = sListen.Accept();
}
catch{
throw;
}
byte[] buffer = ReadImageFile("path to image");
clientSocket.Send(buffer, buffer.Length, SocketFlags.None);
Console.WriteLine("Send success!");
}
}
private static byte[] ReadImageFile(String img){
FileInfo fileinfo = new FileInfo(img);
byte[] buf = new byte[fileinfo.Length];
FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
fs.Read(buf, 0, buf.Length);
fs.Close();
//fileInfo.Delete ();
GC.ReRegisterForFinalize(fileinfo);
GC.ReRegisterForFinalize(fs);
return buf;
}
Above codes works fine when I write a client in the c# and run it in the pc. However I want to retrieve the bytes transferred by the server in the android device.
The android connected to the server successfully but it will not finish its job, basically it will not pass the ‘while loop in the bellow code’. I think there is something wrong with the byte length because it’s never get to ‘-1’.
Android java code (Client):
Socket socket = new Socket("ip", 4321);
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int read = is.read(buffer);
while(read != -1){
read = is.read(buffer);
}
is.close();
socket.close();
I do appreciate any help in advance,
Thanks,
The client read() method will never return -1 until the server closes the connection. You're not doing that so it never happens.
I don't get the point of your Java code. The read(byte[]) method you are using writes 1024 bytes (or less) in the buffer again and again. You are overwriting your previous buffer content. You probably would like to write the downloaded data to somewhere, like an OutputStream. Example:
Socket socket = new Socket("ip", 4321);
InputStream is = socket.getInputStream();
OutputStream os = ...; // Where to save data, for example, new ByteArrayOutputStream();
copyStreams(is, os);
is.close();
socket.close();
public static void copyStreams(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int numBytesRead;
for (;;) {
bytesRead = is.read(buffer);
if (bytesRead <= 0)
break;
os.write(buffer, 0, bytesRead);
}
}

Categories