[corlib] Avoid unnecessary ephemeron array resizes
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsKey.cs
1 //
2 // MonoBtlsKey.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.Text;
30 using System.Runtime.InteropServices;
31 using System.Runtime.CompilerServices;
32
33 namespace Mono.Btls
34 {
35         class MonoBtlsKey : MonoBtlsObject
36         {
37                 internal class BoringKeyHandle : MonoBtlsHandle
38                 {
39                         internal BoringKeyHandle (IntPtr handle)
40                                 : base (handle, true)
41                         {
42                         }
43
44                         protected override bool ReleaseHandle ()
45                         {
46                                 mono_btls_key_free (handle);
47                                 return true;
48                         }
49                 }
50
51                 [DllImport (BTLS_DYLIB)]
52                 extern static void mono_btls_key_free (IntPtr handle);
53
54                 [DllImport (BTLS_DYLIB)]
55                 extern static IntPtr mono_btls_key_up_ref (IntPtr handle);
56
57                 [DllImport (BTLS_DYLIB)]
58                 extern static int mono_btls_key_get_bytes (IntPtr handle, out IntPtr data, out int size, int include_private_bits);
59
60                 [DllImport (BTLS_DYLIB)]
61                 extern static int mono_btls_key_get_bits (IntPtr handle);
62
63                 [DllImport (BTLS_DYLIB)]
64                 extern static int mono_btls_key_is_rsa (IntPtr handle);
65
66                 new internal BoringKeyHandle Handle {
67                         get { return (BoringKeyHandle)base.Handle; }
68                 }
69
70                 internal MonoBtlsKey (BoringKeyHandle handle)
71                         : base (handle)
72                 {
73                 }
74
75                 public byte[] GetBytes (bool include_private_bits)
76                 {
77                         int size;
78                         IntPtr data;
79
80                         var ret = mono_btls_key_get_bytes (Handle.DangerousGetHandle (), out data, out size, include_private_bits ? 1 : 0);
81                         CheckError (ret);
82
83                         var buffer = new byte [size];
84                         Marshal.Copy (data, buffer, 0, size);
85                         FreeDataPtr (data);
86                         return buffer;
87                 }
88
89                 public bool IsRsa {
90                         get {
91                                 return mono_btls_key_is_rsa (Handle.DangerousGetHandle ()) != 0;
92                         }
93                 }
94
95                 public MonoBtlsKey Copy ()
96                 {
97                         CheckThrow ();
98                         var copy = mono_btls_key_up_ref (Handle.DangerousGetHandle ());
99                         CheckError (copy != IntPtr.Zero);
100                         return new MonoBtlsKey (new BoringKeyHandle (copy));
101                 }
102         }
103 }
104 #endif