Esempio n. 1
0
        //
        // Either keyFile or keyContainer has to be non-null
        //
        void LoadPublicKey(string keyFile, string keyContainer)
        {
            if (keyContainer != null)
            {
                try {
                    private_key = new StrongNameKeyPair(keyContainer);
                    public_key  = private_key.PublicKey;
                } catch {
                    Error_AssemblySigning("The specified key container `" + keyContainer + "' does not exist");
                }

                return;
            }

            bool key_file_exists = File.Exists(keyFile);

            //
            // For attribute based KeyFile do additional lookup
            // in output assembly path
            //
            if (!key_file_exists && Compiler.Settings.StrongNameKeyFile == null)
            {
                //
                // The key file can be relative to output assembly
                //
                string test_path = Path.Combine(Path.GetDirectoryName(file_name), keyFile);
                key_file_exists = File.Exists(test_path);
                if (key_file_exists)
                {
                    keyFile = test_path;
                }
            }

            if (!key_file_exists)
            {
                Error_AssemblySigning("The specified key file `" + keyFile + "' does not exist");
                return;
            }

            using (FileStream fs = new FileStream(keyFile, FileMode.Open, FileAccess.Read)) {
                byte[] snkeypair = new byte[fs.Length];
                fs.Read(snkeypair, 0, snkeypair.Length);

                // check for ECMA key
                if (snkeypair.Length == 16)
                {
                    public_key = snkeypair;
                    return;
                }

                try {
                    // take it, with or without, a private key
                    RSA rsa = CryptoConvert.FromCapiKeyBlob(snkeypair);
                    // and make sure we only feed the public part to Sys.Ref
                    byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob(rsa);

                    // AssemblyName.SetPublicKey requires an additional header
                    byte[] publicKeyHeader = new byte[8] {
                        0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00
                    };

                    // Encode public key
                    public_key = new byte[12 + publickey.Length];
                    Buffer.BlockCopy(publicKeyHeader, 0, public_key, 0, publicKeyHeader.Length);

                    // Length of Public Key (in bytes)
                    int lastPart = public_key.Length - 12;
                    public_key[8]  = (byte)(lastPart & 0xFF);
                    public_key[9]  = (byte)((lastPart >> 8) & 0xFF);
                    public_key[10] = (byte)((lastPart >> 16) & 0xFF);
                    public_key[11] = (byte)((lastPart >> 24) & 0xFF);

                    Buffer.BlockCopy(publickey, 0, public_key, 12, publickey.Length);
                } catch {
                    Error_AssemblySigning("The specified key file `" + keyFile + "' has incorrect format");
                    return;
                }

                if (delay_sign)
                {
                    return;
                }

                try {
                    // TODO: Is there better way to test for a private key presence ?
                    CryptoConvert.FromCapiPrivateKeyBlob(snkeypair);
                    private_key = new StrongNameKeyPair(snkeypair);
                } catch { }
            }
        }
Esempio n. 2
0
        // TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way.
        public AssemblyName GetAssemblyName(string name, string output)
        {
            if (OptAttributes != null)
            {
                foreach (Attribute a in OptAttributes.Attrs)
                {
                    // cannot rely on any resolve-based members before you call Resolve
                    if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly")
                    {
                        continue;
                    }

                    // TODO: This code is buggy: comparing Attribute name without resolving is wrong.
                    //       However, this is invoked by CodeGen.Init, when none of the namespaces
                    //       are loaded yet.
                    // TODO: Does not handle quoted attributes properly
                    switch (a.Name)
                    {
                    case "AssemblyKeyFile":
                    case "AssemblyKeyFileAttribute":
                    case "System.Reflection.AssemblyKeyFileAttribute":
                        if (RootContext.StrongNameKeyFile != null)
                        {
                            Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError());
                            Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                           "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
                        }
                        else
                        {
                            string value = a.GetString();
                            if (value != null && value.Length != 0)
                            {
                                RootContext.StrongNameKeyFile = value;
                            }
                        }
                        break;

                    case "AssemblyKeyName":
                    case "AssemblyKeyNameAttribute":
                    case "System.Reflection.AssemblyKeyNameAttribute":
                        if (RootContext.StrongNameKeyContainer != null)
                        {
                            Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError());
                            Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                           "keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
                        }
                        else
                        {
                            string value = a.GetString();
                            if (value != null && value.Length != 0)
                            {
                                RootContext.StrongNameKeyContainer = value;
                            }
                        }
                        break;

                    case "AssemblyDelaySign":
                    case "AssemblyDelaySignAttribute":
                    case "System.Reflection.AssemblyDelaySignAttribute":
                        RootContext.StrongNameDelaySign = a.GetBoolean();
                        break;
                    }
                }
            }

            AssemblyName an = new AssemblyName();

            an.Name = Path.GetFileNameWithoutExtension(name);

            // note: delay doesn't apply when using a key container
            if (RootContext.StrongNameKeyContainer != null)
            {
                an.KeyPair = new StrongNameKeyPair(RootContext.StrongNameKeyContainer);
                return(an);
            }

            // strongname is optional
            if (RootContext.StrongNameKeyFile == null)
            {
                return(an);
            }

            string AssemblyDir = Path.GetDirectoryName(output);

            // the StrongName key file may be relative to (a) the compiled
            // file or (b) to the output assembly. See bugzilla #55320
            // http://bugzilla.ximian.com/show_bug.cgi?id=55320

            // (a) relative to the compiled file
            string filename = Path.GetFullPath(RootContext.StrongNameKeyFile);
            bool   exist    = File.Exists(filename);

            if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty))
            {
                // (b) relative to the outputed assembly
                filename = Path.GetFullPath(Path.Combine(AssemblyDir, RootContext.StrongNameKeyFile));
                exist    = File.Exists(filename);
            }

            if (exist)
            {
                using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
                    byte[] snkeypair = new byte [fs.Length];
                    fs.Read(snkeypair, 0, snkeypair.Length);

                    if (RootContext.StrongNameDelaySign)
                    {
                        // delayed signing - DO NOT include private key
                        SetPublicKey(an, snkeypair);
                    }
                    else
                    {
                        // no delay so we make sure we have the private key
                        try {
                            CryptoConvert.FromCapiPrivateKeyBlob(snkeypair);
                            an.KeyPair = new StrongNameKeyPair(snkeypair);
                        }
                        catch (CryptographicException) {
                            if (snkeypair.Length == 16)
                            {
                                // error # is different for ECMA key
                                Report.Error(1606, "Could not sign the assembly. " +
                                             "ECMA key can only be used to delay-sign assemblies");
                            }
                            else
                            {
                                Error_AssemblySigning("The specified file `" + RootContext.StrongNameKeyFile + "' does not have a private key");
                            }
                            return(null);
                        }
                    }
                }
            }
            else
            {
                Error_AssemblySigning("The specified file `" + RootContext.StrongNameKeyFile + "' does not exist");
                return(null);
            }
            return(an);
        }