diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs b/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs index 6461f23b0892c94b125653d9ea0d6a7714dc2190..e00df4164c2033bc3fc2cb503f171413cfebb23c 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.cs @@ -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() { diff --git a/src/Compilers/Core/Desktop/DesktopStrongNameProvider.cs b/src/Compilers/Core/Desktop/DesktopStrongNameProvider.cs index 5fce2b88b45e91b01f199947c2b5bf207259fc38..6916ece855c41bca08707f11ed1dfee5e8a1eb30 100644 --- a/src/Compilers/Core/Desktop/DesktopStrongNameProvider.cs +++ b/src/Compilers/Core/Desktop/DesktopStrongNameProvider.cs @@ -161,7 +161,7 @@ private void ReadKeysFromContainer(string keyContainer, out ImmutableArray { publicKey = GetPublicKey(keyContainer); } - catch (COMException ex) + catch (Exception ex) { throw new IOException(ex.Message); } @@ -173,22 +173,21 @@ private void ReadKeysFromPath(string fullPath, out ImmutableArray keyPair, try { fileContent = ReadAllBytes(fullPath); + if (IsPublicKeyBlob(fileContent)) + { + publicKey = ImmutableArray.CreateRange(fileContent); + keyPair = default(ImmutableArray); + } + else + { + publicKey = GetPublicKey(fileContent); + keyPair = ImmutableArray.CreateRange(fileContent); + } } catch (Exception ex) { throw new IOException(ex.Message); } - - if (IsPublicKeyBlob(fileContent)) - { - publicKey = ImmutableArray.CreateRange(fileContent); - keyPair = default(ImmutableArray); - } - else - { - publicKey = GetPublicKey(fileContent); - keyPair = ImmutableArray.CreateRange(fileContent); - } } /// @@ -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 alternativeGetStrongNameInterface; + // internal for testing - internal static ICLRStrongName GetStrongNameInterface() + internal ICLRStrongName GetStrongNameInterface() { - return ClrMetaHost.CurrentRuntime.GetInterface(s_CLSID_CLRStrongName); + return alternativeGetStrongNameInterface?.Invoke() ?? ClrMetaHost.CurrentRuntime.GetInterface(s_CLSID_CLRStrongName); } - // internal for testing - internal static ImmutableArray GetPublicKey(string keyContainer) + internal ImmutableArray GetPublicKey(string keyContainer) { ICLRStrongName strongName = GetStrongNameInterface(); @@ -289,7 +291,7 @@ internal static unsafe bool IsPublicKeyBlob(byte[] keyFileContents) // internal for testing /// - internal static ImmutableArray GetPublicKey(byte[] keyFileContents) + internal ImmutableArray GetPublicKey(byte[] keyFileContents) { try { @@ -309,14 +311,7 @@ internal static ImmutableArray GetPublicKey(byte[] keyFileContents) { fixed (byte* p = keyFileContents) { - try - { - strongName.StrongNameGetPublicKey(null, (IntPtr)p, keyFileContents.Length, out keyBlob, out keyBlobByteCount); - } - catch (ArgumentException ex) - { - throw new IOException(ex.Message); - } + strongName.StrongNameGetPublicKey(null, (IntPtr)p, keyFileContents.Length, out keyBlob, out keyBlobByteCount); } } @@ -329,51 +324,14 @@ internal static ImmutableArray 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 GetPublicKeyAndPossiblyInstall(string keyFilename, string keyContainer) - { - if (keyContainer != null) - { - ImmutableArray 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); - } - */ - /// - 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); } } /// - private static unsafe void Sign(string filePath, ImmutableArray keyPair) + private unsafe void Sign(string filePath, ImmutableArray keyPair) { try { @@ -401,7 +359,7 @@ private static unsafe void Sign(string filePath, ImmutableArray keyPair) strongName.StrongNameSignatureGeneration(filePath, null, (IntPtr)pinned, keyPair.Length, null, out unused); } } - catch (COMException ex) + catch (Exception ex) { throw new IOException(ex.Message, ex); } diff --git a/src/Test/Utilities/SigningTestHelpers.cs b/src/Test/Utilities/SigningTestHelpers.cs index 19ec34e54a37a5efdee39b6926ce6672e8f374db..357bcdf201ebf4e24dbab71f9b2f8991bae95592 100644 --- a/src/Test/Utilities/SigningTestHelpers.cs +++ b/src/Test/Utilities/SigningTestHelpers.cs @@ -22,7 +22,7 @@ internal static class SigningTestHelpers private static bool keyInstalled; internal const string TestContainerName = "RoslynTestContainer"; - internal static readonly ImmutableArray PublicKey = DesktopStrongNameProvider.GetPublicKey(TestResources.SymbolsTests.General.snKey); + internal static readonly ImmutableArray 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)