1 /* wolfSSL-TLS-Client.cs
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 
23 using System;
24 using System.Runtime.InteropServices;
25 using System.Text;
26 using System.IO;
27 using System.Net;
28 using System.Net.Sockets;
29 using wolfSSL.CSharp;
30 
31 public class wolfSSL_TLS_Client
32 {
33     /// <summary>
34     /// Example of a logging function
35     /// </summary>
36     /// <param name="lvl">level of log</param>
37     /// <param name="msg">message to log</param>
standard_log(int lvl, StringBuilder msg)38     public static void standard_log(int lvl, StringBuilder msg)
39     {
40         Console.WriteLine(msg);
41     }
42 
43 
clean(IntPtr ssl, IntPtr ctx)44     private static void clean(IntPtr ssl, IntPtr ctx)
45     {
46         wolfssl.free(ssl);
47         wolfssl.CTX_free(ctx);
48         wolfssl.Cleanup();
49     }
50 
51     /// <summary>
52     /// Verification callback
53     /// </summary>
54     /// <param name="preverify">1=Verify Okay, 0=Failure</param>
55     /// <param name="x509_ctx">Certificate in WOLFSSL_X509_STORE_CTX format</param>
myVerify(int preverify, IntPtr x509_ctx)56     private static int myVerify(int preverify, IntPtr x509_ctx)
57     {
58         /* Use the provided verification */
59         /* Can optionally override failures by returning non-zero value */
60         return preverify;
61     }
62 
Main(string[] args)63     public static void Main(string[] args)
64     {
65         IntPtr ctx;
66         IntPtr ssl;
67         Socket tcp;
68 
69         /* These paths should be changed for use */
70         string caCert = @"ca-cert.pem";
71         StringBuilder dhparam = new StringBuilder("dh2048.pem");
72 
73         StringBuilder buff = new StringBuilder(1024);
74         StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper");
75 
76         //example of function used for setting logging
77         wolfssl.SetLogging(standard_log);
78 
79         wolfssl.Init();
80 
81 
82         Console.WriteLine("Calling ctx Init from wolfSSL");
83         ctx = wolfssl.CTX_new(wolfssl.usev23_client());
84         if (ctx == IntPtr.Zero)
85         {
86             Console.WriteLine("Error in creating ctx structure");
87             return;
88         }
89         Console.WriteLine("Finished init of ctx .... now load in CA");
90 
91 
92         if (!File.Exists(caCert))
93         {
94             Console.WriteLine("Could not find CA cert file");
95             wolfssl.CTX_free(ctx);
96             return;
97         }
98 
99 
100         if (wolfssl.CTX_load_verify_locations(ctx, caCert, null)
101             != wolfssl.SUCCESS)
102         {
103             Console.WriteLine("Error loading CA cert");
104         }
105 
106         StringBuilder ciphers = new StringBuilder(new String(' ', 4096));
107         wolfssl.get_ciphers(ciphers, 4096);
108         Console.WriteLine("Ciphers : " + ciphers.ToString());
109 
110         /* Uncomment Section to enable specific cipher suite */
111 #if false
112         ciphers = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256");
113         if (wolfssl.CTX_set_cipher_list(ctx, ciphers) != wolfssl.SUCCESS)
114         {
115             Console.WriteLine("ERROR CTX_set_cipher_list()");
116             wolfssl.CTX_free(ctx);
117             return;
118         }
119 #endif
120 
121         short minDhKey = 128;
122         wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey);
123 
124         /* Setup Verify Callback */
125         if (wolfssl.CTX_set_verify(ctx, wolfssl.SSL_VERIFY_PEER, myVerify)
126             != wolfssl.SUCCESS)
127         {
128             Console.WriteLine("Error setting verify callback!");
129         }
130 
131 
132         /* set up TCP socket */
133         tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
134                               ProtocolType.Tcp);
135         try
136         {
137             tcp.Connect("localhost", 11111);
138         }
139         catch (Exception e)
140         {
141             Console.WriteLine("tcp.Connect() error " + e.ToString());
142             wolfssl.CTX_free(ctx);
143             return;
144         }
145         if (!tcp.Connected)
146         {
147             Console.WriteLine("tcp.Connect() failed!");
148             tcp.Close();
149             wolfssl.CTX_free(ctx);
150             return;
151         }
152 
153         Console.WriteLine("Connected TCP");
154         ssl = wolfssl.new_ssl(ctx);
155         if (ssl == IntPtr.Zero)
156         {
157             Console.WriteLine("Error in creating ssl object");
158             wolfssl.CTX_free(ctx);
159             return;
160         }
161 
162         Console.WriteLine("Connection made wolfSSL_connect ");
163         if (wolfssl.set_fd(ssl, tcp) != wolfssl.SUCCESS)
164         {
165             /* get and print out the error */
166             Console.WriteLine(wolfssl.get_error(ssl));
167             tcp.Close();
168             clean(ssl, ctx);
169             return;
170         }
171 
172         wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM);
173 
174         if (wolfssl.connect(ssl) != wolfssl.SUCCESS)
175         {
176             /* get and print out the error */
177             Console.WriteLine(wolfssl.get_error(ssl));
178             tcp.Close();
179             clean(ssl, ctx);
180             return;
181         }
182 
183         /* print out results of TLS/SSL accept */
184         Console.WriteLine("SSL version is " + wolfssl.get_version(ssl));
185         Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(ssl));
186 
187 
188         if (wolfssl.write(ssl, reply, reply.Length) != reply.Length)
189         {
190             Console.WriteLine("Error in write");
191             tcp.Close();
192             clean(ssl, ctx);
193             return;
194         }
195 
196         /* read and print out the message then reply */
197         if (wolfssl.read(ssl, buff, 1023) < 0)
198         {
199             Console.WriteLine("Error in read");
200             tcp.Close();
201             clean(ssl, ctx);
202             return;
203         }
204         Console.WriteLine(buff);
205 
206         wolfssl.shutdown(ssl);
207         tcp.Close();
208         clean(ssl, ctx);
209     }
210 }
211