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 && MONO_FEATURE_BTLS 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 BoringX509StoreCtxHandle(IntPtr handle, bool ownsHandle = true)40 internal BoringX509StoreCtxHandle (IntPtr handle, bool ownsHandle = true) 41 : base (handle, ownsHandle) 42 { 43 dontFree = !ownsHandle; 44 } 45 46 #if FIXME BoringX509StoreCtxHandle(IntPtr handle)47 internal BoringX509StoreCtxHandle (IntPtr handle) 48 : base () 49 { 50 base.handle = handle; 51 this.dontFree = true; 52 } 53 #endif 54 ReleaseHandle()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 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_new()70 extern static IntPtr mono_btls_x509_store_ctx_new (); 71 72 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_from_ptr(IntPtr ctx)73 extern static IntPtr mono_btls_x509_store_ctx_from_ptr (IntPtr ctx); 74 75 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_error(IntPtr handle, out IntPtr error_string)76 extern static MonoBtlsX509Error mono_btls_x509_store_ctx_get_error (IntPtr handle, out IntPtr error_string); 77 78 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_error_depth(IntPtr handle)79 extern static int mono_btls_x509_store_ctx_get_error_depth (IntPtr handle); 80 81 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_chain(IntPtr handle)82 extern static IntPtr mono_btls_x509_store_ctx_get_chain (IntPtr handle); 83 84 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_init(IntPtr handle, IntPtr store, IntPtr chain)85 extern static int mono_btls_x509_store_ctx_init (IntPtr handle, IntPtr store, IntPtr chain); 86 87 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_set_param(IntPtr handle, IntPtr param)88 extern static int mono_btls_x509_store_ctx_set_param (IntPtr handle, IntPtr param); 89 90 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_verify_cert(IntPtr handle)91 extern static int mono_btls_x509_store_ctx_verify_cert (IntPtr handle); 92 93 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_by_subject(IntPtr handle, IntPtr name)94 extern static IntPtr mono_btls_x509_store_ctx_get_by_subject (IntPtr handle, IntPtr name); 95 96 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_current_cert(IntPtr handle)97 extern static IntPtr mono_btls_x509_store_ctx_get_current_cert (IntPtr handle); 98 99 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_current_issuer(IntPtr handle)100 extern static IntPtr mono_btls_x509_store_ctx_get_current_issuer (IntPtr handle); 101 102 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_verify_param(IntPtr handle)103 extern static IntPtr mono_btls_x509_store_ctx_get_verify_param (IntPtr handle); 104 105 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_get_untrusted(IntPtr handle)106 extern static IntPtr mono_btls_x509_store_ctx_get_untrusted (IntPtr handle); 107 108 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_up_ref(IntPtr handle)109 extern static IntPtr mono_btls_x509_store_ctx_up_ref (IntPtr handle); 110 111 [DllImport (BTLS_DYLIB)] mono_btls_x509_store_ctx_free(IntPtr handle)112 extern static void mono_btls_x509_store_ctx_free (IntPtr handle); 113 MonoBtlsX509StoreCtx()114 internal MonoBtlsX509StoreCtx () 115 : base (new BoringX509StoreCtxHandle (mono_btls_x509_store_ctx_new ())) 116 { 117 } 118 Create_internal(IntPtr store_ctx)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 MonoBtlsX509StoreCtx(int preverify_ok, IntPtr store_ctx)127 internal MonoBtlsX509StoreCtx (int preverify_ok, IntPtr store_ctx) 128 : base (Create_internal (store_ctx)) 129 { 130 verifyResult = preverify_ok; 131 } 132 MonoBtlsX509StoreCtx(BoringX509StoreCtxHandle ptr, int? verifyResult)133 internal MonoBtlsX509StoreCtx (BoringX509StoreCtxHandle ptr, int? verifyResult) 134 : base (ptr) 135 { 136 this.verifyResult = verifyResult; 137 } 138 GetError()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 GetException()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 GetChain()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 GetUntrusted()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 Initialize(MonoBtlsX509Store store, MonoBtlsX509Chain chain)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 SetVerifyParam(MonoBtlsX509VerifyParam param)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 Verify()197 public int Verify () 198 { 199 verifyResult = mono_btls_x509_store_ctx_verify_cert (Handle.DangerousGetHandle ()); 200 return verifyResult.Value; 201 } 202 LookupBySubject(MonoBtlsX509Name name)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 GetCurrentCertificate()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 GetCurrentIssuer()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 GetVerifyParam()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 Copy()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 245