2 // postecho.cs: TLS/SSL Post Echo Test Program
5 // Gonzalo Paniagua Javier <gonzalo@ximian.com>
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // (C) 2005 Novell (http://www.novell.com)
14 using System.Net.Sockets;
\r
16 using System.Security.Cryptography.X509Certificates;
\r
17 using Mono.Security.Protocol.Tls;
23 Console.WriteLine ("postecho url [size] [--web | --ssl3 | --tls1]");
\r
24 Console.WriteLine (" default size is 1024");
\r
25 Console.WriteLine (" default mode is --tls1");
\r
26 Console.WriteLine ("* a server side script must be installed to run postecho");
\r
29 static string PostWeb (string url, byte[] buffer)
\r
31 string postdata = "TEST=";
32 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
34 req.ContentType = "application/x-www-form-urlencoded";
35 req.ContentLength = 5 + buffer.Length;
36 Stream output = req.GetRequestStream ();
37 byte [] bytes = Encoding.Default.GetBytes (postdata);
38 output.Write (bytes, 0, bytes.Length);
\r
39 output.Write (buffer, 0, buffer.Length);
41 HttpWebResponse response = (HttpWebResponse) req.GetResponse ();
42 StreamReader reader = new StreamReader (response.GetResponseStream ());
43 return reader.ReadToEnd ();
\r
46 static string PostStream (Mono.Security.Protocol.Tls.SecurityProtocolType protocol, string url, byte[] buffer)
\r
48 Uri uri = new Uri (url);
49 string post = "POST " + uri.AbsolutePath + " HTTP/1.0\r\n";
\r
50 post += "Content-Type: application/x-www-form-urlencoded\r\n";
\r
51 post += "Content-Length: " + (buffer.Length + 5).ToString () + "\r\n";
\r
52 post += "Host: " + uri.Host + "\r\n\r\n";
\r
54 byte[] bytes = Encoding.Default.GetBytes (post);
\r
56 IPHostEntry host = Dns.Resolve (uri.Host);
57 IPAddress ip = host.AddressList [0];
58 Socket socket = new Socket (ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
59 socket.Connect (new IPEndPoint (ip, uri.Port));
60 NetworkStream ns = new NetworkStream (socket, false);
61 SslClientStream ssl = new SslClientStream (ns, uri.Host, false, protocol);
62 ssl.ServerCertValidationDelegate += new CertificateValidationCallback (CertificateValidation);
64 ssl.Write (bytes, 0, bytes.Length);
\r
65 ssl.Write (buffer, 0, buffer.Length);
\r
68 StreamReader reader = new StreamReader (ssl, Encoding.UTF8);
\r
69 string result = reader.ReadToEnd ();
\r
70 int start = result.IndexOf ("\r\n\r\n") + 4;
\r
71 start = result.IndexOf ("\r\n\r\n") + 4;
\r
72 return result.Substring (start);
\r
75 static int Main (string[] args)
77 if (args.Length < 1) {
\r
82 string url = args [0];
85 Mono.Security.Protocol.Tls.SecurityProtocolType protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Tls;
87 if (args.Length > 1) {
88 for (int i=1; i < args.Length; i++) {
89 switch (args [i].ToLower ()) {
92 protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Ssl3;
97 protocol = Mono.Security.Protocol.Tls.SecurityProtocolType.Tls;
103 size = Int32.Parse (args [i]);
\r
109 // prepare test buffer
\r
110 byte[] data = new byte[size];
\r
111 for (int i = 0; i < size; i++)
\r
114 string result = (ssl ? PostStream (protocol, url, data) : PostWeb (url, data));
\r
116 if (data.Length != result.Length) {
\r
117 Console.WriteLine ("Invalid length {0}. Expected {1}", result.Length, data.Length);
\r
120 for (int i = 0; i < result.Length; i++) {
\r
121 if (result[i] != 'A') {
\r
122 Console.WriteLine ("Error at {0} - reveived {1}", i, result[i]);
\r
126 Console.WriteLine ("Result OK (length: {0})", result.Length);
\r
130 private static void ShowCertificateError (int error)
\r
132 string message = null;
\r
136 message = "CERT_E_PURPOSE 0x800B0106";
\r
139 message = "CERT_E_CN_NO_MATCH 0x800B010F";
\r
142 message = "TRUST_E_BASIC_CONSTRAINTS 0x80096019";
\r
145 message = "TRUST_E_BAD_DIGEST 0x80096010";
\r
148 message = "CERT_E_VALIDITYPERIODNESTING 0x800B0102";
\r
151 message = "CERT_E_EXPIRED 0x800B0101";
\r
154 message = "CERT_E_CHAINING 0x800B010A";
\r
157 message = "CERT_E_UNTRUSTEDROOT 0x800B0109";
\r
160 message = "unknown (try WinError.h)";
\r
163 Console.WriteLine ("Error #{0}: {1}", error, message);
\r
166 private static bool CertificateValidation (X509Certificate certificate, int[] certificateErrors)
\r
168 if (certificateErrors.Length > 0)
\r
170 Console.WriteLine (certificate.ToString (true));
\r
171 // X509Certificate.ToString(true) doesn't show dates :-(
\r
172 Console.WriteLine ("\tValid From: {0}", certificate.GetEffectiveDateString ());
\r
173 Console.WriteLine ("\tValid Until: {0}{1}", certificate.GetExpirationDateString (), Environment.NewLine);
\r
174 // multiple errors are possible using SslClientStream
\r
175 foreach (int error in certificateErrors)
\r
177 ShowCertificateError (error);
\r
180 // whatever the reason we do not stop the SSL connection
\r