Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[macOS/iOS] Implement RSA, ECDsa signing using macOS 10.12+ API #51914

Merged
merged 3 commits into from
Apr 27, 2021
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 @@ -26,27 +26,27 @@ internal static void EccGenerateKey(
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey)
{
SafeSecKeyRefHandle keychainPublic;
SafeSecKeyRefHandle keychainPrivate;
SafeSecKeyRefHandle publicKey;
SafeSecKeyRefHandle privateKey;
SafeCFErrorHandle error;

int result = AppleCryptoNative_EccGenerateKey(
keySizeInBits,
out keychainPublic,
out keychainPrivate,
out publicKey,
out privateKey,
out error);

using (error)
{
if (result == kSuccess)
{
pPublicKey = keychainPublic;
pPrivateKey = keychainPrivate;
pPublicKey = publicKey;
pPrivateKey = privateKey;
return;
}

using (keychainPrivate)
using (keychainPublic)
using (privateKey)
using (publicKey)
{
if (result == kErrorSeeError)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal static partial class Interop
{
internal static partial class AppleCrypto
{
[DllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_RsaGenerateKey")]
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_RsaGenerateKey(
int keySizeInBits,
out SafeSecKeyRefHandle pPublicKey,
Expand Down Expand Up @@ -124,27 +124,27 @@ internal static void RsaGenerateKey(
out SafeSecKeyRefHandle pPublicKey,
out SafeSecKeyRefHandle pPrivateKey)
{
SafeSecKeyRefHandle keychainPublic;
SafeSecKeyRefHandle keychainPrivate;
SafeSecKeyRefHandle publicKey;
SafeSecKeyRefHandle privateKey;
SafeCFErrorHandle error;

int result = AppleCryptoNative_RsaGenerateKey(
keySizeInBits,
out keychainPublic,
out keychainPrivate,
out publicKey,
out privateKey,
out error);

using (error)
{
if (result == kSuccess)
{
pPublicKey = keychainPublic;
pPrivateKey = keychainPrivate;
pPublicKey = publicKey;
pPrivateKey = privateKey;
return;
}

using (keychainPrivate)
using (keychainPublic)
using (privateKey)
using (publicKey)
{
if (result == kErrorSeeError)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal static partial class AppleCrypto
{
private const int kSuccess = 1;
private const int kErrorSeeError = -2;
private const int kPlatformNotSupported = -5;

private static int AppleCryptoNative_SecKeyImportEphemeral(
ReadOnlySpan<byte> pbKeyBlob,
Expand All @@ -35,96 +36,6 @@ private static extern int AppleCryptoNative_SecKeyImportEphemeral(
out SafeSecKeyRefHandle ppKeyOut,
out int pOSStatus);

private static int AppleCryptoNative_GenerateSignature(
SafeSecKeyRefHandle privateKey,
ReadOnlySpan<byte> pbDataHash,
out SafeCFDataHandle pSignatureOut,
out SafeCFErrorHandle pErrorOut) =>
AppleCryptoNative_GenerateSignature(
privateKey,
ref MemoryMarshal.GetReference(pbDataHash),
pbDataHash.Length,
out pSignatureOut,
out pErrorOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_GenerateSignature(
SafeSecKeyRefHandle privateKey,
ref byte pbDataHash,
int cbDataHash,
out SafeCFDataHandle pSignatureOut,
out SafeCFErrorHandle pErrorOut);

private static int AppleCryptoNative_GenerateSignatureWithHashAlgorithm(
SafeSecKeyRefHandle privateKey,
ReadOnlySpan<byte> pbDataHash,
PAL_HashAlgorithm hashAlgorithm,
out SafeCFDataHandle pSignatureOut,
out SafeCFErrorHandle pErrorOut) =>
AppleCryptoNative_GenerateSignatureWithHashAlgorithm(
privateKey,
ref MemoryMarshal.GetReference(pbDataHash),
pbDataHash.Length,
hashAlgorithm,
out pSignatureOut,
out pErrorOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_GenerateSignatureWithHashAlgorithm(
SafeSecKeyRefHandle privateKey,
ref byte pbDataHash,
int cbDataHash,
PAL_HashAlgorithm hashAlgorithm,
out SafeCFDataHandle pSignatureOut,
out SafeCFErrorHandle pErrorOut);

private static int AppleCryptoNative_VerifySignature(
SafeSecKeyRefHandle publicKey,
ReadOnlySpan<byte> pbDataHash,
ReadOnlySpan<byte> pbSignature,
out SafeCFErrorHandle pErrorOut) =>
AppleCryptoNative_VerifySignature(
publicKey,
ref MemoryMarshal.GetReference(pbDataHash),
pbDataHash.Length,
ref MemoryMarshal.GetReference(pbSignature),
pbSignature.Length,
out pErrorOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_VerifySignature(
SafeSecKeyRefHandle publicKey,
ref byte pbDataHash,
int cbDataHash,
ref byte pbSignature,
int cbSignature,
out SafeCFErrorHandle pErrorOut);

private static int AppleCryptoNative_VerifySignatureWithHashAlgorithm(
SafeSecKeyRefHandle publicKey,
ReadOnlySpan<byte> pbDataHash,
ReadOnlySpan<byte> pbSignature,
PAL_HashAlgorithm hashAlgorithm,
out SafeCFErrorHandle pErrorOut) =>
AppleCryptoNative_VerifySignatureWithHashAlgorithm(
publicKey,
ref MemoryMarshal.GetReference(pbDataHash),
pbDataHash.Length,
ref MemoryMarshal.GetReference(pbSignature),
pbSignature.Length,
hashAlgorithm,
out pErrorOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_VerifySignatureWithHashAlgorithm(
SafeSecKeyRefHandle publicKey,
ref byte pbDataHash,
int cbDataHash,
ref byte pbSignature,
int cbSignature,
PAL_HashAlgorithm hashAlgorithm,
out SafeCFErrorHandle pErrorOut);

[DllImport(Libraries.AppleCryptoNative)]
private static extern ulong AppleCryptoNative_SecKeyGetSimpleKeySizeInBytes(SafeSecKeyRefHandle publicKey);

Expand Down Expand Up @@ -218,133 +129,6 @@ internal static SafeSecKeyRefHandle ImportEphemeralKey(ReadOnlySpan<byte> keyBlo
Debug.Fail($"SecKeyImportEphemeral returned {ret}");
throw new CryptographicException();
}

internal static byte[] GenerateSignature(SafeSecKeyRefHandle privateKey, ReadOnlySpan<byte> dataHash)
{
Debug.Assert(privateKey != null, "privateKey != null");

return ExecuteTransform(
dataHash,
(ReadOnlySpan<byte> source, out SafeCFDataHandle signature, out SafeCFErrorHandle error) =>
AppleCryptoNative_GenerateSignature(
privateKey,
source,
out signature,
out error));
}

internal static byte[] GenerateSignature(
SafeSecKeyRefHandle privateKey,
ReadOnlySpan<byte> dataHash,
PAL_HashAlgorithm hashAlgorithm)
{
Debug.Assert(privateKey != null, "privateKey != null");
Debug.Assert(hashAlgorithm != PAL_HashAlgorithm.Unknown, "hashAlgorithm != PAL_HashAlgorithm.Unknown");

return ExecuteTransform(
dataHash,
(ReadOnlySpan<byte> source, out SafeCFDataHandle signature, out SafeCFErrorHandle error) =>
AppleCryptoNative_GenerateSignatureWithHashAlgorithm(
privateKey,
source,
hashAlgorithm,
out signature,
out error));
}

internal static bool TryGenerateSignature(
SafeSecKeyRefHandle privateKey,
ReadOnlySpan<byte> source,
Span<byte> destination,
PAL_HashAlgorithm hashAlgorithm,
out int bytesWritten)
{
Debug.Assert(privateKey != null, "privateKey != null");
Debug.Assert(hashAlgorithm != PAL_HashAlgorithm.Unknown, "hashAlgorithm != PAL_HashAlgorithm.Unknown");

return TryExecuteTransform(
source,
destination,
out bytesWritten,
delegate (ReadOnlySpan<byte> innerSource, out SafeCFDataHandle outputHandle, out SafeCFErrorHandle errorHandle)
{
return AppleCryptoNative_GenerateSignatureWithHashAlgorithm(
privateKey, innerSource, hashAlgorithm, out outputHandle, out errorHandle);
});
}

internal static bool VerifySignature(
SafeSecKeyRefHandle publicKey,
ReadOnlySpan<byte> dataHash,
ReadOnlySpan<byte> signature)
{
Debug.Assert(publicKey != null, "publicKey != null");

SafeCFErrorHandle error;

int ret = AppleCryptoNative_VerifySignature(
publicKey,
dataHash,
signature,
out error);

const int True = 1;
const int False = 0;

using (error)
{
switch (ret)
{
case True:
return true;
case False:
return false;
case kErrorSeeError:
throw CreateExceptionForCFError(error);
default:
Debug.Fail($"VerifySignature returned {ret}");
throw new CryptographicException();
}
}
}

internal static bool VerifySignature(
SafeSecKeyRefHandle publicKey,
ReadOnlySpan<byte> dataHash,
ReadOnlySpan<byte> signature,
PAL_HashAlgorithm hashAlgorithm)
{
Debug.Assert(publicKey != null, "publicKey != null");
Debug.Assert(hashAlgorithm != PAL_HashAlgorithm.Unknown);

SafeCFErrorHandle error;

int ret = AppleCryptoNative_VerifySignatureWithHashAlgorithm(
publicKey,
dataHash,
signature,
hashAlgorithm,
out error);

const int True = 1;
const int False = 0;

using (error)
{
switch (ret)
{
case True:
return true;
case False:
return false;
case kErrorSeeError:
throw CreateExceptionForCFError(error);
default:
Debug.Fail($"VerifySignature returned {ret}");
throw new CryptographicException();
}
}
}
}
}

Expand Down
Loading