File: System\Security\Cryptography\CngKey.Export.cs
Web Access
Project: src\src\runtime\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;

using ErrorCode = Interop.NCrypt.ErrorCode;

namespace System.Security.Cryptography
{
    /// <summary>
    ///     Managed representation of an NCrypt key
    /// </summary>
    public sealed partial class CngKey : IDisposable
    {
        /// <summary>
        ///     Export the key out of the KSP
        /// </summary>
        public byte[] Export(CngKeyBlobFormat format)
        {
            ArgumentNullException.ThrowIfNull(format);

            int numBytesNeeded;
            ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, null, 0, out numBytesNeeded, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
                throw errorCode.ToCryptographicException();

            byte[] buffer = new byte[numBytesNeeded];
            errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, buffer, buffer.Length, out numBytesNeeded, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
                throw errorCode.ToCryptographicException();

            Array.Resize(ref buffer, numBytesNeeded);
            return buffer;
        }

        internal bool TryExportKeyBlob(
            string blobType,
            Span<byte> destination,
            out int bytesWritten)
        {
            return _keyHandle.TryExportKeyBlob(blobType, destination, out bytesWritten);
        }

        internal byte[] ExportPkcs8KeyBlob(
            ReadOnlySpan<char> password,
            int kdfCount)
        {
            bool ret = CngHelpers.ExportPkcs8KeyBlob(
                allocate: true,
                _keyHandle,
                password,
                kdfCount,
                Span<byte>.Empty,
                out _,
                out byte[]? allocated);

            Debug.Assert(ret);
            Debug.Assert(allocated != null); // since `allocate: true`
            return allocated;
        }

        internal bool TryExportPkcs8KeyBlob(
            ReadOnlySpan<char> password,
            int kdfCount,
            Span<byte> destination,
            out int bytesWritten)
        {
            return CngHelpers.ExportPkcs8KeyBlob(
                false,
                _keyHandle,
                password,
                kdfCount,
                destination,
                out bytesWritten,
                out _);
        }
    }
}