Imported Upstream version 5.2.0.175

Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-06-07 13:16:24 +00:00
parent 4bdbaf4a88
commit 966bba02bb
8776 changed files with 346420 additions and 149650 deletions

View File

@@ -1,5 +1,4 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
@@ -7,32 +6,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Tests", "tests\Commo
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
FreeBSD_Debug|Any CPU = FreeBSD_Debug|Any CPU
FreeBSD_Release|Any CPU = FreeBSD_Release|Any CPU
Linux_Debug|Any CPU = Linux_Debug|Any CPU
Linux_Release|Any CPU = Linux_Release|Any CPU
OSX_Debug|Any CPU = OSX_Debug|Any CPU
OSX_Release|Any CPU = OSX_Release|Any CPU
Windows_Debug|Any CPU = Windows_Debug|Any CPU
Windows_Release|Any CPU = Windows_Release|Any CPU
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C72FD34C-539A-4447-9796-62A229571199}.FreeBSD_Debug|Any CPU.ActiveCfg = FreeBSD_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.FreeBSD_Debug|Any CPU.Build.0 = FreeBSD_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.FreeBSD_Release|Any CPU.ActiveCfg = FreeBSD_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.FreeBSD_Release|Any CPU.Build.0 = FreeBSD_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Linux_Debug|Any CPU.ActiveCfg = Linux_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Linux_Debug|Any CPU.Build.0 = Linux_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Linux_Release|Any CPU.ActiveCfg = Linux_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Linux_Release|Any CPU.Build.0 = Linux_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.OSX_Debug|Any CPU.ActiveCfg = OSX_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.OSX_Debug|Any CPU.Build.0 = OSX_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.OSX_Release|Any CPU.ActiveCfg = OSX_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.OSX_Release|Any CPU.Build.0 = OSX_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Windows_Debug|Any CPU.ActiveCfg = Windows_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Windows_Debug|Any CPU.Build.0 = Windows_Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Windows_Release|Any CPU.ActiveCfg = Windows_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Windows_Release|Any CPU.Build.0 = Windows_Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Debug|Any CPU.ActiveCfg = netstandard1.3-Unix-Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Debug|Any CPU.Build.0 = netstandard1.3-Unix-Debug|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Release|Any CPU.ActiveCfg = netstandard1.3-Unix-Release|Any CPU
{C72FD34C-539A-4447-9796-62A229571199}.Release|Any CPU.Build.0 = netstandard1.3-Unix-Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,5 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
[assembly: System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAssembly]

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
netstandard1.3;
netstandard;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,30 @@
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.Xunit.Performance.Api;
public class PerfHarness
{
public static void Main(string[] args)
{
using (XunitPerformanceHarness harness = new XunitPerformanceHarness(args))
{
foreach(var testName in GetTestAssemblies())
{
harness.RunBenchmarks(GetTestAssembly(testName));
}
}
}
private static string GetTestAssembly(string testName)
{
// Assume test assemblies are colocated/restored next to the PerfHarness.
return Path.Combine(
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), testName);
}
private static IEnumerable<string> GetTestAssemblies()
{
return Directory.EnumerateFiles(".", "*.Performance.Tests.dll");
}
}

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{F5E941C8-AF2F-47AB-A066-FF25470CE382}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>PerfRunner</RootNamespace>
<AssemblyName>PerfRunner</AssemblyName>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
<NoWarn>0436</NoWarn>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard1.3-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="PerfRunner.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' != 'net46'">
<Compile Include="AssemblyAttributes.cs" />
<Compile Include="$(CommonPath)\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAssemblyAttribute.cs">
<Link>Common\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAssemblyAttribute.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="PerfRunner.runtimeconfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>

View File

@@ -0,0 +1,8 @@
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.9.9"
}
}
}

View File

@@ -1,28 +0,0 @@
{
"dependencies": {
"Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
"Microsoft.DotNet.xunit.performance.analysis.cli": "1.0.0-alpha-build0040",
"Microsoft.DotNet.xunit.performance.runner.cli": "1.0.0-alpha-build0040",
"Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040"
},
"frameworks": {
"netstandard1.3": {}
},
"supports": {
"coreFx.Test.netcoreapp1.0": {
"netcoreapp1.0": [
"win7-x86",
"win7-x64",
"osx.10.10-x64",
"centos.7-x64",
"debian.8-x64",
"rhel.7-x64",
"ubuntu.14.04-x64",
"ubuntu.16.04-x64",
"fedora.23-x64",
"linux-x64",
"opensuse.13.2-x64"
]
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Internal.Cryptography
//
// Common infrastructure for AsymmetricAlgorithm-derived classes that layer on OpenSSL.
//
internal static class OpenSslAsymmetricAlgorithmCore
internal static class AsymmetricAlgorithmHelpers
{
public static byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
{

View File

@@ -0,0 +1,55 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
// Declared as signed long, which has sizeof(void*) on OSX.
using CFIndex=System.IntPtr;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary, EntryPoint = "CFArrayGetCount")]
private static extern CFIndex _CFArrayGetCount(SafeCFArrayHandle cfArray);
// Follows the "Get" version of the "Create" rule, so needs to return an IntPtr to
// prevent CFRelease from being called on the SafeHandle close.
[DllImport(Libraries.CoreFoundationLibrary, EntryPoint = "CFArrayGetValueAtIndex")]
private static extern IntPtr CFArrayGetValueAtIndex(SafeCFArrayHandle cfArray, CFIndex index);
internal static long CFArrayGetCount(SafeCFArrayHandle cfArray)
{
return _CFArrayGetCount(cfArray).ToInt64();
}
internal static IntPtr CFArrayGetValueAtIndex(SafeCFArrayHandle cfArray, int index)
{
return CFArrayGetValueAtIndex(cfArray, new CFIndex(index));
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFArrayHandle : SafeHandle
{
internal SafeCFArrayHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}

View File

@@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
// Declared as signed long, which has sizeof(void*) on OSX.
using CFIndex=System.IntPtr;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern unsafe byte* CFDataGetBytePtr(SafeCFDataHandle cfData);
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern CFIndex CFDataGetLength(SafeCFDataHandle cfData);
internal static byte[] CFGetData(SafeCFDataHandle cfData)
{
bool addedRef = false;
try
{
cfData.DangerousAddRef(ref addedRef);
byte[] bytes = new byte[CFDataGetLength(cfData).ToInt64()];
unsafe
{
byte* dataBytes = CFDataGetBytePtr(cfData);
Marshal.Copy((IntPtr)dataBytes, bytes, 0, bytes.Length);
}
return bytes;
}
finally
{
if (addedRef)
{
cfData.DangerousRelease();
}
}
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFDataHandle : SafeHandle
{
internal SafeCFDataHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
internal SafeCFDataHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}

View File

@@ -0,0 +1,66 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using CFAbsoluteTime=System.Double;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
// https://developer.apple.com/reference/corefoundation/cfabsolutetime
private static readonly DateTime s_cfDateEpoch = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Utc);
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern SafeCFDateHandle CFDateCreate(IntPtr zero, CFAbsoluteTime at);
internal static SafeCFDateHandle CFDateCreate(DateTime date)
{
Debug.Assert(
date.Kind != DateTimeKind.Unspecified,
"DateTimeKind.Unspecified should be specified to Local or UTC by the caller");
// UTC stays unchanged, Local is changed.
// Unspecified gets treated as Local (which may or may not be desired).
DateTime utcDate = date.ToUniversalTime();
double epochDeltaSeconds = (utcDate - s_cfDateEpoch).TotalSeconds;
SafeCFDateHandle cfDate = CFDateCreate(IntPtr.Zero, epochDeltaSeconds);
if (cfDate.IsInvalid)
{
cfDate.Dispose();
throw new OutOfMemoryException();
}
return cfDate;
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFDateHandle : SafeHandle
{
internal SafeCFDateHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}

View File

@@ -0,0 +1,69 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
// Declared as signed long, which has sizeof(void*) on OSX.
using CFIndex=System.IntPtr;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern CFIndex CFErrorGetCode(SafeCFErrorHandle cfError);
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern SafeCFStringHandle CFErrorCopyDescription(SafeCFErrorHandle cfError);
internal static int GetErrorCode(SafeCFErrorHandle cfError)
{
unchecked
{
return (int)(CFErrorGetCode(cfError).ToInt64());
}
}
internal static string GetErrorDescription(SafeCFErrorHandle cfError)
{
Debug.Assert(cfError != null);
if (cfError.IsInvalid)
{
return null;
}
Debug.Assert(!cfError.IsClosed);
using (SafeCFStringHandle cfString = CFErrorCopyDescription(cfError))
{
return CFStringToString(cfString);
}
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFErrorHandle : SafeHandle
{
internal SafeCFErrorHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}

View File

@@ -0,0 +1,103 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{
internal static partial class CoreFoundation
{
/// <summary>
/// Returns the interior pointer of the cfString if it has the specified encoding.
/// If it has the wrong encoding, or if the interior pointer isn't being shared for some reason, returns NULL
/// </summary>
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern IntPtr CFStringGetCStringPtr(
SafeCFStringHandle cfString,
CFStringBuiltInEncodings encoding);
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern SafeCFDataHandle CFStringCreateExternalRepresentation(
IntPtr alloc,
SafeCFStringHandle theString,
CFStringBuiltInEncodings encoding,
byte lossByte);
internal static string CFStringToString(SafeCFStringHandle cfString)
{
Debug.Assert(cfString != null);
Debug.Assert(!cfString.IsInvalid);
Debug.Assert(!cfString.IsClosed);
// If the string is already stored internally as UTF-8 we can (usually)
// get the raw pointer to the data blob, then we can Marshal in the string
// via pointer semantics, avoiding a copy.
IntPtr interiorPointer = CFStringGetCStringPtr(
cfString,
CFStringBuiltInEncodings.kCFStringEncodingUTF8);
if (interiorPointer != IntPtr.Zero)
{
return Marshal.PtrToStringUTF8(interiorPointer);
}
SafeCFDataHandle cfData = CFStringCreateExternalRepresentation(
IntPtr.Zero,
cfString,
CFStringBuiltInEncodings.kCFStringEncodingUTF8,
0);
using (cfData)
{
bool addedRef = false;
try
{
cfData.DangerousAddRef(ref addedRef);
unsafe
{
// Note that CFDataGetLength(cfData).ToInt32() will throw on
// too large of an input. Since a >2GB string is pretty unlikely,
// that's considered a good thing here.
return Encoding.UTF8.GetString(
CFDataGetBytePtr(cfData),
CFDataGetLength(cfData).ToInt32());
}
}
finally
{
if (addedRef)
{
cfData.DangerousRelease();
}
}
}
}
}
}
namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFStringHandle : SafeHandle
{
internal SafeCFStringHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
@@ -50,7 +51,21 @@ internal static partial class Interop
IntPtr allocator,
string str,
CFStringBuiltInEncodings encoding);
/// <summary>
/// Creates a CFStringRef from a 8-bit String object. Follows the "Create Rule" where if you create it, you delete it.
/// </summary>
/// <param name="allocator">Should be IntPtr.Zero</param>
/// <param name="str">The string to get a CFStringRef for</param>
/// <param name="encoding">The encoding of the str variable. This should be UTF 8 for OS X</param>
/// <returns>Returns a pointer to a CFString on success; otherwise, returns IntPtr.Zero</returns>
/// <remarks>For *nix systems, the CLR maps ANSI to UTF-8, so be explicit about that</remarks>
[DllImport(Interop.Libraries.CoreFoundationLibrary, CharSet = CharSet.Ansi)]
private static extern SafeCreateHandle CFStringCreateWithCString(
IntPtr allocator,
IntPtr str,
CFStringBuiltInEncodings encoding);
/// <summary>
/// Creates a CFStringRef from a 8-bit String object. Follows the "Create Rule" where if you create it, you delete it.
/// </summary>
@@ -61,6 +76,16 @@ internal static partial class Interop
return CFStringCreateWithCString(IntPtr.Zero, str, CFStringBuiltInEncodings.kCFStringEncodingUTF8);
}
/// <summary>
/// Creates a CFStringRef from a 8-bit String object. Follows the "Create Rule" where if you create it, you delete it.
/// </summary>
/// <param name="utf8str">The string to get a CFStringRef for</param>
/// <returns>Returns a valid SafeCreateHandle to a CFString on success; otherwise, returns an invalid SafeCreateHandle</returns>
internal static SafeCreateHandle CFStringCreateWithCString(IntPtr utf8str)
{
return CFStringCreateWithCString(IntPtr.Zero, utf8str, CFStringBuiltInEncodings.kCFStringEncodingUTF8);
}
/// <summary>
/// Creates a pointer to an unmanaged CFArray containing the input values. Follows the "Create Rule" where if you create it, you delete it.
/// </summary>

View File

@@ -4,6 +4,7 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Microsoft.Win32.SafeHandles;
@@ -26,7 +27,11 @@ internal static partial class Interop
/// <summary>
/// Starts the current thread's RunLoop. If the RunLoop is already running, creates a new, nested, RunLoop in the same stack.
/// </summary>
#if MONO
[MethodImplAttribute(MethodImplOptions.InternalCall)]
#else
[DllImport(Interop.Libraries.CoreFoundationLibrary)]
#endif
internal extern static void CFRunLoopRun();
/// <summary>

View File

@@ -23,7 +23,6 @@ internal static partial class Interop
private const int PROC_PIDTHREADINFO = 5;
private const int PROC_PIDLISTTHREADS = 6;
private const int PROC_PIDPATHINFO_MAXSIZE = 4 * MAXPATHLEN;
private static int PROC_PIDLISTTHREADS_SIZE = (Marshal.SizeOf<uint>() * 2);
// Constants from sys\resource.h
private const int RUSAGE_INFO_V3 = 3;
@@ -199,9 +198,9 @@ internal static partial class Interop
// To make sure it isn't #2, when the result == size, increase the buffer and try again
processes = new int[(int)(numProcesses * 1.10)];
fixed (int* pBuffer = processes)
fixed (int* pBuffer = &processes[0])
{
numProcesses = proc_listallpids(pBuffer, processes.Length * Marshal.SizeOf<int>());
numProcesses = proc_listallpids(pBuffer, processes.Length * sizeof(int));
if (numProcesses <= 0)
{
throw new Win32Exception(SR.CantGetAllPids);
@@ -317,7 +316,7 @@ internal static partial class Interop
}
// Get the process information for the specified pid
int size = Marshal.SizeOf<proc_taskallinfo>();
int size = sizeof(proc_taskallinfo);
proc_taskallinfo info = default(proc_taskallinfo);
int result = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &info, size);
return (result == size ? new proc_taskallinfo?(info) : null);
@@ -346,7 +345,7 @@ internal static partial class Interop
}
// Get the thread information for the specified thread in the specified process
int size = Marshal.SizeOf<proc_threadinfo>();
int size = sizeof(proc_threadinfo);
proc_threadinfo info = default(proc_threadinfo);
int result = proc_pidinfo(pid, PROC_PIDTHREADINFO, (ulong)thread, &info, size);
return (result == size ? new proc_threadinfo?(info) : null);
@@ -371,9 +370,9 @@ internal static partial class Interop
do
{
threadIds = new ulong[size];
fixed (ulong* pBuffer = threadIds)
fixed (ulong* pBuffer = &threadIds[0])
{
result = proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, pBuffer, Marshal.SizeOf<ulong>() * threadIds.Length);
result = proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, pBuffer, sizeof(ulong) * threadIds.Length);
}
if (result <= 0)
@@ -391,12 +390,12 @@ internal static partial class Interop
}
}
}
while (result == Marshal.SizeOf<ulong>() * threadIds.Length);
while (result == sizeof(ulong) * threadIds.Length);
Debug.Assert((result % Marshal.SizeOf<ulong>()) == 0);
Debug.Assert((result % sizeof(ulong)) == 0);
// Loop over each thread and get the thread info
int count = (int)(result / Marshal.SizeOf<ulong>());
int count = (int)(result / sizeof(ulong));
threads.Capacity = count;
for (int i = 0; i < count; i++)
{
@@ -435,7 +434,7 @@ internal static partial class Interop
// The path is a fixed buffer size, so use that and trim it after
int result = 0;
byte* pBuffer = stackalloc byte[PROC_PIDPATHINFO_MAXSIZE];
result = proc_pidpath(pid, pBuffer, (uint)(PROC_PIDPATHINFO_MAXSIZE * Marshal.SizeOf<byte>()));
result = proc_pidpath(pid, pBuffer, (uint)(PROC_PIDPATHINFO_MAXSIZE * sizeof(byte)));
if (result <= 0)
{
throw new Win32Exception();

View File

@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.Apple;
internal static partial class Interop
{
internal static partial class AppleCrypto
{
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_EccGenerateKey(
int keySizeInBits,
SafeKeychainHandle tempKeychain,
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey,
out int pOSStatus);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_EccGetKeySizeInBits")]
internal static extern long EccGetKeySizeInBits(SafeSecKeyRefHandle publicKey);
internal static void EccGenerateKey(
int keySizeInBits,
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey)
{
using (SafeTemporaryKeychainHandle tempKeychain = CreateTemporaryKeychain())
{
SafeSecKeyRefHandle keychainPublic;
SafeSecKeyRefHandle keychainPrivate;
int osStatus;
int result = AppleCryptoNative_EccGenerateKey(
keySizeInBits,
tempKeychain,
out keychainPublic,
out keychainPrivate,
out osStatus);
if (result == 1)
{
pPublicKey = keychainPublic;
pPrivateKey = keychainPrivate;
return;
}
using (keychainPrivate)
using (keychainPublic)
{
if (result == 0)
{
throw CreateExceptionForOSStatus(osStatus);
}
Debug.Fail($"Unexpected result from AppleCryptoNative_EccGenerateKey: {result}");
throw new CryptographicException();
}
}
}
}
}

View File

@@ -3,7 +3,9 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{
@@ -22,6 +24,27 @@ internal static partial class Interop
errorType));
}
internal static Exception CreateExceptionForCFError(SafeCFErrorHandle cfError)
{
Debug.Assert(cfError != null);
if (cfError.IsInvalid)
{
return new CryptographicException();
}
return new AppleCFErrorCryptographicException(cfError);
}
private sealed class AppleCFErrorCryptographicException : CryptographicException
{
internal AppleCFErrorCryptographicException(SafeCFErrorHandle cfError)
: base(Interop.CoreFoundation.GetErrorDescription(cfError))
{
HResult = Interop.CoreFoundation.GetErrorCode(cfError);
}
}
private sealed class AppleCommonCryptoCryptographicException : CryptographicException
{
internal AppleCommonCryptoCryptographicException(int errorCode, string message)

View File

@@ -0,0 +1,339 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.Apple;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{
internal static partial class AppleCrypto
{
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainItemCopyKeychain(
IntPtr item,
out SafeKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_SecKeychainCreate")]
private static extern int AppleCryptoNative_SecKeychainCreateTemporary(
string path,
int utf8PassphraseLength,
byte[] utf8Passphrase,
out SafeTemporaryKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainDelete(IntPtr keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainCopyDefault(out SafeKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainOpen(
string keychainPath,
out SafeKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainEnumerateCerts(
SafeKeychainHandle keychain,
out SafeCFArrayHandle matches,
out int pOSStatus);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainEnumerateIdentities(
SafeKeychainHandle keychain,
out SafeCFArrayHandle matches,
out int pOSStatus);
internal static SafeKeychainHandle SecKeychainItemCopyKeychain(SafeKeychainItemHandle item)
{
bool addedRef = false;
try
{
item.DangerousAddRef(ref addedRef);
var handle = SecKeychainItemCopyKeychain(item.DangerousGetHandle());
return handle;
}
finally
{
if (addedRef)
{
item.DangerousRelease();
}
}
}
internal static SafeKeychainHandle SecKeychainItemCopyKeychain(IntPtr item)
{
SafeKeychainHandle keychain;
int osStatus = AppleCryptoNative_SecKeychainItemCopyKeychain(item, out keychain);
// A whole lot of NULL is expected from this.
// Any key or cert which isn't keychain-backed, and this is the primary way we'd find that out.
if (keychain.IsInvalid)
{
GC.SuppressFinalize(keychain);
}
if (osStatus == 0)
{
return keychain;
}
throw CreateExceptionForOSStatus(osStatus);
}
internal static SafeKeychainHandle SecKeychainCopyDefault()
{
SafeKeychainHandle keychain;
int osStatus = AppleCryptoNative_SecKeychainCopyDefault(out keychain);
if (osStatus == 0)
{
return keychain;
}
keychain.Dispose();
throw CreateExceptionForOSStatus(osStatus);
}
internal static SafeKeychainHandle SecKeychainOpen(string keychainPath)
{
SafeKeychainHandle keychain;
int osStatus = AppleCryptoNative_SecKeychainOpen(keychainPath, out keychain);
if (osStatus == 0)
{
return keychain;
}
keychain.Dispose();
throw CreateExceptionForOSStatus(osStatus);
}
internal static SafeCFArrayHandle KeychainEnumerateCerts(SafeKeychainHandle keychainHandle)
{
SafeCFArrayHandle matches;
int osStatus;
int result = AppleCryptoNative_SecKeychainEnumerateCerts(keychainHandle, out matches, out osStatus);
if (result == 1)
{
return matches;
}
matches.Dispose();
if (result == 0)
throw CreateExceptionForOSStatus(osStatus);
Debug.Fail($"Unexpected result from AppleCryptoNative_SecKeychainEnumerateCerts: {result}");
throw new CryptographicException();
}
internal static SafeCFArrayHandle KeychainEnumerateIdentities(SafeKeychainHandle keychainHandle)
{
SafeCFArrayHandle matches;
int osStatus;
int result = AppleCryptoNative_SecKeychainEnumerateIdentities(keychainHandle, out matches, out osStatus);
if (result == 1)
{
return matches;
}
matches.Dispose();
if (result == 0)
throw CreateExceptionForOSStatus(osStatus);
Debug.Fail($"Unexpected result from AppleCryptoNative_SecKeychainEnumerateCerts: {result}");
throw new CryptographicException();
}
internal static SafeTemporaryKeychainHandle CreateTemporaryKeychain()
{
string tmpKeychainPath = Path.Combine(
Path.GetTempPath(),
Guid.NewGuid().ToString("N") + ".keychain");
// Use a distinct GUID so that if a keychain is abandoned it isn't recoverable.
string tmpKeychainPassphrase = Guid.NewGuid().ToString("N");
byte[] utf8Passphrase = System.Text.Encoding.UTF8.GetBytes(tmpKeychainPassphrase);
SafeTemporaryKeychainHandle keychain;
int osStatus = AppleCryptoNative_SecKeychainCreateTemporary(
tmpKeychainPath,
utf8Passphrase.Length,
utf8Passphrase,
out keychain);
SafeTemporaryKeychainHandle.TrackKeychain(keychain);
if (osStatus != 0)
{
keychain.Dispose();
throw CreateExceptionForOSStatus(osStatus);
}
return keychain;
}
internal static void SecKeychainDelete(IntPtr handle, bool throwOnError=true)
{
int osStatus = AppleCryptoNative_SecKeychainDelete(handle);
if (throwOnError && osStatus != 0)
{
throw CreateExceptionForOSStatus(osStatus);
}
}
}
}
namespace System.Security.Cryptography.Apple
{
internal class SafeKeychainItemHandle : SafeHandle
{
internal SafeKeychainItemHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
SafeTemporaryKeychainHandle.UntrackItem(handle);
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
internal class SafeKeychainHandle : SafeHandle
{
internal SafeKeychainHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}
internal SafeKeychainHandle(IntPtr handle)
: base(handle, ownsHandle: true)
{
}
protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}
public override bool IsInvalid => handle == IntPtr.Zero;
}
internal sealed class SafeTemporaryKeychainHandle : SafeKeychainHandle
{
private static readonly Dictionary<IntPtr, SafeTemporaryKeychainHandle> s_lookup =
new Dictionary<IntPtr, SafeTemporaryKeychainHandle>();
internal SafeTemporaryKeychainHandle()
{
}
protected override bool ReleaseHandle()
{
lock (s_lookup)
{
s_lookup.Remove(handle);
}
Interop.AppleCrypto.SecKeychainDelete(handle, throwOnError: false);
return base.ReleaseHandle();
}
protected override void Dispose(bool disposing)
{
if (disposing && SafeHandleCache<SafeTemporaryKeychainHandle>.IsCachedInvalidHandle(this))
{
return;
}
base.Dispose(disposing);
}
public static SafeTemporaryKeychainHandle InvalidHandle =>
SafeHandleCache<SafeTemporaryKeychainHandle>.GetInvalidHandle(() => new SafeTemporaryKeychainHandle());
internal static void TrackKeychain(SafeTemporaryKeychainHandle toTrack)
{
if (toTrack.IsInvalid)
{
return;
}
lock (s_lookup)
{
Debug.Assert(!s_lookup.ContainsKey(toTrack.handle));
s_lookup[toTrack.handle] = toTrack;
}
}
internal static void TrackItem(SafeKeychainItemHandle keychainItem)
{
if (keychainItem.IsInvalid)
return;
using (SafeKeychainHandle keychain = Interop.AppleCrypto.SecKeychainItemCopyKeychain(keychainItem))
{
if (keychain.IsInvalid)
{
return;
}
lock (s_lookup)
{
SafeTemporaryKeychainHandle temporaryHandle;
if (s_lookup.TryGetValue(keychain.DangerousGetHandle(), out temporaryHandle))
{
bool ignored = false;
temporaryHandle.DangerousAddRef(ref ignored);
}
}
}
}
internal static void UntrackItem(IntPtr keychainItem)
{
using (SafeKeychainHandle keychain = Interop.AppleCrypto.SecKeychainItemCopyKeychain(keychainItem))
{
if (keychain.IsInvalid)
{
return;
}
lock (s_lookup)
{
SafeTemporaryKeychainHandle temporaryHandle;
if (s_lookup.TryGetValue(keychain.DangerousGetHandle(), out temporaryHandle))
{
temporaryHandle.DangerousRelease();
}
}
}
}
}
}

View File

@@ -0,0 +1,175 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.Apple;
using Microsoft.Win32.SafeHandles;
internal static partial class Interop
{
internal static partial class AppleCrypto
{
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaGenerateKey")]
private static extern int AppleCryptoNative_RsaGenerateKey(
int keySizeInBits,
SafeKeychainHandle keychain,
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey,
out int pOSStatus);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaEncryptOaep")]
private static extern int RsaEncryptOaep(
SafeSecKeyRefHandle publicKey,
byte[] pbData,
int cbData,
PAL_HashAlgorithm mgfAlgorithm,
out SafeCFDataHandle pEncryptedOut,
out SafeCFErrorHandle pErrorOut);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaEncryptPkcs")]
private static extern int RsaEncryptPkcs(
SafeSecKeyRefHandle publicKey,
byte[] pbData,
int cbData,
out SafeCFDataHandle pEncryptedOut,
out SafeCFErrorHandle pErrorOut);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaDecryptOaep")]
private static extern int RsaDecryptOaep(
SafeSecKeyRefHandle publicKey,
byte[] pbData,
int cbData,
PAL_HashAlgorithm mgfAlgorithm,
out SafeCFDataHandle pEncryptedOut,
out SafeCFErrorHandle pErrorOut);
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaDecryptPkcs")]
private static extern int RsaDecryptPkcs(
SafeSecKeyRefHandle publicKey,
byte[] pbData,
int cbData,
out SafeCFDataHandle pEncryptedOut,
out SafeCFErrorHandle pErrorOut);
internal static void RsaGenerateKey(
int keySizeInBits,
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey)
{
using (SafeTemporaryKeychainHandle tempKeychain = CreateTemporaryKeychain())
{
SafeSecKeyRefHandle keychainPublic;
SafeSecKeyRefHandle keychainPrivate;
int osStatus;
int result = AppleCryptoNative_RsaGenerateKey(
keySizeInBits,
tempKeychain,
out keychainPublic,
out keychainPrivate,
out osStatus);
if (result == 1)
{
pPublicKey = keychainPublic;
pPrivateKey = keychainPrivate;
return;
}
using (keychainPrivate)
using (keychainPublic)
{
if (result == 0)
{
throw CreateExceptionForOSStatus(osStatus);
}
Debug.Fail($"Unexpected result from AppleCryptoNative_RsaGenerateKey: {result}");
throw new CryptographicException();
}
}
}
internal static byte[] RsaEncrypt(
SafeSecKeyRefHandle publicKey,
byte[] data,
RSAEncryptionPadding padding)
{
return ExecuteTransform(
(out SafeCFDataHandle encrypted, out SafeCFErrorHandle error) =>
{
if (padding == RSAEncryptionPadding.Pkcs1)
{
return RsaEncryptPkcs(publicKey, data, data.Length, out encrypted, out error);
}
Debug.Assert(padding.Mode == RSAEncryptionPaddingMode.Oaep);
return RsaEncryptOaep(
publicKey,
data,
data.Length,
PalAlgorithmFromAlgorithmName(padding.OaepHashAlgorithm),
out encrypted,
out error);
});
}
internal static byte[] RsaDecrypt(
SafeSecKeyRefHandle privateKey,
byte[] data,
RSAEncryptionPadding padding)
{
return ExecuteTransform(
(out SafeCFDataHandle decrypted, out SafeCFErrorHandle error) =>
{
if (padding == RSAEncryptionPadding.Pkcs1)
{
return RsaDecryptPkcs(privateKey, data, data.Length, out decrypted, out error);
}
Debug.Assert(padding.Mode == RSAEncryptionPaddingMode.Oaep);
return RsaDecryptOaep(
privateKey,
data,
data.Length,
PalAlgorithmFromAlgorithmName(padding.OaepHashAlgorithm),
out decrypted,
out error);
});
}
private static Interop.AppleCrypto.PAL_HashAlgorithm PalAlgorithmFromAlgorithmName(
HashAlgorithmName hashAlgorithmName)
{
if (hashAlgorithmName == HashAlgorithmName.MD5)
{
return Interop.AppleCrypto.PAL_HashAlgorithm.Md5;
}
else if (hashAlgorithmName == HashAlgorithmName.SHA1)
{
return Interop.AppleCrypto.PAL_HashAlgorithm.Sha1;
}
else if (hashAlgorithmName == HashAlgorithmName.SHA256)
{
return Interop.AppleCrypto.PAL_HashAlgorithm.Sha256;
}
else if (hashAlgorithmName == HashAlgorithmName.SHA384)
{
return Interop.AppleCrypto.PAL_HashAlgorithm.Sha384;
}
else if (hashAlgorithmName == HashAlgorithmName.SHA512)
{
return Interop.AppleCrypto.PAL_HashAlgorithm.Sha512;
}
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
}
}

Some files were not shown because too many files have changed in this diff Show More