Skip to content

Commit d4fe4a7

Browse files
authored
Create new X509CertificateLoader
The new certificate loader only loads one data type per method, unlike the previous loader mechanism (new X509Certiicate2(bytes, ...)). It also allows for caller configuration to control cost-of-work limits and some common usability gotchas around Windows PFX loading. This change adds the new loader, and changes the X509Certificate2 ctors to use it; a followup will mark the ctors as Obsolete and update usage in the dotnet/runtime codebase.
1 parent b8b3bf2 commit d4fe4a7

File tree

86 files changed

+7995
-2480
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+7995
-2480
lines changed

src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptQueryObject.cs

+15
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,20 @@ internal static unsafe partial bool CryptQueryObject(
5656
IntPtr phMsg,
5757
IntPtr ppvContext
5858
);
59+
60+
[LibraryImport(Libraries.Crypt32, SetLastError = true)]
61+
[return: MarshalAs(UnmanagedType.Bool)]
62+
internal static unsafe partial bool CryptQueryObject(
63+
CertQueryObjectType dwObjectType,
64+
void* pvObject,
65+
ExpectedContentTypeFlags dwExpectedContentTypeFlags,
66+
ExpectedFormatTypeFlags dwExpectedFormatTypeFlags,
67+
int dwFlags, // reserved - always pass 0
68+
IntPtr pdwMsgAndCertEncodingType,
69+
out ContentType pdwContentType,
70+
IntPtr pdwFormatType,
71+
IntPtr phCertStore,
72+
IntPtr phMsg,
73+
out SafeCertContextHandle ppvContext);
5974
}
6075
}

src/libraries/Common/src/Interop/Windows/Crypt32/Interop.PFXImportCertStore.cs

+3
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@ internal static partial class Crypt32
1010
{
1111
[LibraryImport(Libraries.Crypt32, SetLastError = true)]
1212
internal static partial SafeCertStoreHandle PFXImportCertStore(ref DATA_BLOB pPFX, SafePasswordHandle password, PfxCertStoreFlags dwFlags);
13+
14+
[LibraryImport(Libraries.Crypt32, SetLastError = true)]
15+
internal static unsafe partial SafeCertStoreHandle PFXImportCertStore(ref DATA_BLOB pPFX, char* password, PfxCertStoreFlags dwFlags);
1316
}
1417
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Buffers;
5+
6+
namespace System.IO.MemoryMappedFiles
7+
{
8+
internal sealed unsafe class MemoryMappedFileMemoryManager : MemoryManager<byte>
9+
{
10+
private byte* _pointer;
11+
private int _length;
12+
private MemoryMappedFile _mappedFile;
13+
private MemoryMappedViewAccessor _accessor;
14+
15+
public MemoryMappedFileMemoryManager(
16+
byte* pointer,
17+
int length,
18+
MemoryMappedFile mappedFile,
19+
MemoryMappedViewAccessor accessor)
20+
{
21+
_pointer = pointer;
22+
_length = length;
23+
_mappedFile = mappedFile;
24+
_accessor = accessor;
25+
}
26+
27+
#if DEBUG
28+
#pragma warning disable CA2015
29+
~MemoryMappedFileMemoryManager()
30+
#pragma warning restore CA2015
31+
{
32+
Environment.FailFast("MemoryMappedFileMemoryManager was finalized.");
33+
}
34+
#endif
35+
36+
internal static MemoryMappedFileMemoryManager CreateFromFileClamped(
37+
FileStream fileStream,
38+
MemoryMappedFileAccess access = MemoryMappedFileAccess.Read,
39+
HandleInheritability inheritability = HandleInheritability.None,
40+
bool leaveOpen = false)
41+
{
42+
int length = (int)Math.Min(int.MaxValue, fileStream.Length);
43+
MemoryMappedFile mapped = MemoryMappedFile.CreateFromFile(fileStream, null, 0, access, inheritability, leaveOpen);
44+
MemoryMappedViewAccessor? accessor = null;
45+
byte* pointer = null;
46+
47+
try
48+
{
49+
accessor = mapped.CreateViewAccessor(0, length, access);
50+
accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
51+
52+
return new MemoryMappedFileMemoryManager(pointer, length, mapped, accessor);
53+
}
54+
catch (Exception)
55+
{
56+
if (pointer != null)
57+
{
58+
accessor!.SafeMemoryMappedViewHandle.ReleasePointer();
59+
}
60+
61+
accessor?.Dispose();
62+
mapped.Dispose();
63+
throw;
64+
}
65+
}
66+
67+
protected override void Dispose(bool disposing)
68+
{
69+
_pointer = null;
70+
_length = -1;
71+
_accessor?.SafeMemoryMappedViewHandle.ReleasePointer();
72+
_accessor?.Dispose();
73+
_mappedFile?.Dispose();
74+
_accessor = null!;
75+
_mappedFile = null!;
76+
}
77+
78+
public override Span<byte> GetSpan()
79+
{
80+
ThrowIfDisposed();
81+
return new Span<byte>(_pointer, _length);
82+
}
83+
84+
public override MemoryHandle Pin(int elementIndex = 0)
85+
{
86+
ThrowIfDisposed();
87+
return default;
88+
}
89+
90+
public override void Unpin()
91+
{
92+
ThrowIfDisposed();
93+
// nop
94+
}
95+
96+
private void ThrowIfDisposed()
97+
{
98+
#if NET
99+
ObjectDisposedException.ThrowIf(_length < 0, this);
100+
#else
101+
if (_length < 0)
102+
{
103+
throw new ObjectDisposedException(GetType().FullName);
104+
}
105+
#endif
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)