From f7f0b1924904ec7f2792c0a7805a4d0e91ac8955 Mon Sep 17 00:00:00 2001
From: YuliiaKovalova <95473390+YuliiaKovalova@users.noreply.github.com>
Date: Tue, 28 Nov 2023 10:32:45 +0100
Subject: [PATCH] Fix issue with SHA256 instantiation (#9429)
---
.../Microsoft.Build.Tasks.UnitTests.csproj | 6 ++
src/Tasks.UnitTests/SecurityUtil_Tests.cs | 81 ++++++++++++++++++
.../TestResources/ClickOnceProfile.pubxml | 11 +++
src/Tasks.UnitTests/TestResources/mycert.pfx | Bin 0 -> 2590 bytes
src/Tasks/ManifestUtil/mansign2.cs | 8 +-
5 files changed, 104 insertions(+), 2 deletions(-)
create mode 100644 src/Tasks.UnitTests/SecurityUtil_Tests.cs
create mode 100644 src/Tasks.UnitTests/TestResources/ClickOnceProfile.pubxml
create mode 100644 src/Tasks.UnitTests/TestResources/mycert.pfx
diff --git a/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj b/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj
index 733ef007645..6b3d539cacf 100644
--- a/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj
+++ b/src/Tasks.UnitTests/Microsoft.Build.Tasks.UnitTests.csproj
@@ -166,8 +166,14 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
diff --git a/src/Tasks.UnitTests/SecurityUtil_Tests.cs b/src/Tasks.UnitTests/SecurityUtil_Tests.cs
new file mode 100644
index 00000000000..92bcfaf08c8
--- /dev/null
+++ b/src/Tasks.UnitTests/SecurityUtil_Tests.cs
@@ -0,0 +1,81 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Build.Tasks.Deployment.ManifestUtilities;
+using Shouldly;
+using Xunit;
+
+namespace Microsoft.Build.Tasks.UnitTests
+{
+ public class SecurityUtil_Tests
+ {
+ private static string TestAssembliesPaths { get; } = Path.Combine(AppContext.BaseDirectory, "TestResources");
+
+ [WindowsOnlyTheory]
+ [InlineData("v4.5", Constants.DotNetFrameworkIdentifier)]
+ [InlineData("v4.5", Constants.DotNetCoreAppIdentifier)]
+ [SupportedOSPlatform("windows")]
+ public void SignFile_Success(string tfVersion, string tfIdentifier)
+ {
+ Uri timestampUrl = new("http://timestamp.comodoca.com/rfc3161");
+ string clickOnceManifest = Path.Combine(TestAssembliesPaths, "ClickOnceProfile.pubxml");
+ string targetFrameworkVersion = tfVersion;
+ string targetFrameworkIdentifier = tfIdentifier;
+ bool disallowMansignTimestampFallback = false;
+
+ // the certificate was generated locally and does not contain any sensitive information
+ string pathToCertificate = Path.Combine(TestAssembliesPaths, "mycert.pfx");
+ X509Certificate2 certificate = TestCertHelper.MockCertificate(pathToCertificate);
+
+ void SignAction() => SecurityUtilities.SignFile(
+ certificate?.Thumbprint,
+ timestampUrl,
+ clickOnceManifest,
+ targetFrameworkVersion,
+ targetFrameworkIdentifier,
+ disallowMansignTimestampFallback);
+
+ Should.NotThrow(SignAction);
+
+ TestCertHelper.RemoveCertificate(certificate);
+ }
+
+ internal static class TestCertHelper
+ {
+ private static readonly X509Store s_personalStore = new(StoreName.My, StoreLocation.CurrentUser);
+
+ internal static X509Certificate2 MockCertificate(string pathToCertificate)
+ {
+ var certificate = new X509Certificate2(pathToCertificate);
+ UpdateCertificateState(certificate, s_personalStore.Add);
+
+ return certificate;
+ }
+
+ internal static void RemoveCertificate(X509Certificate2 certificate) => UpdateCertificateState(certificate, s_personalStore.Remove);
+
+ private static void UpdateCertificateState(X509Certificate2 certificate, Action updateAction)
+ {
+ try
+ {
+ s_personalStore.Open(OpenFlags.ReadWrite);
+ updateAction(certificate);
+ }
+ finally
+ {
+ s_personalStore.Close();
+ }
+ }
+ }
+ }
+}
diff --git a/src/Tasks.UnitTests/TestResources/ClickOnceProfile.pubxml b/src/Tasks.UnitTests/TestResources/ClickOnceProfile.pubxml
new file mode 100644
index 00000000000..0f18e1617e4
--- /dev/null
+++ b/src/Tasks.UnitTests/TestResources/ClickOnceProfile.pubxml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+GFyhRWlbyN1COOyGVz+n59ISTl8HTCRRaL7OE/wqoqc=fzzu/EybaQbpsDnYtyMLpWpaihS9qwnFwsp+01OrSOv9FD6scw5hDE6Y7f0vfpCq7oTCrlFpGBA2MtPOUfsC3/YOUSI0rzFgZ4zKvYp13cqtpdLEBKrhxmtNWIxZfZr8ByCkxTMjQWUD8LV9/oB561ofOPSkVmrgVrPi6ciUbac9njyaxNXY1EWjplXAHF0Mf8hhsAmM8lZypRJBfZ4tjSmN1nBXkHzKX3X2BrkUTcFxoBiyEE/P6cVPdqAA/fAGtBm4rn8Kpm/ivMXZevR/Y1DkPrnOyHs0VjJacc/G66oTG8BrN7YKj9R/eAtxVQyMQNzpNVb9RxlfL6OIY6lLmQ==6tvmrtrrG1VZfNmU2Bl3UNKJA5MYqNwsb/AgeqqIywgsJAep3pu5D5hA2dFFiMLIC+d+K0PxNgUQpVxkTIX+4aYn6uo+alTek/i1EM0AMZm1pFxmN4WSbSTSrwduuXQLX4hDMP0Sl3TVJL8truWBvGHrtU8/I6dLYrqemEMyOh8C7v802VDLWZW5yq6MSt+KqtnHfILMZzitv7fh2qo+RJ4zvGL+4ZI+S7lwl2ltt9p8nvHDiFSodVwQHEXkPULx7IZfDVNXs6MzgN5NwFGaZtCyktzrcecLRh3UujeViikMZTSQq/DurOuUyzy89QfBPWg+d56EaI4pt/DX5zJ0KQ==AQABCN=YourCertificateName7L0K32UM0IBLmCQiodjr1C77qlV0vD3GTM34xo5nm94=oRPs44JALU/JhGZasau4cn17arKsvShbmTPfkk9NWJV3YEdcvuzzO7l0yaXt29INLFVh9dc7n5mpJhuk4GaydFGY2xQAR/CIHSF7S79iPxKUxtWvYws4Bp7q7kSFDrloW4s3RwWIVksgWWnvhlk21AVDTXhAYEU8IfQX9jmafB0SejBxD9KkQOiAwtV/OWWSWNpGcI84AITMiFvDZDQDER566tGqNHZLeEYunmUqcoQry7X/BFsl2jvzIkAdSAnXJWx3dsYYTl9bngazfrDbZR8f40VicEGvUY9HzL0Ei8IalP6Vwqx9G91m+hH8oVcKSEbi+cRKm6NWLVe5Tgql7w==6tvmrtrrG1VZfNmU2Bl3UNKJA5MYqNwsb/AgeqqIywgsJAep3pu5D5hA2dFFiMLIC+d+K0PxNgUQpVxkTIX+4aYn6uo+alTek/i1EM0AMZm1pFxmN4WSbSTSrwduuXQLX4hDMP0Sl3TVJL8truWBvGHrtU8/I6dLYrqemEMyOh8C7v802VDLWZW5yq6MSt+KqtnHfILMZzitv7fh2qo+RJ4zvGL+4ZI+S7lwl2ltt9p8nvHDiFSodVwQHEXkPULx7IZfDVNXs6MzgN5NwFGaZtCyktzrcecLRh3UujeViikMZTSQq/DurOuUyzy89QfBPWg+d56EaI4pt/DX5zJ0KQ==AQABMIIDGTCCAgGgAwIBAgIQ4HSIXz7yH49M25eRQpRFGjANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNZb3VyQ2VydGlmaWNhdGVOYW1lMB4XDTIzMTExNjEzNTQyMVoXDTM5MTIzMTIzNTk1OVowHjEcMBoGA1UEAxMTWW91ckNlcnRpZmljYXRlTmFtZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOrb5q7a6xtVWXzZlNgZd1DSiQOTGKjcLG/wIHqqiMsILCQHqd6buQ+YQNnRRYjCyAvnfitD8TYFEKVcZEyF/uGmJ+rqPmpU3pP4tRDNADGZtaRcZjeFkm0k0q8Hbrl0C1+IQzD9Epd01SS/La7lgbxh67VPPyOnS2K6nphDMjofAu7/NNlQy1mVucqujErfiqrZx3yCzGc4rb+34dqqPkSeM7xi/uGSPku5cJdpbbfafJ7xw4hUqHVcEBxF5D1C8eyGXw1TV7OjM4DeTcBRmmbQspLc63HnC0Yd1Lo3lYopDGU0kKvw7qzrlMs8vPUHwT1oPneehGiOKbfw1+cydCkCAwEAAaNTMFEwTwYDVR0BBEgwRoAQKuOh/UZkiI1MMUdwVlT6KaEgMB4xHDAaBgNVBAMTE1lvdXJDZXJ0aWZpY2F0ZU5hbWWCEOB0iF8+8h+PTNuXkUKURRowDQYJKoZIhvcNAQELBQADggEBAAybLoyi46eGUAwqJOORCgbkJMrQQOE/C8reSrBByJbL7g1QLPkaEULfGf8oex8cRYI2/uToZMf+uoyGqu+aGquoYSCBviRXerSnjHvpW1PB8RnpyMN/346F4dVtPWWMVHMKD4Pl0rlFRBVl/trbE9fUP15eE1hySsQxoGzazhrptvogUyjjz+7boh+W1knjwfvLt+aPN/x3o6JNGMa0gmmqICAbOHFKstTSa2DAucrUVbm9oWhTK/27AmTq++GFEdr/YpQU4RY5XRLviT3dAW0LamAFSrrInXX0RBea6/E9pIWxfdcnMt5yZ2FnnrDEVFLiXYI3ZSCjRurZfsROU1M=
diff --git a/src/Tasks.UnitTests/TestResources/mycert.pfx b/src/Tasks.UnitTests/TestResources/mycert.pfx
new file mode 100644
index 0000000000000000000000000000000000000000..2809e31eb9b2d0105099517be56ac4d2d382cb2c
GIT binary patch
literal 2590
zcmZXVc{tQv8^?dM7)Ho0OZJ@@+n6ZISVNSo)r6tpwUsTR)YwDzELmp6pe)&vWD5@l
zsYqq)JSO{+UGe^UuJ?VO>%HFVT=zNO`|~~bef~P#K3|lB7!#Wtth-3e$Vqu0rNksS|iU{9F2_cyOi^1k>
zaHjH`I#EKWxe-t(;|Dkq{*^|?!tin1Jdk}fen2*UJ~&ml6Ys0Pa3`=3t{60rEaS__
zti@w%C6J}^Y^{XY-eE#2n|Joq99?$6JFsK;v9^v%JTDW!jRo;zj77HbYAX35Zs4kP
zz{$_Q@U^2K>EWEJ4pw}-(Gx=^(HXBCzX$I~5Lhi+5P4PQEjp7#|r?=NMOZ=Hm>)
z`nutmVn=1`W|sl-8C@xj`#t53>P_4ky@1QwoKON$05(Z!>c|+n-RHm6SoKPIP-!%L
z|9Gh$SJdD)m<3LmG89w;F&5GrYX{WPy`3n(pu4t0Bn1EM;3Cuqa(?+0V_I
za-xkuFzWA94DjU1p`Oe9A$u%TUIh&eZl+fv;995Sx|NG*iO^_`mtnd5RBK#g{O-|V
z&3<-kbo<+k+Oi0xx_x}c~>=%dt#}wKRCxDC&ul|qppl&2E@u9
zG={TyLUJc}YXqYlRwdOxnMJ97cDtGtnfK9}8excy%AWC-@&Wt}v*R4oENLP^Y#j$w
zw-I3hX^H$tUa7+wPFaB-4eareN%gM?o=nU|q#rBQ_J)6&_^EER=)mWjJmiGB49ap0
z3oq>i>)o3!<2~TN2yMN;yKJ7uvNqDZ%2UdrcqWT=XwqM1Gk;k7im^*#kY)V$IL(r<
zuHckYXzynuFAVl7tOFUvc-p~G_il~oq
zMVWC1e)bh^X-tSJ;B#XeR8m+mYF|#ApADUssM31?J5dDFaOUpidKhxgo1!+UR(NL(
zQIPJU?IJkGk+FGC0d1doqkWqeVp6=l6IOO??phV@{;)K)LP>U0zTl!9ks#co)T5U{
zo`dDzjn811@lCA|5-o_YDx*W>JE^G-vv?F0Pv1cS^idFfVyx1!Ii{@kW_Dt+c2Af5jF78s=SYr56|HX6RP=30>`DO9h
zt5sey<|ocR(Z>xwIM@q#v$xBOgQ$KcZZToyw5rhQ#outES|46_fA1TC)@8r<%N7qV
zaXNchcTCmF{sq%?NN-!)iaTA}2-l*y)0g3C`LDIvyl~6O6xlkNsmTr%(`O1s2*?eXXR%?i#!;X#Vt
z`0`Vu7WYx{Kqc>-g2>S_(ts}ZwK@wPw!o<>s`=*t)j{FzgkPB>2}d1dJTA92W0bcc
zCs$DUJfZOs@;>hoF)DGV+t8N~wJ_=^W0Cu7>g6r;=k$+)z0qvnUJ-C>Vae0)L~3iq
z)=8($XXw7~RUXn%Tz@~8NFEgg91Z~h0CgRKR6s!B5TYgrM8#70B47@<19-p}@B#e5
zxC!_JqJR}R|0do50nD(V4hC+4%m>VU0Vhzq{Z%CjSpKyy5X@WvSHKtL`p=o%Dt5v)
z;D$iJ1GoZsfkj$idv$QA0ji+V1RI?K<0e>$0hKy{2Ao0XH&X+dI;eg-E+AC_i5j2*
zy3XK?M-gF_e;>q%AQ53C5amE20Jx<8<3RrZ1AvxhjtP#0sG#Y(}68m8>p7d;&}dqV@JCH8`Ml63e=4S&vU-|o!o
zKE+!d&q>je%wk=tvvpt%-pyrAgrx|CfebdMP_m}RrJSna8q#fW+8G6rCt6*AQK9OXO99!bz?;8{tOYMBhBXJQLqiRQ&oZjUe
zx**iz)noKNrSLX+>@bzi!CCuUICwQi(xWgch5r_Y>OOmW(T$H=mC?kYY?bJksK$i_|66o0_Y-58sShy)0NTX-w$tb`*1E
zd7ICkcA*MoD7GGGQ^KtO-BOeDPnUQByCduQ@v_~snR%j|ou)|wTvGN8N_I;-UT4dn
zPgXMt-z$9f$9wiFCoKc{uo)iA?Im`-W)0+*2C-*lwc2kZC>kWMwFA!x?3H&EH-^Td
zWv$?KvH6Yx=71H!Qw;f45??*u{*sA^JM7@H?X$Uk19E*rtbx3Wj3(r^tn=S3+7tO1
zelF!=MC|zxF4E?paZ&neicT<`Eqay<^eX`>Q%q9J=`F(!*k;=&xB+)~>#N_;cV)Q@2fL8a%F#~@GsMT~b;|CQTxP*M
zxBelPbh2DSF0p2%BVVM=)U04hmztn@P_M|lK9NNZXV7;Z+-LaXe%02pM^}T5-;cl(
zU4C|&pWuRY%z*KiE9+(~8+E5t9={Iw>6c!nAiW>ZIoH?{IdV(Eie;tTS1C`Q_Yd~a
zDH$Jp66EU9T+G9yC8;MED;wSGWodmPP5$-lsr%%ajd&^?rHv9nF(Mcg*kDirICsvC
vL;OPPY?1n6L+-eIi=rvnN)OJh{Pe|s?1osZlvZ_K!pWj;#l^k3-xu}Yc88c)
literal 0
HcmV?d00001
diff --git a/src/Tasks/ManifestUtil/mansign2.cs b/src/Tasks/ManifestUtil/mansign2.cs
index df887fcbd6c..da2308866d1 100644
--- a/src/Tasks/ManifestUtil/mansign2.cs
+++ b/src/Tasks/ManifestUtil/mansign2.cs
@@ -270,10 +270,14 @@ private void init()
Sha256SignatureMethodUri);
#if RUNTIME_TYPE_NETCORE
- CryptoConfig.AddAlgorithm(typeof(SHA256),
+#pragma warning disable SYSLIB0021 // Type or member is obsolete
+ // SHA256 can not be used since it is an abstract class.
+ // CalculateHashValue internally calls CryptoConfig.CreateFromName and it causes instantiation problems.
+ CryptoConfig.AddAlgorithm(typeof(SHA256Managed),
Sha256DigestMethod);
+#pragma warning restore SYSLIB0021 // Type or member is obsolete
#else
- CryptoConfig.AddAlgorithm(typeof(System.Security.Cryptography.SHA256Cng),
+ CryptoConfig.AddAlgorithm(typeof(SHA256Cng),
Sha256DigestMethod);
#endif
}