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