5 // Martin Baulig <martin.baulig@xamarin.com>
7 // Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 using System.Runtime.CompilerServices;
29 using System.Runtime.InteropServices;
37 class MonoBtlsSslCtx : MonoBtlsObject
39 internal class BoringSslCtxHandle : MonoBtlsHandle
41 public BoringSslCtxHandle (IntPtr handle)
46 protected override bool ReleaseHandle ()
48 mono_btls_ssl_ctx_free (handle);
53 new internal BoringSslCtxHandle Handle {
54 get { return (BoringSslCtxHandle)base.Handle; }
57 [MethodImpl (MethodImplOptions.InternalCall)]
58 extern static IntPtr mono_btls_ssl_ctx_new ();
60 [MethodImpl (MethodImplOptions.InternalCall)]
61 extern static int mono_btls_ssl_ctx_free (IntPtr handle);
63 [MethodImpl (MethodImplOptions.InternalCall)]
64 extern static IntPtr mono_btls_ssl_ctx_up_ref (IntPtr handle);
66 [MethodImpl (MethodImplOptions.InternalCall)]
67 extern static void mono_btls_ssl_ctx_initialize (IntPtr handle, IntPtr instance);
69 [MethodImpl (MethodImplOptions.InternalCall)]
70 extern static void mono_btls_ssl_ctx_set_debug_bio (IntPtr handle, IntPtr bio);
72 [MethodImpl (MethodImplOptions.InternalCall)]
73 extern static void mono_btls_ssl_ctx_set_cert_verify_callback (IntPtr handle, IntPtr func, int cert_required);
75 [MethodImpl (MethodImplOptions.InternalCall)]
76 extern static void mono_btls_ssl_ctx_set_cert_select_callback (IntPtr handle, IntPtr func);
78 [MethodImpl (MethodImplOptions.InternalCall)]
79 extern static void mono_btls_ssl_ctx_set_min_version (IntPtr handle, int version);
81 [MethodImpl (MethodImplOptions.InternalCall)]
82 extern static void mono_btls_ssl_ctx_set_max_version (IntPtr handle, int version);
84 [MethodImpl (MethodImplOptions.InternalCall)]
85 extern static int mono_btls_ssl_ctx_is_cipher_supported (IntPtr handle, short value);
87 [MethodImpl (MethodImplOptions.InternalCall)]
88 extern static int mono_btls_ssl_ctx_set_ciphers (IntPtr handle, int count, IntPtr data, int allow_unsupported);
90 [MethodImpl (MethodImplOptions.InternalCall)]
91 extern static int mono_btls_ssl_ctx_set_verify_param (IntPtr handle, IntPtr param);
93 delegate int NativeVerifyFunc (IntPtr instance, int preverify_ok, IntPtr ctx);
94 delegate int NativeSelectFunc (IntPtr instance);
96 NativeVerifyFunc verifyFunc;
97 NativeSelectFunc selectFunc;
100 MonoBtlsVerifyCallback verifyCallback;
101 MonoBtlsSelectCallback selectCallback;
102 MonoBtlsX509Store store;
106 public MonoBtlsSslCtx ()
107 : this (new BoringSslCtxHandle (mono_btls_ssl_ctx_new ()))
111 internal MonoBtlsSslCtx (BoringSslCtxHandle handle)
114 instance = GCHandle.Alloc (this);
115 instancePtr = GCHandle.ToIntPtr (instance);
116 mono_btls_ssl_ctx_initialize (
117 handle.DangerousGetHandle (), instancePtr);
119 verifyFunc = NativeVerifyCallback;
120 selectFunc = NativeSelectCallback;
121 verifyFuncPtr = Marshal.GetFunctionPointerForDelegate (verifyFunc);
122 selectFuncPtr = Marshal.GetFunctionPointerForDelegate (selectFunc);
124 store = new MonoBtlsX509Store (Handle);
127 internal MonoBtlsSslCtx Copy ()
129 var copy = mono_btls_ssl_ctx_up_ref (Handle.DangerousGetHandle ());
130 return new MonoBtlsSslCtx (new BoringSslCtxHandle (copy));
133 public MonoBtlsX509Store CertificateStore {
134 get { return store; }
137 int VerifyCallback (bool preverify_ok, MonoBtlsX509StoreCtx ctx)
139 if (verifyCallback != null)
140 return verifyCallback (ctx);
145 [MonoPInvokeCallback (typeof (NativeVerifyFunc))]
147 static int NativeVerifyCallback (IntPtr instance, int preverify_ok, IntPtr store_ctx)
149 var c = (MonoBtlsSslCtx)GCHandle.FromIntPtr (instance).Target;
150 using (var ctx = new MonoBtlsX509StoreCtx (preverify_ok, store_ctx)) {
152 return c.VerifyCallback (preverify_ok != 0, ctx);
153 } catch (Exception ex) {
160 int SelectCallback ()
162 if (selectCallback != null)
163 return selectCallback ();
168 [MonoPInvokeCallback (typeof (NativeSelectFunc))]
170 static int NativeSelectCallback (IntPtr instance)
172 var c = (MonoBtlsSslCtx)GCHandle.FromIntPtr (instance).Target;
174 return c.SelectCallback ();
175 } catch (Exception ex) {
181 public void SetDebugBio (MonoBtlsBio bio)
184 mono_btls_ssl_ctx_set_debug_bio (Handle.DangerousGetHandle (), bio.Handle.DangerousGetHandle ());
187 public void SetVerifyCallback (MonoBtlsVerifyCallback callback, bool client_cert_required)
191 verifyCallback = callback;
192 mono_btls_ssl_ctx_set_cert_verify_callback (
193 Handle.DangerousGetHandle (), verifyFuncPtr,
194 client_cert_required ? 1 : 0);
197 public void SetSelectCallback (MonoBtlsSelectCallback callback)
201 selectCallback = callback;
202 mono_btls_ssl_ctx_set_cert_select_callback (
203 Handle.DangerousGetHandle (), selectFuncPtr);
206 public void SetMinVersion (int version)
209 mono_btls_ssl_ctx_set_min_version (Handle.DangerousGetHandle (), version);
212 public void SetMaxVersion (int version)
215 mono_btls_ssl_ctx_set_max_version (Handle.DangerousGetHandle (), version);
218 public bool IsCipherSupported (short value)
221 return mono_btls_ssl_ctx_is_cipher_supported (Handle.DangerousGetHandle (), value) != 0;
224 public void SetCiphers (short[] ciphers, bool allow_unsupported)
227 var data = Marshal.AllocHGlobal (ciphers.Length * 2);
229 Marshal.Copy (ciphers, 0, data, ciphers.Length);
230 var ret = mono_btls_ssl_ctx_set_ciphers (
231 Handle.DangerousGetHandle (),
232 ciphers.Length, data, allow_unsupported ? 1 : 0);
233 CheckError (ret > 0);
235 Marshal.FreeHGlobal (data);
239 public void SetVerifyParam (MonoBtlsX509VerifyParam param)
242 var ret = mono_btls_ssl_ctx_set_verify_param (
243 Handle.DangerousGetHandle (),
244 param.Handle.DangerousGetHandle ());
248 protected override void Close ()
254 if (instance.IsAllocated)