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

[iOS] Implement iOS PAL for S.S.C.X509Certificates #52191

Merged
merged 28 commits into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6228623
Implement iOS PAL for S.S.C.X509Certificates
filipnavara Apr 30, 2021
92c5ac6
Remove debugging code
filipnavara May 3, 2021
770337f
Fix AppleCryptoNative_X509GetPublicKey usage and implementation
filipnavara May 3, 2021
6d4c67c
Revert workaround for AppleAppBuilder bug
filipnavara May 3, 2021
10d3b1e
Avoid double lookup for PEM markers, remove dead DSA code
filipnavara May 3, 2021
ba2010a
Fix accidental removal of temporary keychain tracking on macOS
filipnavara May 3, 2021
c814a74
Unify some platform support macros
filipnavara May 4, 2021
c0ed204
One more test cleanup
filipnavara May 4, 2021
f0bbee9
Fix couple of leaks in native code and handle allocation failures
filipnavara May 4, 2021
eb82822
More interop cleanup
filipnavara May 4, 2021
48fe4e7
clang-format
filipnavara May 4, 2021
7d315e0
Remove dead code
filipnavara May 4, 2021
cd1b4f8
Extract common code from AppleCertificatePal
filipnavara May 6, 2021
149d470
Improve the AppleCertificatePal split
filipnavara May 7, 2021
c895646
Remove DSA completely from the iOS side of code
filipnavara May 7, 2021
be6db37
Reuse more code on import/export
filipnavara May 7, 2021
510e3a3
Split X509Pal into partial files and reuse them on iOS
filipnavara May 7, 2021
35df973
Reuse TempExportPal
filipnavara May 7, 2021
dd2dd09
Update comments
filipnavara May 7, 2021
d71b4b5
Group shared files in .csproj
filipnavara May 7, 2021
c7c1f2b
Update excluded tests
filipnavara May 7, 2021
f1c1999
Revert test exclusion
filipnavara May 8, 2021
ce15038
Improve implementation of AppleCryptoNative_X509GetPublicKey on Mac C…
filipnavara May 8, 2021
fa57851
Address feedback
filipnavara May 12, 2021
847fb06
Address feedback
filipnavara May 12, 2021
a75f859
Shorten more SkipOnPlatform messages
filipnavara May 12, 2021
03d267c
Fix build of tests
filipnavara May 12, 2021
d74211c
Merge remote-tracking branch 'origin/main' into ios-x509-scratch
filipnavara May 12, 2021
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
@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.Apple;

using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class AppleCrypto
{
[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainEnumerateCerts(
out SafeCFArrayHandle matches);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_SecKeychainEnumerateIdentities(
out SafeCFArrayHandle matches);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509StoreAddCertificate(
SafeHandle certOrIdentity);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509StoreRemoveCertificate(
SafeHandle certOrIdentity,
bool isReadOnlyMode);

internal static SafeCFArrayHandle KeychainEnumerateCerts()
{
SafeCFArrayHandle matches;
int osStatus = AppleCryptoNative_SecKeychainEnumerateCerts(out matches);

if (osStatus == 0)
{
return matches;
}

matches.Dispose();
throw CreateExceptionForOSStatus(osStatus);
}

internal static SafeCFArrayHandle KeychainEnumerateIdentities()
{
SafeCFArrayHandle matches;
int osStatus = AppleCryptoNative_SecKeychainEnumerateIdentities(out matches);

if (osStatus == 0)
{
return matches;
}

matches.Dispose();
throw CreateExceptionForOSStatus(osStatus);
}

internal static void X509StoreAddCertificate(SafeHandle certOrIdentity)
{
int osStatus = AppleCryptoNative_X509StoreAddCertificate(certOrIdentity);

if (osStatus != 0)
{
throw CreateExceptionForOSStatus(osStatus);
}
}

internal static void X509StoreRemoveCertificate(SafeHandle certOrIdentity, bool isReadOnlyMode)
{
const int errSecItemNotFound = -25300;

int osStatus = AppleCryptoNative_X509StoreRemoveCertificate(certOrIdentity, isReadOnlyMode);

if (osStatus == 0 && isReadOnlyMode)
{
// The certificate exists in the store otherwise we would get errSecItemNotFound error
throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
}

if (osStatus != 0 && osStatus != errSecItemNotFound)
{
throw CreateExceptionForOSStatus(osStatus);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ private static extern int AppleCryptoNative_SecKeychainEnumerateIdentities(
out SafeCFArrayHandle matches,
out int pOSStatus);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509StoreAddCertificate(
SafeKeychainItemHandle cert,
SafeKeychainHandle keychain,
out int pOSStatus);

[DllImport(Libraries.AppleCryptoNative)]
private static extern int AppleCryptoNative_X509StoreRemoveCertificate(
SafeKeychainItemHandle cert,
SafeKeychainHandle keychain,
bool isReadOnlyMode,
out int pOSStatus);

private static SafeKeychainHandle SecKeychainItemCopyKeychain(SafeHandle item)
{
bool addedRef = false;
Expand Down Expand Up @@ -290,6 +303,54 @@ internal static void SecKeychainDelete(IntPtr handle, bool throwOnError=true)
throw CreateExceptionForOSStatus(osStatus);
}
}

internal static void X509StoreAddCertificate(SafeKeychainItemHandle certOrIdentity, SafeKeychainHandle keychain)
{
int osStatus;
int ret = AppleCryptoNative_X509StoreAddCertificate(certOrIdentity, keychain, out osStatus);

if (ret == 0)
{
throw CreateExceptionForOSStatus(osStatus);
}

if (ret != 1)
{
Debug.Fail($"Unexpected result from AppleCryptoNative_X509StoreAddCertificate: {ret}");
throw new CryptographicException();
}
}

internal static void X509StoreRemoveCertificate(SafeKeychainItemHandle certHandle, SafeKeychainHandle keychain, bool isReadOnlyMode)
{
int osStatus;
int ret = AppleCryptoNative_X509StoreRemoveCertificate(certHandle, keychain, isReadOnlyMode, out osStatus);

if (ret == 0)
{
throw CreateExceptionForOSStatus(osStatus);
}

const int SuccessOrNoMatch = 1;
const int UserTrustExists = 2;
const int AdminTrustExists = 3;
const int ReadOnlyDelete = 4;

switch (ret)
{
case SuccessOrNoMatch:
break;
case UserTrustExists:
throw new CryptographicException(SR.Cryptography_X509Store_WouldModifyUserTrust);
case AdminTrustExists:
throw new CryptographicException(SR.Cryptography_X509Store_WouldModifyAdminTrust);
case ReadOnlyDelete:
throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly);
default:
Debug.Fail($"Unexpected result from AppleCryptoNative_X509StoreRemoveCertificate: {ret}");
throw new CryptographicException();
}
}
}
}

Expand Down
Loading