diff options
Diffstat (limited to 'mcs/class/referencesource/mscorlib/system/security/cryptography')
74 files changed, 1544 insertions, 163 deletions
diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/HashAlgorithmName.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/HashAlgorithmName.cs new file mode 100644 index 00000000000..3e75d7b5ad1 --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/HashAlgorithmName.cs @@ -0,0 +1,109 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +namespace System.Security.Cryptography +{ + // Strongly typed string representing the name of a hash algorithm. + // Open ended to allow extensibility while giving the discoverable feel of an enum for common values. + + /// <summary> + /// Specifies the name of a cryptographic hash algorithm. + /// </summary> + /// Asymmetric Algorithms implemented using Microsoft's CNG (Cryptography Next Generation) API + /// will interpret the underlying string value as a CNG algorithm identifier: + /// * https://msdn.microsoft.com/en-us/library/windows/desktop/aa375534(v=vs.85).aspx + /// + /// As with CNG, the names are case-sensitive. + /// + /// Asymmetric Algorithms implemented using other technologies: + /// * Must recognize at least "MD5", "SHA1", "SHA256", "SHA384", and "SHA512". + /// * Should recognize additional CNG IDs for any other hash algorithms that they also support. + /// </remarks> + public struct HashAlgorithmName : IEquatable<HashAlgorithmName> + { + // Returning a new instance every time is free here since HashAlgorithmName is a struct with + // a single string field. The optimized codegen should be equivalent to return "MD5". + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing "MD5" + /// </summary> + public static HashAlgorithmName MD5 { get { return new HashAlgorithmName("MD5"); } } + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing "SHA1" + /// </summary> + public static HashAlgorithmName SHA1 { get { return new HashAlgorithmName("SHA1"); } } + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing "SHA256" + /// </summary> + public static HashAlgorithmName SHA256 { get { return new HashAlgorithmName("SHA256"); } } + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing "SHA384" + /// </summary> + public static HashAlgorithmName SHA384 { get { return new HashAlgorithmName("SHA384"); } } + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing "SHA512" + /// </summary> + public static HashAlgorithmName SHA512 { get { return new HashAlgorithmName("SHA512"); } } + + private readonly string _name; + + /// <summary> + /// Gets a <see cref="HashAlgorithmName" /> representing a custom name. + /// </summary> + /// <param name="name">The custom hash algorithm name.</param> + public HashAlgorithmName(string name) + { + // Note: No validation because we have to deal with default(HashAlgorithmName) regardless. + _name = name; + } + + /// <summary> + /// Gets the underlying string representation of the algorithm name. + /// </summary> + /// <remarks> + /// May be null or empty to indicate that no hash algorithm is applicable. + /// </remarks> + public string Name + { + get { return _name; } + } + + public override string ToString() + { + return _name ?? String.Empty; + } + + public override bool Equals(object obj) + { + return obj is HashAlgorithmName && Equals((HashAlgorithmName)obj); + } + + public bool Equals(HashAlgorithmName other) + { + // NOTE: intentionally ordinal and case sensitive, matches CNG. + return _name == other._name; + } + + public override int GetHashCode() + { + return _name == null ? 0 : _name.GetHashCode(); + } + + public static bool operator ==(HashAlgorithmName left, HashAlgorithmName right) + { + return left.Equals(right); + } + + public static bool operator !=(HashAlgorithmName left, HashAlgorithmName right) + { + return !(left == right); + } + } +} diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPadding.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPadding.cs new file mode 100644 index 00000000000..9494908361d --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPadding.cs @@ -0,0 +1,130 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +namespace System.Security.Cryptography +{ + /// <summary> + /// Specifies the padding mode and parameters to use with RSA encryption or decryption operations. + /// </summary> + public sealed class RSAEncryptionPadding : IEquatable<RSAEncryptionPadding> + { + private static readonly RSAEncryptionPadding s_pkcs1 = new RSAEncryptionPadding(RSAEncryptionPaddingMode.Pkcs1, default(HashAlgorithmName)); + private static readonly RSAEncryptionPadding s_oaepSHA1 = CreateOaep(HashAlgorithmName.SHA1); + private static readonly RSAEncryptionPadding s_oaepSHA256 = CreateOaep(HashAlgorithmName.SHA256); + private static readonly RSAEncryptionPadding s_oaepSHA384 = CreateOaep(HashAlgorithmName.SHA384); + private static readonly RSAEncryptionPadding s_oaepSHA512 = CreateOaep(HashAlgorithmName.SHA512); + + /// <summary> + /// <see cref="RSAEncryptionPaddingMode.Pkcs1"/> mode. + /// </summary> + public static RSAEncryptionPadding Pkcs1 { get { return s_pkcs1; } } + + /// <summary> + /// <see cref="RSAEncryptionPaddingMode.Oaep"/> mode with SHA1 hash algorithm. + /// </summary> + public static RSAEncryptionPadding OaepSHA1 { get { return s_oaepSHA1; } } + + /// <summary> + /// <see cref="RSAEncrytpionPaddingMode.Oaep"/> mode with SHA256 hash algorithm. + /// </summary> + public static RSAEncryptionPadding OaepSHA256 { get { return s_oaepSHA256; } } + + /// <summary> + /// <see cref="RSAEncrytpionPaddingMode.Oaep"/> mode with SHA384 hash algorithm. + /// </summary> + public static RSAEncryptionPadding OaepSHA384 { get { return s_oaepSHA384; } } + + /// <summary> + /// <see cref="RSAEncrytpionPaddingMode.Oaep"/> mode with SHA512 hash algorithm. + /// </summary> + public static RSAEncryptionPadding OaepSHA512 { get { return s_oaepSHA512; } } + + private RSAEncryptionPaddingMode _mode; + private HashAlgorithmName _oaepHashAlgorithm; + + private RSAEncryptionPadding(RSAEncryptionPaddingMode mode, HashAlgorithmName oaepHashAlgorithm) + { + _mode = mode; + _oaepHashAlgorithm = oaepHashAlgorithm; + } + + /// <summary> + /// Creates a new instance instance representing <see cref="RSAEncryptionPaddingMode.Oaep"/> + /// with the given hash algorithm. + /// </summary> + public static RSAEncryptionPadding CreateOaep(HashAlgorithmName hashAlgorithm) + { + if (String.IsNullOrEmpty(hashAlgorithm.Name)) + { + throw new ArgumentException(Environment.GetResourceString("Cryptography_HashAlgorithmNameNullOrEmpty"), "hashAlgorithm"); + } + + return new RSAEncryptionPadding(RSAEncryptionPaddingMode.Oaep, hashAlgorithm); + } + + /// <summary> + /// Gets the padding mode to use. + /// </summary> + public RSAEncryptionPaddingMode Mode + { + get { return _mode; } + } + + /// <summary> + /// Gets the padding mode to use in conjunction with <see cref="RSAEncryptionPaddingMode.Oaep"/>. + /// </summary> + /// <remarks> + /// If <see cref="Mode"/> is not <see cref="RSAEncryptionPaddingMode.Oaep"/>, then <see cref="HashAlgorithmName.Name" /> will be null. + /// </remarks> + public HashAlgorithmName OaepHashAlgorithm + { + get { return _oaepHashAlgorithm; } + } + + public override int GetHashCode() + { + return CombineHashCodes(_mode.GetHashCode(), _oaepHashAlgorithm.GetHashCode()); + } + + // Same as non-public Tuple.CombineHashCodes + private static int CombineHashCodes(int h1, int h2) + { + return (((h1 << 5) + h1) ^ h2); + } + + public override bool Equals(object obj) + { + return Equals(obj as RSAEncryptionPadding); + } + + public bool Equals(RSAEncryptionPadding other) + { + return other != null + && _mode == other._mode + && _oaepHashAlgorithm == other._oaepHashAlgorithm; + } + + public static bool operator ==(RSAEncryptionPadding left, RSAEncryptionPadding right) + { + if (Object.ReferenceEquals(left, null)) + { + return Object.ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + public static bool operator !=(RSAEncryptionPadding left, RSAEncryptionPadding right) + { + return !(left == right); + } + + public override string ToString() + { + return _mode.ToString() + _oaepHashAlgorithm.Name; + } + } +} diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPaddingMode.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPaddingMode.cs new file mode 100644 index 00000000000..7c1bb10d44f --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSAEncryptionPaddingMode.cs @@ -0,0 +1,32 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +namespace System.Security.Cryptography +{ + /// <summary> + /// Specifies the padding mode to use with RSA encryption or decryption operations. + /// </summary> + public enum RSAEncryptionPaddingMode + { + /// <summary> + /// PKCS #1 v1.5. + /// </summary> + /// <remarks> + /// This mode correpsonds to the RSAES-PKCS1-v1_5 encryption scheme described in the PKCS #1 RSA Encryption Standard. + /// It is supported for compatibility with existing applications. + /// </remarks> + Pkcs1, + + /// <summary> + /// Optimal Asymmetric Encryption Padding. + /// </summary> + /// <remarks> + /// This mode corresponds to the RSAES-OEAP encryption scheme described in the PKCS #1 RSA Encryption Standard. + /// It is recommended for new applications. + /// </remarks> + Oaep, + } +} diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePadding.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePadding.cs new file mode 100644 index 00000000000..61989c70232 --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePadding.cs @@ -0,0 +1,87 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +namespace System.Security.Cryptography +{ + // NOTE: This is *currently* 1:1 with the enum, but it exists to reserve room for more options + // such as custom # of PSS salt bytes without having to modify other parts of the API + // surface. + + /// <summary> + /// Specifies the padding mode and parameters to use with RSA signature creation or verification operations. + /// </summary> + public sealed class RSASignaturePadding : IEquatable<RSASignaturePadding> + { + private static readonly RSASignaturePadding s_pkcs1 = new RSASignaturePadding(RSASignaturePaddingMode.Pkcs1); + private static readonly RSASignaturePadding s_pss = new RSASignaturePadding(RSASignaturePaddingMode.Pss); + + private readonly RSASignaturePaddingMode _mode; + + private RSASignaturePadding(RSASignaturePaddingMode mode) + { + _mode = mode; + } + + /// <summary> + /// <see cref="RSASignaturePaddingMode.Pkcs1"/> mode. + /// </summary> + public static RSASignaturePadding Pkcs1 + { + get { return s_pkcs1; } + } + + /// <summary> + /// <see cref="RSASignaturePaddingMode.Pss"/> mode with the number of salt bytes equal to the size of the hash. + /// </summary> + public static RSASignaturePadding Pss + { + get { return s_pss; } + } + + /// <summary> + /// Gets the padding mode to use. + /// </summary> + public RSASignaturePaddingMode Mode + { + get { return _mode; } + } + + public override int GetHashCode() + { + return _mode.GetHashCode(); + } + + public override bool Equals(object obj) + { + return Equals(obj as RSASignaturePadding); + } + + public bool Equals(RSASignaturePadding other) + { + return other != null && _mode == other._mode; + } + + public static bool operator ==(RSASignaturePadding left, RSASignaturePadding right) + { + if (Object.ReferenceEquals(left, null)) + { + return Object.ReferenceEquals(right, null); + } + + return left.Equals(right); + } + + public static bool operator !=(RSASignaturePadding left, RSASignaturePadding right) + { + return !(left == right); + } + + public override string ToString() + { + return _mode.ToString(); + } + } +} diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePaddingMode.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePaddingMode.cs new file mode 100644 index 00000000000..356852937fd --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/RSASignaturePaddingMode.cs @@ -0,0 +1,32 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +namespace System.Security.Cryptography +{ + /// <summary> + /// Specifies the padding mode to use with RSA signature creation or verification operations. + /// </summary> + public enum RSASignaturePaddingMode + { + /// <summary> + /// PKCS #1 v1.5. + /// </summary> + /// <remarks> + /// This corresponds to the RSASSA-PKCS1-v1.5 signature scheme of the PKCS #1 RSA Encryption Standard. + /// It is supported for compatibility with existing applications. + /// </remarks> + Pkcs1, + + /// <summary> + /// Probabilistic Signature Scheme. + /// </summary> + /// <remarks> + /// This corresponds to the RSASSA-PKCS1-v1.5 signature scheme of the PKCS #1 RSA Encryption Standard. + /// It is recommended for new applications. + /// </remarks> + Pss, + } +}
\ No newline at end of file diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricalgorithm.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricalgorithm.cs index 027dc7304aa..45cdaa749e6 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricalgorithm.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -11,7 +11,7 @@ // namespace System.Security.Cryptography { -[System.Runtime.InteropServices.ComVisible(true)] + [System.Runtime.InteropServices.ComVisible(true)] public abstract class AsymmetricAlgorithm : IDisposable { protected int KeySizeValue; protected KeySizes[] LegalKeySizesValue; @@ -71,13 +71,19 @@ namespace System.Security.Cryptography { public virtual KeySizes[] LegalKeySizes { get { return (KeySizes[]) LegalKeySizesValue.Clone(); } } - - public abstract String SignatureAlgorithm { - get; + + // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract. + public virtual String SignatureAlgorithm { + get { + throw new NotImplementedException(); + } } - public abstract String KeyExchangeAlgorithm { - get; + // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract. + public virtual String KeyExchangeAlgorithm { + get { + throw new NotImplementedException(); + } } // @@ -98,7 +104,14 @@ namespace System.Security.Cryptography { return (AsymmetricAlgorithm) CryptoConfig.CreateFromName(algName); } - public abstract void FromXmlString(String xmlString); - public abstract String ToXmlString(bool includePrivateParameters); + // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract. + public virtual void FromXmlString(String xmlString) { + throw new NotImplementedException(); + } + + // This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract. + public virtual String ToXmlString(bool includePrivateParameters) { + throw new NotImplementedException(); + } } } diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs index f9272ee23e6..1492e46ba29 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs index 1da8d9b89a3..5dca811ed20 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetrickeyexchangeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs index 232e711da08..df836d2b039 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs index 6911141f48a..37f1d65f64c 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/asymmetricsignatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/base64transforms.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/base64transforms.cs index 91ffbd4f42b..05efe3c3e4a 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/base64transforms.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/base64transforms.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/capinative.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/capinative.cs new file mode 100644 index 00000000000..ea377f350a3 --- /dev/null +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/capinative.cs @@ -0,0 +1,598 @@ +// ==++== +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// ==--== + +// +// This source file is marked up so that it can be built both as part of the BCL and as part of the fx tree +// as well. Since the security annotation process is different between the two trees, SecurityCritical +// attributes appear directly in this file, instead of being marked up by the BCL annotator tool. +// + +using System; +using System.Diagnostics; +using System.Globalization; +using System.Runtime.ConstrainedExecution; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Microsoft.Win32.SafeHandles; +using System.Diagnostics.Contracts; + +namespace System.Security.Cryptography { + + /// <summary> + /// Native interop with CAPI. Native code definitions can be found in wincrypt.h + /// </summary> + internal static class CapiNative { + /// <summary> + /// Class fields for CAPI algorithm identifiers + /// </summary> + internal enum AlgorithmClass + { + Any = (0 << 13), // ALG_CLASS_ANY + Signature = (1 << 13), // ALG_CLASS_SIGNATURE + Hash = (4 << 13), // ALG_CLASS_HASH + KeyExchange = (5 << 13), // ALG_CLASS_KEY_EXCHANGE + } + + /// <summary> + /// Type identifier fields for CAPI algorithm identifiers + /// </summary> + internal enum AlgorithmType + { + Any = (0 << 9), // ALG_TYPE_ANY + Rsa = (2 << 9), // ALG_TYPE_RSA + } + + /// <summary> + /// Sub identifiers for CAPI algorithm identifiers + /// </summary> + internal enum AlgorithmSubId + { + Any = 0, // ALG_SID_ANY + + RsaAny = 0, // ALG_SID_RSA_ANY + + Sha1 = 4, // ALG_SID_SHA1 + Sha256 = 12, // ALG_SID_SHA_256 + Sha384 = 13, // ALG_SID_SHA_384 + Sha512 = 14, // ALG_SID_SHA_512 + } + + /// <summary> + /// CAPI algorithm identifiers + /// </summary> + internal enum AlgorithmID + { + None = 0, + + RsaSign = (AlgorithmClass.Signature | AlgorithmType.Rsa | AlgorithmSubId.RsaAny), // CALG_RSA_SIGN + RsaKeyExchange = (AlgorithmClass.KeyExchange | AlgorithmType.Rsa | AlgorithmSubId.RsaAny), // CALG_RSA_KEYX + + Sha1 = (AlgorithmClass.Hash | AlgorithmType.Any | AlgorithmSubId.Sha1), // CALG_SHA1 + Sha256 = (AlgorithmClass.Hash | AlgorithmType.Any | AlgorithmSubId.Sha256), // CALG_SHA_256 + Sha384 = (AlgorithmClass.Hash | AlgorithmType.Any | AlgorithmSubId.Sha384), // CALG_SHA_384 + Sha512 = (AlgorithmClass.Hash | AlgorithmType.Any | AlgorithmSubId.Sha512), // CALG_SHA_512 + } + + /// <summary> + /// Flags for the CryptAcquireContext API + /// </summary> + [Flags] + internal enum CryptAcquireContextFlags { + None = 0x00000000, + NewKeyset = 0x00000008, // CRYPT_NEWKEYSET + DeleteKeyset = 0x00000010, // CRYPT_DELETEKEYSET + MachineKeyset = 0x00000020, // CRYPT_MACHINE_KEYSET + Silent = 0x00000040, // CRYPT_SILENT + VerifyContext = unchecked((int)0xF0000000) // CRYPT_VERIFYCONTEXT + } + + /// <summary> + /// Error codes returned by CAPI + /// </summary> + internal enum ErrorCode { + Ok = 0x00000000, + MoreData = 0x000000ea, // ERROR_MORE_DATA + BadHash = unchecked((int)0x80090002), // NTE_BAD_HASH + BadData = unchecked((int)0x80090005), // NTE_BAD_DATA + BadSignature = unchecked((int)0x80090006), // NTE_BAD_SIGNATURE + NoKey = unchecked((int)0x8009000d) // NTE_NO_KEY + } + + /// <summary> + /// Properties of CAPI hash objects + /// </summary> + internal enum HashProperty { + None = 0, + HashValue = 0x0002, // HP_HASHVAL + HashSize = 0x0004, // HP_HASHSIZE + } + + /// <summary> + /// Flags for the CryptGenKey API + /// </summary> + [Flags] + internal enum KeyGenerationFlags { + None = 0x00000000, + Exportable = 0x00000001, // CRYPT_EXPORTABLE + UserProtected = 0x00000002, // CRYPT_USER_PROTECTED + Archivable = 0x00004000 // CRYPT_ARCHIVABLE + } + + /// <summary> + /// Properties that can be read or set on a key + /// </summary> + internal enum KeyProperty { + None = 0, + AlgorithmID = 7, // KP_ALGID + KeyLength = 9 // KP_KEYLEN + } + + /// <summary> + /// Key numbers for identifying specific keys within a single container + /// </summary> + internal enum KeySpec { + KeyExchange = 1, // AT_KEYEXCHANGE + Signature = 2 // AT_SIGNATURE + } + + /// <summary> + /// Well-known names of crypto service providers + /// </summary> + internal static class ProviderNames { + // MS_ENHANCED_PROV + internal const string MicrosoftEnhanced = "Microsoft Enhanced Cryptographic Provider v1.0"; + } + + /// <summary> + /// Provider type accessed in a crypto service provider. These provide the set of algorithms + /// available to use for an application. + /// </summary> + internal enum ProviderType { + RsaFull = 1 // PROV_RSA_FULL + } + + [System.Security.SecurityCritical] + internal static class UnsafeNativeMethods { + /// <summary> + /// Open a crypto service provider, if a key container is specified KeyContainerPermission + /// should be demanded. + /// </summary> + [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptAcquireContext([Out] out SafeCspHandle phProv, + string pszContainer, + string pszProvider, + ProviderType dwProvType, + CryptAcquireContextFlags dwFlags); + + /// <summary> + /// Create an object to hash data with + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptCreateHash(SafeCspHandle hProv, + AlgorithmID Algid, + IntPtr hKey, // SafeCspKeyHandle + int dwFlags, + [Out] out SafeCspHashHandle phHash); + + /// <summary> + /// Create a new key in the given key container + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptGenKey(SafeCspHandle hProv, + int Algid, + uint dwFlags, + [Out] out SafeCspKeyHandle phKey); + + /// <summary> + /// Fill a buffer with randomly generated data + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptGenRandom(SafeCspHandle hProv, + int dwLen, + [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbBuffer); + + /// <summary> + /// Fill a buffer with randomly generated data + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern unsafe bool CryptGenRandom(SafeCspHandle hProv, + int dwLen, + byte* pbBuffer); + + /// <summary> + /// Read the value of a property from a hash object + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptGetHashParam(SafeCspHashHandle hHash, + HashProperty dwParam, + [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, + [In, Out] ref int pdwDataLen, + int dwFlags); + + /// <summary> + /// Read the value of a property from a key + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptGetKeyParam(SafeCspKeyHandle hKey, + KeyProperty dwParam, + [In, Out, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, + [In, Out] ref int pdwDataLen, + int dwFlags); + + /// <summary> + /// Import a key blob into a CSP + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptImportKey(SafeCspHandle hProv, + [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, + int pdwDataLen, + IntPtr hPubKey, // SafeCspKeyHandle + KeyGenerationFlags dwFlags, + [Out] out SafeCspKeyHandle phKey); + + /// <summary> + /// Set the value of a property on a hash object + /// </summary> + [DllImport("advapi32", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptSetHashParam(SafeCspHashHandle hHash, + HashProperty dwParam, + [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData, + int dwFlags); + + /// <summary> + /// Verify the a digital signature + /// </summary> + [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool CryptVerifySignature(SafeCspHashHandle hHash, + [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbSignature, + int dwSigLen, + SafeCspKeyHandle hPubKey, + string sDescription, + int dwFlags); + } + + /// <summary> + /// Acquire a handle to a crypto service provider and optionally a key container + /// </summary> + [SecurityCritical] + internal static SafeCspHandle AcquireCsp(string keyContainer, + string providerName, + ProviderType providerType, + CryptAcquireContextFlags flags) { + Contract.Assert(keyContainer == null, "Key containers are not supported"); + + // Specifying both verify context (for an ephemeral key) and machine keyset (for a persisted machine key) + // does not make sense. Additionally, Widows is beginning to lock down against uses of MACHINE_KEYSET + // (for instance in the app container), even if verify context is present. Therefore, if we're using + // an ephemeral key, strip out MACHINE_KEYSET from the flags. + if (((flags & CryptAcquireContextFlags.VerifyContext) == CryptAcquireContextFlags.VerifyContext) && + ((flags & CryptAcquireContextFlags.MachineKeyset) == CryptAcquireContextFlags.MachineKeyset)) { + flags &= ~CryptAcquireContextFlags.MachineKeyset; + } + + SafeCspHandle cspHandle = null; + if (!UnsafeNativeMethods.CryptAcquireContext(out cspHandle, + keyContainer, + providerName, + providerType, + flags)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + + return cspHandle; + } + + /// <summary> + /// Create a CSP hash object for the specified hash algorithm + /// </summary> + [SecurityCritical] + internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm) { + Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); + Contract.Assert(((AlgorithmClass)algorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm"); + + SafeCspHashHandle hashHandle = null; + if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out hashHandle)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + + return hashHandle; + } + + /// <summary> + /// Fill a buffer with random data generated by the CSP + /// </summary> + [SecurityCritical] + internal static void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer) { + Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); + Contract.Assert(buffer != null && buffer.Length > 0, "buffer != null && buffer.Length > 0"); + + if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, buffer.Length, buffer)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + } + + /// <summary> + /// Fill part of a buffer with random data generated by the CSP + /// </summary> + [SecurityCritical] + internal static unsafe void GenerateRandomBytes(SafeCspHandle cspHandle, byte[] buffer, int offset, int count) + { + Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); + Contract.Assert(buffer != null && buffer.Length > 0, "buffer != null && buffer.Length > 0"); + Contract.Assert(offset >= 0 && count > 0, "offset >= 0 && count > 0"); + Contract.Assert(buffer.Length >= offset + count, "buffer.Length >= offset + count"); + + fixed (byte* pBuffer = &buffer[offset]) + { + if (!UnsafeNativeMethods.CryptGenRandom(cspHandle, count, pBuffer)) + { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + } + } + + /// <summary> + /// Get a DWORD sized property of a hash object + /// </summary> + [SecurityCritical] + internal static int GetHashPropertyInt32(SafeCspHashHandle hashHandle, HashProperty property) { + byte[] rawProperty = GetHashProperty(hashHandle, property); + Contract.Assert(rawProperty.Length == sizeof(int) || rawProperty.Length == 0, "Unexpected property size"); + return rawProperty.Length == sizeof(int) ? BitConverter.ToInt32(rawProperty, 0) : 0; + } + + /// <summary> + /// Get an arbitrary property of a hash object + /// </summary> + [SecurityCritical] + internal static byte[] GetHashProperty(SafeCspHashHandle hashHandle, HashProperty property) { + Contract.Assert(hashHandle != null && !hashHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid"); + + int bufferSize = 0; + byte[] buffer = null; + + // Figure out how big of a buffer we need to hold the property + if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, buffer, ref bufferSize, 0)) { + int errorCode = Marshal.GetLastWin32Error(); + if (errorCode != (int)ErrorCode.MoreData) { + throw new CryptographicException(errorCode); + } + } + + // Now get the property bytes directly + buffer = new byte[bufferSize]; + if (!UnsafeNativeMethods.CryptGetHashParam(hashHandle, property, buffer, ref bufferSize, 0)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + + return buffer; + } + + /// <summary> + /// Get a DWORD sized property of a key stored in a CSP + /// </summary> + [SecurityCritical] + internal static int GetKeyPropertyInt32(SafeCspKeyHandle keyHandle, KeyProperty property) { + byte[] rawProperty = GetKeyProperty(keyHandle, property); + Contract.Assert(rawProperty.Length == sizeof(int) || rawProperty.Length == 0, "Unexpected property size"); + return rawProperty.Length == sizeof(int) ? BitConverter.ToInt32(rawProperty, 0) : 0; + } + + /// <summary> + /// Get an arbitrary property of a key stored in a CSP + /// </summary> + [SecurityCritical] + internal static byte[] GetKeyProperty(SafeCspKeyHandle keyHandle, KeyProperty property) { + Contract.Assert(keyHandle != null && !keyHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid"); + + int bufferSize = 0; + byte[] buffer = null; + + // Figure out how big of a buffer we need to hold the property + if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, buffer, ref bufferSize, 0)) { + int errorCode = Marshal.GetLastWin32Error(); + if (errorCode != (int)ErrorCode.MoreData) { + throw new CryptographicException(errorCode); + } + } + + // Now get the property bytes directly + buffer = new byte[bufferSize]; + if (!UnsafeNativeMethods.CryptGetKeyParam(keyHandle, property, buffer, ref bufferSize, 0)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + + return buffer; + } + + /// <summary> + /// Set an arbitrary property on a hash object + /// </summary> + [SecurityCritical] + internal static void SetHashProperty(SafeCspHashHandle hashHandle, + HashProperty property, + byte[] value) { + Contract.Assert(hashHandle != null && !hashHandle.IsInvalid, "hashHandle != null && !hashHandle.IsInvalid"); + + if (!UnsafeNativeMethods.CryptSetHashParam(hashHandle, property, value, 0)) { + throw new CryptographicException(Marshal.GetLastWin32Error()); + } + } + + /// <summary> + /// Verify that the digital signature created with the specified hash and asymmetric algorithm + /// is valid for the given hash value. + /// </summary> + [SecurityCritical] + internal static bool VerifySignature(SafeCspHandle cspHandle, + SafeCspKeyHandle keyHandle, + AlgorithmID signatureAlgorithm, + AlgorithmID hashAlgorithm, + byte[] hashValue, + byte[] signature) { + Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid"); + Contract.Assert(keyHandle != null && !keyHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid"); + Contract.Assert(((AlgorithmClass)signatureAlgorithm & AlgorithmClass.Signature) == AlgorithmClass.Signature, "Invalid signature algorithm"); + Contract.Assert(((AlgorithmClass)hashAlgorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm"); + Contract.Assert(hashValue != null, "hashValue != null"); + Contract.Assert(signature != null, "signature != null"); + + // CAPI and the CLR have inverse byte orders for signatures, so we need to reverse before verifying + byte[] signatureValue = new byte[signature.Length]; + Array.Copy(signature, signatureValue, signatureValue.Length); + Array.Reverse(signatureValue); + + using (SafeCspHashHandle hashHandle = CreateHashAlgorithm(cspHandle, hashAlgorithm)) { + // Make sure the hash value is the correct size and import it into the CSP + if (hashValue.Length != GetHashPropertyInt32(hashHandle, HashProperty.HashSize)) { + throw new CryptographicException((int)ErrorCode.BadHash); + } + SetHashProperty(hashHandle, HashProperty.HashValue, hashValue); + + // Do the signature verification. A TRUE result means that the signature was valid. A FALSE + // result either means an invalid signature or some other error, so we need to check the last + // error to see which occured. + if (UnsafeNativeMethods.CryptVerifySignature(hashHandle, + signatureValue, + signatureValue.Length, + keyHandle, + null, + 0)) { + return true; + } + else { + int error = Marshal.GetLastWin32Error(); + + if (error != (int)ErrorCode.BadSignature) { + throw new CryptographicException(error); + } + + return false; + } + } + } + } + + /// <summary> + /// SafeHandle representing a native HCRYPTPROV on Windows, or representing all state associated with + /// loading a CSSM CSP on the Mac. The HCRYPTPROV SafeHandle usage is straightforward, however CSSM + /// usage is slightly different. + /// + /// For CSSM we hold three pieces of state: + /// * m_initializedCssm - a flag indicating that CSSM_Init() was successfully called + /// * m_cspModuleGuid - the module GUID of the CSP we loaded, if that CSP was successfully loaded + /// * handle - handle resulting from attaching to the CSP + /// + /// We need to keep all three pieces of state, since we need to teardown in a specific order. If + /// these pieces of state were in seperate SafeHandles we could not guarantee their order of + /// finalization. + /// </summary> + [SecurityCritical] + internal sealed class SafeCspHandle : SafeHandleZeroOrMinusOneIsInvalid { + + private SafeCspHandle() : base(true) { + } + + [DllImport("advapi32")] +#if FEATURE_CORECLR || FEATURE_CER + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] +#endif // FEATURE_CORECLR || FEATURE_CER + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool CryptReleaseContext(IntPtr hProv, int dwFlags); + + /// <summary> + /// Clean up the safe handle's resources. + /// + /// On Windows the cleanup is a straightforward release of the HCRYPTPROV handle. However, on + /// the Mac, CSSM requires that we release resources in the following order: + /// + /// 1. Detach from the CSP + /// 2. Unload the CSP + /// 3. Terminate CSSM + /// + /// Both the unload and terminate operations are ref-counted by CSSM, so it is safe to do these + /// even if other handles are open on the CSP or other CSSM objects are in use. + /// </summary> + [SecurityCritical] + protected override bool ReleaseHandle() { + return CryptReleaseContext(handle, 0); + } + + } + + /// <summary> + /// SafeHandle representing a native HCRYPTHASH + /// </summary> + [SecurityCritical] + internal sealed class SafeCspHashHandle : SafeHandleZeroOrMinusOneIsInvalid { + private SafeCspHashHandle() : base(true) { + } + + [DllImport("advapi32")] +#if FEATURE_CORECLR || FEATURE_CER + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] +#endif // FEATURE_CORECLR || FEATURE_CER + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool CryptDestroyHash(IntPtr hKey); + + [SecurityCritical] + protected override bool ReleaseHandle() { + return CryptDestroyHash(handle); + } + } + + /// <summary> + /// SafeHandle representing a native HCRYPTKEY on Windows. + /// + /// On the Mac, we generate our keys by hand, so they are really just CSSM_KEY structures along with + /// the associated data blobs. Because of this, the only resource that needs to be released when the + /// key is freed is the memory associated with the key blob. + /// + /// However, in order for a SafeCspKeyHandle to marshal as a CSSM_KEY_PTR, as one would expect, the + /// handle value on the Mac is actually a pointer to the CSSM_KEY. We maintain a seperate m_data + /// pointer which is the buffer holding the actual key data. + /// + /// Both of these details add a further invarient that on the Mac a SafeCspKeyHandle may never be an + /// [out] parameter from an API. This is because we always expect that we control the memory buffer + /// that the CSSM_KEY resides in and that we don't have to call CSSM_FreeKey on the data. + /// + /// Keeping this in a SafeHandle rather than just marshaling the key structure direclty buys us a + /// level of abstraction, in that if we ever do need to work with keys that require a CSSM_FreeKey + /// call, we can continue to use the same key handle object. It also means that keys are represented + /// by the same type on both Windows and Mac, so that consumers of the CapiNative layer don't have + /// to know the difference between the two. + /// </summary> + [SecurityCritical] + internal sealed class SafeCspKeyHandle : SafeHandleZeroOrMinusOneIsInvalid { + + internal SafeCspKeyHandle() : base(true) { + } + + [DllImport("advapi32")] +#if FEATURE_CORECLR || FEATURE_CER + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] +#endif // FEATURE_CORECLR || FEATURE_CER + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool CryptDestroyKey(IntPtr hKey); + + [SecurityCritical] + protected override bool ReleaseHandle() { + return CryptDestroyKey(handle); + } + } +} diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/crypto.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/crypto.cs index 8315aefb43c..0e9cc0fa86d 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/crypto.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/crypto.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -20,7 +20,7 @@ namespace System.Security.Cryptography { // and ciphertext-stealing (CTS). Not all implementations will support all modes. [Serializable] [System.Runtime.InteropServices.ComVisible(true)] - public enum CipherMode { // Please keep in [....] with wincrypt.h + public enum CipherMode { // Please keep in sync with wincrypt.h CBC = 1, ECB = 2, OFB = 3, diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoapitransform.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoapitransform.cs index 96765edbf32..ebd6ef63097 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoapitransform.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoapitransform.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -332,7 +332,7 @@ namespace System.Security.Cryptography { } #endif -#if FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS +#if (FEATURE_CRYPTO && FEATURE_X509_SECURESTRINGS) || FEATURE_CORECLR private SecureString m_keyPassword; public SecureString KeyPassword { get { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoconfig.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoconfig.cs index 348d0ec8a1d..7a81d9b05fd 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoconfig.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptoconfig.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -57,6 +57,7 @@ namespace System.Security.Cryptography { // on Vista and the FIPS registry key downlevel. // +#if !FEATURE_CORECLR if (Utils._GetEnforceFipsPolicySetting()) { if (Environment.OSVersion.Version.Major >= 6) { bool fipsEnabled; @@ -73,7 +74,9 @@ namespace System.Security.Cryptography { s_haveFipsAlgorithmPolicy = true; } } - else { + else +#endif // !FEATURE_CORECLR + { s_fipsAlgorithmPolicy = false; s_haveFipsAlgorithmPolicy = true; } @@ -194,7 +197,7 @@ namespace System.Security.Cryptography { #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO Type RSACryptoServiceProviderType = typeof(System.Security.Cryptography.RSACryptoServiceProvider); #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO -#if FEATURE_CRYPTO +#if FEATURE_CRYPTO && !FEATURE_CORECLR Type DSACryptoServiceProviderType = typeof(System.Security.Cryptography.DSACryptoServiceProvider); Type DESCryptoServiceProviderType = typeof(System.Security.Cryptography.DESCryptoServiceProvider); Type TripleDESCryptoServiceProviderType = typeof(System.Security.Cryptography.TripleDESCryptoServiceProvider); @@ -308,7 +311,7 @@ namespace System.Security.Cryptography { ht.Add("System.Security.Cryptography.RSA", RSACryptoServiceProviderType); ht.Add("System.Security.Cryptography.AsymmetricAlgorithm", RSACryptoServiceProviderType); #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO -#if FEATURE_CRYPTO +#if FEATURE_CRYPTO && !FEATURE_CORECLR ht.Add("DSA", DSACryptoServiceProviderType); ht.Add("System.Security.Cryptography.DSA", DSACryptoServiceProviderType); ht.Add("ECDsa", ECDsaCngType); @@ -362,7 +365,7 @@ namespace System.Security.Cryptography { #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO ht.Add("http://www.w3.org/2001/04/xmlenc#sha256", SHA256ManagedType); #endif //FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO -#if FEATURE_CRYPTO +#if FEATURE_CRYPTO && !FEATURE_CORECLR ht.Add("http://www.w3.org/2001/04/xmlenc#sha512", SHA512ManagedType); ht.Add("http://www.w3.org/2001/04/xmlenc#ripemd160", RIPEMD160ManagedType); @@ -461,7 +464,7 @@ namespace System.Security.Cryptography { [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] private static void InitializeConfigInfo() { -#if FEATURE_CRYPTO +#if FEATURE_CRYPTO && !FEATURE_CORECLR if (machineNameHT == null) { lock(InternalSyncObject) diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptostream.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptostream.cs index efbe8b77384..71cd2fd18ea 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptostream.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/cryptostream.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/derivebytes.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/derivebytes.cs index 41b18c8e5ac..ee2265e727b 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/derivebytes.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/derivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -13,12 +13,7 @@ namespace System.Security.Cryptography { [System.Runtime.InteropServices.ComVisible(true)] public abstract class DeriveBytes - // On Orcas DeriveBytes is not disposable, so we cannot add the IDisposable implementation to the - // CoreCLR mscorlib. However, this type does need to be disposable since subtypes can and do hold onto - // native resources. Therefore, on desktop mscorlibs we add an IDisposable implementation. -#if !FEATURE_CORECLR : IDisposable -#endif // !FEATURE_CORECLR { // // public methods diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/des.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/des.cs index 1ee88690879..56d89ed2ee4 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/des.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/des.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs index 43e779d8731..bb01d69877b 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsa.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsa.cs index 51f9a9ae4cc..2e6feaae3a8 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsa.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsa.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs index 318b09813ab..469b1f49d11 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsacryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs index 3f8d457d9df..bf57d241cac 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignatureformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignatureformatter.cs index 8bc61b1c355..260113a9e12 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignatureformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/dsasignatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hashalgorithm.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hashalgorithm.cs index 6b033c2f1d6..479a0b68d79 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hashalgorithm.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hashalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -195,9 +195,12 @@ namespace System.Security.Cryptography { // implementation. Post-Orcas the desktop has an implicit IDispoable implementation. #if FEATURE_CORECLR void IDisposable.Dispose() -#else - public void Dispose() + { + Dispose(); + } #endif // FEATURE_CORECLR + + public void Dispose() { Dispose(true); GC.SuppressFinalize(this); diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmac.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmac.cs index 6c00533d3e5..32b61120db2 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmac.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmac.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacmd5.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacmd5.cs index da536c01f03..0a3347113d7 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacmd5.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacmd5.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacripemd160.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacripemd160.cs index 991d877ff7e..8b2aabebda8 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacripemd160.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacripemd160.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha1.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha1.cs index 1d0b4e75d6b..f31252e2745 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha1.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha1.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha256.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha256.cs index 72e2b56e67d..ef7986240e3 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha256.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha256.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha384.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha384.cs index 1e7418a89f1..e1a973c1c3d 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha384.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha384.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha512.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha512.cs index e8af775a36c..f252b7f53b4 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha512.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/hmacsha512.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/icryptotransform.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/icryptotransform.cs index 68747a9001e..cc6068be927 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/icryptotransform.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/icryptotransform.cs @@ -7,9 +7,9 @@ * * ICryptoTransform.cs // -// <OWNER>[....]</OWNER> +// <OWNER>ShawnFa</OWNER> * - * Author: [....] + * Author: bal * */ diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs index f726d36a05f..d5b501ce558 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/icspasymmetricalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/keyedhashalgorithm.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/keyedhashalgorithm.cs index 0cb2075cc53..6fb7dccd1aa 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/keyedhashalgorithm.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/keyedhashalgorithm.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/mactripledes.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/mactripledes.cs index a0d4e7d9255..19d8be12240 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/mactripledes.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/mactripledes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/maskgenerationmethod.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/maskgenerationmethod.cs index 63c09e7c0ec..0aa22ac46bb 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/maskgenerationmethod.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/maskgenerationmethod.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>ShawnFa</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/md5.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/md5.cs index 2d4bdb70ff9..1029764fd01 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/md5.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/md5.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs index 33c71335eba..bbd42c334cd 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/md5cryptoserviceprovider.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/passwordderivebytes.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/passwordderivebytes.cs index ba6b40ec0ef..a18ec5af8f3 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/passwordderivebytes.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/passwordderivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs index cb2d19469e4..c88a2811b2d 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/pkcs1maskgenerationmethod.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/randomnumbergenerator.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/randomnumbergenerator.cs index 82a129167ce..bd78f5ea4d8 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/randomnumbergenerator.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/randomnumbergenerator.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -18,7 +18,7 @@ namespace System.Security.Cryptography { // On Orcas RandomNumberGenerator is not disposable, so we cannot add the IDisposable implementation to the // CoreCLR mscorlib. However, this type does need to be disposable since subtypes can and do hold onto // native resources. Therefore, on desktop mscorlibs we add an IDisposable implementation. -#if !FEATURE_CORECLR +#if !FEATURE_CORECLR || FEATURE_CORESYSTEM : IDisposable #endif // !FEATURE_CORECLR { @@ -54,6 +54,19 @@ namespace System.Security.Cryptography { public abstract void GetBytes(byte[] data); + public virtual void GetBytes(byte[] data, int offset, int count) { + if (data == null) throw new ArgumentNullException("data"); + if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (offset + count > data.Length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + + if (count > 0) { + byte[] tempData = new byte[count]; + GetBytes(tempData); + Array.Copy(tempData, 0, data, offset, count); + } + } + #if (!FEATURE_CORECLR && !SILVERLIGHT) || FEATURE_LEGACYNETCFCRYPTO public virtual void GetNonZeroBytes(byte[] data) { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2.cs index e8542464bc3..a33eb7255d1 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs index c97acf8e60b..7d51c3a60da 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rfc2898derivebytes.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rfc2898derivebytes.cs index 9585beea6de..ab8edce4816 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rfc2898derivebytes.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rfc2898derivebytes.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -18,6 +18,10 @@ namespace System.Security.Cryptography { using System.IO; using System.Text; using System.Diagnostics.Contracts; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.Versioning; + using System.Security.Cryptography.X509Certificates; [System.Runtime.InteropServices.ComVisible(true)] public class Rfc2898DeriveBytes : DeriveBytes @@ -25,6 +29,8 @@ namespace System.Security.Cryptography { private byte[] m_buffer; private byte[] m_salt; private HMACSHA1 m_hmacsha1; // The pseudo-random generator function used in PBKDF2 + private byte[] m_password; + private CspParameters m_cspParams = new CspParameters(); private uint m_iterations; private uint m_block; @@ -39,6 +45,10 @@ namespace System.Security.Cryptography { public Rfc2898DeriveBytes(string password, int saltSize) : this(password, saltSize, 1000) {} + // This method needs to be safe critical, because in debug builds the C# compiler will include null + // initialization of the _safeProvHandle field in the method. Since SafeProvHandle is critical, a + // transparent reference triggers an error using PasswordDeriveBytes. + [SecuritySafeCritical] public Rfc2898DeriveBytes(string password, int saltSize, int iterations) { if (saltSize < 0) throw new ArgumentOutOfRangeException("saltSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); @@ -49,7 +59,8 @@ namespace System.Security.Cryptography { Salt = salt; IterationCount = iterations; - m_hmacsha1 = new HMACSHA1(new UTF8Encoding(false).GetBytes(password)); + m_password = new UTF8Encoding(false).GetBytes(password); + m_hmacsha1 = new HMACSHA1(m_password); Initialize(); } @@ -57,9 +68,14 @@ namespace System.Security.Cryptography { public Rfc2898DeriveBytes(string password, byte[] salt, int iterations) : this (new UTF8Encoding(false).GetBytes(password), salt, iterations) {} + // This method needs to be safe critical, because in debug builds the C# compiler will include null + // initialization of the _safeProvHandle field in the method. Since SafeProvHandle is critical, a + // transparent reference triggers an error using PasswordDeriveBytes. + [SecuritySafeCritical] public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations) { Salt = salt; IterationCount = iterations; + m_password = password; m_hmacsha1 = new HMACSHA1(password); Initialize(); } @@ -191,5 +207,61 @@ namespace System.Security.Cryptography { m_block++; return ret; } + + [System.Security.SecuritySafeCritical] // auto-generated + public byte[] CryptDeriveKey(string algname, string alghashname, int keySize, byte[] rgbIV) + { + if (keySize < 0) + throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize")); + + int algidhash = X509Utils.NameOrOidToAlgId(alghashname, OidGroup.HashAlgorithm); + if (algidhash == 0) + throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidAlgorithm")); + + int algid = X509Utils.NameOrOidToAlgId(algname, OidGroup.AllGroups); + if (algid == 0) + throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidAlgorithm")); + + // Validate the rgbIV array + if (rgbIV == null) + throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidIV")); + + byte[] key = null; + DeriveKey(ProvHandle, algid, algidhash, + m_password, m_password.Length, keySize << 16, rgbIV, rgbIV.Length, + JitHelpers.GetObjectHandleOnStack(ref key)); + return key; + } + + [System.Security.SecurityCritical] // auto-generated + private SafeProvHandle _safeProvHandle = null; + private SafeProvHandle ProvHandle + { + [System.Security.SecurityCritical] // auto-generated + get + { + if (_safeProvHandle == null) + { + lock (this) + { + if (_safeProvHandle == null) + { + SafeProvHandle safeProvHandle = Utils.AcquireProvHandle(m_cspParams); + System.Threading.Thread.MemoryBarrier(); + _safeProvHandle = safeProvHandle; + } + } + } + return _safeProvHandle; + } + } + + [System.Security.SecurityCritical] // auto-generated + [ResourceExposure(ResourceScope.None)] + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity] + private static extern void DeriveKey(SafeProvHandle hProv, int algid, int algidHash, + byte[] password, int cbPassword, int dwFlags, byte[] IV, int cbIV, + ObjectHandleOnStack retKey); + } } diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndael.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndael.cs index 1c7a9f75c2a..46211eb3074 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndael.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndael.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs index b12bdfbece7..c394cec048a 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs index 79829fac683..dc93a6317d8 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rijndaelmanagedtransform.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160.cs index a75deb9a76d..094a3319b04 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160managed.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160managed.cs index bf13aabcddb..4196bd8de20 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160managed.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/ripemd160managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs index 63b2dc29c89..226632e81e2 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rngcryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -171,6 +171,20 @@ namespace System.Security.Cryptography { CapiNative.GenerateRandomBytes(m_cspHandle, data); } } + + #if FEATURE_CORECLR + [System.Security.SecuritySafeCritical] // auto-generated + #endif + public override void GetBytes(byte[] data, int offset, int count) { + if (data == null) throw new ArgumentNullException("data"); + if (offset < 0) throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + if (offset + count > data.Length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + + if (count > 0) { + CapiNative.GenerateRandomBytes(m_cspHandle, data, offset, count); + } + } #endif // !FEATURE_CORECLR #if !FEATURE_PAL diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsa.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsa.cs index 98d3280cefe..f196b12ba77 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsa.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsa.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -11,6 +11,7 @@ // namespace System.Security.Cryptography { + using System.IO; using System.Text; using System.Runtime.Serialization; using System.Security.Util; @@ -44,17 +45,7 @@ namespace System.Security.Cryptography { [System.Runtime.InteropServices.ComVisible(true)] public abstract class RSA : AsymmetricAlgorithm { - // - // Extending this class allows us to know that you are really implementing - // an RSA key. This is required for anybody providing a new RSA key value - // implemention. - // - // The class provides no methods, fields or anything else. Its only purpose is - // as a heirarchy member for identification of algorithm. - // - protected RSA() { } - // // public methods // @@ -71,13 +62,186 @@ namespace System.Security.Cryptography { return (RSA) CryptoConfig.CreateFromName(algName); } - // Apply the private key to the data. This function represents a - // raw RSA operation -- no implicit depadding of the imput value - abstract public byte[] DecryptValue(byte[] rgb); + // + // New RSA encrypt/decrypt/sign/verify RSA abstractions in .NET 4.6+ and .NET Core + // + // Methods that throw DerivedClassMustOverride are effectively abstract but we + // cannot mark them as such as it would be a breaking change. We'll make them + // abstract in .NET Core. + + public virtual byte[] Encrypt(byte[] data, RSAEncryptionPadding padding) { + throw DerivedClassMustOverride(); + } + + public virtual byte[] Decrypt(byte[] data, RSAEncryptionPadding padding) { + throw DerivedClassMustOverride(); + } + + public virtual byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + throw DerivedClassMustOverride(); + } + + public virtual bool VerifyHash(byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + throw DerivedClassMustOverride(); + } + + protected virtual byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) { + throw DerivedClassMustOverride(); + } + + protected virtual byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) { + throw DerivedClassMustOverride(); + } + + public byte[] SignData(byte[] data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + return SignData(data, 0, data.Length, hashAlgorithm, padding); + } + + public virtual byte[] SignData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (offset < 0 || offset > data.Length) { + throw new ArgumentOutOfRangeException("offset"); + } + if (count < 0 || count > data.Length - offset) { + throw new ArgumentOutOfRangeException("count"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + byte[] hash = HashData(data, offset, count, hashAlgorithm); + return SignHash(hash, hashAlgorithm, padding); + } + + public virtual byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + byte[] hash = HashData(data, hashAlgorithm); + return SignHash(hash, hashAlgorithm, padding); + } + + public bool VerifyData(byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + return VerifyData(data, 0, data.Length, signature, hashAlgorithm, padding); + } + + public virtual bool VerifyData(byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (offset < 0 || offset > data.Length) { + throw new ArgumentOutOfRangeException("offset"); + } + if (count < 0 || count > data.Length - offset) { + throw new ArgumentOutOfRangeException("count"); + } + if (signature == null) { + throw new ArgumentNullException("signature"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + byte[] hash = HashData(data, offset, count, hashAlgorithm); + return VerifyHash(hash, signature, hashAlgorithm, padding); + } + + public bool VerifyData(Stream data, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (signature == null) { + throw new ArgumentNullException("signature"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + byte[] hash = HashData(data, hashAlgorithm); + return VerifyHash(hash, signature, hashAlgorithm, padding); + } + + private static Exception DerivedClassMustOverride() { + return new NotImplementedException(Environment.GetResourceString("NotSupported_SubclassOverride")); + } + + internal static Exception HashAlgorithmNameNullOrEmpty() { + return new ArgumentException(Environment.GetResourceString("Cryptography_HashAlgorithmNameNullOrEmpty"), "hashAlgorithm"); + } + + // + // Legacy encrypt/decrypt RSA abstraction from .NET < 4.6 + // + // These should be obsolete, but we can't mark them as such here due to rules around not introducing + // source breaks to scenarios that compile against the GAC. + // + // They used to be abstract, but the only concrete implementation in RSACryptoServiceProvider threw + // NotSupportedException! This has been moved up to the base so all subclasses can ignore them moving forward. + // They will also be removed from .NET Core altogether. + // + // The original intent was for these to perform the RSA algorithm without padding/depadding. This can + // be seen by how the RSAXxx(De)Formatter classes call them in the non-RSACryptoServiceProvider case -- + // they do the padding/depadding in managed code. + // + // Unfortunately, these formatter classes are still incompatible with RSACng or any derived class that does not + // implement EncryptValue, DecryptValue as the formatters speculatively expected non-RSACryptoServiceProvider + // to do. That needs to be fixed in a subsequent release. We can still do it as it would move an exception to a + // correct result... + // + + // [Obsolete] + public virtual byte[] DecryptValue(byte[] rgb) { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method")); + } + + // [Obsolete] + public virtual byte[] EncryptValue(byte[] rgb) { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method")); + } + + // + // These should also be obsolete (on the base). They aren't well defined nor are they used + // anywhere in the FX apart from checking that they're not null. + // + // For new derived RSA classes, we'll just return "RSA" which is analagous to what ECDsa + // and ECDiffieHellman do. + // + // Note that for compat, RSACryptoServiceProvider still overrides and returns RSA-PKCS1-KEYEX + // and http://www.w3.org/2000/09/xmldsig#rsa-sha1 + // + + public override string KeyExchangeAlgorithm { + get { return "RSA"; } + } + + public override string SignatureAlgorithm { + get { return "RSA"; } + } - // Apply the public key to the data. Again, this is a raw operation, no - // automatic padding. - abstract public byte[] EncryptValue(byte[] rgb); // Import/export functions diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs index fd285c5514a..e27577d7a9c 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -502,5 +502,145 @@ namespace System.Security.Cryptography { private static bool IsPublic(RSAParameters rsaParams) { return (rsaParams.P == null); } + + // + // Adapt new RSA abstraction to legacy RSACryptoServiceProvider surface area. + // + + // NOTE: For the new API, we go straight to CAPI for fixed set of hash algorithms and don't use crypto config here. + // + // Reasons: + // 1. We're moving away from crypto config and we won't have it when porting to .NET Core + // + // 2. It's slow to lookup and slow to use as the base HashAlgorithm adds considerable overhead + // (redundant defensive copy + double-initialization for the single-use case). + // + + [SecuritySafeCritical] + protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) { + // we're sealed and the base should have checked this already + Contract.Assert(data != null); + Contract.Assert(offset >= 0 && offset <= data.Length); + Contract.Assert(count >= 0 && count <= data.Length); + Contract.Assert(!String.IsNullOrEmpty(hashAlgorithm.Name)); + + using (SafeHashHandle hashHandle = Utils.CreateHash(Utils.StaticProvHandle, GetAlgorithmId(hashAlgorithm))) { + Utils.HashData(hashHandle, data, offset, count); + return Utils.EndHash(hashHandle); + } + } + + [SecuritySafeCritical] + protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) { + // we're sealed and the base should have checked this already + Contract.Assert(data != null); + Contract.Assert(!String.IsNullOrEmpty(hashAlgorithm.Name)); + + using (SafeHashHandle hashHandle = Utils.CreateHash(Utils.StaticProvHandle, GetAlgorithmId(hashAlgorithm))) { + // Read the data 4KB at a time, providing similar read characteristics to a standard HashAlgorithm + byte[] buffer = new byte[4096]; + int bytesRead = 0; + do { + bytesRead = data.Read(buffer, 0, buffer.Length); + if (bytesRead > 0) { + Utils.HashData(hashHandle, buffer, 0, bytesRead); + } + } while (bytesRead > 0); + + return Utils.EndHash(hashHandle); + } + } + + private static int GetAlgorithmId(HashAlgorithmName hashAlgorithm) { + switch (hashAlgorithm.Name) { + case "MD5": + return Constants.CALG_MD5; + case "SHA1": + return Constants.CALG_SHA1; + case "SHA256": + return Constants.CALG_SHA_256; + case "SHA384": + return Constants.CALG_SHA_384; + case "SHA512": + return Constants.CALG_SHA_512; + default: + throw new CryptographicException(Environment.GetResourceString("Cryptography_UnknownHashAlgorithm", hashAlgorithm.Name)); + } + } + + public override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + if (padding == RSAEncryptionPadding.Pkcs1) { + return Encrypt(data, fOAEP: false); + } else if (padding == RSAEncryptionPadding.OaepSHA1) { + return Encrypt(data, fOAEP: true); + } else { + throw PaddingModeNotSupported(); + } + } + + public override byte[] Decrypt(byte[] data, RSAEncryptionPadding padding) { + if (data == null) { + throw new ArgumentNullException("data"); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + + if (padding == RSAEncryptionPadding.Pkcs1) { + return Decrypt(data, fOAEP: false); + } else if (padding == RSAEncryptionPadding.OaepSHA1) { + return Decrypt(data, fOAEP: true); + } else { + throw PaddingModeNotSupported(); + } + } + + public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (hash == null) { + throw new ArgumentNullException("hash"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + if (padding != RSASignaturePadding.Pkcs1) { + throw PaddingModeNotSupported(); + } + + return SignHash(hash, GetAlgorithmId(hashAlgorithm)); + } + + public override bool VerifyHash(byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { + if (hash == null) { + throw new ArgumentNullException("hash"); + } + if (signature == null) { + throw new ArgumentNullException("signature"); + } + if (String.IsNullOrEmpty(hashAlgorithm.Name)) { + throw HashAlgorithmNameNullOrEmpty(); + } + if (padding == null) { + throw new ArgumentNullException("padding"); + } + if (padding != RSASignaturePadding.Pkcs1) { + throw PaddingModeNotSupported(); + } + + return VerifyHash(hash, GetAlgorithmId(hashAlgorithm), signature); + } + + private static Exception PaddingModeNotSupported() { + return new CryptographicException(Environment.GetResourceString("Cryptography_InvalidPaddingMode")); + } } } diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs index 416b29f5079..87910a4e171 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangedeformatter.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs index 68746fe1773..3162663047a 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsaoaepkeyexchangeformatter.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs index ed412c64dba..3ea79366871 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangedeformatter.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs index 19f34b6d6fb..a741449a8bd 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1keyexchangeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // namespace System.Security.Cryptography { diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs index 01363fefbdd..3c500c5fdb6 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signaturedeformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs index 249ea4b072c..9157b7bf243 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/rsapkcs1signatureformatter.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/safecryptohandles.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/safecryptohandles.cs index 19b8885deef..e7dc76c0944 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/safecryptohandles.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/safecryptohandles.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1.cs index 772e725d66a..c1a4b21232c 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs index ed886250ff9..0b25472e251 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1cryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1managed.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1managed.cs index ef07a4b17c8..863cea2e183 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1managed.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha1managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256.cs index e403045f332..5230a1eaebc 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256managed.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256managed.cs index 41711c80843..242bfff1b17 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256managed.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha256managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384.cs index 268be7eae9b..64036523daa 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384managed.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384managed.cs index d17eaaa5301..c10ab52f6d6 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384managed.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha384managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512.cs index cfff7e2bb3a..a5e1a9f80b4 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512managed.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512managed.cs index 31641440b60..20ec6a6b7b7 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512managed.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/sha512managed.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/signaturedescription.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/signaturedescription.cs index f115e8afc39..4f02d3702c8 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/signaturedescription.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/signaturedescription.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/symmetricalgorithm.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/symmetricalgorithm.cs index e1b332657ac..d2c2a022b20 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/symmetricalgorithm.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/symmetricalgorithm.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -41,9 +41,12 @@ namespace System.Security.Cryptography { // implementation. Post-Orcas the desktop has an implicit IDispoable implementation. #if FEATURE_CORECLR void IDisposable.Dispose() -#else - public void Dispose() + { + Dispose(); + } #endif // FEATURE_CORECLR + + public void Dispose() { Dispose(true); GC.SuppressFinalize(this); diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledes.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledes.cs index 2481830012f..c26517093e3 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledes.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledes.cs @@ -4,7 +4,7 @@ using System.Diagnostics.Contracts; // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs index aaa5948e46b..25e63a78a89 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/utils.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/utils.cs index f18ade9e402..c9677213bcc 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/utils.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/utils.cs @@ -3,7 +3,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== -// <OWNER>[....]</OWNER> +// <OWNER>Microsoft</OWNER> // // @@ -87,7 +87,7 @@ namespace System.Security.Cryptography internal const int CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | 1); #endif // FEATURE_CRYPTO - internal const int PROV_RSA_FULL = 1; + internal const int PROV_RSA_FULL = 1; internal const int PROV_DSS_DH = 13; internal const int PROV_RSA_AES = 24; @@ -142,6 +142,10 @@ namespace System.Security.Cryptography { } + // Provider type to use by default for RSA operations. We want to use RSA-AES CSP + // since it enables access to SHA-2 operations. All currently supported OSes support RSA-AES. + internal const int DefaultRsaProviderType = Constants.PROV_RSA_AES; +#if !MONO #if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO // Private object for locking instead of locking on a public type for SQL reliability work. private static Object s_InternalSyncObject = new Object(); @@ -149,40 +153,7 @@ namespace System.Security.Cryptography private static Object InternalSyncObject { get { return s_InternalSyncObject; } } -#endif // FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO - - // Provider type to use by default for RSA operations. On systems which support the RSA-AES CSP, we - // want to use that since it enables access to SHA-2 operations, downlevel we fall back to the - // RSA-FULL CSP. - private static volatile int _defaultRsaProviderType; - private static volatile bool _haveDefaultRsaProviderType; - internal static int DefaultRsaProviderType - { - get { - if (!_haveDefaultRsaProviderType) - { -#if MONO - // The default provider value must remain 1 for Mono, otherwise we won't be able - // to locate keypairs that were serialized by Mono versions 4.0 and lower. - // (The ProviderType property in the CspParameters class affects serialization) - _defaultRsaProviderType = 1; -#else - // The AES CSP is only supported on WinXP and higher - bool osSupportsAesCsp = Environment.OSVersion.Platform == PlatformID.Win32NT && - (Environment.OSVersion.Version.Major > 5 || - (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1)); - - _defaultRsaProviderType = osSupportsAesCsp ? Constants.PROV_RSA_AES : Constants.PROV_RSA_FULL; -#endif - _haveDefaultRsaProviderType = true; - } - return _defaultRsaProviderType; - } - } -#if !MONO -#if FEATURE_CRYPTO || FEATURE_LEGACYNETCFCRYPTO -#if !FEATURE_PAL [System.Security.SecurityCritical] // auto-generated private static volatile SafeProvHandle _safeProvHandle; internal static SafeProvHandle StaticProvHandle { @@ -191,16 +162,13 @@ namespace System.Security.Cryptography if (_safeProvHandle == null) { lock (InternalSyncObject) { if (_safeProvHandle == null) { - SafeProvHandle safeProvHandle = AcquireProvHandle(new CspParameters(DefaultRsaProviderType)); - Thread.MemoryBarrier(); - _safeProvHandle = safeProvHandle; + _safeProvHandle = AcquireProvHandle(new CspParameters(DefaultRsaProviderType)); } } } return _safeProvHandle; } } -#endif // !FEATURE_PAL [System.Security.SecurityCritical] // auto-generated private static volatile SafeProvHandle _safeDssProvHandle; @@ -210,9 +178,7 @@ namespace System.Security.Cryptography if (_safeDssProvHandle == null) { lock (InternalSyncObject) { if (_safeDssProvHandle == null) { - SafeProvHandle safeProvHandle = CreateProvHandle(new CspParameters(Constants.PROV_DSS_DH), true); - Thread.MemoryBarrier(); - _safeDssProvHandle = safeProvHandle; + _safeDssProvHandle = CreateProvHandle(new CspParameters(Constants.PROV_DSS_DH), true); } } } @@ -512,8 +478,9 @@ namespace System.Security.Cryptography } } #endif // FEATURE_CRYPTO + #endif - private static volatile RNGCryptoServiceProvider _rng = null; + private static volatile RNGCryptoServiceProvider _rng; internal static RNGCryptoServiceProvider StaticRandomNumberGenerator { get { if (_rng == null) diff --git a/mcs/class/referencesource/mscorlib/system/security/cryptography/x509certificates/x509certificate.cs b/mcs/class/referencesource/mscorlib/system/security/cryptography/x509certificates/x509certificate.cs index 114fbc7241b..31d9a126e94 100644 --- a/mcs/class/referencesource/mscorlib/system/security/cryptography/x509certificates/x509certificate.cs +++ b/mcs/class/referencesource/mscorlib/system/security/cryptography/x509certificates/x509certificate.cs @@ -26,9 +26,7 @@ namespace System.Security.Cryptography.X509Certificates { [System.Runtime.InteropServices.ComVisible(true)] public enum X509ContentType { Unknown = 0x00, - Cert = 0x01 -#if !FEATURE_CORECLR - , + Cert = 0x01, SerializedCert = 0x02, #if !FEATURE_PAL Pfx = 0x03, @@ -37,7 +35,6 @@ namespace System.Security.Cryptography.X509Certificates { SerializedStore = 0x04, Pkcs7 = 0x05, Authenticode = 0x06 -#endif // !FEATURE_CORECLR } // DefaultKeySet, UserKeySet and MachineKeySet are mutually exclusive @@ -45,20 +42,20 @@ namespace System.Security.Cryptography.X509Certificates { [Flags] [System.Runtime.InteropServices.ComVisible(true)] public enum X509KeyStorageFlags { - DefaultKeySet = 0x00 -#if !FEATURE_CORECLR - , + DefaultKeySet = 0x00, UserKeySet = 0x01, MachineKeySet = 0x02, Exportable = 0x04, UserProtected = 0x08, PersistKeySet = 0x10 -#endif // !FEATURE_CORECLR } [Serializable] [System.Runtime.InteropServices.ComVisible(true)] - public class X509Certificate : IDeserializationCallback, ISerializable { + public class X509Certificate : + IDisposable, + IDeserializationCallback, + ISerializable { private const string m_format = "X509"; private string m_subjectName; private string m_issuerName; @@ -416,7 +413,6 @@ namespace System.Security.Cryptography.X509Certificates { CultureInfo culture = CultureInfo.CurrentCulture; if (!culture.DateTimeFormat.Calendar.IsValidDay(date.Year, date.Month, date.Day, 0)) { -#if !FEATURE_ONLY_CORE_CALENDARS // The most common case of culture failing to work is in the Um-AlQuara calendar. In this case, // we can fall back to the Hijri calendar, otherwise fall back to the invariant culture. if (culture.DateTimeFormat.Calendar is UmAlQuraCalendar) { @@ -424,7 +420,6 @@ namespace System.Security.Cryptography.X509Certificates { culture.DateTimeFormat.Calendar = new HijriCalendar(); } else -#endif // !FEATURE_ONLY_CORE_CALENDARS { culture = CultureInfo.InvariantCulture; } @@ -577,6 +572,17 @@ namespace System.Security.Cryptography.X509Certificates { } m_certContextCloned = false; } + + public void Dispose() { + Dispose(true); + } + + [System.Security.SecuritySafeCritical] + protected virtual void Dispose(bool disposing) { + if (disposing) { + Reset(); + } + } #if FEATURE_SERIALIZATION /// <internalonly/> |