Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ internal static partial class NCrypt
[LibraryImport(Interop.Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)]
internal static partial ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList, ref byte pbOutput, int cbOutput, out int pcbResult, int dwFlags);

[LibraryImport(Interop.Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)]
internal static partial ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, IntPtr pParameterList, Span<byte> pbOutput, int cbOutput, out int pcbResult, int dwFlags);

[LibraryImport(Interop.Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)]
internal static partial ErrorCode NCryptExportKey(SafeNCryptKeyHandle hKey, IntPtr hExportKey, string pszBlobType, ref NCryptBufferDesc pParameterList, ref byte pbOutput, int cbOutput, out int pcbResult, int dwFlags);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ private static partial ErrorCode NCryptDeriveKey(
out int pcbResult,
SecretAgreementFlags dwFlags);

[LibraryImport(Interop.Libraries.NCrypt, StringMarshalling = StringMarshalling.Utf16)]
private static partial ErrorCode NCryptDeriveKey(
SafeNCryptSecretHandle hSharedSecret,
string pwszKDF,
IntPtr pParameterList,
Span<byte> pbDerivedKey,
int cbDerivedKey,
out int pcbResult,
SecretAgreementFlags dwFlags);

/// <summary>
/// Derive key material from a hash or HMAC KDF
/// </summary>
Expand Down Expand Up @@ -257,5 +267,35 @@ internal static byte[] DeriveKeyMaterialTruncate(
Array.Reverse(result);
return result;
}

internal static bool TryDeriveKeyMaterialTruncate(
SafeNCryptSecretHandle secretAgreement,
SecretAgreementFlags flags,
Span<byte> destination,
Comment thread
vcsjones marked this conversation as resolved.
out int bytesWritten)
{
ErrorCode error = NCryptDeriveKey(
secretAgreement,
BCryptNative.KeyDerivationFunction.Raw,
IntPtr.Zero,
destination,
destination.Length,
out int localWritten,
flags);

switch (error)
{
case ErrorCode.ERROR_SUCCESS:
destination.Slice(0, localWritten).Reverse();
bytesWritten = localWritten;
return true;
case ErrorCode c when c.IsBufferTooSmall():
destination.Clear();
bytesWritten = 0;
return false;
default:
throw error.ToCryptographicException();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ internal static SafeNCryptKeyHandle ImportKeyBlob(
string blobType,
ReadOnlySpan<byte> keyBlob,
string curveName,
SafeNCryptProviderHandle provider)
SafeNCryptProviderHandle provider,
int flags = 0)
{
ErrorCode errorCode;
SafeNCryptKeyHandle keyHandle;
Expand Down Expand Up @@ -173,7 +174,7 @@ internal static SafeNCryptKeyHandle ImportKeyBlob(
out keyHandle,
ref MemoryMarshal.GetReference(keyBlob),
keyBlob.Length,
0);
flags);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@ internal static void ReadEncryptedPkcs8<TRet>(
out ret);
}

internal static void ReadEncryptedPkcs8<TRet, TState>(
string[] validOids,
ReadOnlySpan<byte> source,
ReadOnlySpan<char> password,
TState state,
KeyReader<TRet, TState> keyReader,
out int bytesRead,
out TRet ret)
#if NET
where TState : allows ref struct
#endif
{
ReadEncryptedPkcs8(
validOids,
source,
password,
ReadOnlySpan<byte>.Empty,
state,
keyReader,
out bytesRead,
out ret);
}

internal static void ReadEncryptedPkcs8<TRet>(
string[] validOids,
ReadOnlySpan<byte> source,
Expand All @@ -50,6 +73,29 @@ internal static void ReadEncryptedPkcs8<TRet>(
out ret);
}

internal static void ReadEncryptedPkcs8<TRet, TState>(
string[] validOids,
ReadOnlySpan<byte> source,
ReadOnlySpan<byte> passwordBytes,
TState state,
KeyReader<TRet, TState> keyReader,
out int bytesRead,
out TRet ret)
#if NET
where TState : allows ref struct
#endif
{
ReadEncryptedPkcs8(
validOids,
source,
ReadOnlySpan<char>.Empty,
passwordBytes,
state,
keyReader,
out bytesRead,
out ret);
}

private static void ReadEncryptedPkcs8<TRet>(
string[] validOids,
ReadOnlySpan<byte> source,
Expand All @@ -58,6 +104,30 @@ private static void ReadEncryptedPkcs8<TRet>(
KeyReader<TRet> keyReader,
out int bytesRead,
out TRet ret)
{
ReadEncryptedPkcs8<TRet, KeyReader<TRet>>(
validOids,
source,
password,
passwordBytes,
keyReader,
static (key, kr, in algId, out ret) => kr(key, algId, out ret),
out bytesRead,
out ret);
}

private static void ReadEncryptedPkcs8<TRet, TState>(
string[] validOids,
ReadOnlySpan<byte> source,
ReadOnlySpan<char> password,
ReadOnlySpan<byte> passwordBytes,
TState state,
KeyReader<TRet, TState> keyReader,
out int bytesRead,
out TRet ret)
#if NET
where TState : allows ref struct
#endif
{
int read;
ValueEncryptedPrivateKeyInfoAsn epki;
Expand Down Expand Up @@ -92,6 +162,7 @@ private static void ReadEncryptedPkcs8<TRet>(
ReadPkcs8(
validOids,
decryptedMemory.Span,
state,
keyReader,
out int innerRead,
out ret);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ internal static partial class KeyFormatHelper
{
internal delegate void KeyReader<TRet>(ReadOnlySpan<byte> key, in ValueAlgorithmIdentifierAsn algId, out TRet ret);

internal delegate void KeyReader<TRet, TState>(ReadOnlySpan<byte> key, TState state, in ValueAlgorithmIdentifierAsn algId, out TRet ret)
#if NET
where TState : allows ref struct;
#else
;
#endif

internal static void ReadSubjectPublicKeyInfo<TRet>(
string[] validOids,
ReadOnlySpan<byte> source,
Expand Down Expand Up @@ -78,6 +85,26 @@ internal static void ReadPkcs8<TRet>(
KeyReader<TRet> keyReader,
out int bytesRead,
out TRet ret)
{
ReadPkcs8<TRet, KeyReader<TRet>>(
validOids,
source,
keyReader,
static (key, kr, in algId, out ret) => kr(key, algId, out ret),
Comment thread
vcsjones marked this conversation as resolved.
out bytesRead,
out ret);
}

internal static void ReadPkcs8<TRet, TState>(
string[] validOids,
ReadOnlySpan<byte> source,
TState state,
KeyReader<TRet, TState> keyReader,
out int bytesRead,
out TRet ret)
#if NET
where TState : allows ref struct
#endif
{
try
{
Expand All @@ -91,7 +118,7 @@ internal static void ReadPkcs8<TRet>(
}

// Fails if there are unconsumed bytes.
keyReader(privateKeyInfo.PrivateKey, privateKeyInfo.PrivateKeyAlgorithm, out ret);
keyReader(privateKeyInfo.PrivateKey, state, privateKeyInfo.PrivateKeyAlgorithm, out ret);
bytesRead = read;
}
catch (AsnContentException e)
Expand Down
Loading
Loading