Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8d12002
Updated MS.DiaSymReader.Native to 16.11.27-beta1.23180.1
hoyosjs Mar 31, 2023
6edec23
Merge in 'release/7.0' changes
dotnet-bot Apr 5, 2023
f5f7b34
Merge in 'release/7.0' changes
dotnet-bot Apr 6, 2023
0fddbf9
Merge in 'release/7.0' changes
dotnet-bot Apr 7, 2023
08e0f70
CVE-2023-24936: Check type is allowed when deserializing insatance ty…
ajcvickers Mar 16, 2023
33b8556
Merged PR 30054: Check type is allowed when deserializing insatance t…
Apr 7, 2023
45cad1d
Updated MS.DiaSymReader.Native to 16.11.27-beta1.23180.1
hoyosjs Apr 10, 2023
0b43eeb
Merge in 'release/7.0' changes
dotnet-bot Apr 11, 2023
5f1ec97
Merge in 'release/7.0' changes
dotnet-bot Apr 11, 2023
41b6f22
Merge in 'release/7.0' changes
dotnet-bot Apr 12, 2023
e3acf02
Merge in 'release/7.0' changes
dotnet-bot Apr 12, 2023
2a25ee7
Merge in 'release/7.0' changes
dotnet-bot Apr 17, 2023
0418529
Change loading sequence for Windows PDB parsing
hoyosjs Apr 20, 2023
d689f47
Merge in 'release/7.0' changes
dotnet-bot May 3, 2023
806235b
Tar: Ensure trailing separator in sanitized path for extraction
carlossanlop May 3, 2023
1746b88
Merge in 'release/7.0' changes
dotnet-bot May 3, 2023
921628f
Merged PR 30131: Only clean up elements that have been marshalled in …
jtschuster May 8, 2023
eb0d56e
Merge in 'release/7.0' changes
dotnet-bot May 15, 2023
7d21bfd
Merged PR 31140: [release/7.0] Add delay load hook for singlefilehost…
elinor-fung May 16, 2023
4906b56
[release/7.0] Only use shipped version of symreader
hoyosjs May 18, 2023
8e3442d
Merged PR 31292: [7.0] Apply iteration work limits to X509 certificat…
krwq May 19, 2023
5b20af4
Merged PR 31513: [internal/release/7.0] Merge from public
mmitche May 24, 2023
33b133c
Merge commit '5b20af47d99620150c53eaf5db8636fdf730b126' into internal…
vseanreesermsft Jun 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.22415.6</optimizationlinuxarm64MIBCRuntimeVersion>
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.22415.6</optimizationPGOCoreCLRVersion>
<!-- Not auto-updated. -->
<MicrosoftDiaSymReaderNativeVersion>16.11.23-beta1.23063.1</MicrosoftDiaSymReaderNativeVersion>
<MicrosoftDiaSymReaderNativeVersion>16.11.27-beta1.23180.1</MicrosoftDiaSymReaderNativeVersion>
<SystemCommandLineVersion>2.0.0-beta4.22355.1</SystemCommandLineVersion>
<TraceEventVersion>3.0.3</TraceEventVersion>
<NETStandardLibraryRefVersion>2.1.0</NETStandardLibraryRefVersion>
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/dlls/mscoree/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set(CLR_SOURCES

if(CLR_CMAKE_TARGET_WIN32)
list(APPEND CLR_SOURCES
delayloadhook.cpp
${CLR_SRC_NATIVE_DIR}/libs/Common/delayloadhook_windows.cpp
Native.rc
)

Expand Down
27 changes: 9 additions & 18 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2311,26 +2311,17 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
"reachable or needs to be reimplemented for CoreCLR!");
}

// We're going to be working with Windows PDB format symbols. Attempt to CoCreate the symbol binder.
// CoreCLR supports not having a symbol reader installed, so CoCreate searches the PATH env var
// and then tries coreclr dll location.
// On desktop, the framework installer is supposed to install diasymreader.dll as well
// and so this shouldn't happen.
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, NATIVE_SYMBOL_READER_DLL, IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
PathString symbolReaderPath;
hr = GetClrModuleDirectory(symbolReaderPath);
if (FAILED(hr))
{
PathString symbolReaderPath;
hr = GetClrModuleDirectory(symbolReaderPath);
if (FAILED(hr))
{
RETURN (NULL);
}
symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL);
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
if (FAILED(hr))
{
RETURN (NULL);
}
RETURN (NULL);
}
symbolReaderPath.Append(NATIVE_SYMBOL_READER_DLL);
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS, symbolReaderPath.GetUnicode(), IID_ISymUnmanagedBinder, (void**)&pBinder, NULL);
if (FAILED(hr))
{
RETURN (NULL);
}

LOG((LF_CORDB, LL_INFO10, "M::GISUR: Created binder\n"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Formats.Asn1;
using System.Security.Cryptography.Asn1.Pkcs7;
using System.Security.Cryptography.Pkcs;
using Internal.Cryptography;

#if BUILDING_PKCS
using Helpers = Internal.Cryptography.PkcsHelpers;
#endif

namespace System.Security.Cryptography.Asn1.Pkcs12
{
internal partial struct PfxAsn
{
private const int MaxIterationWork = 300_000;
private static ReadOnlySpan<char> EmptyPassword => ""; // don't use ReadOnlySpan<byte>.Empty because it will get confused with default.
private static ReadOnlySpan<char> NullPassword => default;

internal bool VerifyMac(
ReadOnlySpan<char> macPassword,
ReadOnlySpan<byte> authSafeContents)
Expand Down Expand Up @@ -84,5 +95,245 @@ internal bool VerifyMac(
MacData.Value.Mac.Digest.Span);
}
}

internal ulong CountTotalIterations()
{
checked
{
ulong count = 0;

// RFC 7292 section 4.1:
// the contentType field of authSafe shall be of type data
// or signedData. The content field of the authSafe shall, either
// directly (data case) or indirectly (signedData case), contain a BER-
// encoded value of type AuthenticatedSafe.
// We don't support authSafe that is signedData, so enforce that it's just data.
if (AuthSafe.ContentType != Oids.Pkcs7Data)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

ReadOnlyMemory<byte> authSafeContents = Helpers.DecodeOctetStringAsMemory(AuthSafe.Content);
AsnValueReader outerAuthSafe = new AsnValueReader(authSafeContents.Span, AsnEncodingRules.BER); // RFC 7292 PDU says BER
AsnValueReader authSafeReader = outerAuthSafe.ReadSequence();
outerAuthSafe.ThrowIfNotEmpty();

bool hasSeenEncryptedInfo = false;

while (authSafeReader.HasData)
{
ContentInfoAsn.Decode(ref authSafeReader, authSafeContents, out ContentInfoAsn contentInfo);

ReadOnlyMemory<byte> contentData;
ArraySegment<byte>? rentedData = null;

try
{
if (contentInfo.ContentType != Oids.Pkcs7Data)
{
if (contentInfo.ContentType == Oids.Pkcs7Encrypted)
{
if (hasSeenEncryptedInfo)
{
// We will process at most one encryptedData ContentInfo. This is the most typical scenario where
// certificates are stored in an encryptedData ContentInfo, and keys are shrouded in a data ContentInfo.
throw new CryptographicException(SR.Cryptography_X509_PfxWithoutPassword);
}

ArraySegment<byte> content = DecryptContentInfo(contentInfo, out uint iterations);
contentData = content;
rentedData = content;
hasSeenEncryptedInfo = true;
count += iterations;
}
else
{
// Not a common scenario. It's not data or encryptedData, so they need to go through the
// regular PKCS12 loader.
throw new CryptographicException(SR.Cryptography_X509_PfxWithoutPassword);
}
}
else
{
contentData = Helpers.DecodeOctetStringAsMemory(contentInfo.Content);
}

AsnValueReader outerSafeBag = new AsnValueReader(contentData.Span, AsnEncodingRules.BER);
AsnValueReader safeBagReader = outerSafeBag.ReadSequence();
outerSafeBag.ThrowIfNotEmpty();

while (safeBagReader.HasData)
{
SafeBagAsn.Decode(ref safeBagReader, contentData, out SafeBagAsn bag);

// We only need to count iterations on PKCS8ShroudedKeyBag.
// * KeyBag is PKCS#8 PrivateKeyInfo and doesn't do iterations.
// * CertBag, either for x509Certificate or sdsiCertificate don't do iterations.
// * CRLBag doesn't do iterations.
// * SecretBag doesn't do iteations.
// * Nested SafeContents _can_ do iterations, but Windows ignores it. So we will ignore it too.
if (bag.BagId == Oids.Pkcs12ShroudedKeyBag)
{
AsnValueReader pkcs8ShroudedKeyReader = new AsnValueReader(bag.BagValue.Span, AsnEncodingRules.BER);
EncryptedPrivateKeyInfoAsn.Decode(
ref pkcs8ShroudedKeyReader,
bag.BagValue,
out EncryptedPrivateKeyInfoAsn epki);

count += IterationsFromParameters(epki.EncryptionAlgorithm);
}
}
}
finally
{
if (rentedData.HasValue)
{
CryptoPool.Return(rentedData.Value);
}
}
}

if (MacData.HasValue)
{
if (MacData.Value.IterationCount < 0)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

count += (uint)MacData.Value.IterationCount;
}

return count;
}
}

private static ArraySegment<byte> DecryptContentInfo(ContentInfoAsn contentInfo, out uint iterations)
{
EncryptedDataAsn encryptedData = EncryptedDataAsn.Decode(contentInfo.Content, AsnEncodingRules.BER);

if (encryptedData.Version != 0 && encryptedData.Version != 2)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

// The encrypted contentInfo can only wrap a PKCS7 data.
if (encryptedData.EncryptedContentInfo.ContentType != Oids.Pkcs7Data)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

if (!encryptedData.EncryptedContentInfo.EncryptedContent.HasValue)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

iterations = IterationsFromParameters(encryptedData.EncryptedContentInfo.ContentEncryptionAlgorithm);

// This encryptData is encrypted with more rounds than we are willing to process. Bail out of the whole thing.
if (iterations > MaxIterationWork)
{
throw new CryptographicException(SR.Cryptography_X509_PfxWithoutPassword);
}

int encryptedValueLength = encryptedData.EncryptedContentInfo.EncryptedContent.Value.Length;
byte[] destination = CryptoPool.Rent(encryptedValueLength);
int written = 0;

try
{
try
{
written = PasswordBasedEncryption.Decrypt(
in encryptedData.EncryptedContentInfo.ContentEncryptionAlgorithm,
EmptyPassword,
default,
encryptedData.EncryptedContentInfo.EncryptedContent.Value.Span,
destination);
}
catch
{
// If empty password didn't work, try null password.
written = PasswordBasedEncryption.Decrypt(
in encryptedData.EncryptedContentInfo.ContentEncryptionAlgorithm,
NullPassword,
default,
encryptedData.EncryptedContentInfo.EncryptedContent.Value.Span,
destination);
}
}
finally
{
if (written == 0)
{
// This means the decryption operation failed and destination could contain
// partial data. Clear it to be hygienic.
CryptographicOperations.ZeroMemory(destination);
}
}

return new ArraySegment<byte>(destination, 0, written);
}

private static uint IterationsFromParameters(in AlgorithmIdentifierAsn algorithmIdentifier)
{
switch (algorithmIdentifier.Algorithm)
{
case Oids.PasswordBasedEncryptionScheme2:
if (!algorithmIdentifier.Parameters.HasValue)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

PBES2Params pbes2Params = PBES2Params.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER);

// PBES2 only defines PKBDF2 for now. See RFC 8018 A.4
if (pbes2Params.KeyDerivationFunc.Algorithm != Oids.Pbkdf2)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

if (!pbes2Params.KeyDerivationFunc.Parameters.HasValue)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

Pbkdf2Params pbkdf2Params = Pbkdf2Params.Decode(pbes2Params.KeyDerivationFunc.Parameters.Value, AsnEncodingRules.BER);

if (pbkdf2Params.IterationCount < 0)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

return (uint)pbkdf2Params.IterationCount;

// PBES1
case Oids.PbeWithMD5AndDESCBC:
case Oids.PbeWithMD5AndRC2CBC:
case Oids.PbeWithSha1AndDESCBC:
case Oids.PbeWithSha1AndRC2CBC:
case Oids.Pkcs12PbeWithShaAnd3Key3Des:
case Oids.Pkcs12PbeWithShaAnd2Key3Des:
case Oids.Pkcs12PbeWithShaAnd128BitRC2:
case Oids.Pkcs12PbeWithShaAnd40BitRC2:
if (!algorithmIdentifier.Parameters.HasValue)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

PBEParameter pbeParameters = PBEParameter.Decode(
algorithmIdentifier.Parameters.Value,
AsnEncodingRules.BER);

if (pbeParameters.IterationCount < 0)
{
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}

return (uint)pbeParameters.IterationCount;

default:
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding);
}
}
}
}
Loading