Imported Upstream version 5.4.0.167

Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-08-21 15:34:15 +00:00
parent e49d6f06c0
commit 536cd135cc
12856 changed files with 563812 additions and 223249 deletions

View File

@@ -12,68 +12,8 @@ namespace Internal.Cryptography
//
// Common infrastructure for AsymmetricAlgorithm-derived classes that layer on OpenSSL.
//
internal static class AsymmetricAlgorithmHelpers
internal static partial class AsymmetricAlgorithmHelpers
{
public static byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
{
// The classes that call us are sealed and their base class has checked this already.
Debug.Assert(data != null);
Debug.Assert(count >= 0 && count <= data.Length);
Debug.Assert(offset >= 0 && offset <= data.Length - count);
Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
using (HashAlgorithm hasher = GetHashAlgorithm(hashAlgorithm))
{
return hasher.ComputeHash(data, offset, count);
}
}
public static byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
{
// The classes that call us are sealed and their base class has checked this already.
Debug.Assert(data != null);
Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
using (HashAlgorithm hasher = GetHashAlgorithm(hashAlgorithm))
{
return hasher.ComputeHash(data);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "MD5 is used when the user asks for it.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is used when the user asks for it.")]
private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithmName)
{
HashAlgorithm hasher;
if (hashAlgorithmName == HashAlgorithmName.MD5)
{
hasher = MD5.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA1)
{
hasher = SHA1.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA256)
{
hasher = SHA256.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA384)
{
hasher = SHA384.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA512)
{
hasher = SHA512.Create();
}
else
{
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
return hasher;
}
/// <summary>
/// Convert Ieee1363 format of (r, s) to Der format
/// </summary>

View File

@@ -0,0 +1,77 @@
// 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.IO;
using System.Security.Cryptography;
namespace Internal.Cryptography
{
//
// Common infrastructure for AsymmetricAlgorithm-derived classes that layer on OpenSSL.
//
internal static partial class AsymmetricAlgorithmHelpers
{
public static byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
{
// The classes that call us are sealed and their base class has checked this already.
Debug.Assert(data != null);
Debug.Assert(count >= 0 && count <= data.Length);
Debug.Assert(offset >= 0 && offset <= data.Length - count);
Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
using (HashAlgorithm hasher = GetHashAlgorithm(hashAlgorithm))
{
return hasher.ComputeHash(data, offset, count);
}
}
public static byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm)
{
// The classes that call us are sealed and their base class has checked this already.
Debug.Assert(data != null);
Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
using (HashAlgorithm hasher = GetHashAlgorithm(hashAlgorithm))
{
return hasher.ComputeHash(data);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "MD5 is used when the user asks for it.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is used when the user asks for it.")]
private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithmName)
{
HashAlgorithm hasher;
if (hashAlgorithmName == HashAlgorithmName.MD5)
{
hasher = MD5.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA1)
{
hasher = SHA1.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA256)
{
hasher = SHA256.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA384)
{
hasher = SHA384.Create();
}
else if (hashAlgorithmName == HashAlgorithmName.SHA512)
{
hasher = SHA512.Create();
}
else
{
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
return hasher;
}
}
}

View File

@@ -39,6 +39,9 @@ internal static partial class Interop
string keychainPath,
out SafeKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SetKeychainNeverLock(SafeKeychainHandle keychain);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainEnumerateCerts(
SafeKeychainHandle keychain,
@@ -179,6 +182,11 @@ internal static partial class Interop
SafeTemporaryKeychainHandle.TrackKeychain(keychain);
if (osStatus == 0)
{
osStatus = AppleCryptoNative_SetKeychainNeverLock(keychain);
}
if (osStatus != 0)
{
keychain.Dispose();

View File

@@ -55,36 +55,50 @@ internal static partial class Interop
StoreEnumerator userEnumerator,
StoreEnumerator machineEnumerator)
{
int result;
SafeCFArrayHandle matches;
int osStatus;
const int RetryLimit = 3;
int osStatus = 0;
if (location == StoreLocation.CurrentUser)
// Occasionally calls to enumerate the trust list get errSecInvalidRecord.
// So, if we fail with result 0 ("see osStatus") just retry and see if the
// intermediate state has flushed itself.
for (int i = 0; i < RetryLimit; i++)
{
result = userEnumerator(out matches, out osStatus);
}
else if (location == StoreLocation.LocalMachine)
{
result = machineEnumerator(out matches, out osStatus);
}
else
{
Debug.Fail($"Unrecognized StoreLocation value: {location}");
int result;
SafeCFArrayHandle matches;
if (location == StoreLocation.CurrentUser)
{
result = userEnumerator(out matches, out osStatus);
}
else if (location == StoreLocation.LocalMachine)
{
result = machineEnumerator(out matches, out osStatus);
}
else
{
Debug.Fail($"Unrecognized StoreLocation value: {location}");
throw new CryptographicException();
}
if (result == 1)
{
return matches;
}
matches.Dispose();
if (result == 0)
{
// Instead of limiting it to particular error codes, just try it again.
// A permanent error will be stable, a temporary one will hopefully go away.
continue;
}
Debug.Fail($"Unexpected result from {location} trust store enumeration: {result}");
throw new CryptographicException();
}
if (result == 1)
{
return matches;
}
matches.Dispose();
if (result == 0)
throw CreateExceptionForOSStatus(osStatus);
Debug.Fail($"Unexpected result from {location} trust store enumeration: {result}");
throw new CryptographicException();
throw CreateExceptionForOSStatus(osStatus);
}
}
}

View File

@@ -74,6 +74,14 @@ internal static partial class Interop
out SafeCFDataHandle pExportOut,
out int pOSStatus);
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509CopyWithPrivateKey(
SafeSecCertificateHandle certHandle,
SafeSecKeyRefHandle privateKeyHandle,
SafeKeychainHandle targetKeychain,
out SafeSecIdentityHandle pIdentityHandleOut,
out int pOSStatus);
internal static byte[] X509GetRawData(SafeSecCertificateHandle cert)
{
int osStatus;
@@ -342,6 +350,38 @@ internal static partial class Interop
}
}
internal static SafeSecIdentityHandle X509CopyWithPrivateKey(
SafeSecCertificateHandle certHandle,
SafeSecKeyRefHandle privateKeyHandle,
SafeKeychainHandle targetKeychain)
{
SafeSecIdentityHandle identityHandle;
int osStatus;
int result = AppleCryptoNative_X509CopyWithPrivateKey(
certHandle,
privateKeyHandle,
targetKeychain,
out identityHandle,
out osStatus);
if (result == 1)
{
Debug.Assert(!identityHandle.IsInvalid);
return identityHandle;
}
identityHandle.Dispose();
if (result == 0)
{
throw CreateExceptionForOSStatus(osStatus);
}
Debug.Fail($"AppleCryptoNative_X509CopyWithPrivateKey returned {result}");
throw new CryptographicException();
}
private static byte[] X509Export(X509ContentType contentType, SafeCreateHandle cfPassphrase, IntPtr[] certHandles)
{
Debug.Assert(contentType == X509ContentType.Pkcs7 || contentType == X509ContentType.Pkcs12);

View File

@@ -74,34 +74,5 @@ internal static partial class Interop
return true;
}
}
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_IPv6StringToAddress", SetLastError = true)]
internal static extern unsafe int IPv6StringToAddress(string address, string port, byte* buffer, int bufferLength, out uint scope);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_IPv4StringToAddress", SetLastError = true)]
internal static extern unsafe int IPv4StringToAddress(string address, byte* buffer, int bufferLength, out ushort port);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_IPAddressToString")]
internal static extern unsafe int IPAddressToString(byte* address, int addressLength, bool isIPv6, byte* str, int stringLength, uint scope = 0);
internal static unsafe uint IPAddressToString(byte[] address, bool isIPv6, StringBuilder addressString, uint scope = 0)
{
Debug.Assert(address != null, "address was null");
Debug.Assert((address.Length == IPv4AddressBytes) || (address.Length == IPv6AddressBytes), $"Unexpected address length: {address.Length}");
int err;
fixed (byte* rawAddress = &address[0])
{
int bufferLength = isIPv6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN;
byte* buffer = stackalloc byte[bufferLength];
err = IPAddressToString(rawAddress, address.Length, isIPv6, buffer, bufferLength, scope);
if (err == 0)
{
addressString.Append(Marshal.PtrToStringAnsi((IntPtr)buffer));
}
}
return unchecked((uint)err);
}
}
}

View File

@@ -11,6 +11,6 @@ internal static partial class Interop
internal static partial class Sys
{
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ReceiveMessage")]
internal static extern unsafe Error ReceiveMessage(SafeHandle socket, MessageHeader* messageHeader, SocketFlags flags, long* received);
internal static extern unsafe Error ReceiveMessage(IntPtr socket, MessageHeader* messageHeader, SocketFlags flags, long* received);
}
}

View File

@@ -11,6 +11,6 @@ internal static partial class Interop
internal static partial class Sys
{
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SendMessage")]
internal static extern unsafe Error SendMessage(SafeHandle socket, MessageHeader* messageHeader, SocketFlags flags, long* sent);
internal static extern unsafe Error SendMessage(IntPtr socket, MessageHeader* messageHeader, SocketFlags flags, long* sent);
}
}

View File

@@ -27,6 +27,8 @@ internal static partial class Interop
internal long MTime;
internal long CTime;
internal long BirthTime;
internal long Dev;
internal long Ino;
}
internal static class FileTypes

View File

@@ -24,8 +24,15 @@ internal static partial class Interop
static HttpInitializer()
{
#if !SYSNETHTTP_NO_OPENSSL
// CURL uses OpenSSL which me must initialize first to guarantee thread-safety
CryptoInitializer.Initialize();
string opensslVersion = Interop.Http.GetSslVersionDescription();
if (string.IsNullOrEmpty(opensslVersion) ||
opensslVersion.IndexOf(Interop.Http.OpenSsl10Description, StringComparison.OrdinalIgnoreCase) != -1)
{
// CURL uses OpenSSL which me must initialize first to guarantee thread-safety
// Only initialize for OpenSSL/1.0, any newer versions may have mismatched
// pointers, resulting in segfaults.
CryptoInitializer.Initialize();
}
#endif
if (EnsureCurlIsInitialized() != 0)

View File

@@ -46,5 +46,8 @@ internal static partial class Interop
[DllImport(Libraries.HttpNative, EntryPoint = "HttpNative_GetSslVersionDescription")]
internal static extern string GetSslVersionDescription();
internal const string OpenSsl10Description = "openssl/1.0";
internal const string SecureTransportDescription = "SecureTransport";
}
}

View File

@@ -132,8 +132,16 @@ internal static partial class Interop
using (d_bn = new SafeBignumHandle(d_bn_not_owned, false))
{
// Match Windows semantics where qx, qy, and d have same length
int keySizeBits = EcKeyGetSize(key);
int expectedSize = (keySizeBits + 7) / 8;
int cbKey = GetMax(qx_cb, qy_cb, d_cb);
Debug.Assert(
cbKey <= expectedSize,
$"Expected output size was {expectedSize}, which a parameter exceeded. qx={qx_cb}, qy={qy_cb}, d={d_cb}");
cbKey = GetMax(cbKey, expectedSize);
parameters.Q = new ECPoint
{
X = Crypto.ExtractBignum(qx_bn, cbKey),

View File

@@ -66,35 +66,47 @@ internal static partial class Interop
throw new CryptographicException();
}
IntPtr n, e, d, p, dmp1, q, dmq1, iqmp;
if (!GetRsaParameters(key, out n, out e, out d, out p, out dmp1, out q, out dmq1, out iqmp))
bool addedRef = false;
try
{
throw new CryptographicException();
key.DangerousAddRef(ref addedRef);
IntPtr n, e, d, p, dmp1, q, dmq1, iqmp;
if (!GetRsaParameters(key, out n, out e, out d, out p, out dmp1, out q, out dmq1, out iqmp))
{
throw new CryptographicException();
}
int modulusSize = Crypto.RsaSize(key);
// RSACryptoServiceProvider expects P, DP, Q, DQ, and InverseQ to all
// be padded up to half the modulus size.
int halfModulus = modulusSize / 2;
RSAParameters rsaParameters = new RSAParameters
{
Modulus = Crypto.ExtractBignum(n, modulusSize),
Exponent = Crypto.ExtractBignum(e, 0),
};
if (includePrivateParameters)
{
rsaParameters.D = Crypto.ExtractBignum(d, modulusSize);
rsaParameters.P = Crypto.ExtractBignum(p, halfModulus);
rsaParameters.DP = Crypto.ExtractBignum(dmp1, halfModulus);
rsaParameters.Q = Crypto.ExtractBignum(q, halfModulus);
rsaParameters.DQ = Crypto.ExtractBignum(dmq1, halfModulus);
rsaParameters.InverseQ = Crypto.ExtractBignum(iqmp, halfModulus);
}
return rsaParameters;
}
int modulusSize = Crypto.RsaSize(key);
// RSACryptoServiceProvider expects P, DP, Q, DQ, and InverseQ to all
// be padded up to half the modulus size.
int halfModulus = modulusSize / 2;
RSAParameters rsaParameters = new RSAParameters
finally
{
Modulus = Crypto.ExtractBignum(n, modulusSize),
Exponent = Crypto.ExtractBignum(e, 0),
};
if (includePrivateParameters)
{
rsaParameters.D = Crypto.ExtractBignum(d, modulusSize);
rsaParameters.P = Crypto.ExtractBignum(p, halfModulus);
rsaParameters.DP = Crypto.ExtractBignum(dmp1, halfModulus);
rsaParameters.Q = Crypto.ExtractBignum(q, halfModulus);
rsaParameters.DQ = Crypto.ExtractBignum(dmq1, halfModulus);
rsaParameters.InverseQ = Crypto.ExtractBignum(iqmp, halfModulus);
if (addedRef)
key.DangerousRelease();
}
return rsaParameters;
}
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_GetRsaParameters")]

View File

@@ -41,6 +41,9 @@ internal static partial class Interop
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslGetError")]
internal static extern SslErrorCode SslGetError(IntPtr ssl, int ret);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetQuietShutdown")]
internal static extern void SslSetQuietShutdown(SafeSslHandle ssl, int mode);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslDestroy")]
internal static extern void SslDestroy(IntPtr ssl);
@@ -80,6 +83,9 @@ internal static partial class Interop
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslShutdown")]
internal static extern int SslShutdown(IntPtr ssl);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslShutdown")]
internal static extern int SslShutdown(SafeSslHandle ssl);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetBio")]
internal static extern void SslSetBio(SafeSslHandle ssl, SafeBioHandle rbio, SafeBioHandle wbio);
@@ -286,17 +292,16 @@ namespace Microsoft.Win32.SafeHandles
{
Debug.Assert(!IsInvalid, "Expected a valid context in Disconnect");
// Because we set "quiet shutdown" on the SSL_CTX, SslShutdown is supposed
// to always return 1 (completed success). In "close-notify" shutdown (the
// opposite of quiet) there's also 0 (incomplete success) and negative
// (probably async IO WANT_READ/WANT_WRITE, but need to check) return codes
// to handle.
//
// If quiet shutdown is ever not set, see
// https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html
// for guidance on how to rewrite this method.
int retVal = Interop.Ssl.SslShutdown(handle);
Debug.Assert(retVal == 1);
// Here, we are ignoring checking for <0 return values from Ssl_Shutdown,
// since the underlying memory bio is already disposed, we are not
// interested in reading or writing to it.
if (retVal == 0)
{
// Do a bi-directional shutdown.
retVal = Interop.Ssl.SslShutdown(handle);
}
}
private SafeSslHandle() : base(IntPtr.Zero, true)

View File

@@ -129,7 +129,11 @@ internal static partial class Interop
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509StoreCtxInit")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool X509StoreCtxInit(SafeX509StoreCtxHandle ctx, SafeX509StoreHandle store, SafeX509Handle x509);
internal static extern bool X509StoreCtxInit(
SafeX509StoreCtxHandle ctx,
SafeX509StoreHandle store,
SafeX509Handle x509,
SafeX509StackHandle extraCerts);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509VerifyCert")]
internal static extern int X509VerifyCert(SafeX509StoreCtxHandle ctx);

View File

@@ -35,18 +35,6 @@ namespace Internal.NativeCrypto
public const string Sha512 = "SHA512"; // BCRYPT_SHA512_ALGORITHM
}
/// <summary>
/// Magic numbers identifying blob types
/// </summary>
internal enum KeyBlobMagicNumber {
ECDHPublicP256 = 0x314B4345, // BCRYPT_ECDH_PUBLIC_P256_MAGIC
ECDHPublicP384 = 0x334B4345, // BCRYPT_ECDH_PUBLIC_P384_MAGIC
ECDHPublicP521 = 0x354B4345, // BCRYPT_ECDH_PUBLIC_P521_MAGIC
ECDsaPublicP256 = 0x31534345, // BCRYPT_ECDSA_PUBLIC_P256_MAGIC
ECDsaPublicP384 = 0x33534345, // BCRYPT_ECDSA_PUBLIC_P384_MAGIC
ECDsaPublicP521 = 0x35534345 // BCRYPT_ECDSA_PUBLIC_P521_MAGIC
}
internal static class KeyDerivationFunction
{
public const string Hash = "HASH"; // BCRYPT_KDF_HASH
@@ -303,18 +291,6 @@ namespace Internal.NativeCrypto
private static extern uint BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, int dwFlags);
}
internal sealed class SafeHashHandle : SafeBCryptHandle
{
protected sealed override bool ReleaseHandle()
{
uint ntStatus = BCryptDestroyHash(handle);
return ntStatus == 0;
}
[DllImport(Libraries.BCrypt)]
private static extern uint BCryptDestroyHash(IntPtr hHash);
}
internal sealed class SafeKeyHandle : SafeBCryptHandle
{
private SafeAlgorithmHandle _parentHandle = null;

View File

@@ -1,22 +0,0 @@
// 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 System.Security;
internal partial class Interop
{
internal partial class Crypt32
{
internal const uint CRYPTPROTECTMEMORY_BLOCK_SIZE = 16;
internal const uint CRYPTPROTECTMEMORY_SAME_PROCESS = 0;
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CryptProtectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
[DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CryptUnprotectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
}
}

View File

@@ -776,14 +776,6 @@ internal static partial class Interop
return GetKnownHeader(request, 0, headerIndex);
}
internal static unsafe string GetKnownHeader(byte[] memoryBlob, IntPtr originalAddress, int headerIndex)
{
fixed (byte* pMemoryBlob = memoryBlob)
{
return GetKnownHeader((HTTP_REQUEST*)pMemoryBlob, pMemoryBlob - (byte*)originalAddress, headerIndex);
}
}
private static unsafe string GetVerb(HTTP_REQUEST* request, long fixup)
{
string verb = null;

View File

@@ -26,6 +26,7 @@ internal partial class Interop
internal const int ERROR_FILE_EXISTS = 0x50;
internal const int ERROR_INVALID_PARAMETER = 0x57;
internal const int ERROR_BROKEN_PIPE = 0x6D;
internal const int ERROR_CALL_NOT_IMPLEMENTED = 0x78;
internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
internal const int ERROR_INVALID_NAME = 0x7B;
internal const int ERROR_NEGATIVE_SEEK = 0x83;
@@ -53,6 +54,9 @@ internal partial class Interop
internal const int ERROR_NO_TOKEN = 0x3f0;
internal const int ERROR_DLL_INIT_FAILED = 0x45A;
internal const int ERROR_COUNTER_TIMEOUT = 0x461;
internal const int ERROR_NO_ASSOCIATION = 0x483;
internal const int ERROR_DDE_FAIL = 0x484;
internal const int ERROR_DLL_NOT_FOUND = 0x485;
internal const int ERROR_NOT_FOUND = 0x490;
internal const int ERROR_NON_ACCOUNT_SID = 0x4E9;
internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;

View File

@@ -7,9 +7,11 @@ using System.Runtime.InteropServices;
internal static partial class Interop
{
internal static partial class Kernel32
[StructLayout(LayoutKind.Sequential)]
internal struct UNICODE_STRING
{
[DllImport(Interop.Libraries.Kernel32)]
internal extern static int GetCurrentThreadId();
internal ushort Length;
internal ushort MaximumLength;
internal IntPtr Buffer;
}
}

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