Skip to content

Commit c88db8e

Browse files
jankratochvilczJan KratochvilCopilot
authored
Enlighten ResolveKeySource for multithreaded mode (dotnet#13623)
Adds `[MSBuildMultiThreadableTask]` and `IMultiThreadableTask` to `ResolveKeySource`. Absolutizes `KeyFile` before `File.OpenRead()` and `CertificateFile` before `FileExists`/`GetCertContentType`/`Import`/`X509Certificate2` ctor, while preserving the original paths for `[Output] ResolvedKeyFile` property and error messages. Fixes dotnet#13620 Parent epic: dotnet#11834 Co-authored-by: Jan Kratochvil <jankratochvl@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 70b8335 commit c88db8e

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

src/Tasks/ResolveKeySource.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ namespace Microsoft.Build.Tasks
2020
/// <summary>
2121
/// Determine the strong name key source
2222
/// </summary>
23-
public class ResolveKeySource : TaskExtension
23+
[MSBuildMultiThreadableTask]
24+
public class ResolveKeySource : TaskExtension, IMultiThreadableTask
2425
{
26+
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;
27+
2528
private const string pfxFileExtension = ".pfx";
2629
#if !RUNTIME_TYPE_NETCORE
2730
private const string pfxFileContainerPrefix = "VS_KEY_";
@@ -118,14 +121,15 @@ private bool ResolveAssemblyKey()
118121
FileStream fs = null;
119122
try
120123
{
124+
AbsolutePath keyFilePath = TaskEnvironment.GetAbsolutePath(KeyFile);
121125
string currentUserName = Environment.UserDomainName + "\\" + Environment.UserName;
122126
// we use the curent user name to randomize the associated container name, i.e different user on the same machine will export to different keys
123127
// this is because SNAPI by default will create keys in "per-machine" crypto store (visible for all the user) but will set the permission such only
124128
// creator will be able to use it. This will make imposible for other user both to sign or export the key again (since they also can not delete that key).
125129
// Now different users will use different container name. We use ToLower(invariant) because this is what the native equivalent of this function (Create new key, or VC++ import-er).
126130
// use as well and we want to keep the hash (and key container name the same) otherwise user could be prompt for a password twice.
127131
byte[] userNameBytes = System.Text.Encoding.Unicode.GetBytes(currentUserName.ToLower(CultureInfo.InvariantCulture));
128-
fs = File.OpenRead(KeyFile);
132+
fs = File.OpenRead(keyFilePath);
129133
int fileLength = (int)fs.Length;
130134
var keyBytes = new byte[fileLength];
131135
fs.ReadFromStream(keyBytes, 0, fileLength);
@@ -205,15 +209,16 @@ private bool ResolveManifestKey()
205209
if (!string.IsNullOrEmpty(CertificateFile) && !certInStore)
206210
{
207211
#if FEATURE_PFX_SIGNING
212+
AbsolutePath certificateFilePath = TaskEnvironment.GetAbsolutePath(CertificateFile);
208213
// if the cert isn't on disk, we can't import it
209-
if (!FileSystems.Default.FileExists(CertificateFile))
214+
if (!FileSystems.Default.FileExists(certificateFilePath))
210215
{
211216
Log.LogErrorWithCodeFromResources("ResolveKeySource.CertificateNotInStore");
212217
}
213218
else
214219
{
215220
// add the cert to the store optionally prompting for the password
216-
if (X509Certificate2.GetCertContentType(CertificateFile) == X509ContentType.Pfx)
221+
if (X509Certificate2.GetCertContentType(certificateFilePath) == X509ContentType.Pfx)
217222
{
218223
bool imported = false;
219224
// first try it with no password
@@ -222,7 +227,7 @@ private bool ResolveManifestKey()
222227
try
223228
{
224229
personalStore.Open(OpenFlags.ReadWrite);
225-
cert.Import(CertificateFile, (string)null, X509KeyStorageFlags.PersistKeySet);
230+
cert.Import(certificateFilePath, (string)null, X509KeyStorageFlags.PersistKeySet);
226231
personalStore.Add(cert);
227232
ResolvedThumbprint = cert.Thumbprint;
228233
imported = true;
@@ -250,7 +255,7 @@ private bool ResolveManifestKey()
250255
var personalStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
251256
try
252257
{
253-
var cert = new X509Certificate2(CertificateFile);
258+
var cert = new X509Certificate2(certificateFilePath);
254259
personalStore.Open(OpenFlags.ReadWrite);
255260
personalStore.Add(cert);
256261
ResolvedThumbprint = cert.Thumbprint;

0 commit comments

Comments
 (0)