b2e863b085a0366ac5b43f8324aa8c41a919fba2
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsX509Lookup.cs
1 //
2 // MonoBtlsX509Lookup.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 using System.Collections.Generic;
32
33 namespace Mono.Btls
34 {
35         class MonoBtlsX509Lookup : MonoBtlsObject
36         {
37                 internal class BoringX509LookupHandle : MonoBtlsHandle
38                 {
39                         public BoringX509LookupHandle (IntPtr handle)
40                                 : base (handle, true)
41                         {
42                         }
43
44                         protected override bool ReleaseHandle ()
45                         {
46                                 mono_btls_x509_lookup_free (handle);
47                                 return true;
48                         }
49                 }
50
51                 new internal BoringX509LookupHandle Handle {
52                         get { return (BoringX509LookupHandle)base.Handle; }
53                 }
54
55                 [DllImport (BTLS_DYLIB)]
56                 extern static IntPtr mono_btls_x509_lookup_new (IntPtr store, MonoBtlsX509LookupType type);
57
58                 [DllImport (BTLS_DYLIB)]
59                 extern static int mono_btls_x509_lookup_load_file (IntPtr handle, IntPtr file, MonoBtlsX509FileType type);
60
61                 [DllImport (BTLS_DYLIB)]
62                 extern static int mono_btls_x509_lookup_add_dir (IntPtr handle, IntPtr dir, MonoBtlsX509FileType type);
63
64                 [DllImport (BTLS_DYLIB)]
65                 extern static int mono_btls_x509_lookup_add_mono (IntPtr handle, IntPtr monoLookup);
66
67                 [DllImport (BTLS_DYLIB)]
68                 extern static void mono_btls_x509_lookup_method_mono_init (
69                         IntPtr handle, IntPtr instance, IntPtr by_subject_func);
70
71                 [DllImport (BTLS_DYLIB)]
72                 extern static int mono_btls_x509_lookup_init (IntPtr handle);
73
74                 [DllImport (BTLS_DYLIB)]
75                 extern static int mono_btls_x509_lookup_shutdown (IntPtr handle);
76
77                 [DllImport (BTLS_DYLIB)]
78                 extern static IntPtr mono_btls_x509_lookup_by_subject (IntPtr handle, IntPtr name);
79
80                 [DllImport (BTLS_DYLIB)]
81                 extern static IntPtr mono_btls_x509_lookup_by_fingerprint (IntPtr handle, IntPtr bytes, int len);
82
83                 [DllImport (BTLS_DYLIB)]
84                 extern static void mono_btls_x509_lookup_free (IntPtr handle);
85
86                 [DllImport (BTLS_DYLIB)]
87                 extern static IntPtr mono_btls_x509_lookup_peek_lookup (IntPtr handle);
88
89                 MonoBtlsX509LookupType type;
90                 List<MonoBtlsX509LookupMono> monoLookups;
91
92 #if FIXME
93                 // Do we need this?
94                 internal MonoBtlsX509Lookup (BoringX509LookupHandle handle)
95                         : base (handle)
96                 {
97                 }
98 #endif
99
100                 static BoringX509LookupHandle Create_internal (MonoBtlsX509Store store, MonoBtlsX509LookupType type)
101                 {
102                         var handle = mono_btls_x509_lookup_new (
103                                 store.Handle.DangerousGetHandle (), type);
104                         if (handle == IntPtr.Zero)
105                                 throw new MonoBtlsException ();
106                         return new BoringX509LookupHandle (handle);
107                 }
108
109                 internal MonoBtlsX509Lookup (MonoBtlsX509Store store, MonoBtlsX509LookupType type)
110                         : base (Create_internal (store, type))
111                 {
112                         this.type = type;
113                 }
114
115                 internal IntPtr GetNativeLookup ()
116                 {
117                         return mono_btls_x509_lookup_peek_lookup (Handle.DangerousGetHandle ());
118                 }
119
120                 public void LoadFile (string file, MonoBtlsX509FileType type)
121                 {
122                         IntPtr filePtr = IntPtr.Zero;
123                         try {
124                                 if (file != null)
125                                         filePtr = Marshal.StringToHGlobalAnsi (file);
126                                 var ret = mono_btls_x509_lookup_load_file (
127                                         Handle.DangerousGetHandle (), filePtr, type);
128                                 CheckError (ret);
129                         } finally {
130                                 if (filePtr != IntPtr.Zero)
131                                         Marshal.FreeHGlobal (filePtr);
132                         }
133                 }
134
135                 public void AddDirectory (string dir, MonoBtlsX509FileType type)
136                 {
137                         IntPtr dirPtr = IntPtr.Zero;
138                         try {
139                                 if (dir != null)
140                                         dirPtr = Marshal.StringToHGlobalAnsi (dir);
141                                 var ret = mono_btls_x509_lookup_add_dir (
142                                         Handle.DangerousGetHandle (), dirPtr, type);
143                                 CheckError (ret);
144                         } finally {
145                                 if (dirPtr != IntPtr.Zero)
146                                         Marshal.FreeHGlobal (dirPtr);
147                         }
148                 }
149
150                 // Takes ownership of the 'monoLookup'.
151                 internal void AddMono (MonoBtlsX509LookupMono monoLookup)
152                 {
153                         if (type != MonoBtlsX509LookupType.MONO)
154                                 throw new NotSupportedException ();
155                         var ret = mono_btls_x509_lookup_add_mono (
156                                 Handle.DangerousGetHandle (), monoLookup.Handle.DangerousGetHandle ());
157                         CheckError (ret);
158
159                         if (monoLookups == null)
160                                 monoLookups = new List<MonoBtlsX509LookupMono> ();
161                         monoLookups.Add (monoLookup);
162                 }
163
164                 public void Initialize ()
165                 {
166                         var ret = mono_btls_x509_lookup_init (Handle.DangerousGetHandle ());
167                         CheckError (ret);
168                 }
169
170                 public void Shutdown ()
171                 {
172                         var ret = mono_btls_x509_lookup_shutdown (Handle.DangerousGetHandle ());
173                         CheckError (ret);
174                 }
175
176                 public MonoBtlsX509 LookupBySubject (MonoBtlsX509Name name)
177                 {
178                         var handle = mono_btls_x509_lookup_by_subject (
179                                 Handle.DangerousGetHandle (),
180                                 name.Handle.DangerousGetHandle ());
181                         if (handle == IntPtr.Zero)
182                                 return null;
183                         return new MonoBtlsX509 (new MonoBtlsX509.BoringX509Handle (handle));
184                 }
185
186                 public MonoBtlsX509 LookupByFingerPrint (byte[] fingerprint)
187                 {
188                         var bytes = Marshal.AllocHGlobal (fingerprint.Length);
189                         try {
190                                 Marshal.Copy (fingerprint, 0, bytes, fingerprint.Length);
191                                 var handle = mono_btls_x509_lookup_by_fingerprint (
192                                         Handle.DangerousGetHandle (),
193                                         bytes, fingerprint.Length);
194                                 if (handle == IntPtr.Zero)
195                                         return null;
196                                 return new MonoBtlsX509 (new MonoBtlsX509.BoringX509Handle (handle));
197                         } finally {
198                                 if (bytes != IntPtr.Zero)
199                                         Marshal.FreeHGlobal (bytes);
200                         }
201                 }
202
203                 protected override void Close ()
204                 {
205                         try {
206                                 if (monoLookups != null) {
207                                         foreach (var monoLookup in monoLookups)
208                                                 monoLookup.Dispose ();
209                                 monoLookups = null;
210                                 }
211                         } finally {
212                                 base.Close ();
213                         }
214                 }
215         }
216 }
217 #endif