[btls] Create a native BTLS key handle for X509CertificateImplBtls.PrivateKey
[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
52                 [DllImport (BTLS_DYLIB)]
53                 extern static IntPtr mono_btls_key_new ();
54
55                 [DllImport (BTLS_DYLIB)]
56                 extern static void mono_btls_key_free (IntPtr handle);
57
58                 [DllImport (BTLS_DYLIB)]
59                 extern static IntPtr mono_btls_key_up_ref (IntPtr handle);
60
61                 [DllImport (BTLS_DYLIB)]
62                 extern static int mono_btls_key_get_bytes (IntPtr handle, out IntPtr data, out int size, int include_private_bits);
63
64                 [DllImport (BTLS_DYLIB)]
65                 extern static int mono_btls_key_get_bits (IntPtr handle);
66
67                 [DllImport (BTLS_DYLIB)]
68                 extern static int mono_btls_key_is_rsa (IntPtr handle);
69
70                 [DllImport (BTLS_DYLIB)]
71                 extern static int mono_btls_key_assign_rsa_private_key (IntPtr handle, byte[] der, int der_length);
72
73                 new internal BoringKeyHandle Handle {
74                         get { return (BoringKeyHandle)base.Handle; }
75                 }
76
77                 internal MonoBtlsKey (BoringKeyHandle handle)
78                         : base (handle)
79                 {
80                 }
81
82                 public byte[] GetBytes (bool include_private_bits)
83                 {
84                         int size;
85                         IntPtr data;
86
87                         var ret = mono_btls_key_get_bytes (Handle.DangerousGetHandle (), out data, out size, include_private_bits ? 1 : 0);
88                         CheckError (ret);
89
90                         var buffer = new byte [size];
91                         Marshal.Copy (data, buffer, 0, size);
92                         FreeDataPtr (data);
93                         return buffer;
94                 }
95
96                 public bool IsRsa {
97                         get {
98                                 return mono_btls_key_is_rsa (Handle.DangerousGetHandle ()) != 0;
99                         }
100                 }
101
102                 public MonoBtlsKey Copy ()
103                 {
104                         CheckThrow ();
105                         var copy = mono_btls_key_up_ref (Handle.DangerousGetHandle ());
106                         CheckError (copy != IntPtr.Zero);
107                         return new MonoBtlsKey (new BoringKeyHandle (copy));
108                 }
109
110                 public static MonoBtlsKey CreateFromRSAPrivateKey (System.Security.Cryptography.RSA privateKey)
111                 {
112                         var keyData = Mono.Security.Cryptography.PKCS8.PrivateKeyInfo.Encode (privateKey);
113                         var key = new MonoBtlsKey (new BoringKeyHandle (mono_btls_key_new ()));
114
115                         var ret = mono_btls_key_assign_rsa_private_key (key.Handle.DangerousGetHandle (), keyData, keyData.Length);
116                         if (ret == 0)
117                                 throw new MonoBtlsException ("Assigning private key failed.");
118
119                         return key;
120                 }
121         }
122 }
123 #endif