41df1298f9cb8758fb96a75471de876dfc65b5ec
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsX509StoreCtx.cs
1 //
2 // MonoBtlsX509StoreCtx.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
8 //
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:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
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
25 // THE SOFTWARE.
26 #if SECURITY_DEP
27 using System;
28 using System.IO;
29 using System.Runtime.InteropServices;
30 using System.Runtime.CompilerServices;
31
32 namespace Mono.Btls
33 {
34         class MonoBtlsX509StoreCtx : MonoBtlsObject
35         {
36                 internal class BoringX509StoreCtxHandle : MonoBtlsHandle
37                 {
38                         bool dontFree;
39
40                         internal BoringX509StoreCtxHandle (IntPtr handle, bool ownsHandle = true)
41                                 : base (handle, ownsHandle)
42                         {
43                                 dontFree = !ownsHandle;
44                         }
45
46                         #if FIXME
47                         internal BoringX509StoreCtxHandle (IntPtr handle)
48                                 : base ()
49                         {
50                                 base.handle = handle;
51                                 this.dontFree = true;
52                         }
53                         #endif
54
55                         protected override bool ReleaseHandle ()
56                         {
57                                 if (!dontFree)
58                                         mono_btls_x509_store_ctx_free (handle);
59                                 return true;
60                         }
61                 }
62
63                 int? verifyResult;
64
65                 new internal BoringX509StoreCtxHandle Handle {
66                         get { return (BoringX509StoreCtxHandle)base.Handle; }
67                 }
68
69                 [MethodImpl (MethodImplOptions.InternalCall)]
70                 extern static IntPtr mono_btls_x509_store_ctx_new ();
71
72                 [MethodImpl (MethodImplOptions.InternalCall)]
73                 extern static IntPtr mono_btls_x509_store_ctx_from_ptr (IntPtr ctx);
74
75                 [MethodImpl (MethodImplOptions.InternalCall)]
76                 extern static MonoBtlsX509Error mono_btls_x509_store_ctx_get_error (IntPtr handle, out IntPtr error_string);
77
78                 [MethodImpl (MethodImplOptions.InternalCall)]
79                 extern static int mono_btls_x509_store_ctx_get_error_depth (IntPtr handle);
80
81                 [MethodImpl (MethodImplOptions.InternalCall)]
82                 extern static IntPtr mono_btls_x509_store_ctx_get_chain (IntPtr handle);
83
84                 [MethodImpl (MethodImplOptions.InternalCall)]
85                 extern static int mono_btls_x509_store_ctx_init (IntPtr handle, IntPtr store, IntPtr chain);
86
87                 [MethodImpl (MethodImplOptions.InternalCall)]
88                 extern static int mono_btls_x509_store_ctx_set_param (IntPtr handle, IntPtr param);
89
90                 [MethodImpl (MethodImplOptions.InternalCall)]
91                 extern static int mono_btls_x509_store_ctx_verify_cert (IntPtr handle);
92
93                 [MethodImpl (MethodImplOptions.InternalCall)]
94                 extern static IntPtr mono_btls_x509_store_ctx_get_by_subject (IntPtr handle, IntPtr name);
95
96                 [MethodImpl (MethodImplOptions.InternalCall)]
97                 extern static IntPtr mono_btls_x509_store_ctx_get_current_cert (IntPtr handle);
98
99                 [MethodImpl (MethodImplOptions.InternalCall)]
100                 extern static IntPtr mono_btls_x509_store_ctx_get_current_issuer (IntPtr handle);
101
102                 [MethodImpl (MethodImplOptions.InternalCall)]
103                 extern static IntPtr mono_btls_x509_store_ctx_get_verify_param (IntPtr handle);
104
105                 [MethodImpl (MethodImplOptions.InternalCall)]
106                 extern static IntPtr mono_btls_x509_store_ctx_get_untrusted (IntPtr handle);
107
108                 [MethodImpl (MethodImplOptions.InternalCall)]
109                 extern static IntPtr mono_btls_x509_store_ctx_up_ref (IntPtr handle);
110
111                 [MethodImpl (MethodImplOptions.InternalCall)]
112                 extern static void mono_btls_x509_store_ctx_free (IntPtr handle);
113
114                 internal MonoBtlsX509StoreCtx ()
115                         : base (new BoringX509StoreCtxHandle (mono_btls_x509_store_ctx_new ()))
116                 {
117                 }
118
119                 static BoringX509StoreCtxHandle Create_internal (IntPtr store_ctx)
120                 {
121                         var handle = mono_btls_x509_store_ctx_from_ptr (store_ctx);
122                         if (handle == IntPtr.Zero)
123                                 throw new MonoBtlsException ();
124                         return new BoringX509StoreCtxHandle (handle);
125                 }
126
127                 internal MonoBtlsX509StoreCtx (int preverify_ok, IntPtr store_ctx)
128                         : base (Create_internal (store_ctx))
129                 {
130                         verifyResult = preverify_ok;
131                 }
132
133                 internal MonoBtlsX509StoreCtx (BoringX509StoreCtxHandle ptr, int? verifyResult)
134                         : base (ptr)
135                 {
136                         this.verifyResult = verifyResult;
137                 }
138
139                 public MonoBtlsX509Error GetError ()
140                 {
141                         IntPtr error_string_ptr;
142                         return mono_btls_x509_store_ctx_get_error (Handle.DangerousGetHandle (), out error_string_ptr);
143                 }
144
145                 public MonoBtlsX509Exception GetException ()
146                 {
147                         IntPtr error_string_ptr;
148                         var error = mono_btls_x509_store_ctx_get_error (Handle.DangerousGetHandle (), out error_string_ptr);
149                         if (error == 0)
150                                 return null;
151                         if (error_string_ptr != IntPtr.Zero) {
152                                 var error_string = Marshal.PtrToStringAnsi (error_string_ptr);
153                                 return new MonoBtlsX509Exception (error, error_string);
154                         }
155                         return new MonoBtlsX509Exception (error, "Unknown verify error.");
156                 }
157
158                 public MonoBtlsX509Chain GetChain ()
159                 {
160                         var chain = mono_btls_x509_store_ctx_get_chain (Handle.DangerousGetHandle ());
161                         CheckError (chain != IntPtr.Zero);
162                         return new MonoBtlsX509Chain (new MonoBtlsX509Chain.BoringX509ChainHandle (chain));
163                 }
164
165                 public MonoBtlsX509Chain GetUntrusted ()
166                 {
167                         var chain = mono_btls_x509_store_ctx_get_untrusted (Handle.DangerousGetHandle ());
168                         CheckError (chain != IntPtr.Zero);
169                         return new MonoBtlsX509Chain (new MonoBtlsX509Chain.BoringX509ChainHandle (chain));
170                 }
171
172                 public void Initialize (MonoBtlsX509Store store, MonoBtlsX509Chain chain)
173                 {
174                         var ret = mono_btls_x509_store_ctx_init (
175                                 Handle.DangerousGetHandle (),
176                                 store.Handle.DangerousGetHandle (),
177                                 chain.Handle.DangerousGetHandle ());
178                         CheckError (ret);
179                 }
180
181                 public void SetVerifyParam (MonoBtlsX509VerifyParam param)
182                 {
183                         var ret = mono_btls_x509_store_ctx_set_param (
184                                 Handle.DangerousGetHandle (),
185                                 param.Handle.DangerousGetHandle ());
186                         CheckError (ret);
187                 }
188
189                 public int VerifyResult {
190                         get {
191                                 if (verifyResult == null)
192                                         throw new InvalidOperationException ();
193                                 return verifyResult.Value;
194                         }
195                 }
196
197                 public int Verify ()
198                 {
199                         verifyResult = mono_btls_x509_store_ctx_verify_cert (Handle.DangerousGetHandle ());
200                         return verifyResult.Value;
201                 }
202
203                 public MonoBtlsX509 LookupBySubject (MonoBtlsX509Name name)
204                 {
205                         var handle = mono_btls_x509_store_ctx_get_by_subject (
206                                 Handle.DangerousGetHandle (), name.Handle.DangerousGetHandle ());
207                         if (handle == IntPtr.Zero)
208                                 return null;
209                         return new MonoBtlsX509 (new MonoBtlsX509.BoringX509Handle (handle));
210                 }
211
212                 public MonoBtlsX509 GetCurrentCertificate ()
213                 {
214                         var x509 = mono_btls_x509_store_ctx_get_current_cert (Handle.DangerousGetHandle ());
215                         if (x509 == IntPtr.Zero)
216                                 return null;
217                         return new MonoBtlsX509 (new MonoBtlsX509.BoringX509Handle (x509));
218                 }
219
220                 public MonoBtlsX509 GetCurrentIssuer ()
221                 {
222                         var x509 = mono_btls_x509_store_ctx_get_current_issuer (Handle.DangerousGetHandle ());
223                         if (x509 == IntPtr.Zero)
224                                 return null;
225                         return new MonoBtlsX509 (new MonoBtlsX509.BoringX509Handle (x509));
226                 }
227
228                 public MonoBtlsX509VerifyParam GetVerifyParam ()
229                 {
230                         var param = mono_btls_x509_store_ctx_get_verify_param (Handle.DangerousGetHandle ());
231                         if (param == IntPtr.Zero)
232                                 return null;
233                         return new MonoBtlsX509VerifyParam (new MonoBtlsX509VerifyParam.BoringX509VerifyParamHandle (param));
234                 }
235
236                 public MonoBtlsX509StoreCtx Copy ()
237                 {
238                         var copy = mono_btls_x509_store_ctx_up_ref (Handle.DangerousGetHandle ());
239                         CheckError (copy != IntPtr.Zero);
240                         return new MonoBtlsX509StoreCtx (new BoringX509StoreCtxHandle (copy), verifyResult);
241                 }
242         }
243 }
244 #endif