Imported Upstream version 5.16.0.100

Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-08-07 15:19:03 +00:00
parent 0a9828183b
commit 7d7f676260
4419 changed files with 170950 additions and 90273 deletions

View File

@ -195,13 +195,39 @@ namespace System.Security.Cryptography
public static System.Security.Cryptography.ECCurve nistP521 { get { throw null; } }
}
}
public abstract partial class ECDiffieHellman : System.Security.Cryptography.AsymmetricAlgorithm
{
protected ECDiffieHellman() { }
public override string KeyExchangeAlgorithm { get { throw null; } }
public abstract System.Security.Cryptography.ECDiffieHellmanPublicKey PublicKey { get; }
public override string SignatureAlgorithm { get { throw null; } }
public static new System.Security.Cryptography.ECDiffieHellman Create() { throw null; }
public static System.Security.Cryptography.ECDiffieHellman Create(System.Security.Cryptography.ECCurve curve) { throw null; }
public static System.Security.Cryptography.ECDiffieHellman Create(System.Security.Cryptography.ECParameters parameters) { throw null; }
public static new System.Security.Cryptography.ECDiffieHellman Create(string algorithm) { throw null; }
public byte[] DeriveKeyFromHash(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual byte[] DeriveKeyFromHash(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[] secretPrepend, byte[] secretAppend) { throw null; }
public byte[] DeriveKeyFromHmac(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[] hmacKey) { throw null; }
public virtual byte[] DeriveKeyFromHmac(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend) { throw null; }
public virtual byte[] DeriveKeyMaterial(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey) { throw null; }
public virtual byte[] DeriveKeyTls(System.Security.Cryptography.ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed) { throw null; }
public virtual System.Security.Cryptography.ECParameters ExportExplicitParameters(bool includePrivateParameters) { throw null; }
public virtual System.Security.Cryptography.ECParameters ExportParameters(bool includePrivateParameters) { throw null; }
public override void FromXmlString(string xmlString) { }
public virtual void GenerateKey(System.Security.Cryptography.ECCurve curve) { }
public virtual void ImportParameters(System.Security.Cryptography.ECParameters parameters) { }
public override string ToXmlString(bool includePrivateParameters) { throw null; }
}
public abstract partial class ECDiffieHellmanPublicKey : System.IDisposable
{
protected ECDiffieHellmanPublicKey() { }
protected ECDiffieHellmanPublicKey(byte[] keyBlob) { }
public void Dispose() { }
protected virtual void Dispose(bool disposing) { }
public virtual byte[] ToByteArray() { throw null; }
public virtual string ToXmlString() { throw null; }
public virtual System.Security.Cryptography.ECParameters ExportExplicitParameters() { throw null; }
public virtual System.Security.Cryptography.ECParameters ExportParameters() { throw null; }
}
public abstract partial class ECDsa : System.Security.Cryptography.AsymmetricAlgorithm
{

View File

@ -10,17 +10,17 @@ namespace System.Security.Cryptography
{
public abstract partial class DSA : System.Security.Cryptography.AsymmetricAlgorithm
{
public virtual bool TryCreateSignature(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TryCreateSignature(ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm) { throw null; }
public virtual bool VerifySignature(ReadOnlySpan<byte> rgbHash, ReadOnlySpan<byte> rgbSignature) { throw null; }
public virtual bool VerifySignature(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature) { throw null; }
}
public abstract partial class ECDsa : System.Security.Cryptography.AsymmetricAlgorithm
{
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten) { throw null; }
public virtual bool VerifyData(ReadOnlySpan<byte> data, ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm) { throw null; }
public virtual bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature) { throw null; }
}
@ -31,16 +31,17 @@ namespace System.Security.Cryptography
}
public abstract partial class RandomNumberGenerator : System.IDisposable
{
public static void Fill(Span<byte> data) => throw null;
public virtual void GetBytes(System.Span<byte> data) { }
public virtual void GetNonZeroBytes(System.Span<byte> data) { }
}
public abstract partial class RSA : System.Security.Cryptography.AsymmetricAlgorithm
{
public virtual bool TryDecrypt(System.ReadOnlySpan<byte> source, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
public virtual bool TryEncrypt(System.ReadOnlySpan<byte> source, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(System.ReadOnlySpan<byte> source, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool TryDecrypt(System.ReadOnlySpan<byte> data, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
public virtual bool TryEncrypt(System.ReadOnlySpan<byte> data, System.Span<byte> destination, RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(System.ReadOnlySpan<byte> hash, System.Span<byte> destination, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool VerifyData(System.ReadOnlySpan<byte> data, System.ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { throw null; }
public virtual bool VerifyHash(System.ReadOnlySpan<byte> hash, System.ReadOnlySpan<byte> signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding) { throw null; }
}

View File

@ -27,7 +27,7 @@ namespace Internal.Cryptography
return new AppleDigestProvider(Interop.AppleCrypto.PAL_HashAlgorithm.Sha512);
}
throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
}
public static HashProvider CreateMacProvider(string hashAlgorithmId, byte[] key)
@ -46,7 +46,7 @@ namespace Internal.Cryptography
return new AppleHmacProvider(Interop.AppleCrypto.PAL_HashAlgorithm.Sha512, key);
}
throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
}
// -----------------------------

View File

@ -27,7 +27,7 @@ namespace Internal.Cryptography
case HashAlgorithmNames.MD5:
return new EvpHashProvider(Interop.Crypto.EvpMd5());
}
throw new CryptographicException();
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
}
public static unsafe HashProvider CreateMacProvider(string hashAlgorithmId, byte[] key)
@ -45,7 +45,7 @@ namespace Internal.Cryptography
case HashAlgorithmNames.MD5:
return new HmacHashProvider(Interop.Crypto.EvpMd5(), key);
}
throw new CryptographicException();
throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId));
}
// -----------------------------

View File

@ -3,16 +3,17 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.Private;
namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private void GetBytes(ref byte pbBuffer, int count)
private static unsafe void GetBytes(byte* pbBuffer, int count)
{
Debug.Assert(count > 0);
Interop.AppleCrypto.GetRandomBytes(ref pbBuffer, count);
Interop.AppleCrypto.GetRandomBytes(pbBuffer, count);
}
}
}

View File

@ -8,11 +8,11 @@ namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private void GetBytes(ref byte pbBuffer, int count)
private static unsafe void GetBytes(byte* pbBuffer, int count)
{
Debug.Assert(count > 0);
if (!Interop.Crypto.GetRandomBytes(ref pbBuffer, count))
if (!Interop.Crypto.GetRandomBytes(pbBuffer, count))
{
throw Interop.Crypto.CreateOpenSslCryptographicException();
}

View File

@ -3,16 +3,17 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Diagnostics.Private;
namespace System.Security.Cryptography
{
partial class RandomNumberGeneratorImplementation
{
private void GetBytes(ref byte pbBuffer, int count)
private static unsafe void GetBytes(byte* pbBuffer, int count)
{
Debug.Assert(count > 0);
Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(ref pbBuffer, count);
Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(IntPtr.Zero, pbBuffer, count, Interop.BCrypt.BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (status != Interop.BCrypt.NTSTATUS.STATUS_SUCCESS)
throw Interop.BCrypt.CreateCryptographicException(status);
}

View File

@ -8,6 +8,16 @@ namespace System.Security.Cryptography
{
internal sealed partial class RandomNumberGeneratorImplementation : RandomNumberGenerator
{
// As long as each implementation can provide a static GetBytes(ref byte buf, int length)
// they can share this one implementation of FillSpan.
internal static unsafe void FillSpan(Span<byte> data)
{
if (data.Length > 0)
{
fixed (byte* ptr = data) GetBytes(ptr, data.Length);
}
}
public override void GetBytes(byte[] data)
{
if (data == null) throw new ArgumentNullException(nameof(data));
@ -20,11 +30,11 @@ namespace System.Security.Cryptography
GetBytes(new Span<byte>(data, offset, count));
}
public override void GetBytes(Span<byte> data)
public override unsafe void GetBytes(Span<byte> data)
{
if (data.Length > 0)
{
GetBytes(ref MemoryMarshal.GetReference(data), data.Length);
fixed (byte* ptr = data) GetBytes(ptr, data.Length);
}
}

View File

@ -79,6 +79,18 @@
<data name="Arg_CryptographyException" xml:space="preserve">
<value>Error occurred during a cryptographic operation.</value>
</data>
<data name="Cryptography_ArgECDHKeySizeMismatch" xml:space="preserve">
<value>The keys from both parties must be the same size to generate a secret agreement.</value>
</data>
<data name="Cryptography_ArgECDHRequiresECDHKey" xml:space="preserve">
<value>Keys used with the ECDiffieHellmanCng algorithm must have an algorithm group of ECDiffieHellman.</value>
</data>
<data name="Cryptography_TlsRequiresLabelAndSeed" xml:space="preserve">
<value>The TLS key derivation function requires both the label and seed properties to be set.</value>
</data>
<data name="Cryptography_TlsRequires64ByteSeed" xml:space="preserve">
<value>The TLS key derivation function requires a seed value of exactly 64 bytes.</value>
</data>
<data name="Cryptography_BadHashSize_ForAlgorithm" xml:space="preserve">
<value>The provided value of {0} bytes does not match the expected size of {1} bytes for the algorithm ({2}).</value>
</data>
@ -94,6 +106,9 @@
<data name="Cryptography_DSA_KeyGenNotSupported" xml:space="preserve">
<value>DSA keys can be imported, but new key generation is not supported on this platform.</value>
</data>
<data name="Cryptography_Encryption_MessageTooLong" xml:space="preserve">
<value>The message exceeds the maximum allowable length for the chosen options ({0}).</value>
</data>
<data name="Cryptography_ECXmlSerializationFormatRequired" xml:space="preserve">
<value>XML serialization of an elliptic curve key requires using an overload which specifies the XML format to be used.</value>
</data>
@ -161,7 +176,7 @@
<value>This operation is not supported for this class.</value>
</data>
<data name="Cryptography_InvalidPadding" xml:space="preserve">
<value>Specified padding mode is not valid for this algorithm.</value>
<value>Padding is invalid and cannot be removed.</value>
</data>
<data name="Cryptography_InvalidRsaParameters" xml:space="preserve">
<value>The specified RSA parameters are not valid; both Exponent and Modulus are required fields.</value>
@ -172,6 +187,9 @@
<data name="Cryptography_Invalid_IA5String" xml:space="preserve">
<value>The string contains a character not in the 7 bit ASCII character set.</value>
</data>
<data name="Cryptography_KeyTooSmall" xml:space="preserve">
<value>The key is too small for the requested operation.</value>
</data>
<data name="Cryptography_MissingIV" xml:space="preserve">
<value>The cipher mode specified requires that an initialization vector (IV) be used.</value>
</data>
@ -190,6 +208,9 @@
<data name="Cryptography_NotValidPublicOrPrivateKey" xml:space="preserve">
<value>Key is not a valid public or private key.</value>
</data>
<data name="Cryptography_OAEP_Decryption_Failed" xml:space="preserve">
<value>Error occurred while decoding OAEP padding.</value>
</data>
<data name="Cryptography_OpenInvalidHandle" xml:space="preserve">
<value>Cannot open an invalid handle.</value>
</data>
@ -211,6 +232,12 @@
<data name="Cryptography_Rijndael_BlockSize" xml:space="preserve">
<value>BlockSize must be 128 in this implementation.</value>
</data>
<data name="Cryptography_RSA_DecryptWrongSize" xml:space="preserve">
<value>The length of the data to decrypt is not valid for the size of this key.</value>
</data>
<data name="Cryptography_SignHash_WrongSize" xml:space="preserve">
<value>The provided hash value is not the expected size for the specified hash algorithm.</value>
</data>
<data name="Cryptography_TransformBeyondEndOfBuffer" xml:space="preserve">
<value>Attempt to transform beyond end of buffer.</value>
</data>

View File

@ -47,7 +47,10 @@
<Compile Include="System\Security\Cryptography\ECCurve.cs" />
<Compile Include="System\Security\Cryptography\ECCurve.ECCurveType.cs" />
<Compile Include="System\Security\Cryptography\ECCurve.NamedCurves.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellman.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellman.Xml.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanPublicKey.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanPublicKey.ExportParameters.cs" />
<Compile Include="System\Security\Cryptography\ECDsa.cs" />
<Compile Include="System\Security\Cryptography\ECDsa.Xml.cs" />
<Compile Include="System\Security\Cryptography\ECParameters.cs" />
@ -104,12 +107,21 @@
<Compile Include="$(CommonPath)\Internal\Cryptography\UniversalCryptoDecryptor.cs">
<Link>Internal\Cryptography\UniversalCryptoDecryptor.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\RsaPaddingProcessor.cs">
<Link>Common\System\Security\Cryptography\RsaPaddingProcessor.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' and '$(IsPartialFacadeAssembly)' != 'true'">
<Compile Include="System\Security\Cryptography\CngKeyLite.cs" />
<Compile Include="System\Security\Cryptography\DSACng.cs" />
<Compile Include="System\Security\Cryptography\ECCngKey.cs" />
<Compile Include="System\Security\Cryptography\ECDsaCng.cs" />
<Compile Include="System\Security\Cryptography\ECDsaCng.Key.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellman.Create.Cng.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanCng.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanCng.Derive.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanCng.Key.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellmanCngPublicKey.cs" />
<Compile Include="System\Security\Cryptography\RSACng.cs" />
<Compile Include="Internal\Cryptography\AesImplementation.Windows.cs" />
<Compile Include="Internal\Cryptography\DesImplementation.Windows.cs" />
@ -129,11 +141,11 @@
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\Cng.cs">
<Link>Common\Interop\Windows\BCrypt\Cng.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs">
<Link>Common\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs</Link>
<Compile Include="$(CommonPath)\CoreLib\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs">
<Link>Common\CoreLib\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\Interop.NTSTATUS.cs">
<Link>Common\Interop\Windows\BCrypt\Interop.NTSTATUS.cs</Link>
<Compile Include="$(CommonPath)\CoreLib\Interop\Windows\BCrypt\Interop.NTSTATUS.cs">
<Link>Common\CoreLib\Interop\Windows\BCrypt\Interop.NTSTATUS.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\Interop.AsymmetricEncryption.Types.cs">
<Link>Common\Interop\Windows\BCrypt\Interop.AsymmetricEncryption.Types.cs</Link>
@ -168,6 +180,15 @@
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\Interop.BCryptPropertyStrings.cs">
<Link>Interop\Windows\BCrypt\Interop.BCryptPropertyStrings.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\NCrypt\Interop.NCryptDeriveKeyMaterial.cs">
<Link>Internal\Windows\NCrypt\Interop.NCryptDeriveKeyMaterial.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\NCrypt\Interop.NCryptDeriveSecretAgreement.cs">
<Link>Internal\Windows\NCrypt\Interop.NCryptDeriveSecretAgreement.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\NCrypt\Interop.NCryptBuffer.cs">
<Link>Internal\Windows\NCrypt\Interop.NCryptBuffer.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\BCrypt\BCryptAlgorithmCache.cs">
<Link>Internal\Windows\BCrypt\BCryptAlgorithmCache.cs</Link>
</Compile>
@ -255,6 +276,12 @@
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECCng.ImportExport.cs">
<Link>Common\System\Security\Cryptography\ECCng.ImportExport.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanCng.cs">
<Link>Common\System\Security\Cryptography\ECDsaCng.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanCng.ImportExport.cs">
<Link>Common\System\Security\Cryptography\ECDsaCng.ImportExport.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDsaCng.cs">
<Link>Common\System\Security\Cryptography\ECDsaCng.cs</Link>
</Compile>
@ -305,6 +332,15 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EcKey.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EcKey.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.EcKey.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.EcKey.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Ecdh.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Ecdh.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.ERR.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.ERR.cs</Link>
</Compile>
@ -344,23 +380,41 @@
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeEvpMdCtxHandle.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeEvpMdCtxHandle.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeEvpPkeyCtxHandle.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeEvpPkeyCtxHandle.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeHmacCtxHandle.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeHmacCtxHandle.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeInteriorHandle.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeInteriorHandle.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeEvpPKeyHandle.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeEvpPKeyHandle.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeRsaHandle.Unix.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeRsaHandle.Unix.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\DSAOpenSsl.cs">
<Link>Common\System\Security\Cryptography\DSAOpenSsl.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanOpenSsl.cs">
<Link>Common\System\Security\Cryptography\ECDiffieHellmanOpenSsl.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanOpenSsl.Derive.cs">
<Link>Common\System\Security\Cryptography\ECDiffieHellmanOpenSsl.Derive.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanOpenSslPublicKey.cs">
<Link>Common\System\Security\Cryptography\ECDiffieHellmanOpenSslPublicKey.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDsaOpenSsl.cs">
<Link>Common\System\Security\Cryptography\ECDsaOpenSsl.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDsaOpenSsl.ImportExport.cs">
<Link>Common\System\Security\Cryptography\ECDsaOpenSsl.ImportExport.cs</Link>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECOpenSsl.cs">
<Link>Common\System\Security\Cryptography\ECOpenSsl.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECOpenSsl.ImportExport.cs">
<Link>Common\System\Security\Cryptography\ECOpenSsl.ImportExport.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\RSAOpenSsl.cs">
<Link>Common\System\Security\Cryptography\RSAOpenSsl.cs</Link>
@ -373,6 +427,7 @@
<Compile Include="Internal\Cryptography\RC2Implementation.Unix.cs" />
<Compile Include="Internal\Cryptography\TripleDesImplementation.Unix.cs" />
<Compile Include="System\Security\Cryptography\ECDsaOpenSsl.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellman.Create.OpenSsl.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetsOSX)' == 'true' ">
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.cs">
@ -405,6 +460,9 @@
<Compile Include="$(CommonPath)\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Hmac.cs">
<Link>Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Hmac.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.KeyAgree.cs">
<Link>Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.KeyAgree.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Keychain.cs">
<Link>Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.Keychain.cs</Link>
</Compile>
@ -441,6 +499,12 @@
<Compile Include="$(CommonPath)\System\Security\Cryptography\DSASecurityTransforms.cs">
<Link>Common\System\Security\Cryptography\DSASecurityTransforms.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\EccSecurityTransforms.cs">
<Link>Common\System\Security\Cryptography\EccSecurityTransforms.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanSecurityTransforms.cs">
<Link>Common\System\Security\Cryptography\ECDiffieHellmanSecurityTransforms.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDsaSecurityTransforms.cs">
<Link>Common\System\Security\Cryptography\ECDsaSecurityTransforms.cs</Link>
</Compile>
@ -460,6 +524,7 @@
<Compile Include="Internal\Cryptography\RandomNumberGeneratorImplementation.OSX.cs" />
<Compile Include="Internal\Cryptography\RC2Implementation.OSX.cs" />
<Compile Include="Internal\Cryptography\TripleDesImplementation.OSX.cs" />
<Compile Include="System\Security\Cryptography\ECDiffieHellman.Create.SecurityTransforms.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetsUnix)' == 'true'">
<Compile Include="$(CommonPath)\Internal\Cryptography\AsymmetricAlgorithmHelpers.Der.cs">
@ -474,10 +539,14 @@
<Compile Include="$(CommonPath)\System\Security\Cryptography\DerSequenceReader.cs">
<Link>Common\System\Security\Cryptography\DerSequenceReader.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Security\Cryptography\ECDiffieHellmanDerivation.cs">
<Link>Common\System\Security\Cryptography\ECDiffieHellmanDerivation.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true'">
<Reference Include="System.Buffers" />
<Reference Include="System.Collections" />
<Reference Include="System.Collections.Concurrent" />
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.Memory" />

View File

@ -16,8 +16,9 @@ namespace System.Security.Cryptography
{
internal static class CngKeyLite
{
private static class KeyPropertyName
internal static class KeyPropertyName
{
internal const string AlgorithmGroup = "Algorithm Group"; // NCRYPT_ALGORITHM_GROUP_PROPERTY
internal const string ECCCurveName = "ECCCurveName"; // NCRYPT_ECC_CURVE_NAME
internal const string ECCParameters = "ECCParameters"; // BCRYPT_ECC_PARAMETERS
internal const string ExportPolicy = "Export Policy"; // NCRYPT_EXPORT_POLICY_PROPERTY
@ -327,7 +328,7 @@ namespace System.Security.Cryptography
/// Retrieve a well-known CNG string property. (Note: desktop compat: this helper likes to return special values rather than throw exceptions for missing
/// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.)
/// </summary>
private static string GetPropertyAsString(SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options)
internal static string GetPropertyAsString(SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options)
{
Debug.Assert(!ncryptHandle.IsInvalid);
byte[] value = GetProperty(ncryptHandle, propertyName, options);
@ -449,6 +450,10 @@ namespace Microsoft.Win32.SafeHandles
{
}
internal class SafeNCryptSecretHandle : SafeNCryptHandle
{
}
internal class DuplicateSafeNCryptKeyHandle : SafeNCryptKeyHandle
{
public DuplicateSafeNCryptKeyHandle(SafeNCryptKeyHandle original)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
namespace System.Security.Cryptography
{
@ -29,6 +30,8 @@ namespace System.Security.Cryptography
private const string OID_OIWSEC_SHA512 = "2.16.840.1.101.3.4.2.3";
private const string OID_OIWSEC_RIPEMD160 = "1.3.36.3.2.1";
private const string ECDsaIdentifier = "ECDsa";
private static volatile Dictionary<string, string> s_defaultOidHT = null;
private static volatile Dictionary<string, object> s_defaultNameHT = null;
private static volatile Dictionary<string, Type> appNameHT = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
@ -184,7 +187,12 @@ namespace System.Security.Cryptography
ht.Add("DSA", DSACryptoServiceProviderType);
ht.Add("System.Security.Cryptography.DSA", DSACryptoServiceProviderType);
ht.Add("ECDsa", ECDsaCngType);
// Windows will register the public ECDsaCng type. Non-Windows gets a special handler.
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
ht.Add(ECDsaIdentifier, ECDsaCngType);
}
ht.Add("ECDsaCng", ECDsaCngType);
ht.Add("System.Security.Cryptography.ECDsaCng", ECDsaCngType);
@ -357,6 +365,15 @@ namespace System.Security.Cryptography
}
}
// Special case asking for "ECDsa" since the default map from .NET Framework uses
// a Windows-only type.
if (retvalType == null &&
(args == null || args.Length == 1) &&
name == ECDsaIdentifier)
{
return ECDsa.Create();
}
// Maybe they gave us a classname.
if (retvalType == null)
{

View File

@ -129,9 +129,9 @@ namespace System.Security.Cryptography
return VerifySignature(hash, signature);
}
public virtual bool TryCreateSignature(ReadOnlySpan<byte> source, Span<byte> destination, out int bytesWritten)
public virtual bool TryCreateSignature(ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten)
{
byte[] sig = CreateSignature(source.ToArray());
byte[] sig = CreateSignature(hash.ToArray());
if (sig.Length <= destination.Length)
{
new ReadOnlySpan<byte>(sig).CopyTo(destination);
@ -145,13 +145,13 @@ namespace System.Security.Cryptography
}
}
protected virtual bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
protected virtual bool TryHashData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
byte[] array = ArrayPool<byte>.Shared.Rent(source.Length);
byte[] array = ArrayPool<byte>.Shared.Rent(data.Length);
try
{
source.CopyTo(array);
byte[] hash = HashData(array, 0, source.Length, hashAlgorithm);
data.CopyTo(array);
byte[] hash = HashData(array, 0, data.Length, hashAlgorithm);
if (destination.Length >= hash.Length)
{
new ReadOnlySpan<byte>(hash).CopyTo(destination);
@ -166,19 +166,19 @@ namespace System.Security.Cryptography
}
finally
{
Array.Clear(array, 0, source.Length);
Array.Clear(array, 0, data.Length);
ArrayPool<byte>.Shared.Return(array);
}
}
public virtual bool TrySignData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
public virtual bool TrySignData(ReadOnlySpan<byte> data, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten)
{
if (string.IsNullOrEmpty(hashAlgorithm.Name))
{
throw HashAlgorithmNameNullOrEmpty();
}
if (TryHashData(source, destination, hashAlgorithm, out int hashLength) &&
if (TryHashData(data, destination, hashAlgorithm, out int hashLength) &&
TryCreateSignature(destination.Slice(0, hashLength), destination, out bytesWritten))
{
return true;
@ -214,8 +214,8 @@ namespace System.Security.Cryptography
}
}
public virtual bool VerifySignature(ReadOnlySpan<byte> rgbHash, ReadOnlySpan<byte> rgbSignature) =>
VerifySignature(rgbHash.ToArray(), rgbSignature.ToArray());
public virtual bool VerifySignature(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature) =>
VerifySignature(hash.ToArray(), signature.ToArray());
private static Exception DerivedClassMustOverride() =>
new NotImplementedException(SR.NotSupported_SubclassOverride);

View File

@ -0,0 +1,216 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using Internal.NativeCrypto;
using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography
{
internal sealed partial class ECCngKey
{
private SafeNCryptKeyHandle _keyHandle;
private int _lastKeySize;
private string _lastAlgorithm;
private readonly string _algorithmGroup;
internal ECCngKey(string algorithmGroup)
{
Debug.Assert(
algorithmGroup == BCryptNative.AlgorithmName.ECDH ||
algorithmGroup == BCryptNative.AlgorithmName.ECDsa);
_algorithmGroup = algorithmGroup;
}
internal int KeySize { get; private set; }
internal string GetCurveName(int callerKeySizeProperty)
{
// Ensure key\handle is created
using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle(callerKeySizeProperty))
{
string algorithm = _lastAlgorithm;
if (ECCng.IsECNamedCurve(algorithm))
{
return CngKeyLite.GetCurveName(keyHandle);
}
// Use hard-coded values (for use with pre-Win10 APIs)
return ECCng.SpecialNistAlgorithmToCurveName(algorithm);
}
}
internal SafeNCryptKeyHandle GetDuplicatedKeyHandle(int callerKeySizeProperty)
{
if (ECCng.IsECNamedCurve(_lastAlgorithm))
{
// Curve was previously created, so use that
return new DuplicateSafeNCryptKeyHandle(_keyHandle);
}
else
{
if (_lastKeySize != callerKeySizeProperty)
{
// Map the current key size to a CNG algorithm name
string algorithm;
bool isEcdsa = _algorithmGroup == BCryptNative.AlgorithmName.ECDsa;
switch (callerKeySizeProperty)
{
case 256:
algorithm = isEcdsa
? BCryptNative.AlgorithmName.ECDsaP256
: BCryptNative.AlgorithmName.ECDHP256;
break;
case 384:
algorithm = isEcdsa
? BCryptNative.AlgorithmName.ECDsaP384
: BCryptNative.AlgorithmName.ECDHP384;
break;
case 521:
algorithm = isEcdsa
? BCryptNative.AlgorithmName.ECDsaP521
: BCryptNative.AlgorithmName.ECDHP521;
break;
default:
Debug.Fail("Should not have invalid key size");
throw new ArgumentException(SR.Cryptography_InvalidKeySize);
}
if (_keyHandle != null)
{
DisposeKey();
}
_keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, callerKeySizeProperty);
_lastKeySize = callerKeySizeProperty;
_lastAlgorithm = algorithm;
KeySize = callerKeySizeProperty;
}
return new DuplicateSafeNCryptKeyHandle(_keyHandle);
}
}
internal void GenerateKey(ECCurve curve)
{
curve.Validate();
if (_keyHandle != null)
{
DisposeKey();
}
string algorithm = null;
int keySize = 0;
if (curve.IsNamed)
{
if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
{
throw new PlatformNotSupportedException(
string.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value));
}
// Map curve name to algorithm to support pre-Win10 curves
if (_algorithmGroup == BCryptNative.AlgorithmName.ECDsa)
{
algorithm = ECCng.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName);
}
else
{
Debug.Assert(_algorithmGroup == BCryptNative.AlgorithmName.ECDH);
algorithm = ECCng.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName);
}
if (ECCng.IsECNamedCurve(algorithm))
{
try
{
_keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, curve.Oid.FriendlyName);
keySize = CngKeyLite.GetKeyLength(_keyHandle);
}
catch (CryptographicException e)
{
// Map to PlatformNotSupportedException if appropriate
Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult;
if (curve.IsNamed && errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER ||
errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED)
{
throw new PlatformNotSupportedException(
string.Format(SR.Cryptography_CurveNotSupported, curve.Oid.FriendlyName), e);
}
throw;
}
}
else
{
// Get the proper KeySize from algorithm name
switch (algorithm)
{
case BCryptNative.AlgorithmName.ECDsaP256:
case BCryptNative.AlgorithmName.ECDHP256:
keySize = 256;
break;
case BCryptNative.AlgorithmName.ECDsaP384:
case BCryptNative.AlgorithmName.ECDHP384:
keySize = 384;
break;
case BCryptNative.AlgorithmName.ECDsaP521:
case BCryptNative.AlgorithmName.ECDHP521:
keySize = 521;
break;
default:
Debug.Fail(string.Format("Unknown algorithm {0}", algorithm.ToString()));
throw new ArgumentException(SR.Cryptography_InvalidKeySize);
}
_keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, keySize);
}
}
else if (curve.IsExplicit)
{
algorithm = _algorithmGroup;
_keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, ref curve);
keySize = CngKeyLite.GetKeyLength(_keyHandle);
}
else
{
throw new PlatformNotSupportedException(
string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString()));
}
_lastAlgorithm = algorithm;
_lastKeySize = keySize;
KeySize = keySize;
}
internal void DisposeKey()
{
if (_keyHandle != null)
{
_keyHandle.Dispose();
_keyHandle = null;
}
_lastAlgorithm = null;
_lastKeySize = 0;
}
internal void SetHandle(SafeNCryptKeyHandle keyHandle, string algorithmName)
{
_keyHandle?.Dispose();
_keyHandle = keyHandle;
_lastAlgorithm = algorithmName;
KeySize = CngKeyLite.GetKeyLength(keyHandle);
_lastKeySize = KeySize;
}
}
}

View File

@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Security.Cryptography
{
public abstract partial class ECDiffieHellman : AsymmetricAlgorithm
{
public static new ECDiffieHellman Create()
{
return new ECDiffieHellmanImplementation.ECDiffieHellmanCng();
}
public static ECDiffieHellman Create(ECCurve curve)
{
return new ECDiffieHellmanImplementation.ECDiffieHellmanCng(curve);
}
public static ECDiffieHellman Create(ECParameters parameters)
{
ECDiffieHellman ecdh = new ECDiffieHellmanImplementation.ECDiffieHellmanCng();
try
{
ecdh.ImportParameters(parameters);
return ecdh;
}
catch
{
ecdh.Dispose();
throw;
}
}
}
}

View File

@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Security.Cryptography
{
public abstract partial class ECDiffieHellman : AsymmetricAlgorithm
{
public static new ECDiffieHellman Create()
{
return new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl();
}
public static ECDiffieHellman Create(ECCurve curve)
{
return new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl(curve);
}
public static ECDiffieHellman Create(ECParameters parameters)
{
ECDiffieHellman ecdh = new ECDiffieHellmanImplementation.ECDiffieHellmanOpenSsl();
try
{
ecdh.ImportParameters(parameters);
return ecdh;
}
catch
{
ecdh.Dispose();
throw;
}
}
}
}

View File

@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Security.Cryptography
{
public abstract partial class ECDiffieHellman : AsymmetricAlgorithm
{
public static new ECDiffieHellman Create()
{
return new ECDiffieHellmanImplementation.ECDiffieHellmanSecurityTransforms();
}
public static ECDiffieHellman Create(ECCurve curve)
{
ECDiffieHellman ecdh = Create();
try
{
ecdh.GenerateKey(curve);
return ecdh;
}
catch
{
ecdh.Dispose();
throw;
}
}
public static ECDiffieHellman Create(ECParameters parameters)
{
ECDiffieHellman ecdh = Create();
try
{
ecdh.ImportParameters(parameters);
return ecdh;
}
catch
{
ecdh.Dispose();
throw;
}
}
}
}

View File

@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Security.Cryptography
{
public abstract partial class ECDiffieHellman : AsymmetricAlgorithm
{
public override void FromXmlString(string xmlString)
{
throw new NotImplementedException(SR.Cryptography_ECXmlSerializationFormatRequired);
}
public override string ToXmlString(bool includePrivateParameters)
{
throw new NotImplementedException(SR.Cryptography_ECXmlSerializationFormatRequired);
}
}
}

View File

@ -0,0 +1,170 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Security.Cryptography
{
/// <summary>
/// Abstract base class for implementations of elliptic curve Diffie-Hellman to derive from
/// </summary>
public abstract partial class ECDiffieHellman : AsymmetricAlgorithm
{
public override string KeyExchangeAlgorithm
{
get { return "ECDiffieHellman"; }
}
public override string SignatureAlgorithm
{
get { return null; }
}
public static new ECDiffieHellman Create(string algorithm)
{
if (algorithm == null)
{
throw new ArgumentNullException(nameof(algorithm));
}
return CryptoConfig.CreateFromName(algorithm) as ECDiffieHellman;
}
public abstract ECDiffieHellmanPublicKey PublicKey { get; }
// This method must be implemented by derived classes. In order to conform to the contract, it cannot be abstract.
public virtual byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// Derive key material using the formula HASH(x) where x is the computed result of the EC Diffie-Hellman algorithm.
/// </summary>
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
/// <returns>A hashed output suitable for key material</returns>
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
public byte[] DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm)
{
return DeriveKeyFromHash(otherPartyPublicKey, hashAlgorithm, null, null);
}
/// <summary>
/// Derive key material using the formula HASH(secretPrepend || x || secretAppend) where x is the computed
/// result of the EC Diffie-Hellman algorithm.
/// </summary>
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
/// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
/// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
/// <returns>A hashed output suitable for key material</returns>
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
public virtual byte[] DeriveKeyFromHash(
ECDiffieHellmanPublicKey otherPartyPublicKey,
HashAlgorithmName hashAlgorithm,
byte[] secretPrepend,
byte[] secretAppend)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// Derive key material using the formula HMAC(hmacKey, x) where x is the computed
/// result of the EC Diffie-Hellman algorithm.
/// </summary>
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
/// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
/// <returns>A hashed output suitable for key material</returns>
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
public byte[] DeriveKeyFromHmac(
ECDiffieHellmanPublicKey otherPartyPublicKey,
HashAlgorithmName hashAlgorithm,
byte[] hmacKey)
{
return DeriveKeyFromHmac(otherPartyPublicKey, hashAlgorithm, hmacKey, null, null);
}
/// <summary>
/// Derive key material using the formula HMAC(hmacKey, secretPrepend || x || secretAppend) where x is the computed
/// result of the EC Diffie-Hellman algorithm.
/// </summary>
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
/// <param name="hashAlgorithm">The identifier for the hash algorithm to use.</param>
/// <param name="hmacKey">The key to use in the HMAC. A <c>null</c> value indicates that the result of the EC Diffie-Hellman algorithm should be used as the HMAC key.</param>
/// <param name="secretPrepend">A value to prepend to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
/// <param name="secretAppend">A value to append to the derived secret before hashing. A <c>null</c> value is treated as an empty array.</param>
/// <returns>A hashed output suitable for key material</returns>
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
public virtual byte[] DeriveKeyFromHmac(
ECDiffieHellmanPublicKey otherPartyPublicKey,
HashAlgorithmName hashAlgorithm,
byte[] hmacKey,
byte[] secretPrepend,
byte[] secretAppend)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// Derive key material using the TLS pseudo-random function (PRF) derivation algorithm.
/// </summary>
/// <param name="otherPartyPublicKey">The public key of the party with which to derive a mutual secret.</param>
/// <param name="prfLabel">The ASCII encoded PRF label.</param>
/// <param name="prfSeed">The 64-byte PRF seed.</param>
/// <returns>A 48-byte output of the TLS pseudo-random function.</returns>
/// <exception cref="ArgumentException"><paramref name="otherPartyPublicKey"/> is over a different curve than this key</exception>
/// <exception cref="ArgumentNullException"><paramref name="prfLabel"/> is null</exception>
/// <exception cref="ArgumentNullException"><paramref name="prfSeed"/> is null</exception>
/// <exception cref="CryptographicException"><paramref name="prfSeed"/> is not exactly 64 bytes in length</exception>
public virtual byte[] DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)
{
throw DerivedClassMustOverride();
}
private static Exception DerivedClassMustOverride()
{
return new NotImplementedException(SR.NotSupported_SubclassOverride);
}
/// <summary>
/// When overridden in a derived class, exports the named or explicit ECParameters for an ECCurve.
/// If the curve has a name, the Curve property will contain named curve parameters, otherwise it
/// will contain explicit parameters.
/// </summary>
/// <param name="includePrivateParameters">true to include private parameters, otherwise, false.</param>
/// <returns>The ECParameters representing the point on the curve for this key.</returns>
public virtual ECParameters ExportParameters(bool includePrivateParameters)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// When overridden in a derived class, exports the explicit ECParameters for an ECCurve.
/// </summary>
/// <param name="includePrivateParameters">true to include private parameters, otherwise, false.</param>
/// <returns>The ECParameters representing the point on the curve for this key, using the explicit curve format.</returns>
public virtual ECParameters ExportExplicitParameters(bool includePrivateParameters)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// When overridden in a derived class, imports the specified ECParameters.
/// </summary>
/// <param name="parameters">The curve parameters.</param>
public virtual void ImportParameters(ECParameters parameters)
{
throw DerivedClassMustOverride();
}
/// <summary>
/// When overridden in a derived class, generates a new public/private keypair for the specified curve.
/// </summary>
/// <param name="curve">The curve to use.</param>
public virtual void GenerateKey(ECCurve curve)
{
throw new NotSupportedException(SR.NotSupported_SubclassOverride);
}
}
}

View File

@ -0,0 +1,72 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Internal.NativeCrypto;
using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography
{
internal static partial class ECDiffieHellmanImplementation
{
public sealed partial class ECDiffieHellmanCng : ECDiffieHellman
{
// For the public ECDiffieHellmanCng this is exposed as the HashAlgorithm property
// which is a CngAlgorithm type. We're not doing that, but we do need the default value
// for DeriveKeyMaterial.
public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
{
if (otherPartyPublicKey == null)
{
throw new ArgumentNullException(nameof(otherPartyPublicKey));
}
// ECDiffieHellmanCng on .NET Framework will throw an ArgumentException in this method
// if otherPartyPublicKey is not an ECDiffieHellmanCngPublicKey. All of the other methods
// will use Import/Export to coerce the correct type for interop.
// None of the other Core types will match that behavior, so the ECDiffieHellman.Create() on
// Windows on .NET Core won't, either.
// The default behavior for ECDiffieHellmanCng / ECDiffieHellman.Create() on .NET Framework was
// to derive from hash, no prepend, no append, SHA-2-256.
return DeriveKeyFromHash(otherPartyPublicKey, HashAlgorithmName.SHA256);
}
private SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey)
{
if (otherPartyPublicKey == null)
{
throw new ArgumentNullException(nameof(otherPartyPublicKey));
}
ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters();
using (ECDiffieHellmanCng otherPartyCng = (ECDiffieHellmanCng)Create(otherPartyParameters))
using (SafeNCryptKeyHandle otherPartyHandle = otherPartyCng.GetDuplicatedKeyHandle())
{
string importedKeyAlgorithmGroup =
CngKeyLite.GetPropertyAsString(
otherPartyHandle,
CngKeyLite.KeyPropertyName.AlgorithmGroup,
CngPropertyOptions.None);
if (importedKeyAlgorithmGroup != BCryptNative.AlgorithmName.ECDH)
{
throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey));
}
if (CngKeyLite.GetKeyLength(otherPartyHandle) != KeySize)
{
throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey));
}
using (SafeNCryptKeyHandle localHandle = GetDuplicatedKeyHandle())
{
return Interop.NCrypt.DeriveSecretAgreement(localHandle, otherPartyHandle);
}
}
}
}
}
}

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