private static int RsaEncryptPkcs( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) => RsaEncryptPkcs(publicKey, ref MemoryMarshal.GetReference(pbData), cbData, out pEncryptedOut, out pErrorOut);
internal static unsafe byte[] ExportPkcs8(SafeSecKeyRefHandle key, ReadOnlySpan <char> password) { using (SafeCFDataHandle data = Interop.AppleCrypto.SecKeyExportData(key, exportPrivate: true, password)) { ReadOnlySpan <byte> systemExport = Interop.CoreFoundation.CFDataDangerousGetSpan(data); fixed(byte *ptr = systemExport) { using (PointerMemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, systemExport.Length)) { // Apple's PKCS8 export exports using PBES2, which Win7, Win8.1, and Apple all fail to // understand in their PKCS12 readers, so re-encrypt using the Win7 PKCS12-PBE parameters. // // Since Apple only reliably exports keys with encrypted PKCS#8 there's not a // "so export it plaintext and only encrypt it once" option. AsnWriter writer = KeyFormatHelper.ReencryptPkcs8( password, manager.Memory, password, UnixExportProvider.s_windowsPbe); return(writer.Encode()); } } } }
internal static byte[] CFGetData(SafeCFDataHandle cfData) { bool addedRef = false; try { cfData.DangerousAddRef(ref addedRef); byte[] bytes = new byte[CFDataGetLength(cfData).ToInt64()]; unsafe { byte *dataBytes = CFDataGetBytePtr(cfData); Marshal.Copy((IntPtr)dataBytes, bytes, 0, bytes.Length); } return(bytes); } finally { if (addedRef) { cfData.DangerousRelease(); } } }
private static extern int RsaDecryptOaep( SafeSecKeyRefHandle publicKey, ref byte pbData, int cbData, PAL_HashAlgorithm mgfAlgorithm, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut);
internal static unsafe bool TryCFWriteData(SafeCFDataHandle cfData, Span <byte> destination, out int bytesWritten) { bool addedRef = false; try { cfData.DangerousAddRef(ref addedRef); long length = CFDataGetLength(cfData).ToInt64(); if (destination.Length < length) { bytesWritten = 0; return(false); } byte *dataBytes = CFDataGetBytePtr(cfData); fixed(byte *destinationPtr = &MemoryMarshal.GetReference(destination)) { Buffer.MemoryCopy(dataBytes, destinationPtr, destination.Length, length); } bytesWritten = (int)length; return(true); } finally { if (addedRef) { cfData.DangerousRelease(); } } }
// // Used only by client SSL code, never returns null. // internal static string[] GetRequestCertificateAuthorities(SafeDeleteContext securityContext) { SafeSslHandle sslContext = ((SafeDeleteSslContext)securityContext).SslContext; if (sslContext == null) { return(Array.Empty <string>()); } using (SafeCFArrayHandle dnArray = Interop.AppleCrypto.SslCopyCADistinguishedNames(sslContext)) { long size = Interop.CoreFoundation.CFArrayGetCount(dnArray); if (size == 0) { return(Array.Empty <string>()); } string[] distinguishedNames = new string[size]; for (int i = 0; i < size; i++) { IntPtr element = Interop.CoreFoundation.CFArrayGetValueAtIndex(dnArray, i); using (SafeCFDataHandle cfData = new SafeCFDataHandle(element, ownsHandle: false)) { byte[] dnData = Interop.CoreFoundation.CFGetData(cfData); X500DistinguishedName dn = new X500DistinguishedName(dnData); distinguishedNames[i] = dn.Name; } } return(distinguishedNames); } }
private static int RsaDecryptPkcs( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) => RsaDecryptPkcs(publicKey, ref pbData.DangerousGetPinnableReference(), cbData, out pEncryptedOut, out pErrorOut);
internal static unsafe Span <byte> CFDataDangerousGetSpan(SafeCFDataHandle cfData) { long length = CFDataGetLength(cfData).ToInt64(); byte *dataBytes = CFDataGetBytePtr(cfData); return(new Span <byte>(dataBytes, checked ((int)length))); }
private static extern int AppleCryptoNative_GenerateSignatureWithHashAlgorithm( SafeSecKeyRefHandle privateKey, ref byte pbDataHash, int cbDataHash, PAL_HashAlgorithm hashAlgorithm, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut);
private static partial int RsaDecryptOaep( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, PAL_HashAlgorithm mgfAlgorithm, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut);
private static int RsaDecryptOaep( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, PAL_HashAlgorithm mgfAlgorithm, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) => RsaDecryptOaep(publicKey, ref pbData.DangerousGetPinnableReference(), cbData, mgfAlgorithm, out pEncryptedOut, out pErrorOut);
private static unsafe extern int AppleCryptoNative_SecKeyCreateSignature( SafeSecKeyRefHandle privateKey, byte *pbDataHash, int cbDataHash, PAL_HashAlgorithm hashAlgorithm, PAL_SignatureAlgorithm signatureAlgorithm, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut);
private static int AppleCryptoNative_GenerateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> pbDataHash, int cbDataHash, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut) => AppleCryptoNative_GenerateSignature( privateKey, ref MemoryMarshal.GetReference(pbDataHash), cbDataHash, out pSignatureOut, out pErrorOut);
private static int AppleCryptoNative_GenerateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> pbDataHash, int cbDataHash, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut) => AppleCryptoNative_GenerateSignature( privateKey, ref pbDataHash.DangerousGetPinnableReference(), cbDataHash, out pSignatureOut, out pErrorOut);
private static int RsaDecryptOaep( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, PAL_HashAlgorithm mgfAlgorithm, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) => RsaDecryptOaep(publicKey, ref MemoryMarshal.GetReference(pbData), cbData, mgfAlgorithm, out pEncryptedOut, out pErrorOut);
internal static byte[] SecKeyExport( SafeSecKeyRefHandle?key, bool exportPrivate, string password) { using (SafeCFDataHandle cfData = SecKeyExportData(key, exportPrivate, password)) { return(CoreFoundation.CFGetData(cfData)); } }
internal static byte[] CreateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> dataHash, PAL_HashAlgorithm hashAlgorithm, PAL_SignatureAlgorithm signatureAlgorithm) { using (SafeCFDataHandle signature = NativeCreateSignature(privateKey, dataHash, hashAlgorithm, signatureAlgorithm)) { return(CoreFoundation.CFGetData(signature)); } }
private static unsafe int RsaDecryptPkcs( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) { fixed(byte *pbDataPtr = &pbData.DangerousGetPinnableReference()) { return(RsaDecryptPkcs(publicKey, pbDataPtr, cbData, out pEncryptedOut, out pErrorOut)); } }
internal static bool TryCreateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> dataHash, Span <byte> destination, PAL_HashAlgorithm hashAlgorithm, PAL_SignatureAlgorithm signatureAlgorithm, out int bytesWritten) { using (SafeCFDataHandle signature = NativeCreateSignature(privateKey, dataHash, hashAlgorithm, signatureAlgorithm)) { return(CoreFoundation.TryCFWriteData(signature, destination, out bytesWritten)); } }
private static unsafe int RsaEncryptOaep( SafeSecKeyRefHandle publicKey, ReadOnlySpan <byte> pbData, int cbData, PAL_HashAlgorithm mgfAlgorithm, out SafeCFDataHandle pEncryptedOut, out SafeCFErrorHandle pErrorOut) { fixed(byte *pbDataPtr = &pbData.DangerousGetPinnableReference()) { return(RsaEncryptOaep(publicKey, pbDataPtr, cbData, mgfAlgorithm, out pEncryptedOut, out pErrorOut)); } }
private static unsafe int AppleCryptoNative_GenerateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> pbDataHash, int cbDataHash, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut) { fixed(byte *pbDataHashPtr = &pbDataHash.DangerousGetPinnableReference()) { return(AppleCryptoNative_GenerateSignature( privateKey, pbDataHashPtr, cbDataHash, out pSignatureOut, out 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);
internal static string CFStringToString(SafeCFStringHandle cfString) { Debug.Assert(cfString != null); Debug.Assert(!cfString.IsInvalid); Debug.Assert(!cfString.IsClosed); // If the string is already stored internally as UTF-8 we can (usually) // get the raw pointer to the data blob, then we can Marshal in the string // via pointer semantics, avoiding a copy. IntPtr interiorPointer = CFStringGetCStringPtr( cfString, CFStringBuiltInEncodings.kCFStringEncodingUTF8); if (interiorPointer != IntPtr.Zero) { return(Marshal.PtrToStringUTF8(interiorPointer) !); } SafeCFDataHandle cfData = CFStringCreateExternalRepresentation( IntPtr.Zero, cfString, CFStringBuiltInEncodings.kCFStringEncodingUTF8, 0); using (cfData) { bool addedRef = false; try { cfData.DangerousAddRef(ref addedRef); unsafe { // Note that CFDataGetLength(cfData).ToInt32() will throw on // too large of an input. Since a >2GB string is pretty unlikely, // that's considered a good thing here. return(Encoding.UTF8.GetString( CFDataGetBytePtr(cfData), CFDataGetLength(cfData).ToInt32())); } } finally { if (addedRef) { cfData.DangerousRelease(); } } } }
internal static string CFStringToString(SafeCFStringHandle cfString) { Debug.Assert(cfString != null); Debug.Assert(!cfString.IsInvalid); Debug.Assert(!cfString.IsClosed); #if HAVE_PTRTOSTRINGUTF8 IntPtr interiorPointer = CFStringGetCStringPtr( cfString, CFStringBuiltInEncodings.kCFStringEncodingUTF8); if (interiorPointer != IntPtr.Zero) { return(Marshal.PtrToStringUTF8(interiorPointer)); } #endif SafeCFDataHandle cfData = CFStringCreateExternalRepresentation( IntPtr.Zero, cfString, CFStringBuiltInEncodings.kCFStringEncodingUTF8, 0); using (cfData) { bool addedRef = false; try { cfData.DangerousAddRef(ref addedRef); unsafe { // Note that CFDataGetLength(cfData).ToInt32() will throw on // too large of an input. Since a >2GB string is pretty unlikely, // that's considered a good thing here. return(Encoding.UTF8.GetString( CFDataGetBytePtr(cfData), CFDataGetLength(cfData).ToInt32())); } } finally { if (addedRef) { cfData.DangerousRelease(); } } } }
internal static byte[] CFGetData(SafeCFDataHandle cfData) { bool addedRef = false; try { cfData.DangerousAddRef(ref addedRef); return(CFDataDangerousGetSpan(cfData).ToArray()); } finally { if (addedRef) { cfData.DangerousRelease(); } } }
private static unsafe int AppleCryptoNative_SecKeyCreateSignature( SafeSecKeyRefHandle privateKey, ReadOnlySpan <byte> dataHash, PAL_HashAlgorithm hashAlgorithm, PAL_SignatureAlgorithm signatureAlgorithm, out SafeCFDataHandle pSignatureOut, out SafeCFErrorHandle pErrorOut) { fixed(byte *pDataHash = dataHash) { return(AppleCryptoNative_SecKeyCreateSignature( privateKey, pDataHash, dataHash.Length, hashAlgorithm, signatureAlgorithm, out pSignatureOut, out pErrorOut)); } }
private static bool ProcessPrimitiveResponse( int returnValue, SafeCFDataHandle cfData, SafeCFErrorHandle cfError, Span <byte> destination, out int bytesWritten) { if (returnValue == kErrorSeeError) { throw CreateExceptionForCFError(cfError); } if (returnValue == kSuccess && !cfData.IsInvalid) { return(CoreFoundation.TryCFWriteData(cfData, destination, out bytesWritten)); } Debug.Fail($"Unknown return value ({returnValue}) or no data object returned"); throw new CryptographicException(); }
private static partial CFIndex CFDataGetLength(SafeCFDataHandle cfData);
private static unsafe partial byte *CFDataGetBytePtr(SafeCFDataHandle cfData);
internal static extern int SslGetAlpnSelected(SafeSslHandle ssl, out SafeCFDataHandle protocol);