diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs index 5186018760af23..93a88661d25ab8 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.SecKeyRef.cs @@ -15,6 +15,8 @@ internal static partial class AppleCrypto private const int kSuccess = 1; private const int kErrorSeeError = -2; private const int kPlatformNotSupported = -5; + private const int kKeyIsSensitive = -6; + private const int kKeyIsNotExtractable = -7; internal enum PAL_KeyAlgorithm : uint { @@ -125,12 +127,6 @@ internal static bool TrySecKeyCopyExternalRepresentation( SafeSecKeyRefHandle key, out byte[] externalRepresentation) { - const int errSecPassphraseRequired = -25260; - - // macOS Sonoma 14.4 started returning errSecInvalidKeyAttributeMask when a key could not be exported - // because it must be exported with a password. - const int errSecInvalidKeyAttributeMask = -67738; - int result = AppleCryptoNative_SecKeyCopyExternalRepresentation( key, out SafeCFDataHandle data, @@ -144,12 +140,12 @@ internal static bool TrySecKeyCopyExternalRepresentation( case kSuccess: externalRepresentation = CoreFoundation.CFGetData(data); return true; + case kKeyIsSensitive: + externalRepresentation = []; + return false; + case kKeyIsNotExtractable: + throw new CryptographicException(SR.Cryptography_KeyNotExtractable); case kErrorSeeError: - if (Interop.CoreFoundation.GetErrorCode(errorHandle) is errSecPassphraseRequired or errSecInvalidKeyAttributeMask) - { - externalRepresentation = Array.Empty(); - return false; - } throw CreateExceptionForCFError(errorHandle); default: Debug.Fail($"SecKeyCopyExternalRepresentation returned {result}"); diff --git a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index 8f39a254b6cc56..a0a9e1e4afcf72 100644 --- a/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -465,6 +465,9 @@ Key Blob not in expected format. + + The key does not permit being exported. + The key is too small for the requested operation. diff --git a/src/libraries/System.Security.Cryptography/tests/Resources/Strings.resx b/src/libraries/System.Security.Cryptography/tests/Resources/Strings.resx index 684a789df83a61..2588869aee8097 100644 --- a/src/libraries/System.Security.Cryptography/tests/Resources/Strings.resx +++ b/src/libraries/System.Security.Cryptography/tests/Resources/Strings.resx @@ -75,6 +75,9 @@ The string contains a character not in the 7 bit ASCII character set. + + The key does not permit being exported. + Removing the requested certificate would modify user trust settings, and has been denied. diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.c index 05147521f1898e..e717eeb92a59cc 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.c @@ -72,9 +72,31 @@ int32_t AppleCryptoNative_SecKeyCopyExternalRepresentation(SecKeyRef pKey, assert(pErrorOut != NULL); *pErrorOut = NULL; + *ppDataOut = NULL; + int32_t ret = 0; + CFDictionaryRef attributes = SecKeyCopyAttributes(pKey); - *ppDataOut = SecKeyCopyExternalRepresentation(pKey, pErrorOut); - return *ppDataOut == NULL ? kErrorSeeError : 1; + if (attributes != NULL) + { + if (CFDictionaryGetValue(attributes, kSecAttrIsExtractable) == kCFBooleanFalse) + { + ret = kKeyIsNotExtractable; + } + else if (CFDictionaryGetValue(attributes, kSecAttrIsSensitive) == kCFBooleanTrue) + { + ret = kKeyIsSensitive; + } + + CFRelease(attributes); + } + + if (ret == 0) + { + *ppDataOut = SecKeyCopyExternalRepresentation(pKey, pErrorOut); + ret = *ppDataOut == NULL ? kErrorSeeError : 1; + } + + return ret; } SecKeyRef AppleCryptoNative_SecKeyCopyPublicKey(SecKeyRef privateKey) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.h index 083a9f9af5b97d..97543db915c576 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.h +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_seckey.h @@ -16,6 +16,8 @@ static const int32_t kErrorSeeError = -2; static const int32_t kErrorUnknownAlgorithm = -3; static const int32_t kErrorUnknownState = -4; static const int32_t kPlatformNotSupported = -5; +static const int32_t kKeyIsSensitive = -6; +static const int32_t kKeyIsNotExtractable = -7; enum {