Imported Upstream version 4.3.2.467

Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
Xamarin Public Jenkins
2016-02-22 11:00:01 -05:00
parent f302175246
commit f3e3aab35a
4097 changed files with 122406 additions and 82300 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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,
}
}

View File

@@ -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();
}
}
}

View File

@@ -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,
}
}

View File

@@ -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();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -7,9 +7,9 @@
*
* ICryptoTransform.cs
//
// <OWNER>[....]</OWNER>
// <OWNER>ShawnFa</OWNER>
*
* Author: [....]
* Author: bal
*
*/

View File

@@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
// <OWNER>ShawnFa</OWNER>
//
namespace System.Security.Cryptography {

View File

@@ -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)
{

View File

@@ -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,62 @@ namespace System.Security.Cryptography {
m_block++;
return ret;
}
#if !MONO
[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);
#endif
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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"));
}
}
}

View File

@@ -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);

View File

@@ -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,11 @@ 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 +154,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 +163,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 +179,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);
}
}
}
@@ -513,7 +480,8 @@ 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)

Some files were not shown because too many files have changed in this diff Show More