[btls] Convert BTLS icalls to pinvokes by invoking them using [DllImp… (#3799)
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsX509Name.cs
1 //
2 // MonoBtlsX509Name.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.Text;
30 using System.Runtime.InteropServices;
31 using System.Runtime.CompilerServices;
32
33 namespace Mono.Btls
34 {
35         class MonoBtlsX509Name : MonoBtlsObject
36         {
37                 internal class BoringX509NameHandle : MonoBtlsHandle
38                 {
39                         bool dontFree;
40
41                         internal BoringX509NameHandle (IntPtr handle, bool ownsHandle)
42                                 : base (handle, ownsHandle)
43                         {
44                                 this.dontFree = !ownsHandle;
45                         }
46
47                         protected override bool ReleaseHandle ()
48                         {
49                                 if (!dontFree)
50                                         mono_btls_x509_name_free (handle);
51                                 return true;
52                         }
53                 }
54
55                 [DllImport (BTLS_DYLIB)]
56                 extern static int mono_btls_x509_name_print_bio (IntPtr handle, IntPtr bio);
57
58                 [DllImport (BTLS_DYLIB)]
59                 extern static int mono_btls_x509_name_print_string (IntPtr handle, IntPtr buffer, int size);
60
61                 [DllImport (BTLS_DYLIB)]
62                 extern static int mono_btls_x509_name_get_raw_data (IntPtr handle, out IntPtr buffer, int use_canon_enc);
63
64                 [DllImport (BTLS_DYLIB)]
65                 extern static long mono_btls_x509_name_hash (IntPtr handle);
66
67                 [DllImport (BTLS_DYLIB)]
68                 extern static long mono_btls_x509_name_hash_old (IntPtr handle);
69
70                 [DllImport (BTLS_DYLIB)]
71                 extern static int mono_btls_x509_name_get_entry_count (IntPtr handle);
72
73                 [DllImport (BTLS_DYLIB)]
74                 extern static MonoBtlsX509NameEntryType mono_btls_x509_name_get_entry_type (IntPtr name, int index);
75
76                 [DllImport (BTLS_DYLIB)]
77                 extern static int mono_btls_x509_name_get_entry_oid (IntPtr name, int index, IntPtr buffer, int size);
78
79                 [DllImport (BTLS_DYLIB)]
80                 extern static int mono_btls_x509_name_get_entry_oid_data (IntPtr name, int index, out IntPtr data);
81
82                 [DllImport (BTLS_DYLIB)]
83                 extern static int mono_btls_x509_name_get_entry_value (IntPtr name, int index, out int tag, out IntPtr str);
84
85                 [DllImport (BTLS_DYLIB)]
86                 extern unsafe static IntPtr mono_btls_x509_name_from_data (void* data, int len, int use_canon_enc);
87
88                 [DllImport (BTLS_DYLIB)]
89                 extern static void mono_btls_x509_name_free (IntPtr handle);
90
91                 new internal BoringX509NameHandle Handle {
92                         get { return (BoringX509NameHandle)base.Handle; }
93                 }
94
95                 internal MonoBtlsX509Name (BoringX509NameHandle handle)
96                         : base (handle)
97                 {
98                 }
99
100                 public string GetString ()
101                 {
102                         const int size = 4096;
103                         var data = Marshal.AllocHGlobal (size);
104                         try {
105                                 var ret = mono_btls_x509_name_print_string (
106                                         Handle.DangerousGetHandle (), data, size);
107                                 CheckError (ret);
108                                 return Marshal.PtrToStringAnsi (data);
109                         } finally {
110                                 Marshal.FreeHGlobal (data);
111                         }
112                 }
113
114                 public void PrintBio (MonoBtlsBio bio)
115                 {
116                         var ret = mono_btls_x509_name_print_bio (
117                                 Handle.DangerousGetHandle (),
118                                 bio.Handle.DangerousGetHandle ());
119                         CheckError (ret);
120                 }
121
122                 public byte[] GetRawData (bool use_canon_enc)
123                 {
124                         IntPtr data;
125                         var ret = mono_btls_x509_name_get_raw_data (
126                                 Handle.DangerousGetHandle (),
127                                 out data, use_canon_enc ? 1 : 0);
128                         CheckError (ret > 0);
129                         var buffer = new byte [ret];
130                         Marshal.Copy (data, buffer, 0, ret);
131                         FreeDataPtr (data);
132                         return buffer;
133                 }
134
135                 public long GetHash ()
136                 {
137                         return mono_btls_x509_name_hash (Handle.DangerousGetHandle ());
138                 }
139
140                 public long GetHashOld ()
141                 {
142                         return mono_btls_x509_name_hash_old (Handle.DangerousGetHandle ());
143                 }
144
145                 public int GetEntryCount ()
146                 {
147                         return mono_btls_x509_name_get_entry_count (Handle.DangerousGetHandle ());
148                 }
149
150                 public MonoBtlsX509NameEntryType GetEntryType (int index)
151                 {
152                         if (index >= GetEntryCount ())
153                                 throw new ArgumentOutOfRangeException ();
154                         return mono_btls_x509_name_get_entry_type (
155                                 Handle.DangerousGetHandle (), index);
156                 }
157
158                 public string GetEntryOid (int index)
159                 {
160                         if (index >= GetEntryCount ())
161                                 throw new ArgumentOutOfRangeException ();
162
163                         const int size = 4096;
164                         var data = Marshal.AllocHGlobal (size);
165                         try {
166                                 var ret = mono_btls_x509_name_get_entry_oid (
167                                         Handle.DangerousGetHandle (),
168                                         index, data, size);
169                                 CheckError (ret > 0);
170                                 return Marshal.PtrToStringAnsi (data);
171                         } finally {
172                                 Marshal.FreeHGlobal (data);
173                         }
174                 }
175
176                 public byte[] GetEntryOidData (int index)
177                 {
178                         IntPtr data;
179                         var ret = mono_btls_x509_name_get_entry_oid_data (
180                                 Handle.DangerousGetHandle (), index, out data);
181                         CheckError (ret > 0);
182
183                         var bytes = new byte[ret];
184                         Marshal.Copy (data, bytes, 0, ret);
185                         return bytes;
186                 }
187
188                 public unsafe string GetEntryValue (int index, out int tag)
189                 {
190                         if (index >= GetEntryCount ())
191                                 throw new ArgumentOutOfRangeException ();
192                         IntPtr data;
193                         var ret = mono_btls_x509_name_get_entry_value (
194                                 Handle.DangerousGetHandle (), index, out tag, out data);
195                         if (ret <= 0)
196                                 return null;
197                         try {
198                                 return new UTF8Encoding ().GetString ((byte*)data, ret);
199                         } finally {
200                                 if (data != IntPtr.Zero)
201                                         FreeDataPtr (data);
202                         }
203                 }
204
205                 public static unsafe MonoBtlsX509Name CreateFromData (byte[] data, bool use_canon_enc)
206                 {
207                         fixed (void *ptr = data) {
208                                 var handle = mono_btls_x509_name_from_data (ptr, data.Length, use_canon_enc ? 1 : 0);
209                                 if (handle == IntPtr.Zero)
210                                         throw new MonoBtlsException ("mono_btls_x509_name_from_data() failed.");
211                                 return new MonoBtlsX509Name (new BoringX509NameHandle (handle, false));
212                         }
213                 }
214         }
215 }
216 #endif