File: src\libraries\Common\src\System\Security\Cryptography\ECDiffieHellmanOpenSslPublicKey.cs
Web Access
Project: src\src\libraries\System.Security.Cryptography\src\System.Security.Cryptography.csproj (System.Security.Cryptography)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics.CodeAnalysis;
using Microsoft.Win32.SafeHandles;
 
namespace System.Security.Cryptography
{
    internal sealed class ECDiffieHellmanOpenSslPublicKey : ECDiffieHellmanPublicKey
    {
        private ECOpenSsl? _key;
 
        internal ECDiffieHellmanOpenSslPublicKey(SafeEvpPKeyHandle pkeyHandle)
        {
            ArgumentNullException.ThrowIfNull(pkeyHandle);
 
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));
 
            // 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 == null || key.IsInvalid)
            {
                key?.Dispose();
 
                // This may happen when EVP_PKEY was created by provider and getting EC_KEY is not possible.
                // Since you cannot mix EC_KEY and EVP_PKEY params API we need to export and re-import the public key.
                ECParameters ecParams = ECOpenSsl.ExportParameters(pkeyHandle, includePrivateParameters: false);
                _key = new ECOpenSsl(ecParams);
            }
            else
            {
                _key = new ECOpenSsl(key);
            }
        }
 
        internal ECDiffieHellmanOpenSslPublicKey(ECParameters parameters)
        {
            _key = new ECOpenSsl(parameters);
        }
 
#pragma warning disable 0672 // Member overrides an obsolete member.
        public override string ToXmlString()
#pragma warning restore 0672
        {
            throw new PlatformNotSupportedException();
        }
 
#pragma warning disable 0672 // Member overrides an obsolete member.
        public override byte[] ToByteArray()
#pragma warning restore 0672
        {
            throw new PlatformNotSupportedException();
        }
 
        public override ECParameters ExportExplicitParameters() =>
            ECOpenSsl.ExportExplicitParameters(GetKey(), includePrivateParameters: false);
 
        public override ECParameters ExportParameters() =>
            ECOpenSsl.ExportParameters(GetKey(), includePrivateParameters: false);
 
        internal bool HasCurveName => Interop.Crypto.EcKeyHasCurveName(GetKey());
 
        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 = GetKey();
            return Interop.Crypto.CreateEvpPkeyFromEcKey(currentKey);
        }
 
        [MemberNotNull(nameof(_key))]
        private void ThrowIfDisposed()
        {
            ObjectDisposedException.ThrowIf(_key is null, this);
        }
 
        private SafeEcKeyHandle GetKey()
        {
            ThrowIfDisposed();
            return _key.Value;
        }
    }
}