提交 10660496 编写于 作者: V VSadov

Made compiler more robust in cases where signing services are not available.

There are cases where underlying platform does not provide signing services in the form that we consume. We need to be able to handle such cases gracefully without crashes.
***NO_CI***
 (changeset 1412127)
上级 a3b135d1
......@@ -152,6 +152,36 @@ public void PubKeyFromKeyFileAttribute_AssemblyKeyFileResolver_RelativeToCurrent
Assert.True(ByteSequenceComparer.Equals(s_publicKey, comp.Assembly.Identity.PublicKey));
}
[Fact]
public void SigningNotAvailable001()
{
string keyFileDir = Path.GetDirectoryName(s_keyPairFile);
string keyFileName = Path.GetFileName(s_keyPairFile);
string s = String.Format("{0}{1}{2}", @"[assembly: System.Reflection.AssemblyKeyFile(@""..\", keyFileName, @""")] public class C {}");
var syntaxTree = Parse(s, @"IVTAndStrongNameTests\AnotherTempDir\temp.cs");
// verify failure
var comp = CSharpCompilation.Create(
GetUniqueName(),
new[] { syntaxTree },
new[] { MscorlibRef },
TestOptions.ReleaseDll.WithStrongNameProvider(GetProviderWithPath(PathUtilities.CombineAbsoluteAndRelativePaths(keyFileDir, @"TempSubDir\"))));
var provider = (DesktopStrongNameProvider)comp.Options.StrongNameProvider;
provider.alternativeGetStrongNameInterface = () =>
{
throw new DllNotFoundException("aaa.dll not found.");
};
comp.VerifyEmitDiagnostics(
// error CS7027: Error signing output with public key from file '..\KeyPair_6187d0d6-f691-47fd-985b-03570bc0668d.snk' -- aaa.dll not found.
Diagnostic(ErrorCode.ERR_PublicKeyFileFailure).WithArguments("..\\" + keyFileName, "aaa.dll not found.").WithLocation(1, 1)
);
}
[Fact]
public void PubKeyFromKeyContainerAttribute()
{
......
......@@ -161,7 +161,7 @@ private void ReadKeysFromContainer(string keyContainer, out ImmutableArray<byte>
{
publicKey = GetPublicKey(keyContainer);
}
catch (COMException ex)
catch (Exception ex)
{
throw new IOException(ex.Message);
}
......@@ -173,12 +173,6 @@ private void ReadKeysFromPath(string fullPath, out ImmutableArray<byte> keyPair,
try
{
fileContent = ReadAllBytes(fullPath);
}
catch (Exception ex)
{
throw new IOException(ex.Message);
}
if (IsPublicKeyBlob(fileContent))
{
publicKey = ImmutableArray.CreateRange(fileContent);
......@@ -190,6 +184,11 @@ private void ReadKeysFromPath(string fullPath, out ImmutableArray<byte> keyPair,
keyPair = ImmutableArray.CreateRange(fileContent);
}
}
catch (Exception ex)
{
throw new IOException(ex.Message);
}
}
/// <exception cref="IOException"></exception>
internal override void SignAssembly(StrongNameKeys keys, Stream inputStream, Stream outputStream)
......@@ -230,14 +229,17 @@ internal override void SignAssembly(StrongNameKeys keys, Stream inputStream, Str
private static Guid s_CLSID_CLRStrongName =
new Guid(0xB79B0ACD, 0xF5CD, 0x409b, 0xB5, 0xA5, 0xA1, 0x62, 0x44, 0x61, 0x0B, 0x92);
// for testing/mocking
internal Func<ICLRStrongName> alternativeGetStrongNameInterface;
// internal for testing
internal static ICLRStrongName GetStrongNameInterface()
internal ICLRStrongName GetStrongNameInterface()
{
return ClrMetaHost.CurrentRuntime.GetInterface<ICLRStrongName>(s_CLSID_CLRStrongName);
return alternativeGetStrongNameInterface?.Invoke() ?? ClrMetaHost.CurrentRuntime.GetInterface<ICLRStrongName>(s_CLSID_CLRStrongName);
}
// internal for testing
internal static ImmutableArray<byte> GetPublicKey(string keyContainer)
internal ImmutableArray<byte> GetPublicKey(string keyContainer)
{
ICLRStrongName strongName = GetStrongNameInterface();
......@@ -289,7 +291,7 @@ internal static unsafe bool IsPublicKeyBlob(byte[] keyFileContents)
// internal for testing
/// <exception cref="IOException"/>
internal static ImmutableArray<byte> GetPublicKey(byte[] keyFileContents)
internal ImmutableArray<byte> GetPublicKey(byte[] keyFileContents)
{
try
{
......@@ -308,16 +310,9 @@ internal static ImmutableArray<byte> GetPublicKey(byte[] keyFileContents)
unsafe
{
fixed (byte* p = keyFileContents)
{
try
{
strongName.StrongNameGetPublicKey(null, (IntPtr)p, keyFileContents.Length, out keyBlob, out keyBlobByteCount);
}
catch (ArgumentException ex)
{
throw new IOException(ex.Message);
}
}
}
byte[] pubKey = new byte[keyBlobByteCount];
......@@ -329,51 +324,14 @@ internal static ImmutableArray<byte> GetPublicKey(byte[] keyFileContents)
return result;
}
catch (COMException ex)
catch (Exception ex)
{
throw new IOException(ex.Message);
}
}
/* leave this out for now. We'll make the command line compilers have this behavior, but
* not the compiler library. This differs from previous versions because specifying a keyfile
* and container through either the command line or attributes gave this "install the key" behavior.
*
*
//EDMAURER alink had weird, MSDN spec'd behavior. from MSDN "In case both /keyfile and /keycontainer are
//specified (either by command-line option or by custom attribute) in the same compilation, the compiler
//first tries the key container. If that succeeds, then the assembly is signed with the information in the
//key container. If the compiler does not find the key container, it tries the file specified with /keyfile.
//If this succeeds, the assembly is signed with the information in the key file, and the key information is
//installed in the key container (similar to sn -i) so that on the next compilation, the key container will
//be valid.
private static ImmutableArray<byte> GetPublicKeyAndPossiblyInstall(string keyFilename, string keyContainer)
{
if (keyContainer != null)
{
ImmutableArray<byte> result = GetPublicKey(keyContainer);
if (result.IsNotNull)
return result;
}
if (keyFilename != null)
{
byte[] keyFileContents = System.IO.File.ReadAllBytes(keyFilename);
if (keyContainer != null)
InstallKey(keyFileContents, keyFilename);
return GetPublicKey(keyFileContents);
}
return default(ImmutableArray<byte>);
}
*/
/// <exception cref="IOException"/>
private static void Sign(string filePath, string keyName)
private void Sign(string filePath, string keyName)
{
try
{
......@@ -382,14 +340,14 @@ private static void Sign(string filePath, string keyName)
int unused;
strongName.StrongNameSignatureGeneration(filePath, keyName, IntPtr.Zero, 0, null, out unused);
}
catch (COMException ex)
catch (Exception ex)
{
throw new IOException(ex.Message, ex);
}
}
/// <exception cref="IOException"/>
private static unsafe void Sign(string filePath, ImmutableArray<byte> keyPair)
private unsafe void Sign(string filePath, ImmutableArray<byte> keyPair)
{
try
{
......@@ -401,7 +359,7 @@ private static unsafe void Sign(string filePath, ImmutableArray<byte> keyPair)
strongName.StrongNameSignatureGeneration(filePath, null, (IntPtr)pinned, keyPair.Length, null, out unused);
}
}
catch (COMException ex)
catch (Exception ex)
{
throw new IOException(ex.Message, ex);
}
......
......@@ -22,7 +22,7 @@ internal static class SigningTestHelpers
private static bool keyInstalled;
internal const string TestContainerName = "RoslynTestContainer";
internal static readonly ImmutableArray<byte> PublicKey = DesktopStrongNameProvider.GetPublicKey(TestResources.SymbolsTests.General.snKey);
internal static readonly ImmutableArray<byte> PublicKey = new DesktopStrongNameProvider().GetPublicKey(TestResources.SymbolsTests.General.snKey);
// Modifies machine wide state.
internal unsafe static void InstallKey()
......@@ -38,7 +38,7 @@ private unsafe static void InstallKey(byte[] keyBlob, string keyName)
{
try
{
ICLRStrongName strongName = DesktopStrongNameProvider.GetStrongNameInterface();
ICLRStrongName strongName = new DesktopStrongNameProvider().GetStrongNameInterface();
//EDMAURER use marshal to be safe?
fixed (byte* p = keyBlob)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册