If you attempt to use any of the *OpenSsl primitives on macOS, this will currently abort the whole process.
This changes them to check for OpenSSL's presence and throw an appropriate exception instead of aborting.
When used as an internal implementation, the aborting behavior remains.
public DSAOpenSsl(int keySize)
{
+ ThrowIfNotSupported();
LegalKeySizesValue = s_legalKeySizes;
base.KeySize = keySize;
_key = new Lazy<SafeDsaHandle>(GenerateKey);
_key = new Lazy<SafeDsaHandle>(newKey);
}
+ static partial void ThrowIfNotSupported();
+
private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) };
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
public ECDiffieHellmanOpenSsl(ECCurve curve)
{
+ ThrowIfNotSupported();
_key = new ECOpenSsl(curve);
KeySizeValue = _key.KeySize;
}
public ECDiffieHellmanOpenSsl(int keySize)
{
+ ThrowIfNotSupported();
base.KeySize = keySize;
_key = new ECOpenSsl(this);
}
ThrowIfDisposed();
return _key.Value;
}
+
+ static partial void ThrowIfNotSupported();
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
/// <exception cref="ArgumentNullException">if <paramref name="curve" /> is null.</exception>
public ECDsaOpenSsl(ECCurve curve)
{
+ ThrowIfNotSupported();
_key = new ECOpenSsl(curve);
ForceSetKeySize(_key.KeySize);
}
/// <param name="keySize">Size of the key to generate, in bits.</param>
public ECDsaOpenSsl(int keySize)
{
+ ThrowIfNotSupported();
// Use the base setter to get the validation and field assignment without the
// side effect of dereferencing _key.
base.KeySize = keySize;
);
}
}
+
+ static partial void ThrowIfNotSupported();
}
#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
public RSAOpenSsl(int keySize)
{
+ ThrowIfNotSupported();
base.KeySize = keySize;
_key = new Lazy<SafeEvpPKeyHandle>(GenerateKey);
}
}
}
+ static partial void ThrowIfNotSupported();
+
private static Exception PaddingModeNotSupported() =>
new CryptographicException(SR.Cryptography_InvalidPaddingMode);
<root>
- <!--
- Microsoft ResX Schema
-
+ <!--
+ Microsoft ResX Schema
+
Version 2.0
-
- The primary goals of this format is to allow a simple XML format
- that is mostly human readable. The generation and parsing of the
- various data types are done through the TypeConverter classes
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
associated with the data types.
-
+
Example:
-
+
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
-
- There are any number of "resheader" rows that contain simple
+
+ There are any number of "resheader" rows that contain simple
name/value pairs.
-
- Each data row contains a name, and value. The row also contains a
- type or mimetype. Type corresponds to a .NET class that support
- text/value conversion through the TypeConverter architecture.
- Classes that don't support this are serialized and stored with the
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
mimetype set.
-
- The mimetype is used for serialized objects, and tells the
- ResXResourceReader how to depersist the object. This is currently not
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
-
- Note - application/x-microsoft.net.object.binary.base64 is the format
- that the ResXResourceWriter will generate, however the reader can
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
-
+
mimetype: application/x-microsoft.net.object.binary.base64
- value : The object must be serialized with
+ value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
-
+
mimetype: application/x-microsoft.net.object.soap.base64
- value : The object must be serialized with
+ value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
- value : The object must be serialized into a byte array
+ value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<data name="Cryptography_NotValidPublicOrPrivateKey" xml:space="preserve">
<value>Key is not a valid public or private key.</value>
</data>
+ <data name="Cryptography_AlgorithmNotSupported" xml:space="preserve">
+ <value>Algorithm '{0}' is not supported on this platform.</value>
+ </data>
<data name="PlatformNotSupported_CryptographyOpenSSL" xml:space="preserve">
<value>OpenSSL is not supported on this platform.</value>
</data>
Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs" />
<Compile Include="$(CommonPath)Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs"
Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs" />
+ <Compile Include="$(CommonPath)Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslAvailable.cs"
+ Link="Common\Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslAvailable.cs" />
<Compile Include="$(CommonPath)Microsoft\Win32\SafeHandles\Asn1SafeHandles.Unix.cs"
Link="Common\Microsoft\Win32\SafeHandles\Asn1SafeHandles.Unix.cs" />
<Compile Include="$(CommonPath)Microsoft\Win32\SafeHandles\SafeBignumHandle.Unix.cs"
{
public DSAOpenSsl(DSAParameters parameters)
{
+ ThrowIfNotSupported();
// Make _key be non-null before calling ImportParameters
_key = new Lazy<SafeDsaHandle>();
ImportParameters(parameters);
if (pkeyHandle.IsInvalid)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
+ ThrowIfNotSupported();
// If dsa is valid it has already been up-ref'd, so we can just use this handle as-is.
SafeDsaHandle key = Interop.Crypto.EvpPkeyGetDsa(pkeyHandle);
if (key.IsInvalid)
if (handle == IntPtr.Zero)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(handle));
+ ThrowIfNotSupported();
SafeDsaHandle ecKeyHandle = SafeDsaHandle.DuplicateHandle(handle);
SetKey(ecKeyHandle);
}
throw;
}
}
+
+ static partial void ThrowIfNotSupported()
+ {
+ if (!Interop.OpenSslNoInit.OpenSslIsAvailable)
+ {
+ throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(DSAOpenSsl)));
+ }
+ }
}
}
if (pkeyHandle.IsInvalid)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
+ ThrowIfNotSupported();
// If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);
if (key.IsInvalid)
if (handle == IntPtr.Zero)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(handle));
+ ThrowIfNotSupported();
SafeEcKeyHandle ecKeyHandle = SafeEcKeyHandle.DuplicateHandle(handle);
_key = new ECOpenSsl(ecKeyHandle);
KeySizeValue = _key.KeySize;
throw;
}
}
+
+ static partial void ThrowIfNotSupported()
+ {
+ if (!Interop.OpenSslNoInit.OpenSslIsAvailable)
+ {
+ throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(ECDiffieHellmanOpenSsl)));
+ }
+ }
}
}
if (pkeyHandle.IsInvalid)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
+ ThrowIfNotSupported();
// If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);
if (key.IsInvalid)
if (handle == IntPtr.Zero)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(handle));
+ ThrowIfNotSupported();
SafeEcKeyHandle ecKeyHandle = SafeEcKeyHandle.DuplicateHandle(handle);
_key = new ECOpenSsl(ecKeyHandle);
KeySizeValue = _key.KeySize;
throw;
}
}
+
+ static partial void ThrowIfNotSupported()
+ {
+ if (!Interop.OpenSslNoInit.OpenSslIsAvailable)
+ {
+ throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(ECDsaOpenSsl)));
+ }
+ }
}
}
{
public RSAOpenSsl(RSAParameters parameters)
{
+ ThrowIfNotSupported();
+
// Make _key be non-null before calling ImportParameters
_key = new Lazy<SafeEvpPKeyHandle>();
ImportParameters(parameters);
if (handle == IntPtr.Zero)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(handle));
+ ThrowIfNotSupported();
SafeEvpPKeyHandle pkey = Interop.Crypto.EvpPKeyCreateRsa(handle);
Debug.Assert(!pkey.IsInvalid);
if (pkeyHandle.IsInvalid)
throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
+ ThrowIfNotSupported();
SafeEvpPKeyHandle newKey = Interop.Crypto.EvpPKeyDuplicate(
pkeyHandle,
Interop.Crypto.EvpAlgorithmId.RSA);
{
return Interop.Crypto.EvpPKeyDuplicate(GetKey(), Interop.Crypto.EvpAlgorithmId.RSA);
}
+
+ static partial void ThrowIfNotSupported()
+ {
+ if (!Interop.OpenSslNoInit.OpenSslIsAvailable)
+ {
+ throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_AlgorithmNotSupported, nameof(RSAOpenSsl)));
+ }
+ }
}
}