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 @@ -7,8 +7,106 @@

namespace Internal.Cryptography
{
internal static class PemKeyImportHelpers
internal static class PemKeyHelpers
{
public delegate bool TryExportKeyAction<T>(T arg, Span<byte> destination, out int bytesWritten);
public delegate bool TryExportEncryptedKeyAction<T>(
T arg,
ReadOnlySpan<char> password,
PbeParameters pbeParameters,
Span<byte> destination,
out int bytesWritten);

public static unsafe bool TryExportToEncryptedPem<T>(
T arg,
ReadOnlySpan<char> password,
PbeParameters pbeParameters,
TryExportEncryptedKeyAction<T> exporter,
Span<char> destination,
out int charsWritten)
{
int bufferSize = 4096;

while (true)
{
byte[] buffer = CryptoPool.Rent(bufferSize);
int bytesWritten = 0;
bufferSize = buffer.Length;

// Fixed to prevent GC moves.
fixed (byte* bufferPtr = buffer)
{
try
{
if (exporter(arg, password, pbeParameters, buffer, out bytesWritten))
{
Span<byte> writtenSpan = new Span<byte>(buffer, 0, bytesWritten);
return PemEncoding.TryWrite(PemLabels.EncryptedPkcs8PrivateKey, writtenSpan, destination, out charsWritten);
}
}
finally
{
CryptoPool.Return(buffer, bytesWritten);
}

bufferSize = checked(bufferSize * 2);
}
}
}

public static unsafe bool TryExportToPem<T>(
T arg,
string label,
TryExportKeyAction<T> exporter,
Span<char> destination,
out int charsWritten)
{
int bufferSize = 4096;

while (true)
{
byte[] buffer = CryptoPool.Rent(bufferSize);
int bytesWritten = 0;
bufferSize = buffer.Length;

// Fixed to prevent GC moves.
fixed (byte* bufferPtr = buffer)
{
try
{
if (exporter(arg, buffer, out bytesWritten))
{
Span<byte> writtenSpan = new Span<byte>(buffer, 0, bytesWritten);
return PemEncoding.TryWrite(label, writtenSpan, destination, out charsWritten);
}
}
finally
{
CryptoPool.Return(buffer, bytesWritten);
}

bufferSize = checked(bufferSize * 2);
}
}
}

internal static string CreatePemFromData(string label, ReadOnlyMemory<byte> data)
{
int pemSize = PemEncoding.GetEncodedSize(label.Length, data.Length);

return string.Create(pemSize, (label, data), static (destination, args) =>
{
(string label, ReadOnlyMemory<byte> data) = args;

if (!PemEncoding.TryWrite(label, data.Span, destination, out int charsWritten) ||
charsWritten != destination.Length)
{
Debug.Fail("Pre-allocated buffer was not the correct size.");
throw new CryptographicException();
}
});
}

public delegate void ImportKeyAction(ReadOnlySpan<byte> source, out int bytesRead);
public delegate ImportKeyAction? FindImportActionFunc(ReadOnlySpan<char> label);
public delegate void ImportEncryptedKeyAction<TPass>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@
Link="Internal\Cryptography\BasicSymmetricCipher.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\Helpers.cs"
Link="Internal\Cryptography\Helpers.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\PemKeyImportHelpers.cs"
Link="Common\Internal\Cryptography\PemKeyImportHelpers.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\PemKeyHelpers.cs"
Link="Common\Internal\Cryptography\PemKeyHelpers.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\ILiteSymmetricCipher.cs"
Link="Internal\Cryptography\ILiteSymmetricCipher.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\SymmetricPadding.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ public virtual unsafe bool TryExportECPrivateKey(Span<byte> destination, out int
/// </remarks>
public override void ImportFromPem(ReadOnlySpan<char> input)
{
PemKeyImportHelpers.ImportPem(input, label => {
PemKeyHelpers.ImportPem(input, label => {
if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
{
return ImportPkcs8PrivateKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ public int GetMaxSignatureSize(DSASignatureFormat signatureFormat)
/// </remarks>
public override void ImportFromPem(ReadOnlySpan<char> input)
{
PemKeyImportHelpers.ImportPem(input, label => {
PemKeyHelpers.ImportPem(input, label => {
if (label.SequenceEqual(PemLabels.Pkcs8PrivateKey))
{
return ImportPkcs8PrivateKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ public override unsafe void ImportEncryptedPkcs8PrivateKey(
/// </remarks>
public override void ImportFromPem(ReadOnlySpan<char> input)
{
PemKeyImportHelpers.ImportPem(input, label => {
PemKeyHelpers.ImportPem(input, label => {
if (label.SequenceEqual(PemLabels.RsaPrivateKey))
{
return ImportRSAPrivateKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ public void Dispose() { }
protected virtual void Dispose(bool disposing) { }
public virtual byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; }
public virtual byte[] ExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; }
public string ExportEncryptedPkcs8PrivateKeyPem(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters) { throw null; }
public virtual byte[] ExportPkcs8PrivateKey() { throw null; }
public string ExportPkcs8PrivateKeyPem() { throw null; }
public virtual byte[] ExportSubjectPublicKeyInfo() { throw null; }
public string ExportSubjectPublicKeyInfoPem() { throw null; }
public virtual void FromXmlString(string xmlString) { }
public virtual void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
public virtual void ImportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.ReadOnlySpan<byte> source, out int bytesRead) { throw null; }
Expand All @@ -76,8 +79,11 @@ public virtual void ImportFromPem(System.ReadOnlySpan<char> input) { }
public virtual string ToXmlString(bool includePrivateParameters) { throw null; }
public virtual bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<byte> passwordBytes, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
public virtual bool TryExportEncryptedPkcs8PrivateKey(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<byte> destination, out int bytesWritten) { throw null; }
public bool TryExportEncryptedPkcs8PrivateKeyPem(System.ReadOnlySpan<char> password, System.Security.Cryptography.PbeParameters pbeParameters, System.Span<char> destination, out int charsWritten) { throw null; }
public virtual bool TryExportPkcs8PrivateKey(System.Span<byte> destination, out int bytesWritten) { throw null; }
public bool TryExportPkcs8PrivateKeyPem(System.Span<char> destination, out int charsWritten) { throw null; }
public virtual bool TryExportSubjectPublicKeyInfo(System.Span<byte> destination, out int bytesWritten) { throw null; }
public bool TryExportSubjectPublicKeyInfoPem(System.Span<char> destination, out int charsWritten) { throw null; }
}
[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")]
public abstract partial class AsymmetricKeyExchangeFormatter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
Link="Common\System\Obsoletions.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\Helpers.cs"
Link="Internal\Cryptography\Helpers.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\PemKeyImportHelpers.cs"
Link="Internal\Cryptography\PemKeyImportHelpers.cs" />
<Compile Include="$(CommonPath)Internal\Cryptography\PemKeyHelpers.cs"
Link="Internal\Cryptography\PemKeyHelpers.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\CryptoPool.cs"
Link="Common\System\Security\Cryptography\CryptoPool.cs" />
<Compile Include="$(CommonPath)System\Security\Cryptography\KeySizeHelpers.cs"
Expand Down
Loading