ImportKeyBlob(blob, hasPrivateKey);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override byte[] ExportEncryptedPkcs8PrivateKey(
ReadOnlySpan<byte> passwordBytes,
PbeParameters pbeParameters)
// 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.Buffers;
using System.Diagnostics;
using System.IO;
using Internal.Cryptography;
public DSAOpenSsl(int keySize)
{
LegalKeySizesValue = s_legalKeySizes;
- KeySize = keySize;
+ base.KeySize = keySize;
_key = new Lazy<SafeDsaHandle>(GenerateKey);
}
// Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
base.KeySize = value;
+ ThrowIfDisposed();
FreeKey();
_key = new Lazy<SafeDsaHandle>(GenerateKey);
}
public override DSAParameters ExportParameters(bool includePrivateParameters)
{
// It's entirely possible that this line will cause the key to be generated in the first place.
- SafeDsaHandle key = _key.Value;
-
- CheckInvalidKey(key);
+ SafeDsaHandle key = GetKey();
DSAParameters dsaParameters = Interop.Crypto.ExportDsaParameters(key, includePrivateParameters);
bool hasPrivateKey = dsaParameters.X != null;
if (hasPrivateKey && parameters.X.Length != parameters.Q.Length)
throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
+ ThrowIfDisposed();
+
SafeDsaHandle key;
if (!Interop.Crypto.DsaKeyCreateByExplicitParameters(
out key,
SetKey(key);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)
{
FreeKey();
+ _key = null;
}
base.Dispose(disposing);
if (rgbHash == null)
throw new ArgumentNullException(nameof(rgbHash));
- SafeDsaHandle key = _key.Value;
+ SafeDsaHandle key = GetKey();
int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
byte[] signature = CryptoPool.Rent(signatureSize);
try
public override bool TryCreateSignature(ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten)
{
byte[] converted;
- SafeDsaHandle key = _key.Value;
+ SafeDsaHandle key = GetKey();
int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
byte[] signature = CryptoPool.Rent(signatureSize);
try
public override bool VerifySignature(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
{
- SafeDsaHandle key = _key.Value;
+ SafeDsaHandle key = GetKey();
int expectedSignatureBytes = Interop.Crypto.DsaSignatureFieldSize(key) * 2;
if (signature.Length != expectedSignatureBytes)
return Interop.Crypto.DsaVerify(key, hash, openSslFormat);
}
+ private void ThrowIfDisposed()
+ {
+ if (_key == null)
+ {
+ throw new ObjectDisposedException(
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ nameof(DSA)
+#else
+ nameof(DSAOpenSsl)
+#endif
+ );
+ }
+ }
+
+ private SafeDsaHandle GetKey()
+ {
+ ThrowIfDisposed();
+
+ SafeDsaHandle key = _key.Value;
+ CheckInvalidKey(key);
+
+ return key;
+ }
+
private void SetKey(SafeDsaHandle newKey)
{
+ // Do not call ThrowIfDisposed here, as it breaks the SafeEvpPKey ctor
+
// Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere
// with the already loaded key.
ForceSetKeySize(BitsPerByte * Interop.Crypto.DsaKeySize(newKey));
using System.Buffers;
using System.Diagnostics;
using System.IO;
-using System.Numerics;
using System.Runtime.InteropServices;
using System.Security.Cryptography.Apple;
using System.Security.Cryptography.Asn1;
public sealed partial class DSASecurityTransforms : DSA
{
private SecKeyPair _keys;
+ private bool _disposed;
public DSASecurityTransforms()
: this(1024)
public DSASecurityTransforms(int keySize)
{
- KeySize = keySize;
+ base.KeySize = keySize;
}
internal DSASecurityTransforms(SafeSecKeyRefHandle publicKey)
// Set the KeySize before freeing the key so that an invalid value doesn't throw away the key
base.KeySize = value;
+ ThrowIfDisposed();
+
if (_keys != null)
{
_keys.Dispose();
const string ExportPassword = "DotnetExportPassphrase";
SecKeyPair keys = GetKeys();
- if (keys.PublicKey == null ||
- (includePrivateParameters && keys.PrivateKey == null))
+ if (includePrivateParameters && keys.PrivateKey == null)
{
throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
}
if (parameters.Q.Length != 20)
throw new CryptographicException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey);
+ ThrowIfDisposed();
+
if (hasPrivateKey)
{
SafeSecKeyRefHandle privateKey = ImportKey(parameters);
}
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
private static SafeSecKeyRefHandle ImportKey(DSAParameters parameters)
{
if (parameters.X != null)
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
fixed (byte* ptr = &MemoryMarshal.GetReference(source))
{
using (MemoryManager<byte> manager = new PointerMemoryManager<byte>(ptr, source.Length))
_keys.Dispose();
_keys = null;
}
+
+ _disposed = true;
}
base.Dispose(disposing);
}
+ private void ThrowIfDisposed()
+ {
+ // The other SecurityTransforms types use _keys.PublicKey == null,
+ // but since Apple doesn't provide DSA key generation we can't easily tell
+ // if a failed attempt to generate a key happened, or we're in a pristine state.
+ //
+ // So this type uses an explicit field, rather than inferred state.
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(DSA));
+ }
+ }
+
internal SecKeyPair GetKeys()
{
+ ThrowIfDisposed();
+
SecKeyPair current = _keys;
if (current != null)
private void SetKey(SecKeyPair newKeyPair)
{
+ ThrowIfDisposed();
+
SecKeyPair current = _keys;
_keys = newKeyPair;
current?.Dispose();
public override void ImportParameters(ECParameters parameters)
{
parameters.Validate();
+ ThrowIfDisposed();
+
ECCurve curve = parameters.Curve;
bool includePrivateParamerters = (parameters.D != null);
public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
{
+ ThrowIfDisposed();
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead);
ProcessPkcs8Response(response);
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
passwordBytes,
source,
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
password,
source,
// 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.Buffers;
using System.Diagnostics;
using Microsoft.Win32.SafeHandles;
if (string.IsNullOrEmpty(hashAlgorithm.Name))
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyFromHash(
otherPartyPublicKey,
hashAlgorithm,
if (string.IsNullOrEmpty(hashAlgorithm.Name))
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyFromHmac(
otherPartyPublicKey,
hashAlgorithm,
if (prfSeed == null)
throw new ArgumentNullException(nameof(prfSeed));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyTls(
otherPartyPublicKey,
prfLabel,
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Win32.SafeHandles;
+
namespace System.Security.Cryptography
{
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
{
if (disposing)
{
- _key.Dispose();
+ _key?.Dispose();
+ _key = null;
}
base.Dispose(disposing);
// Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
base.KeySize = value;
- _key?.Dispose();
+
+ ThrowIfDisposed();
+ _key.Dispose();
_key = new ECOpenSsl(this);
}
}
public override void GenerateKey(ECCurve curve)
{
+ ThrowIfDisposed();
KeySizeValue = _key.GenerateKey(curve);
}
- public override ECDiffieHellmanPublicKey PublicKey =>
- new ECDiffieHellmanOpenSslPublicKey(_key.UpRefKeyHandle());
+ public override ECDiffieHellmanPublicKey PublicKey
+ {
+ get
+ {
+ ThrowIfDisposed();
+ return new ECDiffieHellmanOpenSslPublicKey(_key.UpRefKeyHandle());
+ }
+ }
public override void ImportParameters(ECParameters parameters)
{
+ ThrowIfDisposed();
KeySizeValue = _key.ImportParameters(parameters);
}
public override ECParameters ExportExplicitParameters(bool includePrivateParameters) =>
- ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters);
+ ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters);
public override ECParameters ExportParameters(bool includePrivateParameters) =>
- ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters);
+ ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters);
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
+ private void ThrowIfDisposed()
+ {
+ if (_key == null)
+ {
+ throw new ObjectDisposedException(
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ nameof(ECDiffieHellman)
+#else
+ nameof(ECDiffieHellmanOpenSsl)
+#endif
+ );
+ }
+ }
+
+ private SafeEcKeyHandle GetKey()
+ {
+ ThrowIfDisposed();
+ return _key.Value;
+ }
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
#endif
internal sealed class ECDiffieHellmanOpenSslPublicKey : ECDiffieHellmanPublicKey
{
- private readonly ECOpenSsl _key;
+ private ECOpenSsl _key;
internal ECDiffieHellmanOpenSslPublicKey(SafeEvpPKeyHandle pkeyHandle)
{
}
public override ECParameters ExportExplicitParameters() =>
- ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters: false);
+ ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters: false);
public override ECParameters ExportParameters() =>
- ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters: false);
+ ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters: false);
- internal bool HasCurveName => Interop.Crypto.EcKeyHasCurveName(_key.Value);
+ internal bool HasCurveName => Interop.Crypto.EcKeyHasCurveName(GetKey());
- internal int KeySize => _key.KeySize;
+ internal int KeySize
+ {
+ get
+ {
+ ThrowIfDisposed();
+ return _key.KeySize;
+ }
+ }
protected override void Dispose(bool disposing)
{
if (disposing)
{
_key?.Dispose();
+ _key = null;
}
base.Dispose(disposing);
internal SafeEvpPKeyHandle DuplicateKeyHandle()
{
- SafeEcKeyHandle currentKey = _key.Value;
+ SafeEcKeyHandle currentKey = GetKey();
SafeEvpPKeyHandle pkeyHandle = Interop.Crypto.EvpPkeyCreate();
try
throw;
}
}
+
+ private void ThrowIfDisposed()
+ {
+ if (_key == null)
+ {
+ throw new ObjectDisposedException(
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ nameof(ECDiffieHellmanPublicKey)
+#else
+ nameof(ECDiffieHellmanOpenSslPublicKey)
+#endif
+ );
+ }
+ }
+
+ private SafeEcKeyHandle GetKey()
+ {
+ ThrowIfDisposed();
+ return _key.Value;
+ }
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
{
public sealed partial class ECDiffieHellmanSecurityTransforms : ECDiffieHellman
{
- private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms();
+ private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms(nameof(ECDiffieHellman));
public ECDiffieHellmanSecurityTransforms()
{
- KeySize = 521;
+ base.KeySize = 521;
}
internal ECDiffieHellmanSecurityTransforms(SafeSecKeyRefHandle publicKey)
// Set the KeySize before freeing the key so that an invalid value doesn't throw away the key
base.KeySize = value;
- _ecc.Dispose();
+ _ecc.DisposeKey();
}
}
+ private void ThrowIfDisposed()
+ {
+ _ecc.ThrowIfDisposed();
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)
KeySizeValue = _ecc.ImportSubjectPublicKeyInfo(source, out bytesRead);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override void GenerateKey(ECCurve curve)
{
KeySizeValue = _ecc.GenerateKey(curve);
if (string.IsNullOrEmpty(hashAlgorithm.Name))
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyFromHash(
otherPartyPublicKey,
hashAlgorithm,
if (string.IsNullOrEmpty(hashAlgorithm.Name))
throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyFromHmac(
otherPartyPublicKey,
hashAlgorithm,
if (prfSeed == null)
throw new ArgumentNullException(nameof(prfSeed));
+ ThrowIfDisposed();
+
return ECDiffieHellmanDerivation.DeriveKeyTls(
otherPartyPublicKey,
prfLabel,
public ECDiffieHellmanSecurityTransformsPublicKey(ECParameters ecParameters)
{
Debug.Assert(ecParameters.D == null);
- _ecc = new EccSecurityTransforms();
+ _ecc = new EccSecurityTransforms(nameof(ECDiffieHellmanPublicKey));
_ecc.ImportParameters(ecParameters);
}
if (disposing)
{
_ecc.Dispose();
- _ecc = null;
}
base.Dispose(disposing);
public override ECParameters ExportExplicitParameters() =>
throw new PlatformNotSupportedException(SR.Cryptography_ECC_NamedCurvesOnly);
- public override ECParameters ExportParameters()
- {
- if (_ecc == null)
- {
- throw new ObjectDisposedException(typeof(ECDiffieHellmanSecurityTransformsPublicKey).Name);
- }
+ public override ECParameters ExportParameters() =>
+ _ecc.ExportParameters(includePrivateParameters: false, keySizeInBits: -1);
- return _ecc.ExportParameters(includePrivateParameters: false, keySizeInBits: -1);
- }
-
- internal SafeSecKeyRefHandle KeyHandle
- {
- get
- {
- if (_ecc == null)
- {
- throw new ObjectDisposedException(
- typeof(ECDiffieHellmanSecurityTransformsPublicKey).Name);
- }
-
- return _ecc.GetOrGenerateKeys(-1).PublicKey;
- }
- }
+ internal SafeSecKeyRefHandle KeyHandle =>
+ _ecc.GetOrGenerateKeys(-1).PublicKey;
}
}
}
public override void ImportParameters(ECParameters parameters)
{
parameters.Validate();
+ ThrowIfDisposed();
+
ECCurve curve = parameters.Curve;
bool includePrivateParameters = (parameters.D != null);
public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead);
ProcessPkcs8Response(response);
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
passwordBytes,
source,
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
password,
source,
// 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.Buffers;
-using System.Diagnostics;
using System.IO;
using Internal.Cryptography;
using Microsoft.Win32.SafeHandles;
/// <param name="keySize">Size of the key to generate, in bits.</param>
public ECDsaOpenSsl(int keySize)
{
- KeySize = keySize;
- // Setting KeySize wakes up _key.
- Debug.Assert(_key != null);
+ // Use the base setter to get the validation and field assignment without the
+ // side effect of dereferencing _key.
+ base.KeySize = keySize;
+ _key = new ECOpenSsl(this);
}
/// <summary>
if (hash == null)
throw new ArgumentNullException(nameof(hash));
+ ThrowIfDisposed();
SafeEcKeyHandle key = _key.Value;
int signatureLength = Interop.Crypto.EcDsaSize(key);
byte[] signature = new byte[signatureLength];
public override bool TrySignHash(ReadOnlySpan<byte> hash, Span<byte> destination, out int bytesWritten)
{
+ ThrowIfDisposed();
SafeEcKeyHandle key = _key.Value;
byte[] converted;
public override bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
{
+ ThrowIfDisposed();
+
// The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even
// when they would have leading zeroes. If it's the correct size, then we need to encode it from
// r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects.
{
if (disposing)
{
- _key.Dispose();
+ _key?.Dispose();
+ _key = null;
}
base.Dispose(disposing);
// Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
base.KeySize = value;
- // This is the only place where _key can be null, because it's called by the constructor
- // which sets KeySize.
- _key?.Dispose();
+ ThrowIfDisposed();
+ _key.Dispose();
_key = new ECOpenSsl(this);
}
}
public override void GenerateKey(ECCurve curve)
{
+ ThrowIfDisposed();
_key.GenerateKey(curve);
// Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere
public override void ImportParameters(ECParameters parameters)
{
+ ThrowIfDisposed();
_key.ImportParameters(parameters);
ForceSetKeySize(_key.KeySize);
}
- public override ECParameters ExportExplicitParameters(bool includePrivateParameters) =>
- ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters);
+ public override ECParameters ExportExplicitParameters(bool includePrivateParameters)
+ {
+ ThrowIfDisposed();
+ return ECOpenSsl.ExportExplicitParameters(_key.Value, includePrivateParameters);
+ }
- public override ECParameters ExportParameters(bool includePrivateParameters) =>
- ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters);
+ public override ECParameters ExportParameters(bool includePrivateParameters)
+ {
+ ThrowIfDisposed();
+ return ECOpenSsl.ExportParameters(_key.Value, includePrivateParameters);
+ }
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
+ private void ThrowIfDisposed()
+ {
+ if (_key == null)
+ {
+ throw new ObjectDisposedException(
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ nameof(ECDsa)
+#else
+ nameof(ECDsaOpenSsl)
+#endif
+ );
+ }
+ }
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
{
public sealed partial class ECDsaSecurityTransforms : ECDsa
{
- private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms();
+ private readonly EccSecurityTransforms _ecc = new EccSecurityTransforms(nameof(ECDsa));
public ECDsaSecurityTransforms()
{
- KeySize = 521;
+ base.KeySize = 521;
}
internal ECDsaSecurityTransforms(SafeSecKeyRefHandle publicKey)
// Set the KeySize before freeing the key so that an invalid value doesn't throw away the key
base.KeySize = value;
- _ecc.Dispose();
+ _ecc.DisposeKey();
}
}
public override bool VerifyHash(ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
{
+ ThrowIfDisposed();
+
// The signature format for .NET is r.Concat(s). Each of r and s are of length BitsToBytes(KeySize), even
// when they would have leading zeroes. If it's the correct size, then we need to encode it from
// r.Concat(s) to SEQUENCE(INTEGER(r), INTEGER(s)), because that's the format that OpenSSL expects.
protected override bool TryHashData(ReadOnlySpan<byte> source, Span<byte> destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) =>
AsymmetricAlgorithmHelpers.TryHashData(source, destination, hashAlgorithm, out bytesWritten);
+ private void ThrowIfDisposed()
+ {
+ _ecc.ThrowIfDisposed();
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)
KeySizeValue = _ecc.ImportParameters(parameters);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override void GenerateKey(ECCurve curve)
{
KeySizeValue = _ecc.GenerateKey(curve);
using System.Runtime.InteropServices;
using System.Security.Cryptography.Apple;
using System.Security.Cryptography.Asn1;
-using Internal.Cryptography;
namespace System.Security.Cryptography
{
internal sealed class EccSecurityTransforms : IDisposable
{
private SecKeyPair _keys;
+ private bool _disposed;
+ private readonly string _disposedName;
- public void Dispose()
+ internal EccSecurityTransforms(string disposedTypeName)
+ {
+ Debug.Assert(disposedTypeName != null);
+ _disposedName = disposedTypeName;
+ }
+
+ internal void DisposeKey()
{
_keys?.Dispose();
_keys = null;
}
+ public void Dispose()
+ {
+ DisposeKey();
+ _disposed = true;
+ }
+
internal int GenerateKey(ECCurve curve)
{
curve.Validate();
+ ThrowIfDisposed();
if (!curve.IsNamed)
{
return newPair;
}
+ internal void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(_disposedName);
+ }
+ }
+
internal SecKeyPair GetOrGenerateKeys(int keySizeInBits)
{
+ ThrowIfDisposed();
+
SecKeyPair current = _keys;
if (current != null)
private void SetKey(SecKeyPair keyPair)
{
+ ThrowIfDisposed();
+
SecKeyPair current = _keys;
_keys = keyPair;
current?.Dispose();
const string ExportPassword = "DotnetExportPassphrase";
SecKeyPair keys = GetOrGenerateKeys(keySizeInBits);
- if (keys.PublicKey == null ||
- (includePrivateParameters && keys.PrivateKey == null))
+ if (includePrivateParameters && keys.PrivateKey == null)
{
throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
}
internal int ImportParameters(ECParameters parameters)
{
parameters.Validate();
+ ThrowIfDisposed();
bool isPrivateKey = parameters.D != null;
SecKeyPair newKeys;
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
fixed (byte* ptr = &MemoryMarshal.GetReference(source))
{
using (MemoryManager<byte> manager = new PointerMemoryManager<byte>(ptr, source.Length))
public override void ImportPkcs8PrivateKey(ReadOnlySpan<byte> source, out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportPkcs8PrivateKey(source, out int localRead);
ProcessPkcs8Response(response);
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
passwordBytes,
source,
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
CngPkcs8.Pkcs8Response response = CngPkcs8.ImportEncryptedPkcs8PrivateKey(
password,
source,
public RSAOpenSsl(int keySize)
{
- KeySize = keySize;
+ base.KeySize = keySize;
_key = new Lazy<SafeRsaHandle>(GenerateKey);
}
// Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
base.KeySize = value;
+ ThrowIfDisposed();
FreeKey();
_key = new Lazy<SafeRsaHandle>(GenerateKey);
}
throw new ArgumentNullException(nameof(padding));
Interop.Crypto.RsaPadding rsaPadding = GetInteropPadding(padding, out RsaPaddingProcessor oaepProcessor);
- SafeRsaHandle key = _key.Value;
- CheckInvalidKey(key);
+ SafeRsaHandle key = GetKey();
int rsaSize = Interop.Crypto.RsaSize(key);
byte[] buf = null;
}
Interop.Crypto.RsaPadding rsaPadding = GetInteropPadding(padding, out RsaPaddingProcessor oaepProcessor);
- SafeRsaHandle key = _key.Value;
- CheckInvalidKey(key);
+ SafeRsaHandle key = GetKey();
int keySizeBytes = Interop.Crypto.RsaSize(key);
throw new ArgumentNullException(nameof(padding));
Interop.Crypto.RsaPadding rsaPadding = GetInteropPadding(padding, out RsaPaddingProcessor oaepProcessor);
- SafeRsaHandle key = _key.Value;
- CheckInvalidKey(key);
-
+ SafeRsaHandle key = GetKey();
+
byte[] buf = new byte[Interop.Crypto.RsaSize(key)];
bool encrypted = TryEncrypt(
}
Interop.Crypto.RsaPadding rsaPadding = GetInteropPadding(padding, out RsaPaddingProcessor oaepProcessor);
- SafeRsaHandle key = _key.Value;
- CheckInvalidKey(key);
+ SafeRsaHandle key = GetKey();
return TryEncrypt(key, data, destination, rsaPadding, oaepProcessor, out bytesWritten);
}
public override RSAParameters ExportParameters(bool includePrivateParameters)
{
// It's entirely possible that this line will cause the key to be generated in the first place.
- SafeRsaHandle key = _key.Value;
-
- CheckInvalidKey(key);
+ SafeRsaHandle key = GetKey();
RSAParameters rsaParameters = Interop.Crypto.ExportRsaParameters(key, includePrivateParameters);
bool hasPrivateKey = rsaParameters.D != null;
public override void ImportParameters(RSAParameters parameters)
{
ValidateParameters(ref parameters);
+ ThrowIfDisposed();
SafeRsaHandle key = Interop.Crypto.RsaCreate();
bool imported = false;
public override unsafe void ImportRSAPublicKey(ReadOnlySpan<byte> source, out int bytesRead)
{
+ ThrowIfDisposed();
+
fixed (byte* ptr = &MemoryMarshal.GetReference(source))
{
using (MemoryManager<byte> manager = new PointerMemoryManager<byte>(ptr, source.Length))
}
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)
{
FreeKey();
+ _key = null;
}
base.Dispose(disposing);
return true;
}
- private static void CheckInvalidKey(SafeRsaHandle key)
+ private void ThrowIfDisposed()
{
+ if (_key == null)
+ {
+ throw new ObjectDisposedException(
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ nameof(RSA)
+#else
+ nameof(RSAOpenSsl)
+#endif
+ );
+ }
+ }
+
+ private SafeRsaHandle GetKey()
+ {
+ ThrowIfDisposed();
+
+ SafeRsaHandle key = _key.Value;
+
if (key == null || key.IsInvalid)
{
throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
}
+
+ return key;
}
private static void CheckReturn(int returnValue)
if (padding.Mode == RSASignaturePaddingMode.Pkcs1)
{
int algorithmNid = GetAlgorithmNid(hashAlgorithm);
- SafeRsaHandle rsa = _key.Value;
+ SafeRsaHandle rsa = GetKey();
int bytesRequired = Interop.Crypto.RsaSize(rsa);
else if (padding.Mode == RSASignaturePaddingMode.Pss)
{
RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
- SafeRsaHandle rsa = _key.Value;
+ SafeRsaHandle rsa = GetKey();
int bytesRequired = Interop.Crypto.RsaSize(rsa);
if (padding == RSASignaturePadding.Pkcs1)
{
int algorithmNid = GetAlgorithmNid(hashAlgorithm);
- SafeRsaHandle rsa = _key.Value;
+ SafeRsaHandle rsa = GetKey();
return Interop.Crypto.RsaVerify(algorithmNid, hash, signature, rsa);
}
else if (padding == RSASignaturePadding.Pss)
{
RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
- SafeRsaHandle rsa = _key.Value;
+ SafeRsaHandle rsa = GetKey();
int requiredBytes = Interop.Crypto.RsaSize(rsa);
public RSASecurityTransforms(int keySize)
{
- KeySize = keySize;
+ base.KeySize = keySize;
}
internal RSASecurityTransforms(SafeSecKeyRefHandle publicKey)
// Set the KeySize before freeing the key so that an invalid value doesn't throw away the key
base.KeySize = value;
+ ThrowIfDisposed();
+
if (_keys != null)
{
_keys.Dispose();
const string ExportPassword = "DotnetExportPassphrase";
SecKeyPair keys = GetKeys();
- if (keys.PublicKey == null ||
- (includePrivateParameters && keys.PrivateKey == null))
+ if (includePrivateParameters && keys.PrivateKey == null)
{
throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
}
public override void ImportParameters(RSAParameters parameters)
{
+ ValidateParameters(parameters);
+ ThrowIfDisposed();
+
bool isPrivateKey = parameters.D != null;
if (isPrivateKey)
ReadOnlySpan<byte> source,
out int bytesRead)
{
+ ThrowIfDisposed();
+
fixed (byte* ptr = &MemoryMarshal.GetReference(source))
{
using (MemoryManager<byte> manager = new PointerMemoryManager<byte>(ptr, source.Length))
public override unsafe void ImportRSAPublicKey(ReadOnlySpan<byte> source, out int bytesRead)
{
+ ThrowIfDisposed();
+
fixed (byte* ptr = &MemoryMarshal.GetReference(source))
{
using (MemoryManager<byte> manager = new PointerMemoryManager<byte>(ptr, source.Length))
}
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding)
{
if (data == null)
throw new ArgumentNullException(nameof(padding));
}
+ ThrowIfDisposed();
+
// The size of encrypt is always the keysize (in ceiling-bytes)
int outputSize = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
byte[] output = new byte[outputSize];
throw new ArgumentNullException(nameof(padding));
}
+ ThrowIfDisposed();
+
int rsaSize = RsaPaddingProcessor.BytesRequiredForBitCount(KeySize);
if (destination.Length < rsaSize)
if (padding == null)
throw new ArgumentNullException(nameof(padding));
+ ThrowIfDisposed();
+
if (padding == RSASignaturePadding.Pkcs1)
{
SecKeyPair keys = GetKeys();
throw new ArgumentNullException(nameof(padding));
}
+ ThrowIfDisposed();
+
RsaPaddingProcessor processor = null;
if (padding.Mode == RSASignaturePaddingMode.Pss)
throw new ArgumentNullException(nameof(padding));
}
+ ThrowIfDisposed();
+
if (padding == RSASignaturePadding.Pkcs1)
{
Interop.AppleCrypto.PAL_HashAlgorithm palAlgId =
{
if (_keys != null)
{
+ // Do not set _keys to null, in order to prevent rehydration.
_keys.Dispose();
- _keys = null;
}
}
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
+ private void ThrowIfDisposed()
+ {
+ SecKeyPair current = _keys;
+
+ if (current != null && current.PublicKey == null)
+ {
+ throw new ObjectDisposedException(nameof(RSA));
+ }
+ }
+
internal SecKeyPair GetKeys()
{
+ ThrowIfDisposed();
SecKeyPair current = _keys;
if (current != null)
private void SetKey(SecKeyPair newKeyPair)
{
+ ThrowIfDisposed();
+
SecKeyPair current = _keys;
_keys = newKeyPair;
current?.Dispose();
}
}
}
+
+ private static void ValidateParameters(in RSAParameters parameters)
+ {
+ if (parameters.Modulus == null || parameters.Exponent == null)
+ throw new CryptographicException(SR.Argument_InvalidValue);
+
+ if (!HasConsistentPrivateKey(parameters))
+ throw new CryptographicException(SR.Argument_InvalidValue);
+ }
+
+ private static bool HasConsistentPrivateKey(in RSAParameters parameters)
+ {
+ if (parameters.D == null)
+ {
+ if (parameters.P != null ||
+ parameters.DP != null ||
+ parameters.Q != null ||
+ parameters.DQ != null ||
+ parameters.InverseQ != null)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (parameters.P == null ||
+ parameters.DP == null ||
+ parameters.Q == null ||
+ parameters.DQ == null ||
+ parameters.InverseQ == null)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
private static Exception HashAlgorithmNameNullOrEmpty() =>
}
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public static void ExportAfterDispose(bool importKey)
+ {
+ DSA key = importKey ? DSAFactory.Create(DSATestData.GetDSA1024Params()) : DSAFactory.Create(512);
+ byte[] hash = new byte[20];
+
+ // Ensure that the key got created, and then Dispose it.
+ using (key)
+ {
+ try
+ {
+ key.CreateSignature(hash);
+ }
+ catch (PlatformNotSupportedException) when (!SupportsKeyGeneration)
+ {
+ }
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => key.ExportParameters(false));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportParameters(true));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportParameters(DSATestData.GetDSA1024Params()));
+ }
+
internal static void AssertKeyEquals(in DSAParameters expected, in DSAParameters actual)
{
Assert.Equal(expected.G, actual.G);
{
public static bool SupportsFips186_3 => DSAFactory.SupportsFips186_3;
+ [ConditionalFact(typeof(DSAFactory), nameof(DSAFactory.SupportsKeyGeneration))]
+ public static void UseAfterDispose_NewKey()
+ {
+ UseAfterDispose(false);
+ }
+
+ [Fact]
+ public static void UseAfterDispose_ImportedKey()
+ {
+ UseAfterDispose(true);
+ }
+
+ private static void UseAfterDispose(bool importKey)
+ {
+ DSA key = importKey ? DSAFactory.Create(DSATestData.GetDSA1024Params()) : DSAFactory.Create(512);
+
+ byte[] pkcs8Private;
+ byte[] pkcs8EncryptedPrivate;
+ byte[] subjectPublicKeyInfo;
+
+ string pwStr = "Hello";
+ // Because the PBE algorithm uses PBES2 the string->byte encoding is UTF-8.
+ byte[] pwBytes = Encoding.UTF8.GetBytes(pwStr);
+
+ PbeParameters pbeParameters = new PbeParameters(
+ PbeEncryptionAlgorithm.Aes192Cbc,
+ HashAlgorithmName.SHA256,
+ 3072);
+
+ // Ensure the key was loaded, then dispose it.
+ // Also ensures all of the inputs are valid for the disposed tests.
+ using (key)
+ {
+ pkcs8Private = key.ExportPkcs8PrivateKey();
+ pkcs8EncryptedPrivate = key.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters);
+ subjectPublicKeyInfo = key.ExportSubjectPublicKeyInfo();
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => key.ImportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwStr, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ Assert.Throws<ObjectDisposedException>(() => key.ExportPkcs8PrivateKey());
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportSubjectPublicKeyInfo());
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ // Check encrypted import with the wrong password.
+ // It shouldn't do enough work to realize it was wrong.
+ pwBytes = Array.Empty<byte>();
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey("", pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ }
+
[Fact]
public static void ReadWriteDsa512Pkcs8()
{
public override bool VerifyData(DSA dsa, byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm) =>
dsa.VerifyData(data, signature, hashAlgorithm);
+ protected override void UseAfterDispose(DSA dsa, byte[] data, byte[] sig)
+ {
+ base.UseAfterDispose(dsa, data, sig);
+ byte[] hash = new byte[20];
+
+ Assert.Throws<ObjectDisposedException>(() => dsa.CreateSignature(hash));
+ Assert.Throws<ObjectDisposedException>(() => dsa.VerifySignature(hash, sig));
+ }
+
[Fact]
public void InvalidStreamArrayArguments_Throws()
{
}
}
+#if netcoreapp
public sealed class DSASignVerify_Span : DSASignVerify
{
public override byte[] SignData(DSA dsa, byte[] data, HashAlgorithmName hashAlgorithm) =>
public override bool VerifyData(DSA dsa, byte[] data, byte[] signature, HashAlgorithmName hashAlgorithm) =>
dsa.VerifyData((ReadOnlySpan<byte>)data, (ReadOnlySpan<byte>)signature, hashAlgorithm);
+ protected override void UseAfterDispose(DSA dsa, byte[] data, byte[] sig)
+ {
+ base.UseAfterDispose(dsa, data, sig);
+ byte[] hash = new byte[20];
+
+ Assert.Throws<ObjectDisposedException>(() => dsa.TryCreateSignature(hash, sig, out _));
+ Assert.Throws<ObjectDisposedException>(() => dsa.VerifySignature(hash.AsSpan(), sig.AsSpan()));
+ }
+
private static byte[] TryWithOutputArray(Func<byte[], (bool, int)> func)
{
for (int length = 1; ; length = checked(length * 2))
}
}
}
-
+#endif
public abstract partial class DSASignVerify
{
public abstract byte[] SignData(DSA dsa, byte[] data, HashAlgorithmName hashAlgorithm);
}
[ConditionalFact(nameof(SupportsKeyGeneration))]
+ public void UseAfterDispose_NewKey()
+ {
+ UseAfterDispose(false);
+ }
+
+ [Fact]
+ public void UseAfterDispose_ImportedKey()
+ {
+ UseAfterDispose(true);
+ }
+
+ private void UseAfterDispose(bool importKey)
+ {
+ DSA key = importKey ? DSAFactory.Create(DSATestData.GetDSA1024Params()) : DSAFactory.Create(512);
+ byte[] data = { 1 };
+ byte[] sig;
+
+ // Ensure the key is populated, then dispose it.
+ using (key)
+ {
+ sig = SignData(key, data, HashAlgorithmName.SHA1);
+ }
+
+ key.Dispose();
+
+ UseAfterDispose(key, data, sig);
+
+ Assert.Throws<ObjectDisposedException>(() => key.ImportParameters(DSATestData.GetDSA1024Params()));
+
+ // Either set_KeySize or SignData should throw.
+ Assert.Throws<ObjectDisposedException>(
+ () =>
+ {
+ key.KeySize = 576;
+ SignData(key, data, HashAlgorithmName.SHA1);
+ });
+ }
+
+ protected virtual void UseAfterDispose(DSA dsa, byte[] data, byte[] sig)
+ {
+ Assert.Throws<ObjectDisposedException>(
+ () => SignData(dsa, data, HashAlgorithmName.SHA1));
+
+ Assert.Throws<ObjectDisposedException>(
+ () => VerifyData(dsa, data, sig, HashAlgorithmName.SHA1));
+ }
+
+ [ConditionalFact(nameof(SupportsKeyGeneration))]
public void SignAndVerifyDataNew1024()
{
using (DSA dsa = DSAFactory.Create(1024))
return EcDiffieHellman.Tests.ECDiffieHellmanFactory.IsCurveValid(oid);
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseAfterDispose(bool importKey)
+ {
+ T key = CreateKey();
+
+ if (importKey)
+ {
+ ImportParameters(key, EccTestData.GetNistP256ReferenceKey());
+ }
+
+ byte[] ecPrivate;
+ byte[] pkcs8Private;
+ byte[] pkcs8EncryptedPrivate;
+ byte[] subjectPublicKeyInfo;
+
+ string pwStr = "Hello";
+ // Because the PBE algorithm uses PBES2 the string->byte encoding is UTF-8.
+ byte[] pwBytes = Encoding.UTF8.GetBytes(pwStr);
+
+ PbeParameters pbeParameters = new PbeParameters(
+ PbeEncryptionAlgorithm.Aes192Cbc,
+ HashAlgorithmName.SHA256,
+ 3072);
+
+ // Ensure the key was loaded, then dispose it.
+ // Also ensures all of the inputs are valid for the disposed tests.
+ using (key)
+ {
+ ecPrivate = ExportECPrivateKey(key);
+ pkcs8Private = key.ExportPkcs8PrivateKey();
+ pkcs8EncryptedPrivate = key.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters);
+ subjectPublicKeyInfo = key.ExportSubjectPublicKeyInfo();
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => ImportECPrivateKey(key, ecPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwStr, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ Assert.Throws<ObjectDisposedException>(() => ExportECPrivateKey(key));
+ Assert.Throws<ObjectDisposedException>(() => TryExportECPrivateKey(key, ecPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportPkcs8PrivateKey());
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ExportSubjectPublicKeyInfo());
+ Assert.Throws<ObjectDisposedException>(() => key.TryExportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ // Check encrypted import with the wrong password.
+ // It shouldn't do enough work to realize it was wrong.
+ pwBytes = Array.Empty<byte>();
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey("", pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ }
+
[Fact]
public void ReadWriteNistP521Pkcs8()
{
("a232cec7be26319e53db0d48470232d37793b06b99e8ed82fac1996b3d1596449087769927d64af657cce62d853c4cf7ff4c"
+ "d069eda230d1c524d225756ffbaf").HexToByteArray();
-#if netcoreapp
internal static ECCurve GetNistP256ExplicitCurve()
{
// SEC2-Ver-1.0, 2.7.2
},
D = "00B4F1AE1E7FDCD4B0E82053C08A908852B26231E6C01670FCC6C3EA2C5D3FED40EDF037".HexToByteArray(),
};
-#endif // netcoreapp
}
}
}
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public static void UseAfterDispose(bool importKey)
+ {
+ ECDiffieHellman key = ECDiffieHellmanFactory.Create();
+ ECDiffieHellmanPublicKey pubKey;
+ HashAlgorithmName hash = HashAlgorithmName.SHA256;
+
+ if (importKey)
+ {
+ key.ImportParameters(EccTestData.GetNistP256ReferenceKey());
+ }
+
+ // Ensure the key is populated, then dispose it.
+ using (key)
+ {
+ pubKey = key.PublicKey;
+ key.DeriveKeyFromHash(pubKey, hash);
+
+ pubKey.Dispose();
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHash(pubKey, hash));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHmac(pubKey, hash, null));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHmac(pubKey, hash, new byte[3]));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyTls(pubKey, new byte[4], new byte[64]));
+
+ pubKey = key.PublicKey;
+ }
+
+ key.Dispose();
+
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHash(pubKey, hash));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHmac(pubKey, hash, null));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyFromHmac(pubKey, hash, new byte[3]));
+ Assert.Throws<ObjectDisposedException>(() => key.DeriveKeyTls(pubKey, new byte[4], new byte[64]));
+ Assert.Throws<ObjectDisposedException>(() => key.GenerateKey(ECCurve.NamedCurves.nistP256));
+ Assert.Throws<ObjectDisposedException>(() => key.ImportParameters(EccTestData.GetNistP256ReferenceKey()));
+
+ // Either set_KeySize or the ExportParameters should throw.
+ Assert.Throws<ObjectDisposedException>(
+ () =>
+ {
+ key.KeySize = 384;
+ key.ExportParameters(false);
+ });
+ }
+
#if netcoreapp
private static ECDiffieHellman OpenKnownKey()
{
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Security.Cryptography.Tests;
using System.Text;
using Xunit;
protected override byte[] SignData(ECDsa ecdsa, byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) =>
ecdsa.SignData(data, offset, count, hashAlgorithm);
+ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig)
+ {
+ base.UseAfterDispose(ecdsa, data, sig);
+ byte[] hash = new byte[32];
+
+ Assert.Throws<ObjectDisposedException>(() => ecdsa.VerifyHash(hash, sig));
+ Assert.Throws<ObjectDisposedException>(() => ecdsa.SignHash(hash));
+ }
+
[Theory, MemberData(nameof(RealImplementations))]
public void SignData_InvalidArguments_Throws(ECDsa ecdsa)
{
[Theory]
[MemberData(nameof(RealImplementations))]
+ public void UseAfterDispose_Import(ECDsa ecdsa)
+ {
+ ecdsa.ImportParameters(EccTestData.GetNistP256ReferenceKey());
+ UseAfterDispose(ecdsa);
+ }
+
+ [Theory]
+ [MemberData(nameof(RealImplementations))]
+ public void UseAfterDispose_NewKey(ECDsa ecdsa)
+ {
+ UseAfterDispose(ecdsa);
+ }
+
+ private void UseAfterDispose(ECDsa ecdsa)
+ {
+ byte[] data = { 1 };
+ byte[] sig;
+
+ // Ensure the key is populated, then dispose it.
+ using (ecdsa)
+ {
+ sig = SignData(ecdsa, data, HashAlgorithmName.SHA256);
+ }
+
+ ecdsa.Dispose();
+
+ UseAfterDispose(ecdsa, data, sig);
+
+ if (!(PlatformDetection.IsFullFramework && ecdsa.GetType().Name.EndsWith("Cng")))
+ {
+ Assert.Throws<ObjectDisposedException>(() => ecdsa.GenerateKey(ECCurve.NamedCurves.nistP256));
+
+ Assert.Throws<ObjectDisposedException>(
+ () => ecdsa.ImportParameters(EccTestData.GetNistP256ReferenceKey()));
+ }
+
+ // Either set_KeySize or SignData should throw.
+ Assert.Throws<ObjectDisposedException>(
+ () =>
+ {
+ ecdsa.KeySize = 384;
+ SignData(ecdsa, data, HashAlgorithmName.SHA256);
+ });
+ }
+
+ protected virtual void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig)
+ {
+ Assert.Throws<ObjectDisposedException>(
+ () => SignData(ecdsa, data, HashAlgorithmName.SHA256));
+
+ Assert.Throws<ObjectDisposedException>(
+ () => VerifyData(ecdsa, data, sig, HashAlgorithmName.SHA256));
+ }
+
+ [Theory]
+ [MemberData(nameof(RealImplementations))]
public void SignData_MaxOffset_ZeroLength_NoThrow(ECDsa ecdsa)
{
// Explicitly larger than Array.Empty
protected override byte[] SignData(ECDsa ecdsa, byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) =>
TryWithOutputArray(dest => ecdsa.TrySignData(new ReadOnlySpan<byte>(data, offset, count), dest, hashAlgorithm, out int bytesWritten) ? (true, bytesWritten) : (false, 0));
+ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig)
+ {
+ base.UseAfterDispose(ecdsa, data, sig);
+ byte[] hash = new byte[32];
+
+ Assert.Throws<ObjectDisposedException>(() => ecdsa.VerifyHash(hash.AsSpan(), sig.AsSpan()));
+ Assert.Throws<ObjectDisposedException>(() => ecdsa.TrySignHash(hash, sig, out _));
+ }
+
[Theory, MemberData(nameof(RealImplementations))]
public void SignData_InvalidArguments_Throws(ECDsa ecdsa)
{
}
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseAfterDispose(bool importKey)
+ {
+ RSA rsa = importKey ? RSAFactory.Create(TestData.RSA2048Params) : RSAFactory.Create(1024);
+ byte[] data = TestData.HelloBytes;
+ byte[] enc;
+
+ using (rsa)
+ {
+ enc = Encrypt(rsa, data, RSAEncryptionPadding.Pkcs1);
+ }
+
+ Assert.Throws<ObjectDisposedException>(
+ () => Decrypt(rsa, enc, RSAEncryptionPadding.Pkcs1));
+ }
+
[Fact]
public void DecryptSavedAnswer()
{
}
}
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public static void ExportAfterDispose(bool importKey)
+ {
+ RSA rsa = importKey ? RSAFactory.Create(TestData.RSA2048Params) : RSAFactory.Create(1024);
+
+ // Ensure that the key got created, and then Dispose it.
+ using (rsa)
+ {
+ rsa.Encrypt(TestData.HelloBytes, RSAEncryptionPadding.Pkcs1);
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportParameters(false));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportParameters(true));
+
+ if (!(PlatformDetection.IsFullFramework && rsa.GetType().Name.EndsWith("Cng")))
+ {
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportParameters(TestData.RSA1024Params));
+ }
+ }
+
internal static void AssertKeyEquals(in RSAParameters expected, in RSAParameters actual)
{
Assert.Equal(expected.Modulus, actual.Modulus);
public static bool Supports384BitPrivateKey { get; } = RSAFactory.Supports384PrivateKey;
public static bool SupportsLargeExponent { get; } = RSAFactory.SupportsLargeExponent;
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public static void UseAfterDispose(bool importKey)
+ {
+ RSA rsa = importKey ? RSAFactory.Create(TestData.RSA2048Params) : RSAFactory.Create(1024);
+ byte[] pkcs1Public;
+ byte[] pkcs1Private;
+ byte[] pkcs8Private;
+ byte[] pkcs8EncryptedPrivate;
+ byte[] subjectPublicKeyInfo;
+
+ string pwStr = "Hello";
+ // Because the PBE algorithm uses PBES2 the string->byte encoding is UTF-8.
+ byte[] pwBytes = TestData.HelloBytes;
+
+ PbeParameters pbeParameters = new PbeParameters(
+ PbeEncryptionAlgorithm.Aes192Cbc,
+ HashAlgorithmName.SHA256,
+ 3072);
+
+ // Ensure the key was loaded, then dispose it.
+ // Also ensures all of the inputs are valid for the disposed tests.
+ using (rsa)
+ {
+ pkcs1Public = rsa.ExportRSAPublicKey();
+ pkcs1Private = rsa.ExportRSAPrivateKey();
+ pkcs8Private = rsa.ExportPkcs8PrivateKey();
+ pkcs8EncryptedPrivate = rsa.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters);
+ subjectPublicKeyInfo = rsa.ExportSubjectPublicKeyInfo();
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportRSAPublicKey(pkcs1Public, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportRSAPrivateKey(pkcs1Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportEncryptedPkcs8PrivateKey(pwStr, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportRSAPublicKey());
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportRSAPublicKey(pkcs1Public, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportRSAPrivateKey());
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportRSAPrivateKey(pkcs1Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportPkcs8PrivateKey());
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportPkcs8PrivateKey(pkcs8Private, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportEncryptedPkcs8PrivateKey(pwStr, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters));
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportEncryptedPkcs8PrivateKey(pwBytes, pbeParameters, pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ExportSubjectPublicKeyInfo());
+ Assert.Throws<ObjectDisposedException>(() => rsa.TryExportSubjectPublicKeyInfo(subjectPublicKeyInfo, out _));
+
+ // Check encrypted import with the wrong password.
+ // It shouldn't do enough work to realize it was wrong.
+ pwBytes = Array.Empty<byte>();
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportEncryptedPkcs8PrivateKey("", pkcs8EncryptedPrivate, out _));
+ Assert.Throws<ObjectDisposedException>(() => rsa.ImportEncryptedPkcs8PrivateKey(pwBytes, pkcs8EncryptedPrivate, out _));
+ }
+
[ConditionalFact(nameof(SupportsLargeExponent))]
public static void ReadWriteBigExponentPrivatePkcs1()
{
}
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void UseAfterDispose(bool importKey)
+ {
+ RSA rsa = importKey ? RSAFactory.Create(TestData.RSA2048Params) : RSAFactory.Create(1024);
+ byte[] data = TestData.HelloBytes;
+ byte[] sig;
+ HashAlgorithmName alg = HashAlgorithmName.SHA1;
+ RSASignaturePadding padding = RSASignaturePadding.Pkcs1;
+
+ using (rsa)
+ {
+ sig = SignData(rsa, data, alg, padding);
+ }
+
+ Assert.Throws<ObjectDisposedException>(
+ () => VerifyData(rsa, sig, data, alg, padding));
+
+ Assert.Throws<ObjectDisposedException>(
+ () => VerifyHash(rsa, sig, data, alg, padding));
+
+ // Either set_KeySize or SignData should throw.
+ Assert.Throws<ObjectDisposedException>(
+ () =>
+ {
+ rsa.KeySize = 1024 + 64;
+ SignData(rsa, data, alg, padding);
+ });
+ }
+
[Fact]
public void InvalidKeySize_DoesNotInvalidateKey()
{
public override void FromXmlString(string xmlString) { }
protected virtual byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
protected virtual byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public abstract void ImportParameters(System.Security.Cryptography.DSAParameters parameters);
+ public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual byte[] SignData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public byte[] SignData(byte[] data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual byte[] SignData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public override string ToXmlString(bool includePrivateParameters) { throw null; }
public virtual bool TryCreateSignature(System.ReadOnlySpan<byte> hash, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportPkcs8PrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportSubjectPublicKeyInfo(System.Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public bool VerifyData(byte[] data, byte[] signature, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public override void FromXmlString(string xmlString) { }
public virtual void GenerateKey(System.Security.Cryptography.ECCurve curve) { }
public virtual void ImportECPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual void ImportParameters(System.Security.Cryptography.ECParameters parameters) { }
+ public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public override string ToXmlString(bool includePrivateParameters) { throw null; }
public virtual bool TryExportECPrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportPkcs8PrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportSubjectPublicKeyInfo(System.Span<byte> destination, out int bytesWritten) { throw null; }
}
public abstract partial class ECDiffieHellmanPublicKey : System.IDisposable
{
protected virtual byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
protected virtual byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual void ImportECPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual void ImportParameters(System.Security.Cryptography.ECParameters parameters) { }
+ public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual byte[] SignData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual byte[] SignData(byte[] data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public virtual byte[] SignData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
public abstract byte[] SignHash(byte[] hash);
public override string ToXmlString(bool includePrivateParameters) { throw null; }
public virtual bool TryExportECPrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportPkcs8PrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportSubjectPublicKeyInfo(System.Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(System.ReadOnlySpan<byte> hash, System.Span<byte> destination, out int bytesWritten) { throw null; }
public override void FromXmlString(string xmlString) { }
protected virtual byte[] HashData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
protected virtual byte[] HashData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public abstract void ImportParameters(System.Security.Cryptography.RSAParameters parameters);
+ public override void ImportPkcs8PrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual void ImportRSAPrivateKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual void ImportRSAPublicKey(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
+ public override void ImportSubjectPublicKeyInfo(System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual byte[] SignData(byte[] data, int offset, int count, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; }
public byte[] SignData(byte[] data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; }
public virtual byte[] SignData(System.IO.Stream data, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding) { throw null; }
public override string ToXmlString(bool includePrivateParameters) { throw null; }
public virtual bool TryDecrypt(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
public virtual bool TryEncrypt(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.RSAEncryptionPadding padding, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportPkcs8PrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
public virtual bool TryExportRSAPrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
public virtual bool TryExportRSAPublicKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
+ public override bool TryExportSubjectPublicKeyInfo(System.Span<byte> destination, out int bytesWritten) { throw null; }
protected virtual bool TryHashData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, out int bytesWritten) { throw null; }
public virtual bool TrySignData(System.ReadOnlySpan<byte> data, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding, out int bytesWritten) { throw null; }
public virtual bool TrySignHash(System.ReadOnlySpan<byte> hash, System.Span<byte> destination, System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.Security.Cryptography.RSASignaturePadding padding, out int bytesWritten) { throw null; }
{
private SafeNCryptKeyHandle _keyHandle;
private int _lastKeySize;
+ private bool _disposed;
+
+ private void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(RSA));
+ }
+ }
private SafeNCryptKeyHandle GetDuplicatedKeyHandle()
{
+ ThrowIfDisposed();
+
int keySize = KeySize;
if (_lastKeySize != keySize)
private void ImportKeyBlob(byte[] dsaBlob, bool includePrivate)
{
+ ThrowIfDisposed();
+
// Use generic blob type for multiple version support
string blobType = includePrivate ?
Interop.BCrypt.KeyBlobType.BCRYPT_PRIVATE_KEY_BLOB :
private void AcceptImport(CngPkcs8.Pkcs8Response response)
{
+ ThrowIfDisposed();
+
SafeNCryptKeyHandle keyHandle = response.KeyHandle;
SetKeyHandle(keyHandle);
}
ForceSetKeySize(newKeySize);
_lastKeySize = newKeySize;
}
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _keyHandle?.Dispose();
+ _keyHandle = null;
+ _disposed = true;
+ }
+
+
+ base.Dispose(disposing);
+ }
}
}
}
private SafeNCryptKeyHandle _keyHandle;
private int _lastKeySize;
private string _lastAlgorithm;
+ private bool _disposed;
private readonly string _algorithmGroup;
+ private readonly string _disposedName;
- internal ECCngKey(string algorithmGroup)
+ internal ECCngKey(string algorithmGroup, string disposedName)
{
Debug.Assert(
algorithmGroup == BCryptNative.AlgorithmName.ECDH ||
algorithmGroup == BCryptNative.AlgorithmName.ECDsa);
_algorithmGroup = algorithmGroup;
+ _disposedName = disposedName;
}
internal int KeySize { get; private set; }
internal SafeNCryptKeyHandle GetDuplicatedKeyHandle(int callerKeySizeProperty)
{
+ ThrowIfDisposed();
+
if (ECCng.IsECNamedCurve(_lastAlgorithm))
{
// Curve was previously created, so use that
internal void GenerateKey(ECCurve curve)
{
curve.Validate();
+ ThrowIfDisposed();
if (_keyHandle != null)
{
KeySize = keySize;
}
+ internal void FullDispose()
+ {
+ DisposeKey();
+ _disposed = true;
+ }
+
internal void DisposeKey()
{
if (_keyHandle != null)
internal void SetHandle(SafeNCryptKeyHandle keyHandle, string algorithmName)
{
+ ThrowIfDisposed();
+
_keyHandle?.Dispose();
_keyHandle = keyHandle;
_lastAlgorithm = algorithmName;
KeySize = CngKeyLite.GetKeyLength(keyHandle);
_lastKeySize = KeySize;
}
+
+ internal void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(_disposedName);
+ }
+ }
}
}
{
public sealed partial class ECDiffieHellmanCng : ECDiffieHellman
{
- private readonly ECCngKey _key = new ECCngKey(BCryptNative.AlgorithmName.ECDH);
+ private readonly ECCngKey _key = new ECCngKey(BCryptNative.AlgorithmName.ECDH, nameof(ECDiffieHellman));
private string GetCurveName(out string oidValue) => _key.GetCurveName(KeySize, out oidValue);
{
public sealed partial class ECDiffieHellmanCng : ECDiffieHellman
{
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _key.FullDispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ private void ThrowIfDisposed()
+ {
+ _key.ThrowIfDisposed();
+ }
+
private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
{
string blobType = includePrivateParameters ?
protected override void Dispose(bool disposing)
{
+ _keyBlob = null;
base.Dispose(disposing);
}
/// <returns>The key and explicit curve parameters used by the ECC object.</returns>
public override ECParameters ExportExplicitParameters()
{
+ if (_keyBlob == null)
+ {
+ throw new ObjectDisposedException(nameof(ECDiffieHellmanPublicKey));
+ }
+
ECParameters ecparams = new ECParameters();
ECCng.ExportPrimeCurveParameters(ref ecparams, _keyBlob, includePrivateParameters: false);
return ecparams;
/// <returns>The key and named curve parameters used by the ECC object.</returns>
public override ECParameters ExportParameters()
{
+ if (_keyBlob == null)
+ {
+ throw new ObjectDisposedException(nameof(ECDiffieHellmanPublicKey));
+ }
+
if (string.IsNullOrEmpty(_curveName))
{
return ExportExplicitParameters();
{
public sealed partial class ECDsaCng : ECDsa
{
- private readonly ECCngKey _key = new ECCngKey(AlgorithmName.ECDsa);
+ private readonly ECCngKey _key = new ECCngKey(AlgorithmName.ECDsa, nameof(ECDsa));
private string GetCurveName(out string oidValue) => _key.GetCurveName(KeySize, out oidValue);
{
public sealed partial class ECDsaCng : ECDsa
{
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _key?.FullDispose();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ private void ThrowIfDisposed()
+ {
+ _key.ThrowIfDisposed();
+ }
+
private void ImportFullKeyBlob(byte[] ecfullKeyBlob, bool includePrivateParameters)
{
string blobType = includePrivateParameters ?
{
private SafeNCryptKeyHandle _keyHandle;
private int _lastKeySize;
+ private bool _disposed;
+
+ private void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(RSA));
+ }
+ }
private SafeNCryptKeyHandle GetDuplicatedKeyHandle()
{
+ ThrowIfDisposed();
+
int keySize = KeySize;
if (_lastKeySize != keySize)
private void ImportKeyBlob(byte[] rsaBlob, bool includePrivate)
{
+ ThrowIfDisposed();
+
string blobType = includePrivate
? Interop.BCrypt.KeyBlobType.BCRYPT_RSAPRIVATE_BLOB
: Interop.BCrypt.KeyBlobType.BCRYPT_RSAPUBLIC_KEY_BLOB;
private void AcceptImport(CngPkcs8.Pkcs8Response response)
{
+ ThrowIfDisposed();
+
SafeNCryptKeyHandle keyHandle = response.KeyHandle;
SetKeyHandle(keyHandle);
}
ForceSetKeySize(newKeySize);
_lastKeySize = newKeySize;
}
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _keyHandle?.Dispose();
+ _keyHandle = null;
+ _disposed = true;
+ }
+
+
+ base.Dispose(disposing);
+ }
}
}
}
//
internal struct CngAlgorithmCore
{
+ private readonly string _disposedName;
public CngAlgorithm DefaultKeyType;
private CngKey _lazyKey;
+ private bool _disposed;
+
+ public CngAlgorithmCore(string disposedName) : this()
+ {
+ _disposedName = disposedName;
+ }
public static CngKey Duplicate(CngKey key)
{
public bool IsKeyGeneratedNamedCurve()
{
+ ThrowIfDisposed();
return (_lazyKey != null && _lazyKey.IsECNamedCurve());
}
public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm)
{
+ ThrowIfDisposed();
+
// If our key size was changed, we need to generate a new key.
if (_lazyKey != null)
{
public CngKey GetOrGenerateKey(ECCurve? curve)
{
+ ThrowIfDisposed();
+
if (_lazyKey != null)
{
return _lazyKey;
public void SetKey(CngKey key)
{
Debug.Assert(key != null);
+ ThrowIfDisposed();
// If we already have a key, clear it out.
DisposeKey();
public void Dispose()
{
DisposeKey();
+ _disposed = true;
+ }
+
+ internal void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(_disposedName);
+ }
}
}
}
{
public sealed partial class DSACng : DSA
{
+ private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(DSACng));
+
/// <summary>
/// Creates a new DSACng object that will use the specified key. The key's
/// <see cref="CngKey.AlgorithmGroup" /> must be Dsa. This constructor
_core.Dispose();
}
- private CngAlgorithmCore _core;
+ private void ThrowIfDisposed()
+ {
+ _core.ThrowIfDisposed();
+ }
}
}
/// </summary>
public sealed partial class ECDiffieHellmanCng : ECDiffieHellman
{
- private CngAlgorithmCore _core = new CngAlgorithmCore { DefaultKeyType = CngAlgorithm.ECDiffieHellman };
+ private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDiffieHellmanCng)) { DefaultKeyType = CngAlgorithm.ECDiffieHellman };
private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256;
private ECDiffieHellmanKeyDerivationFunction _kdf = ECDiffieHellmanKeyDerivationFunction.Hash;
private byte[] _hmacKey;
_core.Dispose();
}
+ private void ThrowIfDisposed()
+ {
+ _core.ThrowIfDisposed();
+ }
+
private void DisposeKey()
{
_core.DisposeKey();
{
private CngKeyBlobFormat _format;
private string _curveName;
+ private bool _disposed;
/// <summary>
/// Wrap a CNG key
protected override void Dispose(bool disposing)
{
+ if (disposing)
+ {
+ _disposed = true;
+ }
+
base.Dispose(disposing);
}
/// <returns></returns>
public CngKey Import()
{
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(ECDiffieHellmanCngPublicKey));
+ }
+
return CngKey.Import(ToByteArray(), _curveName, BlobFormat);
}
{
public sealed partial class ECDsaCng : ECDsa
{
- private CngAlgorithmCore _core;
+ private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(ECDsaCng));
private CngAlgorithm _hashAlgorithm = CngAlgorithm.Sha256;
/// <summary>
_core.Dispose();
}
+ private void ThrowIfDisposed()
+ {
+ _core.ThrowIfDisposed();
+ }
+
private void DisposeKey()
{
_core.DisposeKey();
// 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;
-using System.Diagnostics;
-
using Internal.Cryptography;
namespace System.Security.Cryptography
{
public sealed partial class RSACng : RSA
{
+ private CngAlgorithmCore _core = new CngAlgorithmCore(nameof(RSACng));
+
/// <summary>
/// Creates a new RSACng object that will use the specified key. The key's
/// <see cref="CngKey.AlgorithmGroup" /> must be Rsa. This constructor
_core.Dispose();
}
- private CngAlgorithmCore _core;
+ private void ThrowIfDisposed()
+ {
+ _core.ThrowIfDisposed();
+ }
}
}
uap-Windows_NT;
</BuildConfigurations>
</PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>
_publicOnly = (parameters.X == null);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ _impl.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ _impl.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override string KeyExchangeAlgorithm => _impl.KeyExchangeAlgorithm;
public override int KeySize
using System.Diagnostics;
using System.IO;
using Internal.NativeCrypto;
-using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography
{
private SafeProvHandle _safeProvHandle;
private SHA1 _sha1;
private static volatile CspProviderFlags s_useMachineKeyStore = 0;
+ private bool _disposed;
/// <summary>
/// Initializes a new instance of the DSACryptoServiceProvider class.
protected override void Dispose(bool disposing)
{
- base.Dispose(disposing);
-
- if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
+ if (disposing)
{
- _safeKeyHandle.Dispose();
- }
+ if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
+ {
+ _safeKeyHandle.Dispose();
+ }
- if (_safeProvHandle != null && !_safeProvHandle.IsClosed)
- {
- _safeProvHandle.Dispose();
+ if (_safeProvHandle != null && !_safeProvHandle.IsClosed)
+ {
+ _safeProvHandle.Dispose();
+ }
+
+ _disposed = true;
}
+
+ base.Dispose(disposing);
}
/// <summary>
/// <param name="keyBlob">A byte array that represents a DSA key blob.</param>
public void ImportCspBlob(byte[] keyBlob)
{
+ ThrowIfDisposed();
+
SafeKeyHandle safeKeyHandle;
if (IsPublic(keyBlob))
ImportCspBlob(keyBlob);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
/// <summary>
/// Computes the hash value of the specified input stream and signs the resulting hash value.
/// </summary>
return true;
}
+
+ private void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(DSACryptoServiceProvider));
+ }
+ }
}
}
_publicOnly = (parameters.P == null || parameters.P.Length == 0);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ _impl.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ _impl.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
public override string KeyExchangeAlgorithm => _impl.KeyExchangeAlgorithm;
public override int KeySize
private SafeKeyHandle _safeKeyHandle;
private SafeProvHandle _safeProvHandle;
private static volatile CspProviderFlags s_useMachineKeyStore = 0;
+ private bool _disposed;
public RSACryptoServiceProvider()
: this(0, new CspParameters(CapiHelper.DefaultRsaProviderType,
/// </summary>
protected override void Dispose(bool disposing)
{
- base.Dispose(disposing);
-
- if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
- {
- _safeKeyHandle.Dispose();
- }
- if (_safeProvHandle != null && !_safeProvHandle.IsClosed)
+ if (disposing)
{
- _safeProvHandle.Dispose();
+ if (_safeKeyHandle != null && !_safeKeyHandle.IsClosed)
+ {
+ _safeKeyHandle.Dispose();
+ }
+
+ if (_safeProvHandle != null && !_safeProvHandle.IsClosed)
+ {
+ _safeProvHandle.Dispose();
+ }
+
+ _disposed = true;
}
}
/// <param name="keyBlob"></param>
public void ImportCspBlob(byte[] keyBlob)
{
+ ThrowIfDisposed();
SafeKeyHandle safeKeyHandle;
if (IsPublic(keyBlob))
ImportCspBlob(keyBlob);
}
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<byte> passwordBytes,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
+ }
+
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan<char> password,
+ ReadOnlySpan<byte> source,
+ out int bytesRead)
+ {
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
+
/// <summary>
/// Computes the hash value of a subset of the specified byte array using the
/// specified hash algorithm, and signs the resulting hash value.
{
return new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, "hashAlgorithm");
}
+
+ private void ThrowIfDisposed()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(DSACryptoServiceProvider));
+ }
+ }
}
}
{
public DSAOpenSsl(DSAParameters parameters)
{
+ // Make _key be non-null before calling ImportParameters
+ _key = new Lazy<SafeDsaHandle>();
ImportParameters(parameters);
}
{
public RSAOpenSsl(RSAParameters parameters)
{
+ // Make _key be non-null before calling ImportParameters
+ _key = new Lazy<SafeRsaHandle>();
ImportParameters(parameters);
}
// 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.Security.Cryptography.Dsa.Tests;
using Test.Cryptography;
using Xunit;
Assert.ThrowsAny<CryptographicException>(() => new DSAOpenSsl(pkey));
}
}
+
+ [Fact]
+ public static void VerifyParameterCtor()
+ {
+ using (DSA dsa = new DSAOpenSsl(DSATestData.Dsa576Parameters))
+ {
+ DSAImportExport.AssertKeyEquals(
+ DSATestData.Dsa576Parameters,
+ dsa.ExportParameters(true));
+ }
+ }
}
}
// 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.Security.Cryptography.Rsa.Tests;
using Test.Cryptography;
using Xunit;
Assert.ThrowsAny<CryptographicException>(() => new RSAOpenSsl(pkey));
}
}
+
+ [Fact]
+ public static void VerifyParameterCtor()
+ {
+ using (RSA rsa = new RSAOpenSsl(TestData.RSA1032Parameters))
+ {
+ ImportExport.AssertKeyEquals(TestData.RSA1032Parameters, rsa.ExportParameters(true));
+ }
+ }
}
}