Exemple #1
0
        private static byte[] X509Export(X509ContentType contentType, SafeCreateHandle cfPassphrase, IntPtr[] certHandles)
        {
            Debug.Assert(contentType == X509ContentType.Pkcs7 || contentType == X509ContentType.Pkcs12);

            using (SafeCreateHandle handlesArray = CoreFoundation.CFArrayCreate(certHandles, (UIntPtr)certHandles.Length))
            {
                SafeCFDataHandle exportData;
                int osStatus;

                int result = AppleCryptoNative_X509ExportData(
                    handlesArray,
                    contentType,
                    cfPassphrase,
                    out exportData,
                    out osStatus);

                using (exportData)
                {
                    if (result != 1)
                    {
                        if (result == 0)
                        {
                            throw CreateExceptionForOSStatus(osStatus);
                        }

                        Debug.Fail($"Unexpected result from AppleCryptoNative_X509ExportData: {result}");
                        throw new CryptographicException();
                    }

                    Debug.Assert(!exportData.IsInvalid, "Successful export yielded no data");
                    return(CoreFoundation.CFGetData(exportData));
                }
            }
        }
Exemple #2
0
        internal static byte[] X509GetRawData(SafeSecCertificateHandle cert)
        {
            int osStatus;
            SafeCFDataHandle data;

            int ret = AppleCryptoNative_X509GetRawData(
                cert,
                out data,
                out osStatus);

            using (data)
            {
                if (ret == 1)
                {
                    return(CoreFoundation.CFGetData(data));
                }

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

                Debug.Fail($"Unexpected return value {ret}");
                throw new CryptographicException();
            }
        }
        private static byte[] ExecuteTransform(ReadOnlySpan <byte> source, SecKeyTransform transform)
        {
            const int Success        = 1;
            const int kErrorSeeError = -2;

            SafeCFDataHandle  data;
            SafeCFErrorHandle error;

            int ret = transform(source, out data, out error);

            using (error)
                using (data)
                {
                    if (ret == Success)
                    {
                        return(CoreFoundation.CFGetData(data));
                    }

                    if (ret == kErrorSeeError)
                    {
                        throw CreateExceptionForCFError(error);
                    }

                    Debug.Fail($"transform returned {ret}");
                    throw new CryptographicException();
                }
        }
Exemple #4
0
        internal static bool TrySecKeyCopyExternalRepresentation(
            SafeSecKeyRefHandle key,
            out byte[] externalRepresentation)
        {
            const int errSecPassphraseRequired = -25260;

            int result = AppleCryptoNative_SecKeyCopyExternalRepresentation(
                key,
                out SafeCFDataHandle data,
                out SafeCFErrorHandle errorHandle);

            using (errorHandle)
                using (data)
                {
                    switch (result)
                    {
                    case kSuccess:
                        externalRepresentation = CoreFoundation.CFGetData(data);
                        return(true);

                    case kErrorSeeError:
                        if (Interop.CoreFoundation.GetErrorCode(errorHandle) == errSecPassphraseRequired)
                        {
                            externalRepresentation = Array.Empty <byte>();
                            return(false);
                        }
                        throw CreateExceptionForCFError(errorHandle);

                    default:
                        Debug.Fail($"SecKeyCopyExternalRepresentation returned {result}");
                        throw new CryptographicException();
                    }
                }
        }
 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));
     }
 }
        internal static byte[] SecKeyExport(
            SafeSecKeyRefHandle key,
            bool exportPrivate,
            string password)
        {
            SafeCreateHandle exportPassword = exportPrivate
                ? CoreFoundation.CFStringCreateWithCString(password)
                : s_nullExportString;

            int ret;
            SafeCFDataHandle cfData;
            int osStatus;

            try
            {
                ret = AppleCryptoNative_SecKeyExport(
                    key,
                    exportPrivate ? 1 : 0,
                    exportPassword,
                    out cfData,
                    out osStatus);
            }
            finally
            {
                if (exportPassword != s_nullExportString)
                {
                    exportPassword.Dispose();
                }
            }

            byte[] exportedData;

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

                if (ret != 1)
                {
                    Debug.Fail($"AppleCryptoNative_SecKeyExport returned {ret}");
                    throw new CryptographicException();
                }

                exportedData = CoreFoundation.CFGetData(cfData);
            }

            return(exportedData);
        }
Exemple #8
0
        internal static byte[]? EcdhKeyAgree(
            SafeSecKeyRefHandle privateKey,
            SafeSecKeyRefHandle publicKey,
            Span <byte> opportunisticDestination,
            out int bytesWritten)
        {
            const int Success        = 1;
            const int kErrorSeeError = -2;

            SafeCFDataHandle  data;
            SafeCFErrorHandle error;

            int status = AppleCryptoNative_EcdhKeyAgree(privateKey, publicKey, out data, out error);

            using (data)
                using (error)
                {
                    if (status == kErrorSeeError)
                    {
                        throw CreateExceptionForCFError(error);
                    }

                    if (status == Success && !data.IsInvalid)
                    {
                        if (CoreFoundation.TryCFWriteData(data, opportunisticDestination, out bytesWritten))
                        {
                            return(null);
                        }

                        bytesWritten = 0;
                        return(CoreFoundation.CFGetData(data));
                    }

                    Debug.Fail($"Unexpected status ({status})");
                    throw new CryptographicException();
                }
        }
        internal static DerSequenceReader SecKeyExport(
            SafeSecKeyRefHandle key,
            bool exportPrivate)
        {
            // Apple requires all private keys to be exported encrypted, but since we're trying to export
            // as parsed structures we will need to decrypt it for the user.
            const string ExportPassword = "******";

            SafeCreateHandle exportPassword = exportPrivate
                ? CoreFoundation.CFStringCreateWithCString(ExportPassword)
                : s_nullExportString;

            int ret;
            SafeCFDataHandle cfData;
            int osStatus;

            try
            {
                ret = AppleCryptoNative_SecKeyExport(
                    key,
                    exportPrivate ? 1 : 0,
                    exportPassword,
                    out cfData,
                    out osStatus);
            }
            finally
            {
                if (exportPassword != s_nullExportString)
                {
                    exportPassword.Dispose();
                }
            }

            byte[] exportedData;

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

                if (ret != 1)
                {
                    Debug.Fail($"AppleCryptoNative_SecKeyExport returned {ret}");
                    throw new CryptographicException();
                }

                exportedData = CoreFoundation.CFGetData(cfData);
            }

            DerSequenceReader reader = new DerSequenceReader(exportedData);

            if (!exportPrivate)
            {
                return(reader);
            }

            byte tag = reader.PeekTag();

            // PKCS#8 defines two structures, PrivateKeyInfo, which starts with an integer,
            // and EncryptedPrivateKey, which starts with an encryption algorithm (DER sequence).
            if (tag == (byte)DerSequenceReader.DerTag.Integer)
            {
                return(reader);
            }

            const byte ConstructedSequence =
                DerSequenceReader.ConstructedFlag | (byte)DerSequenceReader.DerTag.Sequence;

            if (tag == ConstructedSequence)
            {
                return(ReadEncryptedPkcs8Blob(ExportPassword, reader));
            }

            Debug.Fail($"Data was neither PrivateKey or EncryptedPrivateKey: {tag:X2}");
            throw new CryptographicException();
        }