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 @@ -232,6 +232,36 @@ internal int ImportParameters(ECParameters parameters)
return size;
}

private static void ExtractPublicKeyFromPrivateKey(ref ECParameters ecParameters)
{
int keySizeInBits = ecParameters.Curve.Oid.Value switch
{
Oids.secp256r1 => 256,
Oids.secp384r1 => 384,
Oids.secp521r1 => 521,
_ => throw DebugFail(), // Apple only supports NIST curves.
};

byte[] privateKey = ecParameters.D!;
int fieldSize = (keySizeInBits + 7) / 8;
Debug.Assert(privateKey.Length == fieldSize);

const int MaxPublicKeySize = 136; // P-521 is 133 bytes, round this off to 136.
Span<byte> publicKey = (stackalloc byte[MaxPublicKeySize]).Slice(0, 1 + 2 * fieldSize);
Interop.AppleCrypto.EccExportPublicKeyFromPrivateKey(keySizeInBits, privateKey, publicKey);
AsymmetricAlgorithmHelpers.DecodeFromUncompressedAnsiX963Key(
publicKey,
hasPrivateKey: false,
out ECParameters publicParameters);
ecParameters.Q = publicParameters.Q;

static Exception DebugFail()
{
Debug.Fail($"Unexpected curve with OID.");
return new CryptographicException();
}
}

private static int GetKeySize(SecKeyPair newKeys)
{
int size = Interop.AppleCrypto.EccGetKeySizeInBits(newKeys.PublicKey);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Diagnostics;
using System.Formats.Asn1;
using System.Runtime.InteropServices;
using System.Security.Cryptography.Apple;
using Internal.Cryptography;

namespace System.Security.Cryptography
{
internal sealed partial class EccAppleCrypto
Expand All @@ -16,35 +9,5 @@ internal sealed partial class EccAppleCrypto
private static ECParameters ExportParametersFromLegacyKey(SecKeyPair keys, bool includePrivateParameters)
=> throw new CryptographicException();
#pragma warning restore IDE0060

private static void ExtractPublicKeyFromPrivateKey(ref ECParameters ecParameters)
{
int keySizeInBits = ecParameters.Curve.Oid.Value switch
{
Oids.secp256r1 => 256,
Oids.secp384r1 => 384,
Oids.secp521r1 => 521,
_ => throw DebugFail(), // Apple only supports NIST curves.
};

byte[] privateKey = ecParameters.D!;
int fieldSize = (keySizeInBits + 7) / 8;
Debug.Assert(privateKey.Length == fieldSize);

const int MaxPublicKeySize = 136; // P-521 is 133 bytes, round this off to 136.
Span<byte> publicKey = (stackalloc byte[MaxPublicKeySize]).Slice(0, 1 + 2 * fieldSize);
Interop.AppleCrypto.EccExportPublicKeyFromPrivateKey(keySizeInBits, privateKey, publicKey);
AsymmetricAlgorithmHelpers.DecodeFromUncompressedAnsiX963Key(
publicKey,
hasPrivateKey: false,
out ECParameters publicParameters);
ecParameters.Q = publicParameters.Q;

static Exception DebugFail()
{
Debug.Fail($"Unexpected curve with OID.");
return new CryptographicException();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Diagnostics;
using System.Formats.Asn1;
using System.Runtime.InteropServices;
using System.Security.Cryptography.Apple;
using Internal.Cryptography;

namespace System.Security.Cryptography
{
internal sealed partial class EccAppleCrypto
Expand Down Expand Up @@ -48,34 +41,5 @@ private static ECParameters ExportParametersFromLegacyKey(SecKeyPair keys, bool
CryptographicOperations.ZeroMemory(keyBlob);
}
}

private static void ExtractPublicKeyFromPrivateKey(ref ECParameters ecParameters)
{
using (SafeSecKeyRefHandle secPrivateKey = ImportLegacyPrivateKey(ref ecParameters))
{
const string ExportPassword = "DotnetExportPassphrase";
byte[] keyBlob = Interop.AppleCrypto.SecKeyExport(secPrivateKey, exportPrivate: true, password: ExportPassword);
EccKeyFormatHelper.ReadEncryptedPkcs8(keyBlob, (ReadOnlySpan<char>)ExportPassword, out _, out ecParameters);
CryptographicOperations.ZeroMemory(keyBlob);
}
}

private static SafeSecKeyRefHandle ImportLegacyPrivateKey(ref ECParameters parameters)
{
AsnWriter keyWriter = EccKeyFormatHelper.WriteECPrivateKey(parameters);

try
{
return keyWriter.Encode(static encoded =>
{
return Interop.AppleCrypto.ImportEphemeralKey(encoded, true);
});
}
finally
{
// Explicitly clear the inner buffer
keyWriter.Reset();
}
}
}
}
Loading