Beispiel #1
0
        private bool Decode(byte[] pvk, string password)
        {
            if (BitConverterLE.ToUInt32(pvk, 0) != 2964713758u)
            {
                return(false);
            }
            if (BitConverterLE.ToUInt32(pvk, 4) != 0u)
            {
                return(false);
            }
            this.keyType   = BitConverterLE.ToInt32(pvk, 8);
            this.encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1u);
            int num  = BitConverterLE.ToInt32(pvk, 16);
            int num2 = BitConverterLE.ToInt32(pvk, 20);

            byte[] array = new byte[num2];
            Buffer.BlockCopy(pvk, 24 + num, array, 0, num2);
            if (num > 0)
            {
                if (password == null)
                {
                    return(false);
                }
                byte[] array2 = new byte[num];
                Buffer.BlockCopy(pvk, 24, array2, 0, num);
                byte[]           array3          = this.DeriveKey(array2, password);
                RC4              rc              = RC4.Create();
                ICryptoTransform cryptoTransform = rc.CreateDecryptor(array3, null);
                cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                try
                {
                    this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(array);
                    this.weak = false;
                }
                catch (CryptographicException)
                {
                    this.weak = true;
                    Buffer.BlockCopy(pvk, 24 + num, array, 0, num2);
                    Array.Clear(array3, 5, 11);
                    RC4 rc2 = RC4.Create();
                    cryptoTransform = rc2.CreateDecryptor(array3, null);
                    cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                    this.rsa = CryptoConvert.FromCapiPrivateKeyBlob(array);
                }
                Array.Clear(array3, 0, array3.Length);
            }
            else
            {
                this.weak = true;
                this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(array);
                Array.Clear(array, 0, array.Length);
            }
            Array.Clear(pvk, 0, pvk.Length);
            return(this.rsa != null);
        }
Beispiel #2
0
        private void SetKeyPair(AssemblyName aname)
        {
            if (keyfile != null)
            {
                if (!File.Exists(keyfile))
                {
                    Report(1044, String.Format("Couldn't open '{0}' key file.", keyfile));
                }

                using (FileStream fs = File.OpenRead(keyfile)) {
                    byte[] data = new byte [fs.Length];
                    try {
                        fs.Read(data, 0, data.Length);

                        if (delaysign == DelaySign.Yes)
                        {
                            SetPublicKey(aname, data);
                        }
                        else
                        {
                            CryptoConvert.FromCapiPrivateKeyBlob(data);
                            aname.KeyPair = new StrongNameKeyPair(data);
                        }
                    }
                    catch (CryptographicException) {
                        if (delaysign != DelaySign.Yes)
                        {
                            if (data.Length == 16)
                            {
                                // error # is different for ECMA key
                                Report(1019, "Could not strongname the assembly. " +
                                       "ECMA key can only be used to delay-sign assemblies");
                            }
                            else
                            {
                                Report(1028, String.Format("Key file {0}' is missing it's private key " +
                                                           "or couldn't be decoded.", keyfile));
                            }
                        }
                        else
                        {
                            Report(1044, String.Format("Couldn't decode '{0}' key file.", keyfile));
                        }
                    }
                    fs.Close();
                }
            }
            else if (keyname != null)
            {
                // delay-sign doesn't apply to key containers
                aname.KeyPair = new StrongNameKeyPair(keyname);
            }
        }
Beispiel #3
0
        private bool Decode(byte[] pvk, string password)
        {
            if (BitConverterLE.ToUInt32(pvk, 0) != 2964713758U || BitConverterLE.ToUInt32(pvk, 4) != 0U)
            {
                return(false);
            }
            this.keyType   = BitConverterLE.ToInt32(pvk, 8);
            this.encrypted = BitConverterLE.ToUInt32(pvk, 12) == 1U;
            int int32_1 = BitConverterLE.ToInt32(pvk, 16);
            int int32_2 = BitConverterLE.ToInt32(pvk, 20);

            byte[] numArray = new byte[int32_2];
            Buffer.BlockCopy((Array)pvk, 24 + int32_1, (Array)numArray, 0, int32_2);
            if (int32_1 > 0)
            {
                if (password == null)
                {
                    return(false);
                }
                byte[] salt = new byte[int32_1];
                Buffer.BlockCopy((Array)pvk, 24, (Array)salt, 0, int32_1);
                byte[] rgbKey = this.DeriveKey(salt, password);
                RC4.Create().CreateDecryptor(rgbKey, (byte[])null).TransformBlock(numArray, 8, numArray.Length - 8, numArray, 8);
                try
                {
                    this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                    this.weak = false;
                }
                catch (CryptographicException)
                {
                    this.weak = true;
                    Buffer.BlockCopy((Array)pvk, 24 + int32_1, (Array)numArray, 0, int32_2);
                    Array.Clear((Array)rgbKey, 5, 11);
                    RC4.Create().CreateDecryptor(rgbKey, (byte[])null).TransformBlock(numArray, 8, numArray.Length - 8, numArray, 8);
                    this.rsa = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                }
                Array.Clear((Array)rgbKey, 0, rgbKey.Length);
            }
            else
            {
                this.weak = true;
                this.rsa  = CryptoConvert.FromCapiPrivateKeyBlob(numArray);
                Array.Clear((Array)numArray, 0, numArray.Length);
            }
            Array.Clear((Array)pvk, 0, pvk.Length);
            return(this.rsa != null);
        }
        private bool Decode(byte[] pvk, string password)
        {
            // DWORD magic
            if (BitConverterLE.ToUInt32(pvk, 0) != magic)
            {
                return(false);
            }
            // DWORD reserved
            if (BitConverterLE.ToUInt32(pvk, 4) != 0x0)
            {
                return(false);
            }
            // DWORD keytype
            keyType = BitConverterLE.ToInt32(pvk, 8);
            // DWORD encrypted
            encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1);
            // DWORD saltlen
            int saltlen = BitConverterLE.ToInt32(pvk, 16);
            // DWORD keylen
            int keylen = BitConverterLE.ToInt32(pvk, 20);

            byte[] keypair = new byte [keylen];
            Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
            // read salt (if present)
            if (saltlen > 0)
            {
                if (password == null)
                {
                    return(false);
                }

                byte[] salt = new byte [saltlen];
                Buffer.BlockCopy(pvk, 24, salt, 0, saltlen);
                // first try with full (128) bits
                byte[] key = DeriveKey(salt, password);
                // decrypt in place and try this
                RC4 rc4 = RC4.Create();
                ICryptoTransform dec = rc4.CreateDecryptor(key, null);
                dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                try
                {
                    rsa  = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                    weak = false;
                }
                catch (CryptographicException)
                {
                    weak = true;
                    // second chance using weak crypto
                    Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
                    // truncate the key to 40 bits
                    Array.Clear(key, 5, 11);
                    // decrypt
                    RC4 rc4b = RC4.Create();
                    dec = rc4b.CreateDecryptor(key, null);
                    dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                    rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                }
                Array.Clear(key, 0, key.Length);
            }
            else
            {
                weak = true;
                // read unencrypted keypair
                rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                Array.Clear(keypair, 0, keypair.Length);
            }

            // zeroize pvk (which could contain the unencrypted private key)
            Array.Clear(pvk, 0, pvk.Length);

            return(rsa != null);
        }
Beispiel #5
0
 public void FromCapiPrivateKeyBlob_Invalid()
 {
     RSA rsa = CryptoConvert.FromCapiPrivateKeyBlob(strongNamePublicKey, 12);
 }
Beispiel #6
0
 public void FromCapiPrivateKeyBlob_InvalidOffset()
 {
     RSA rsa = CryptoConvert.FromCapiPrivateKeyBlob(new byte [0], 0);
 }
Beispiel #7
0
 public void FromCapiPrivateKeyBlob_Null()
 {
     RSA rsa = CryptoConvert.FromCapiPrivateKeyBlob(null);
 }
Beispiel #8
0
        public void FromCapiPrivateKeyBlob()
        {
            RSA rsa = CryptoConvert.FromCapiPrivateKeyBlob(strongName, 0);

            Assert.AreEqual(strongNameString, rsa.ToXmlString(true), "KeyPair");
        }
        //
        // 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 { }
            }
        }