diff options
author | Sebastien Pouliot <sebastien@ximian.com> | 2004-04-22 23:33:27 +0400 |
---|---|---|
committer | Sebastien Pouliot <sebastien@ximian.com> | 2004-04-22 23:33:27 +0400 |
commit | c1b45e55404ccd4fb98c905d72db491b1944c04d (patch) | |
tree | e3e8406b917ddae35abe17ca35469712364c012d /mcs/class | |
parent | 24ab78f95891c14353bbffdcbac8899dc36d67d4 (diff) |
2004-04-22 Sebastien Pouliot <sebastien@ximian.com>
* CryptoConvert.cs: FxCop-ized. Sealed class. Use Buffer.BlockCopy.
* CryptoTools.cs: FxCop-ized. Sealed KeyBuilder class. Delay creation
of RNG object. Use Buffer.BlockCopy.
* DiffieHellman.cs: FxCop-ized. Removed public constructor.
* DiffieHellmanManaged.cs: FxCop-ized. Actualized with changes from
BigInteger.
* KeyPairPersistance.cs: FxCop-ized. Updated version for management
of keypairs.
* MD2Managed.cs: Use Buffer.BlockCopy instead of Array.Copy.
* PKCS1.cs: FxCop-ized. Sealed class. Use Buffer.BlockCopy instead of
Array.Copy. Also includes endian patches from Bernie Solomon.
* PKCS8.cs: FxCop-ized. Sealed class.
* RSAManaged.cs: FxCop-ized. Actualized with changes from BigInteger.
* SymmetricTransform.cs: Use Buffer.BlockCopy instead of Array.Copy.
svn path=/trunk/mcs/; revision=25859
Diffstat (limited to 'mcs/class')
11 files changed, 348 insertions, 186 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Cryptography/ChangeLog index b4e7165c274..d2c368d0121 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/ChangeLog +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/ChangeLog @@ -1,3 +1,20 @@ +2004-04-22 Sebastien Pouliot <sebastien@ximian.com> + + * CryptoConvert.cs: FxCop-ized. Sealed class. Use Buffer.BlockCopy. + * CryptoTools.cs: FxCop-ized. Sealed KeyBuilder class. Delay creation + of RNG object. Use Buffer.BlockCopy. + * DiffieHellman.cs: FxCop-ized. Removed public constructor. + * DiffieHellmanManaged.cs: FxCop-ized. Actualized with changes from + BigInteger. + * KeyPairPersistance.cs: FxCop-ized. Updated version for management + of keypairs. + * MD2Managed.cs: Use Buffer.BlockCopy instead of Array.Copy. + * PKCS1.cs: FxCop-ized. Sealed class. Use Buffer.BlockCopy instead of + Array.Copy. Also includes endian patches from Bernie Solomon. + * PKCS8.cs: FxCop-ized. Sealed class. + * RSAManaged.cs: FxCop-ized. Actualized with changes from BigInteger. + * SymmetricTransform.cs: Use Buffer.BlockCopy instead of Array.Copy. + 2004-04-20 Sebastien Pouliot <sebastien@ximian.com> * CryptoConvert.cs: Synched with corlib version to get endian fixes diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs index f333854b9e2..70fb9fe4a81 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs @@ -9,6 +9,7 @@ // using System; +using System.Globalization; using System.Security.Cryptography; using System.Text; @@ -19,7 +20,11 @@ namespace Mono.Security.Cryptography { #else public #endif - class CryptoConvert { + sealed class CryptoConvert { + + private CryptoConvert () + { + } static private int ToInt32LE (byte [] bytes, int offset) { @@ -46,7 +51,7 @@ namespace Mono.Security.Cryptography { for (int i=0; i < array.Length; i++) { if (array [i] != 0x00) { byte[] result = new byte [array.Length - i]; - Array.Copy (array, i, result, 0, result.Length); + Buffer.BlockCopy (array, i, result, 0, result.Length); return result; } } @@ -85,7 +90,7 @@ namespace Mono.Security.Cryptography { // DWORD public exponent RSAParameters rsap = new RSAParameters (); byte[] exp = new byte [4]; - Array.Copy (blob, offset+16, exp, 0, 4); + Buffer.BlockCopy (blob, offset+16, exp, 0, 4); Array.Reverse (exp); rsap.Exponent = Trim (exp); @@ -93,44 +98,44 @@ namespace Mono.Security.Cryptography { // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; - Array.Copy (blob, pos, rsap.Modulus, 0, byteLen); + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); pos += byteLen; // BYTE prime1[rsapubkey.bitlen/16]; int byteHalfLen = (byteLen >> 1); rsap.P = new byte [byteHalfLen]; - Array.Copy (blob, pos, rsap.P, 0, byteHalfLen); + Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); Array.Reverse (rsap.P); pos += byteHalfLen; // BYTE prime2[rsapubkey.bitlen/16]; rsap.Q = new byte [byteHalfLen]; - Array.Copy (blob, pos, rsap.Q, 0, byteHalfLen); + Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); Array.Reverse (rsap.Q); pos += byteHalfLen; // BYTE exponent1[rsapubkey.bitlen/16]; rsap.DP = new byte [byteHalfLen]; - Array.Copy (blob, pos, rsap.DP, 0, byteHalfLen); + Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); Array.Reverse (rsap.DP); pos += byteHalfLen; // BYTE exponent2[rsapubkey.bitlen/16]; rsap.DQ = new byte [byteHalfLen]; - Array.Copy (blob, pos, rsap.DQ, 0, byteHalfLen); + Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); Array.Reverse (rsap.DQ); pos += byteHalfLen; // BYTE coefficient[rsapubkey.bitlen/16]; rsap.InverseQ = new byte [byteHalfLen]; - Array.Copy (blob, pos, rsap.InverseQ, 0, byteHalfLen); + Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); Array.Reverse (rsap.InverseQ); pos += byteHalfLen; // BYTE privateExponent[rsapubkey.bitlen/8]; rsap.D = new byte [byteLen]; - Array.Copy (blob, pos, rsap.D, 0, byteLen); + Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); Array.Reverse (rsap.D); RSA rsa = (RSA)RSA.Create (); @@ -173,43 +178,43 @@ namespace Mono.Security.Cryptography { byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; // private key part = p.P; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.Q; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DP; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DQ; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.InverseQ; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.D; len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); return blob; } @@ -251,7 +256,7 @@ namespace Mono.Security.Cryptography { // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; - Array.Copy (blob, pos, rsap.Modulus, 0, byteLen); + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); RSA rsa = (RSA)RSA.Create (); @@ -294,7 +299,7 @@ namespace Mono.Security.Cryptography { byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); - Array.Copy (part, 0, blob, pos, len); + Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; return blob; } @@ -360,7 +365,7 @@ namespace Mono.Security.Cryptography { StringBuilder sb = new StringBuilder (input.Length * 2); foreach (byte b in input) { - sb.Append (b.ToString ("X2")); + sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); } return sb.ToString (); } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoTools.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoTools.cs index 111b875728c..4bcecdf8171 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoTools.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoTools.cs @@ -3,9 +3,10 @@ // Shared class for common cryptographic functionalities // // Authors: -// Sebastien Pouliot (spouliot@motus.com) +// Sebastien Pouliot <sebastien@ximian.com> // // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) // using System; @@ -18,17 +19,19 @@ namespace Mono.Security.Cryptography { #else public #endif - class KeyBuilder { + sealed class KeyBuilder { static private RandomNumberGenerator rng; - - static KeyBuilder () + + private KeyBuilder () { - rng = RandomNumberGenerator.Create (); } static public byte[] Key (int size) { + if (rng == null) + rng = RandomNumberGenerator.Create (); + byte[] key = new byte [size]; rng.GetBytes (key); return key; @@ -36,6 +39,9 @@ namespace Mono.Security.Cryptography { static public byte[] IV (int size) { + if (rng == null) + rng = RandomNumberGenerator.Create (); + byte[] iv = new byte [size]; rng.GetBytes (iv); return iv; @@ -87,7 +93,7 @@ namespace Mono.Security.Cryptography { { // 1. fill the rest of the "block" int n = System.Math.Min (blockSize - blockCount, cb); - Array.Copy (rgb, ib, block, blockCount, n); + Buffer.BlockCopy (rgb, ib, block, blockCount, n); blockCount += n; // 2. if block is full then transform it @@ -104,7 +110,7 @@ namespace Mono.Security.Cryptography { // 4. if data is still present fill the "block" with the remainder blockCount = cb - n; if (blockCount > 0) - Array.Copy (rgb, n, block, 0, blockCount); + Buffer.BlockCopy (rgb, n, block, 0, blockCount); } } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellman.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellman.cs index e568ed6de5e..f7ab3533243 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellman.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellman.cs @@ -36,11 +36,6 @@ namespace Mono.Security.Cryptography { } /// <summary> - /// Initializes a new <see cref="DiffieHellman"/> instance. - /// </summary> - public DiffieHellman() {} - - /// <summary> /// When overridden in a derived class, creates the key exchange data. /// </summary> /// <returns>The key exchange data to be sent to the intended recipient.</returns> @@ -48,9 +43,9 @@ namespace Mono.Security.Cryptography { /// <summary> /// When overridden in a derived class, extracts secret information from the key exchange data. /// </summary> - /// <param name="keyEx">The key exchange data within which the secret information is hidden.</param> + /// <param name="keyex">The key exchange data within which the secret information is hidden.</param> /// <returns>The secret information derived from the key exchange data.</returns> - public abstract byte[] DecryptKeyExchange(byte[] keyEx); + public abstract byte[] DecryptKeyExchange (byte[] keyex); /// <summary> /// When overridden in a derived class, exports the <see cref="DHParameters"/>. diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellmanManaged.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellmanManaged.cs index 85689b5b753..e3de3deeee1 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellmanManaged.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/DiffieHellmanManaged.cs @@ -27,16 +27,16 @@ namespace Mono.Security.Cryptography { /// <summary> /// Initializes a new <see cref="DiffieHellmanManaged"/> instance. /// </summary> - /// <param name="bitlen">The length, in bits, of the public P parameter.</param> + /// <param name="bitLength">The length, in bits, of the public P parameter.</param> /// <param name="l">The length, in bits, of the secret value X. This parameter can be set to 0 to use the default size.</param> - /// <param name="keygen">One of the <see cref="DHKeyGeneration"/> values.</param> + /// <param name="method">One of the <see cref="DHKeyGeneration"/> values.</param> /// <remarks>The larger the bit length, the more secure the algorithm is. The default is 1024 bits. The minimum bit length is 128 bits.<br/>The size of the private value will be one fourth of the bit length specified.</remarks> /// <exception cref="ArgumentException">The specified bit length is invalid.</exception> - public DiffieHellmanManaged(int bitlen, int l, DHKeyGeneration keygen) { - if (bitlen < 256 || l < 0) + public DiffieHellmanManaged(int bitLength, int l, DHKeyGeneration method) { + if (bitLength < 256 || l < 0) throw new ArgumentException(); BigInteger p, g; - GenerateKey(bitlen, keygen, out p, out g); + GenerateKey (bitLength, method, out p, out g); Initialize(p, g, null, l, false); } /// <summary> @@ -75,19 +75,19 @@ namespace Mono.Security.Cryptography { // initializes the private variables (throws CryptographicException) private void Initialize(BigInteger p, BigInteger g, BigInteger x, int secretLen, bool checkInput) { if (checkInput) { - if (!p.isProbablePrime() || g <= 0 || g >= p || (x != null && (x <= 0 || x > p - 2))) + if (!p.IsProbablePrime() || g <= 0 || g >= p || (x != null && (x <= 0 || x > p - 2))) throw new CryptographicException(); } // default is to generate a number as large as the prime this // is usually overkill, but it's the most secure thing we can // do if the user doesn't specify a desired secret length ... if (secretLen == 0) - secretLen = p.bitCount(); + secretLen = p.BitCount(); m_P = p; m_G = g; if (x == null) { BigInteger pm1 = m_P - 1; - for(m_X = BigInteger.genRandom(secretLen); m_X >= pm1 || m_X == 0; m_X = BigInteger.genRandom(secretLen)) {} + for(m_X = BigInteger.GenerateRandom(secretLen); m_X >= pm1 || m_X == 0; m_X = BigInteger.GenerateRandom(secretLen)) {} } else { m_X = x; } @@ -97,8 +97,8 @@ namespace Mono.Security.Cryptography { /// </summary> /// <returns>The key exchange data to be sent to the intended recipient.</returns> public override byte[] CreateKeyExchange() { - BigInteger y = m_G.modPow(m_X, m_P); - byte[] ret = y.getBytes(); + BigInteger y = m_G.ModPow(m_X, m_P); + byte[] ret = y.GetBytes(); y.Clear(); return ret; } @@ -109,8 +109,8 @@ namespace Mono.Security.Cryptography { /// <returns>The shared key derived from the key exchange data.</returns> public override byte[] DecryptKeyExchange(byte[] keyEx) { BigInteger pvr = new BigInteger(keyEx); - BigInteger z = pvr.modPow(m_X, m_P); - byte[] ret = z.getBytes(); + BigInteger z = pvr.ModPow(m_X, m_P); + byte[] ret = z.GetBytes(); z.Clear(); return ret; } @@ -148,10 +148,10 @@ namespace Mono.Security.Cryptography { /// <returns>The parameters for <see cref="DiffieHellman"/>.</returns> public override DHParameters ExportParameters(bool includePrivateParameters) { DHParameters ret = new DHParameters(); - ret.P = m_P.getBytes(); - ret.G = m_G.getBytes(); + ret.P = m_P.GetBytes(); + ret.G = m_G.GetBytes(); if (includePrivateParameters) { - ret.X = m_X.getBytes(); + ret.X = m_X.GetBytes(); } return ret; } @@ -197,7 +197,7 @@ namespace Mono.Security.Cryptography { // 4. If g = 1 go to step 2 // BigInteger j = (p - 1) / q; } else { // random - p = BigInteger.genPseudoPrime(bitlen); + p = BigInteger.GeneratePseudoPrime(bitlen); g = new BigInteger(3); // always use 3 as a generator } } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs index 51345cfaef3..b2f6aeb3795 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs @@ -8,7 +8,9 @@ // using System; +using System.Globalization; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; @@ -48,8 +50,10 @@ namespace Mono.Security.Cryptography { /* NOTES * * - There's NO confidentiality / integrity built in this - * persistance mechanism. You better protect your directories - * ACL correctly! + * persistance mechanism. The container directories (both user and + * machine) are created with restrited ACL. The ACL is also checked + * when a key is accessed (so totally public keys won't be used). + * see /mono/mono/metadata/security.c for implementation * * - As we do not use CSP we limit ourselves to provider types (not * names). This means that for a same type and container type, but @@ -65,13 +69,7 @@ namespace Mono.Security.Cryptography { * * - You CAN'T changes properties of the keypair once it's been * created (saved). You must remove the container than save it - * back. This is the same behaviour as windows. - */ - - /* TODO - * - * - Where do we store the machine keys ? - * - zeroize _keyvalue before setting to null !!! + * back. This is the same behaviour as CSP under Windows. */ #if INSIDE_CORLIB @@ -80,9 +78,12 @@ namespace Mono.Security.Cryptography { public #endif class KeyPairPersistence { - - private static bool _pathExists = false; // check at 1st use - private static string _path; + + private static bool _userPathExists = false; // check at 1st use + private static string _userPath; + + private static bool _machinePathExists = false; // check at 1st use + private static string _machinePath; private CspParameters _params; private string _keyvalue; @@ -92,20 +93,17 @@ namespace Mono.Security.Cryptography { // constructors public KeyPairPersistence (CspParameters parameters) - : this (parameters, null) {} + : this (parameters, null) + { + } - public KeyPairPersistence (CspParameters parameters, string keypair) + public KeyPairPersistence (CspParameters parameters, string keyPair) { if (parameters == null) throw new ArgumentNullException ("parameters"); _params = Copy (parameters); - _keyvalue = keypair; - } - - ~KeyPairPersistence () - { - Clear (); + _keyvalue = keyPair; } // properties @@ -113,11 +111,15 @@ namespace Mono.Security.Cryptography { public string Filename { get { if (_filename == null) { - _filename = String.Format ("[{0}][{1}][{2}].xml", + _filename = String.Format (CultureInfo.InvariantCulture, + "[{0}][{1}][{2}].xml", _params.ProviderType, this.ContainerName, _params.KeyNumber); - _filename = System.IO.Path.Combine (Path, _filename); + if (UseMachineKeyStore) + _filename = Path.Combine (MachinePath, _filename); + else + _filename = Path.Combine (UserPath, _filename); } return _filename; } @@ -138,27 +140,15 @@ namespace Mono.Security.Cryptography { // methods - public void Clear () - { - Zeroize (ref _keyvalue); - } - public bool Load () { // see NOTES - new FileIOPermission (FileIOPermissionAccess.Read, Path).Assert (); + new FileIOPermission (FileIOPermissionAccess.Read, this.Filename).Assert (); bool result = File.Exists (this.Filename); if (result) { - string xml = null; - try { - using (StreamReader sr = File.OpenText (this.Filename)) { - xml = sr.ReadToEnd (); - } - FromXml (xml); - } - finally { - Zeroize (ref xml); + using (StreamReader sr = File.OpenText (this.Filename)) { + FromXml (sr.ReadToEnd ()); } } return result; @@ -167,49 +157,189 @@ namespace Mono.Security.Cryptography { public void Save () { // see NOTES - new FileIOPermission (FileIOPermissionAccess.Write, Path).Assert (); + new FileIOPermission (FileIOPermissionAccess.Write, this.Filename).Assert (); using (FileStream fs = File.Open (this.Filename, FileMode.Create)) { StreamWriter sw = new StreamWriter (fs, Encoding.UTF8); sw.Write (this.ToXml ()); sw.Close (); } + // apply protection to newly created files + if (UseMachineKeyStore) + ProtectMachine (Filename); + else + ProtectUser (Filename); } public void Remove () { // see NOTES - new FileIOPermission (FileIOPermissionAccess.Write, Path).Assert (); + new FileIOPermission (FileIOPermissionAccess.Write, this.Filename).Assert (); - Clear (); File.Delete (this.Filename); // it's now possible to change the keypair un the container } - // private stuff + // private static stuff - private static string Path { + private static string UserPath { get { - if (_path == null) { + if ((_userPath == null) || (!_userPathExists)) { lock (typeof (KeyPairPersistence)) { - // TODO ? where to put machine key pairs ? - _path = System.IO.Path.Combine ( + _userPath = Path.Combine ( Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), ".mono"); - _path = System.IO.Path.Combine (_path, "keypairs"); + _userPath = Path.Combine (_userPath, "keypairs"); + + _userPathExists = Directory.Exists (_userPath); + if (!_userPathExists) { + try { + Directory.CreateDirectory (_userPath); + ProtectUser (_userPath); + _userPathExists = true; + } + catch (Exception e) { + throw new CryptographicException ("Could not create key store.", e); + } + } + } + } + // is it properly protected ? + if (!IsUserProtected (_userPath)) { + throw new CryptographicException ("Improperly protected key pairs."); + } + return _userPath; + } + } - if (!_pathExists) { - _pathExists = Directory.Exists (_path); - if (!_pathExists) { - Directory.CreateDirectory (_path); + private static string MachinePath { + get { + if ((_machinePath == null) || (!_machinePathExists)) { + lock (typeof (KeyPairPersistence)) { + _machinePath = Path.Combine ( + Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData), + ".mono"); + _machinePath = Path.Combine (_machinePath, "keypairs"); + + _machinePathExists = Directory.Exists (_machinePath); + if (!_machinePathExists) { + try { + Directory.CreateDirectory (_machinePath); + ProtectMachine (_machinePath); + _machinePathExists = true; + } + catch (Exception e) { + throw new CryptographicException ("Could not create key store.", e); } } } } - return _path; + // is it properly protected ? + if (!IsMachineProtected (_machinePath)) { + throw new CryptographicException ("Improperly protected key pairs."); + } + return _machinePath; } } +#if INSIDE_CORLIB + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal static extern bool _CanSecure (string root); + + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal static extern bool _ProtectUser (string path); + + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal static extern bool _ProtectMachine (string path); + + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal static extern bool _IsUserProtected (string path); + + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal static extern bool _IsMachineProtected (string path); +#else + // Mono.Security.dll assembly can't use the internal + // call (and still run with other runtimes) + + // Note: Class is only available in Mono.Security.dll as + // a management helper (e.g. build a GUI app) + + internal static bool _CanSecure (string root) + { + return true; + } + + internal static bool _ProtectUser (string path) + { + return true; + } + + internal static bool _ProtectMachine (string path) + { + return true; + } + + internal static bool _IsUserProtected (string path) + { + return true; + } + + internal static bool _IsMachineProtected (string path) + { + return true; + } +#endif + // private stuff + + private static bool CanSecure (string path) + { + // we assume POSIX filesystems can always be secured + if ((int) Environment.OSVersion.Platform == 128) + return true; + // while we ask the runtime for Windows OS + return _CanSecure (Path.GetPathRoot (path)); + } + + private static bool ProtectUser (string path) + { + // we cannot protect on some filsystem (like FAT) + if (CanSecure (path)) { + return _ProtectUser (path); + } + // but Mono still needs to run on them :( + return true; + } + + private static bool ProtectMachine (string path) + { + // we cannot protect on some filsystem (like FAT) + if (CanSecure (path)) { + return _ProtectMachine (path); + } + // but Mono still needs to run on them :( + return true; + } + + private static bool IsUserProtected (string path) + { + // we cannot protect on some filsystem (like FAT) + if (CanSecure (path)) { + return _IsUserProtected (path); + } + // but Mono still needs to run on them :( + return true; + } + + private static bool IsMachineProtected (string path) + { + // we cannot protect on some filsystem (like FAT) + if (CanSecure (path)) { + return _IsMachineProtected (path); + } + // but Mono still needs to run on them :( + return true; + } + private bool CanChange { get { return (_keyvalue == null); } } @@ -229,7 +359,7 @@ namespace Mono.Security.Cryptography { // easy to spot _container = "default"; } - else if ((_params.KeyContainerName == null) || (_params.KeyContainerName == String.Empty)) { + else if ((_params.KeyContainerName == null) || (_params.KeyContainerName.Length == 0)) { _container = Guid.NewGuid ().ToString (); } else { @@ -276,7 +406,7 @@ namespace Mono.Security.Cryptography { // keypair is a XML string (requiring parsing) StringBuilder xml = new StringBuilder (); xml.AppendFormat ("<KeyPair>{0}\t<Properties>{0}\t\t<Provider ", Environment.NewLine); - if ((_params.ProviderName != null) && (_params.ProviderName != String.Empty)) { + if ((_params.ProviderName != null) && (_params.ProviderName.Length != 0)) { xml.AppendFormat ("Name=\"{0}\" ", _params.ProviderName); } xml.AppendFormat ("Type=\"{0}\" />{1}\t\t<Container ", _params.ProviderType, Environment.NewLine); @@ -287,15 +417,5 @@ namespace Mono.Security.Cryptography { xml.AppendFormat (">{1}\t\t{0}{1}\t</KeyValue>{1}</KeyPair>{1}", this.KeyValue, Environment.NewLine); return xml.ToString (); } - - private void Zeroize (ref string s) - { - if (s != null) { - // TODO - zeroize the private information ? - // how can we track how it was used by other objects (copies?) - // and/or reverting to unsafe code ? - s = null; - } - } } } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/MD2Managed.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/MD2Managed.cs index b33d77283ef..b73deb9f2c4 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/MD2Managed.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/MD2Managed.cs @@ -90,7 +90,7 @@ namespace Mono.Security.Cryptography { /* Transform as many times as possible. */ if (cbSize >= partLen) { // MD2_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); - Array.Copy (array, ibStart, buffer, index, partLen); + Buffer.BlockCopy (array, ibStart, buffer, index, partLen); // MD2Transform (context->state, context->checksum, context->buffer); MD2Transform (state, checksum, buffer, 0); @@ -106,7 +106,7 @@ namespace Mono.Security.Cryptography { /* Buffer remaining input */ // MD2_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); - Array.Copy (array, ibStart + i, buffer, index, (cbSize - i)); + Buffer.BlockCopy (array, ibStart + i, buffer, index, (cbSize - i)); } protected override byte[] HashFinal () @@ -143,9 +143,9 @@ namespace Mono.Security.Cryptography { /* Form encryption block from state, block, state ^ block. */ // MD2_memcpy ((POINTER)x, (POINTER)state, 16); - Array.Copy (state, 0, x, 0, 16); + Buffer.BlockCopy (state, 0, x, 0, 16); // MD2_memcpy ((POINTER)x+16, (POINTER)block, 16); - Array.Copy (block, index, x, 16, 16); + Buffer.BlockCopy (block, index, x, 16, 16); // for (i = 0; i < 16; i++) x[i+32] = state[i] ^ block[i]; for (int i = 0; i < 16; i++) @@ -161,7 +161,7 @@ namespace Mono.Security.Cryptography { /* Save new state */ // MD2_memcpy ((POINTER)state, (POINTER)x, 16); - Array.Copy (x, 0, state, 0, 16); + Buffer.BlockCopy (x, 0, state, 0, 16); /* Update checksum. */ t = checksum [15]; diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS1.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS1.cs index 2788ccd26ac..c8981b80019 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS1.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS1.cs @@ -21,8 +21,12 @@ namespace Mono.Security.Cryptography { #else public #endif - class PKCS1 { - + sealed class PKCS1 { + + private PKCS1 () + { + } + private static bool Compare (byte[] array1, byte[] array2) { bool result = (array1.Length == array2.Length); @@ -65,7 +69,7 @@ namespace Mono.Security.Cryptography { // I2OSP converts a non-negative integer to an octet string of a specified length. public static byte[] I2OSP (int x, int size) { - byte[] array = BitConverter.GetBytes (x); + byte[] array = BitConverterLE.GetBytes (x); Array.Reverse (array, 0, array.Length); return I2OSP (array, size); } @@ -73,7 +77,7 @@ namespace Mono.Security.Cryptography { public static byte[] I2OSP (byte[] x, int size) { byte[] result = new byte [size]; - Array.Copy (x, 0, result, (result.Length - x.Length), x.Length); + Buffer.BlockCopy (x, 0, result, (result.Length - x.Length), x.Length); return result; } @@ -86,7 +90,7 @@ namespace Mono.Security.Cryptography { i--; if (i > 0) { byte[] result = new byte [x.Length - i]; - Array.Copy (x, i, result, 0, result.Length); + Buffer.BlockCopy (x, i, result, 0, result.Length); return result; } else @@ -136,9 +140,9 @@ namespace Mono.Security.Cryptography { int PSLength = (size - M.Length - 2 * hLen - 2); // DB = lHash || PS || 0x01 || M byte[] DB = new byte [lHash.Length + PSLength + 1 + M.Length]; - Array.Copy (lHash, 0, DB, 0, lHash.Length); + Buffer.BlockCopy (lHash, 0, DB, 0, lHash.Length); DB [(lHash.Length + PSLength)] = 0x01; - Array.Copy (M, 0, DB, (DB.Length - M.Length), M.Length); + Buffer.BlockCopy (M, 0, DB, (DB.Length - M.Length), M.Length); byte[] seed = new byte [hLen]; rng.GetBytes (seed); @@ -149,8 +153,8 @@ namespace Mono.Security.Cryptography { byte[] maskedSeed = xor (seed, seedMask); // EM = 0x00 || maskedSeed || maskedDB byte[] EM = new byte [maskedSeed.Length + maskedDB.Length + 1]; - Array.Copy (maskedSeed, 0, EM, 1, maskedSeed.Length); - Array.Copy (maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length); + Buffer.BlockCopy (maskedSeed, 0, EM, 1, maskedSeed.Length); + Buffer.BlockCopy (maskedDB, 0, EM, maskedSeed.Length + 1, maskedDB.Length); byte[] m = OS2IP (EM); byte[] c = RSAEP (rsa, m); @@ -172,9 +176,9 @@ namespace Mono.Security.Cryptography { // split EM = Y || maskedSeed || maskedDB byte[] maskedSeed = new byte [hLen]; - Array.Copy (EM, 1, maskedSeed, 0, maskedSeed.Length); + Buffer.BlockCopy (EM, 1, maskedSeed, 0, maskedSeed.Length); byte[] maskedDB = new byte [size - hLen - 1]; - Array.Copy (EM, (EM.Length - maskedDB.Length), maskedDB, 0, maskedDB.Length); + Buffer.BlockCopy (EM, (EM.Length - maskedDB.Length), maskedDB, 0, maskedDB.Length); byte[] seedMask = MGF1 (hash, maskedDB, hLen); byte[] seed = xor (maskedSeed, seedMask); @@ -184,7 +188,7 @@ namespace Mono.Security.Cryptography { byte[] lHash = GetEmptyHash (hash); // split DB = lHash' || PS || 0x01 || M byte[] dbHash = new byte [lHash.Length]; - Array.Copy (DB, 0, dbHash, 0, dbHash.Length); + Buffer.BlockCopy (DB, 0, dbHash, 0, dbHash.Length); bool h = Compare (lHash, dbHash); // find separator 0x01 @@ -194,7 +198,7 @@ namespace Mono.Security.Cryptography { int Msize = DB.Length - nPos - 1; byte[] M = new byte [Msize]; - Array.Copy (DB, (nPos + 1), M, 0, Msize); + Buffer.BlockCopy (DB, (nPos + 1), M, 0, Msize); // we could have returned EM[0] sooner but would be helping a timing attack if ((EM[0] != 0) || (!h) || (DB[nPos] != 0x01)) @@ -214,8 +218,8 @@ namespace Mono.Security.Cryptography { rng.GetNonZeroBytes (PS); byte[] EM = new byte [size]; EM [1] = 0x02; - Array.Copy (PS, 0, EM, 2, PSLength); - Array.Copy (M, 0, EM, (size - M.Length), M.Length); + Buffer.BlockCopy (PS, 0, EM, 2, PSLength); + Buffer.BlockCopy (M, 0, EM, (size - M.Length), M.Length); byte[] m = OS2IP (EM); byte[] c = RSAEP (rsa, m); @@ -245,7 +249,7 @@ namespace Mono.Security.Cryptography { return null; mPos++; byte[] M = new byte [EM.Length - mPos]; - Array.Copy (EM, mPos, M, 0, M.Length); + Buffer.BlockCopy (EM, mPos, M, 0, M.Length); return M; } @@ -278,7 +282,7 @@ namespace Mono.Security.Cryptography { return false; // TODO: add more validation byte[] decryptedHash = new byte [hashValue.Length]; - Array.Copy (EM2, EM2.Length - hashValue.Length, decryptedHash, 0, decryptedHash.Length); + Buffer.BlockCopy (EM2, EM2.Length - hashValue.Length, decryptedHash, 0, decryptedHash.Length); result = Compare (decryptedHash, hashValue); } return result; @@ -318,7 +322,7 @@ namespace Mono.Security.Cryptography { t = hashValue; } - Array.Copy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length); + Buffer.BlockCopy (hashValue, 0, t, t.Length - hashValue.Length, hashValue.Length); int PSLength = System.Math.Max (8, emLength - t.Length - 3); // PS = PSLength of 0xff @@ -328,7 +332,7 @@ namespace Mono.Security.Cryptography { EM [1] = 0x01; for (int i=2; i < PSLength + 2; i++) EM[i] = 0xff; - Array.Copy (t, 0, EM, PSLength + 3, t.Length); + Buffer.BlockCopy (t, 0, EM, PSLength + 3, t.Length); return EM; } @@ -359,16 +363,16 @@ namespace Mono.Security.Cryptography { // b. Concatenate the hash of the seed mgfSeed and C to the octet string T: // T = T || Hash (mgfSeed || C) - Array.Copy (mgfSeed, 0, toBeHashed, 0, mgfSeedLength); - Array.Copy (C, 0, toBeHashed, mgfSeedLength, 4); + Buffer.BlockCopy (mgfSeed, 0, toBeHashed, 0, mgfSeedLength); + Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4); byte[] output = hash.ComputeHash (toBeHashed); - Array.Copy (output, 0, T, pos, hLen); + Buffer.BlockCopy (output, 0, T, pos, hLen); pos += mgfSeedLength; } // 4. Output the leading maskLen octets of T as the octet string mask. byte[] mask = new byte [maskLen]; - Array.Copy (T, 0, mask, 0, maskLen); + Buffer.BlockCopy (T, 0, mask, 0, maskLen); return mask; } } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS8.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS8.cs index f6f3447a20e..ffd555e4d6d 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS8.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/PKCS8.cs @@ -3,9 +3,10 @@ // ftp://ftp.rsasecurity.com/pub/pkcs/doc/pkcs-8.doc // // Author: -// Sebastien Pouliot (spouliot@motus.com) +// Sebastien Pouliot <sebastien@ximian.com> // // (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) // using System; @@ -18,7 +19,7 @@ using Mono.Security.X509; namespace Mono.Security.Cryptography { - public class PKCS8 { + public sealed class PKCS8 { public enum KeyInfo { PrivateKey, @@ -26,6 +27,10 @@ namespace Mono.Security.Cryptography { Unknown } + private PKCS8 () + { + } + static public KeyInfo GetType (byte[] data) { if (data == null) @@ -98,8 +103,16 @@ namespace Mono.Security.Cryptography { } public byte[] PrivateKey { - get { return _key; } - set { _key = value; } + get { + if (_key == null) + return null; + return (byte[]) _key.Clone (); + } + set { + if (value == null) + throw new ArgumentNullException ("PrivateKey"); + _key = (byte[]) value.Clone (); + } } public int Version { @@ -131,7 +144,7 @@ namespace Mono.Security.Cryptography { ASN1 algorithm = privateKeyAlgorithm [0]; if (algorithm.Tag != 0x06) throw new CryptographicException ("missing algorithm OID"); - _algorithm = ASN1Convert.ToOID (algorithm); + _algorithm = ASN1Convert.ToOid (algorithm); ASN1 privateKey = privateKeyInfo [2]; _key = privateKey.Value; @@ -148,7 +161,7 @@ namespace Mono.Security.Cryptography { public byte[] GetBytes () { ASN1 privateKeyAlgorithm = new ASN1 (0x30); - privateKeyAlgorithm.Add (ASN1Convert.FromOID (_algorithm)); + privateKeyAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); privateKeyAlgorithm.Add (new ASN1 (0x05)); // ASN.1 NULL ASN1 pki = new ASN1 (0x30); @@ -392,7 +405,7 @@ namespace Mono.Security.Cryptography { ASN1 algorithm = encryptionAlgorithm [0]; if (algorithm.Tag != 0x06) throw new CryptographicException ("invalid algorithm"); - _algorithm = ASN1Convert.ToOID (algorithm); + _algorithm = ASN1Convert.ToOid (algorithm); // parameters ANY DEFINED BY algorithm OPTIONAL if (encryptionAlgorithm.Count > 1) { ASN1 parameters = encryptionAlgorithm [1]; @@ -426,7 +439,7 @@ namespace Mono.Security.Cryptography { throw new CryptographicException ("No algorithm OID specified"); ASN1 encryptionAlgorithm = new ASN1 (0x30); - encryptionAlgorithm.Add (ASN1Convert.FromOID (_algorithm)); + encryptionAlgorithm.Add (ASN1Convert.FromOid (_algorithm)); // parameters ANY DEFINED BY algorithm OPTIONAL if ((_iterations > 0) || (_salt != null)) { diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/RSAManaged.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/RSAManaged.cs index 8de296ff5ca..79d2ae4a186 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/RSAManaged.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/RSAManaged.cs @@ -50,11 +50,13 @@ namespace Mono.Security.Cryptography { private BigInteger n; // modulus private BigInteger e; - public RSAManaged () : this (defaultKeySize) {} + public RSAManaged () : this (defaultKeySize) + { + } - public RSAManaged (int dwKeySize) + public RSAManaged (int keySize) { - KeySizeValue = dwKeySize; + KeySizeValue = keySize; LegalKeySizesValue = new KeySizes [1]; LegalKeySizesValue [0] = new KeySizes (384, 16384, 8); } @@ -75,7 +77,7 @@ namespace Mono.Security.Cryptography { // generate p, prime and (p-1) relatively prime to e for (;;) { - p = BigInteger.genPseudoPrime (pbitlength); + p = BigInteger.GeneratePseudoPrime (pbitlength); if (p % uint_e != 1) break; } @@ -84,14 +86,14 @@ namespace Mono.Security.Cryptography { // generate q, prime and (q-1) relatively prime to e, // and not equal to p for (;;) { - q = BigInteger.genPseudoPrime (qbitlength); + q = BigInteger.GeneratePseudoPrime (qbitlength); if ((q % uint_e != 1) && (p != q)) break; } // calculate the modulus n = p * q; - if (n.bitCount () == KeySize) + if (n.BitCount () == KeySize) break; // if we get here our primes aren't big enough, make the largest @@ -105,18 +107,18 @@ namespace Mono.Security.Cryptography { BigInteger phi = pSub1 * qSub1; // calculate the private exponent - d = e.modInverse (phi); + d = e.ModInverse (phi); // calculate the CRT factors dp = d % pSub1; dq = d % qSub1; - qInv = q.modInverse (p); + qInv = q.ModInverse (p); keypairGenerated = true; isCRTpossible = true; if (KeyGenerated != null) - KeyGenerated (this); + KeyGenerated (this, null); } // overrides from RSA class @@ -125,7 +127,7 @@ namespace Mono.Security.Cryptography { get { // in case keypair hasn't been (yet) generated if (keypairGenerated) - return n.bitCount (); + return n.BitCount (); else return base.KeySize; } @@ -159,9 +161,9 @@ namespace Mono.Security.Cryptography { // optimized by using CRT (Chinese Remainder Theorem) if (isCRTpossible) { // m1 = c^dp mod p - BigInteger m1 = input.modPow (dp, p); + BigInteger m1 = input.ModPow (dp, p); // m2 = c^dq mod q - BigInteger m2 = input.modPow (dq, q); + BigInteger m2 = input.ModPow (dq, q); BigInteger h; if (m2 > m1) { // thanks to benm! @@ -177,9 +179,9 @@ namespace Mono.Security.Cryptography { } else { // m = c^d mod n - output = input.modPow (d, n); + output = input.ModPow (d, n); } - byte[] result = output.getBytes (); + byte[] result = output.GetBytes (); // zeroize value input.Clear (); output.Clear (); @@ -195,8 +197,8 @@ namespace Mono.Security.Cryptography { GenerateKeyPair (); BigInteger input = new BigInteger (rgb); - BigInteger output = input.modPow (e, n); - byte[] result = output.getBytes (); + BigInteger output = input.ModPow (e, n); + byte[] result = output.GetBytes (); // zeroize value input.Clear (); output.Clear (); @@ -212,21 +214,21 @@ namespace Mono.Security.Cryptography { GenerateKeyPair (); RSAParameters param = new RSAParameters (); - param.Exponent = e.getBytes (); - param.Modulus = n.getBytes (); + param.Exponent = e.GetBytes (); + param.Modulus = n.GetBytes (); if (includePrivateParameters) { // some parameters are required for exporting the private key if ((d == null) || (p == null) || (q == null)) throw new CryptographicException ("Missing private key"); - param.D = d.getBytes (); - param.P = p.getBytes (); - param.Q = q.getBytes (); + param.D = d.GetBytes (); + param.P = p.GetBytes (); + param.Q = q.GetBytes (); // but CRT parameters are optionals if ((dp != null) && (dq != null) && (qInv != null)) { // and we include them only if we have them all - param.DP = dp.getBytes (); - param.DQ = dq.getBytes (); - param.InverseQ = qInv.getBytes (); + param.DP = dp.GetBytes (); + param.DQ = dq.GetBytes (); + param.InverseQ = qInv.GetBytes (); } } return param; @@ -310,7 +312,7 @@ namespace Mono.Security.Cryptography { m_disposed = true; } - public delegate void KeyGeneratedEventHandler (object sender); + public delegate void KeyGeneratedEventHandler (object sender, EventArgs e); public event KeyGeneratedEventHandler KeyGenerated; } diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/SymmetricTransform.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/SymmetricTransform.cs index f1e86e45ebf..b870e6521f1 100755 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/SymmetricTransform.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/SymmetricTransform.cs @@ -42,7 +42,7 @@ namespace Mono.Security.Cryptography { BlockSizeByte = (algo.BlockSize >> 3); // mode buffers temp = new byte [BlockSizeByte]; - Array.Copy (rgbIV, 0, temp, 0, BlockSizeByte); + Buffer.BlockCopy (rgbIV, 0, temp, 0, BlockSizeByte); temp2 = new byte [BlockSizeByte]; FeedBackByte = (algo.FeedbackSize >> 3); FeedBackIter = (int) BlockSizeByte / FeedBackByte; @@ -129,14 +129,14 @@ namespace Mono.Security.Cryptography { for (int i = 0; i < BlockSizeByte; i++) temp[i] ^= input[i]; ECB (temp, output); - Array.Copy (output, 0, temp, 0, BlockSizeByte); + Buffer.BlockCopy (output, 0, temp, 0, BlockSizeByte); } else { - Array.Copy (input, 0, temp2, 0, BlockSizeByte); + Buffer.BlockCopy (input, 0, temp2, 0, BlockSizeByte); ECB (input, output); for (int i = 0; i < BlockSizeByte; i++) output[i] ^= temp[i]; - Array.Copy (temp2, 0, temp, 0, BlockSizeByte); + Buffer.BlockCopy (temp2, 0, temp, 0, BlockSizeByte); } } @@ -150,8 +150,8 @@ namespace Mono.Security.Cryptography { for (int i = 0; i < FeedBackByte; i++) output[i + x] = (byte)(temp2[i] ^ input[i + x]); - Array.Copy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte); - Array.Copy (output, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte); + Buffer.BlockCopy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte); + Buffer.BlockCopy (output, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte); } } else { @@ -162,8 +162,8 @@ namespace Mono.Security.Cryptography { ECB (temp, temp2); encrypt = false; - Array.Copy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte); - Array.Copy (input, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte); + Buffer.BlockCopy (temp, FeedBackByte, temp, 0, BlockSizeByte - FeedBackByte); + Buffer.BlockCopy (input, x, temp, BlockSizeByte - FeedBackByte, FeedBackByte); for (int i = 0; i < FeedBackByte; i++) output[i + x] = (byte)(temp2[i] ^ input[i + x]); } @@ -207,9 +207,9 @@ namespace Mono.Security.Cryptography { int total = 0; for (int i = 0; i < full; i++) { - Array.Copy (inputBuffer, offs, workBuff, 0, BlockSizeByte); + Buffer.BlockCopy (inputBuffer, offs, workBuff, 0, BlockSizeByte); Transform (workBuff, workout); - Array.Copy (workout, 0, outputBuffer, outputOffset, BlockSizeByte); + Buffer.BlockCopy (workout, 0, outputBuffer, outputOffset, BlockSizeByte); offs += BlockSizeByte; outputOffset += BlockSizeByte; total += BlockSizeByte; @@ -259,7 +259,7 @@ namespace Mono.Security.Cryptography { byte padding = (byte) (BlockSizeByte - rem); for (int i = res.Length; --i >= (res.Length - padding);) res [i] = padding; - Array.Copy (inputBuffer, inputOffset, res, full, rem); + Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); // the last padded block will be transformed in-place TransformBlock (res, full, BlockSizeByte, res, full); } @@ -294,7 +294,7 @@ namespace Mono.Security.Cryptography { // return output without padding if (total > 0) { byte[] data = new byte [total]; - Array.Copy (res, 0, data, 0, total); + Buffer.BlockCopy (res, 0, data, 0, total); // zeroize decrypted data (copy with padding) Array.Clear (res, 0, res.Length); return data; |