Example #1
0
 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();
                }
            }
        }
Example #4
0
 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);
            }
        }
Example #7
0
 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);
Example #8
0
        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);
Example #10
0
 private static partial int RsaDecryptOaep(
     SafeSecKeyRefHandle publicKey,
     ReadOnlySpan <byte> pbData,
     int cbData,
     PAL_HashAlgorithm mgfAlgorithm,
     out SafeCFDataHandle pEncryptedOut,
     out SafeCFErrorHandle pErrorOut);
Example #11
0
 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);
Example #13
0
 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);
Example #14
0
 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);
Example #15
0
 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));
     }
 }
Example #18
0
 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));
     }
 }
Example #20
0
 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));
     }
 }
Example #21
0
 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));
     }
 }
Example #27
0
        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);
Example #30
0
 internal static extern int SslGetAlpnSelected(SafeSslHandle ssl, out SafeCFDataHandle protocol);