[corlib] Add back X509 support for watchOS.
[mono.git] / mcs / class / corlib / CoreFoundation / CFHelpers.cs
1 #if MONO_FEATURE_APPLETLS || MONO_FEATURE_APPLE_X509
2 using System;
3 using System.Runtime.InteropServices;
4
5 namespace XamMac.CoreFoundation
6 {
7         internal static class CFHelpers
8         {
9                 internal const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation";
10                 internal const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security";
11
12                 [DllImport (CoreFoundationLibrary)]
13                 internal extern static void CFRelease (IntPtr obj);
14
15                 [DllImport (CoreFoundationLibrary)]
16                 internal extern static IntPtr CFRetain (IntPtr obj);
17
18                 [StructLayout (LayoutKind.Sequential)]
19                 struct CFRange {
20                         public IntPtr loc;
21                         public IntPtr len;
22
23                         public CFRange (int loc, int len)
24                                 : this ((long) loc, (long) len)
25                         {
26                         }
27
28                         public CFRange (long l, long len)
29                         {
30                                 this.loc = (IntPtr) l;
31                                 this.len = (IntPtr) len;
32                         }
33                 }
34
35                 [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)]
36                 extern static IntPtr CFStringCreateWithCharacters (IntPtr allocator, string str, IntPtr count);
37
38                 [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)]
39                 extern static IntPtr CFStringGetLength (IntPtr handle);
40
41                 [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)]
42                 extern static IntPtr CFStringGetCharactersPtr (IntPtr handle);
43
44                 [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)]
45                 extern static IntPtr CFStringGetCharacters (IntPtr handle, CFRange range, IntPtr buffer);
46
47                 internal static string FetchString (IntPtr handle)
48                 {
49                         if (handle == IntPtr.Zero)
50                                 return null;
51
52                         string str;
53
54                         int l = (int)CFStringGetLength (handle);
55                         IntPtr u = CFStringGetCharactersPtr (handle);
56                         IntPtr buffer = IntPtr.Zero;
57                         if (u == IntPtr.Zero){
58                                 CFRange r = new CFRange (0, l);
59                                 buffer = Marshal.AllocCoTaskMem (l * 2);
60                                 CFStringGetCharacters (handle, r, buffer);
61                                 u = buffer;
62                         }
63                         unsafe {
64                                 str = new string ((char *) u, 0, l);
65                         }
66
67                         if (buffer != IntPtr.Zero)
68                                 Marshal.FreeCoTaskMem (buffer);
69
70                         return str;
71                 }
72
73                 [DllImport (CoreFoundationLibrary)]
74                 extern static IntPtr CFDataGetLength (IntPtr handle);
75
76                 [DllImport (CoreFoundationLibrary)]
77                 extern static IntPtr CFDataGetBytePtr (IntPtr handle);
78
79                 internal static byte[] FetchDataBuffer (IntPtr handle)
80                 {
81                         var length = (int)CFDataGetLength (handle);
82                         var buffer = new byte [length];
83                         var ptr = CFDataGetBytePtr (handle);
84                         Marshal.Copy (ptr, buffer, 0, buffer.Length);
85                         return buffer;
86                 }
87
88                 [DllImport (CoreFoundationLibrary)]
89                 extern static IntPtr CFDataCreateWithBytesNoCopy (IntPtr allocator, IntPtr bytes, IntPtr length, IntPtr bytesDeallocator);
90
91                 [DllImport (CoreFoundationLibrary)]
92                 extern static IntPtr CFDataCreate (IntPtr allocator, IntPtr bytes, IntPtr length);
93
94                 [DllImport (SecurityLibrary)]
95                 extern static IntPtr SecCertificateCreateWithData (IntPtr allocator, IntPtr cfData);
96
97                 unsafe internal static IntPtr CreateCertificateFromData (byte[] data)
98                 {
99                         fixed (void *ptr = data) {
100                                 var cfdata = CFDataCreate (IntPtr.Zero, (IntPtr)ptr, new IntPtr (data.Length));
101                                 if (cfdata == IntPtr.Zero)
102                                         return IntPtr.Zero;
103
104                                 var certificate = SecCertificateCreateWithData (IntPtr.Zero, cfdata);
105                                 if (cfdata != IntPtr.Zero)
106                                         CFRelease (cfdata);
107                                 return certificate;
108                         }
109                 }
110         }
111 }
112 #endif