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
26 #if SECURITY_DEP && MONO_FEATURE_BTLS
28 using System
.Runtime
.CompilerServices
;
29 using System
.Runtime
.InteropServices
;
33 class MonoBtlsSslCtx
: MonoBtlsObject
35 internal class BoringSslCtxHandle
: MonoBtlsHandle
37 public BoringSslCtxHandle (IntPtr handle
)
42 protected override bool ReleaseHandle ()
44 mono_btls_ssl_ctx_free (handle
);
49 new internal BoringSslCtxHandle Handle
{
50 get { return (BoringSslCtxHandle)base.Handle; }
53 [DllImport (BTLS_DYLIB
)]
54 extern static IntPtr
mono_btls_ssl_ctx_new ();
56 [DllImport (BTLS_DYLIB
)]
57 extern static int mono_btls_ssl_ctx_free (IntPtr handle
);
59 [DllImport (BTLS_DYLIB
)]
60 extern static IntPtr
mono_btls_ssl_ctx_up_ref (IntPtr handle
);
62 [DllImport (BTLS_DYLIB
)]
63 extern static void mono_btls_ssl_ctx_initialize (IntPtr handle
, IntPtr instance
);
65 [DllImport (BTLS_DYLIB
)]
66 extern static void mono_btls_ssl_ctx_set_debug_bio (IntPtr handle
, IntPtr bio
);
68 [DllImport (BTLS_DYLIB
)]
69 extern static void mono_btls_ssl_ctx_set_cert_verify_callback (IntPtr handle
, IntPtr func
, int cert_required
);
71 [DllImport (BTLS_DYLIB
)]
72 extern static void mono_btls_ssl_ctx_set_cert_select_callback (IntPtr handle
, IntPtr func
);
74 [DllImport (BTLS_DYLIB
)]
75 extern static void mono_btls_ssl_ctx_set_min_version (IntPtr handle
, int version
);
77 [DllImport (BTLS_DYLIB
)]
78 extern static void mono_btls_ssl_ctx_set_max_version (IntPtr handle
, int version
);
80 [DllImport (BTLS_DYLIB
)]
81 extern static int mono_btls_ssl_ctx_is_cipher_supported (IntPtr handle
, short value);
83 [DllImport (BTLS_DYLIB
)]
84 extern static int mono_btls_ssl_ctx_set_ciphers (IntPtr handle
, int count
, IntPtr data
, int allow_unsupported
);
86 [DllImport (BTLS_DYLIB
)]
87 extern static int mono_btls_ssl_ctx_set_verify_param (IntPtr handle
, IntPtr param
);
89 delegate int NativeVerifyFunc (IntPtr instance
, int preverify_ok
, IntPtr ctx
);
90 delegate int NativeSelectFunc (IntPtr instance
);
92 NativeVerifyFunc verifyFunc
;
93 NativeSelectFunc selectFunc
;
96 MonoBtlsVerifyCallback verifyCallback
;
97 MonoBtlsSelectCallback selectCallback
;
98 MonoBtlsX509Store store
;
102 public MonoBtlsSslCtx ()
103 : this (new BoringSslCtxHandle (mono_btls_ssl_ctx_new ()))
107 internal MonoBtlsSslCtx (BoringSslCtxHandle handle
)
110 instance
= GCHandle
.Alloc (this);
111 instancePtr
= GCHandle
.ToIntPtr (instance
);
112 mono_btls_ssl_ctx_initialize (
113 handle
.DangerousGetHandle (), instancePtr
);
115 verifyFunc
= NativeVerifyCallback
;
116 selectFunc
= NativeSelectCallback
;
117 verifyFuncPtr
= Marshal
.GetFunctionPointerForDelegate (verifyFunc
);
118 selectFuncPtr
= Marshal
.GetFunctionPointerForDelegate (selectFunc
);
120 store
= new MonoBtlsX509Store (Handle
);
123 internal MonoBtlsSslCtx
Copy ()
125 var copy
= mono_btls_ssl_ctx_up_ref (Handle
.DangerousGetHandle ());
126 return new MonoBtlsSslCtx (new BoringSslCtxHandle (copy
));
129 public MonoBtlsX509Store CertificateStore
{
130 get { return store; }
133 int VerifyCallback (bool preverify_ok
, MonoBtlsX509StoreCtx ctx
)
135 if (verifyCallback
!= null)
136 return verifyCallback (ctx
);
140 [Mono
.Util
.MonoPInvokeCallback (typeof (NativeVerifyFunc
))]
141 static int NativeVerifyCallback (IntPtr instance
, int preverify_ok
, IntPtr store_ctx
)
143 var c
= (MonoBtlsSslCtx
)GCHandle
.FromIntPtr (instance
).Target
;
144 using (var ctx
= new MonoBtlsX509StoreCtx (preverify_ok
, store_ctx
)) {
146 return c
.VerifyCallback (preverify_ok
!= 0, ctx
);
147 } catch (Exception ex
) {
154 int SelectCallback ()
156 if (selectCallback
!= null)
157 return selectCallback ();
161 [Mono
.Util
.MonoPInvokeCallback (typeof (NativeSelectFunc
))]
162 static int NativeSelectCallback (IntPtr instance
)
164 var c
= (MonoBtlsSslCtx
)GCHandle
.FromIntPtr (instance
).Target
;
166 return c
.SelectCallback ();
167 } catch (Exception ex
) {
173 public void SetDebugBio (MonoBtlsBio bio
)
176 mono_btls_ssl_ctx_set_debug_bio (Handle
.DangerousGetHandle (), bio
.Handle
.DangerousGetHandle ());
179 public void SetVerifyCallback (MonoBtlsVerifyCallback callback
, bool client_cert_required
)
183 verifyCallback
= callback
;
184 mono_btls_ssl_ctx_set_cert_verify_callback (
185 Handle
.DangerousGetHandle (), verifyFuncPtr
,
186 client_cert_required
? 1 : 0);
189 public void SetSelectCallback (MonoBtlsSelectCallback callback
)
193 selectCallback
= callback
;
194 mono_btls_ssl_ctx_set_cert_select_callback (
195 Handle
.DangerousGetHandle (), selectFuncPtr
);
198 public void SetMinVersion (int version
)
201 mono_btls_ssl_ctx_set_min_version (Handle
.DangerousGetHandle (), version
);
204 public void SetMaxVersion (int version
)
207 mono_btls_ssl_ctx_set_max_version (Handle
.DangerousGetHandle (), version
);
210 public bool IsCipherSupported (short value)
213 return mono_btls_ssl_ctx_is_cipher_supported (Handle
.DangerousGetHandle (), value) != 0;
216 public void SetCiphers (short[] ciphers
, bool allow_unsupported
)
219 var data
= Marshal
.AllocHGlobal (ciphers
.Length
* 2);
221 Marshal
.Copy (ciphers
, 0, data
, ciphers
.Length
);
222 var ret
= mono_btls_ssl_ctx_set_ciphers (
223 Handle
.DangerousGetHandle (),
224 ciphers
.Length
, data
, allow_unsupported
? 1 : 0);
225 CheckError (ret
> 0);
227 Marshal
.FreeHGlobal (data
);
231 public void SetVerifyParam (MonoBtlsX509VerifyParam param
)
234 var ret
= mono_btls_ssl_ctx_set_verify_param (
235 Handle
.DangerousGetHandle (),
236 param
.Handle
.DangerousGetHandle ());
240 protected override void Close ()
246 if (instance
.IsAllocated
)