コード例 #1
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();
            }
        }
コード例 #2
0
 private static partial int AppleCryptoNative_X509ImportCertificate(
     ref byte pbKeyBlob,
     int cbKeyBlob,
     X509ContentType contentType,
     SafeCreateHandle cfPfxPassphrase,
     out SafeSecCertificateHandle pCertOut,
     out SafeSecIdentityHandle pPrivateKeyOut);
コード例 #3
0
        internal static SafeSecIdentityHandle X509CopyWithPrivateKey(
            SafeSecCertificateHandle certHandle,
            SafeSecKeyRefHandle privateKeyHandle,
            SafeKeychainHandle targetKeychain)
        {
            SafeSecIdentityHandle identityHandle;
            int osStatus;

            int result = AppleCryptoNative_X509CopyWithPrivateKey(
                certHandle,
                privateKeyHandle,
                targetKeychain,
                out identityHandle,
                out osStatus);

            if (result == 1)
            {
                Debug.Assert(!identityHandle.IsInvalid);
                return(identityHandle);
            }

            identityHandle.Dispose();

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

            Debug.Fail($"AppleCryptoNative_X509CopyWithPrivateKey returned {result}");
            throw new CryptographicException();
        }
コード例 #4
0
        internal static AppleCertificatePal ImportPkcs12(UnixPkcs12Reader.CertAndKey certAndKey)
        {
            AppleCertificatePal pal = (AppleCertificatePal)certAndKey.Cert !;

            if (certAndKey.Key != null)
            {
                AppleCertificateExporter exporter = new AppleCertificateExporter(new TempExportPal(pal), certAndKey.Key);
                byte[] smallPfx = exporter.Export(X509ContentType.Pkcs12, s_passwordExportHandle) !;

                SafeSecIdentityHandle    identityHandle;
                SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                    smallPfx,
                    X509ContentType.Pkcs12,
                    s_passwordExportHandle,
                    out identityHandle);

                if (identityHandle.IsInvalid)
                {
                    identityHandle.Dispose();
                    return(new AppleCertificatePal(certHandle));
                }

                certHandle.Dispose();
                return(new AppleCertificatePal(identityHandle));
            }

            return(pal);
        }
コード例 #5
0
        internal static void X509StoreRemoveCertificate(SafeSecCertificateHandle certHandle, SafeKeychainHandle keychain)
        {
            int osStatus;
            int ret = AppleCryptoNative_X509StoreRemoveCertificate(certHandle, keychain, out osStatus);

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

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

            switch (ret)
            {
            case SuccessOrNoMatch:
                break;

            case UserTrustExists:
                throw new CryptographicException(SR.Cryptography_X509Store_WouldModifyUserTrust);

            case AdminTrustExists:
                throw new CryptographicException(SR.Cryptography_X509Store_WouldModifyAdminTrust);

            default:
                Debug.Fail($"Unexpected result from AppleCryptoNative_X509StoreRemoveCertificate: {ret}");
                throw new CryptographicException();
            }
        }
コード例 #6
0
        internal static ICertificatePal ImportPkcs12NonExportable(
            AppleCertificatePal cert,
            SafeSecKeyRefHandle privateKey,
            SafePasswordHandle password,
            SafeKeychainHandle keychain)
        {
            Pkcs12SmallExport exporter = new Pkcs12SmallExport(new TempExportPal(cert), privateKey);

            byte[] smallPfx = exporter.Export(X509ContentType.Pkcs12, password) !;

            SafeSecIdentityHandle    identityHandle;
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                smallPfx,
                X509ContentType.Pkcs12,
                password,
                keychain,
                exportable: false,
                out identityHandle);

            // On Windows and Linux if a PFX uses a LocalKeyId to bind the wrong key to a cert, the
            // nonsensical object of "this cert, that key" is returned.
            //
            // On macOS, because we can't forge CFIdentityRefs without the keychain, we're subject to
            // Apple's more stringent matching of a consistent keypair.
            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            certHandle.Dispose();
            return(new AppleCertificatePal(identityHandle));
        }
コード例 #7
0
        public static SafeSecIdentityHandle GetIdentity(X509Certificate certificate, out SafeSecCertificateHandle[] intermediateCerts)
        {
            var identity = GetIdentity(certificate);

            var impl2 = certificate.Impl as X509Certificate2Impl;

            if (impl2 == null || impl2.IntermediateCertificates == null)
            {
                intermediateCerts = new SafeSecCertificateHandle [0];
                return(identity);
            }

            intermediateCerts = new SafeSecCertificateHandle [impl2.IntermediateCertificates.Count];

            try {
                for (int i = 0; i < intermediateCerts.Length; i++)
                {
                    intermediateCerts [i] = MonoCertificatePal.FromOtherCertificate(impl2.IntermediateCertificates[i]);
                }

                return(identity);
            } catch {
                for (int i = 0; i < intermediateCerts.Length; i++)
                {
                    intermediateCerts [i]?.Dispose();
                }
                identity?.Dispose();
                throw;
            }
        }
コード例 #8
0
ファイル: CertificatePal.cs プロジェクト: stickybun/corefx
        internal AppleCertificatePal(SafeSecIdentityHandle identityHandle)
        {
            Debug.Assert(!identityHandle.IsInvalid);

            _identityHandle = identityHandle;
            _certHandle     = Interop.AppleCrypto.X509GetCertFromIdentity(identityHandle);
        }
コード例 #9
0
        public void Dispose()
        {
            _certHandle?.Dispose();
            _identityHandle?.Dispose();

            _certHandle     = null;
            _identityHandle = null;
        }
コード例 #10
0
 private static extern int AppleCryptoNative_X509ImportCertificate(
     byte[] pbKeyBlob,
     int cbKeyBlob,
     X509ContentType contentType,
     SafeCreateHandle cfPfxPassphrase,
     SafeKeychainHandle tmpKeychain,
     int exportable,
     out SafeSecCertificateHandle pCertOut,
     out SafeSecIdentityHandle pPrivateKeyOut,
     out int pOSStatus);
コード例 #11
0
        public void Dispose()
        {
            _certHandle?.Dispose();
            _identityHandle?.Dispose();

            _certHandle     = null !;
            _identityHandle = null;

            DisposeTempKeychain();
        }
コード例 #12
0
ファイル: CertificatePal.cs プロジェクト: stickybun/corefx
        public void Dispose()
        {
            _certHandle?.Dispose();
            _identityHandle?.Dispose();
            _privateKeyHolder?.Dispose();

            _certHandle       = null;
            _identityHandle   = null;
            _privateKeyHolder = null;
        }
コード例 #13
0
        internal static ICertificatePal FromDerBlob(
            ReadOnlySpan <byte> rawData,
            X509ContentType contentType,
            SafePasswordHandle password,
            X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            if (contentType == X509ContentType.Pkcs7)
            {
                throw new CryptographicException(
                          SR.Cryptography_X509_PKCS7_Unsupported,
                          new PlatformNotSupportedException(SR.Cryptography_X509_PKCS7_Unsupported));
            }

            if (contentType == X509ContentType.Pkcs12)
            {
                if ((keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_X509_PKCS12_ExportableNotSupported);
                }

                if ((keyStorageFlags & X509KeyStorageFlags.PersistKeySet) == X509KeyStorageFlags.PersistKeySet)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_X509_PKCS12_PersistKeySetNotSupported);
                }

                return(ImportPkcs12(rawData, password, ephemeralSpecified));
            }

            SafeSecIdentityHandle    identityHandle;
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                rawData,
                contentType,
                password,
                out identityHandle);

            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            Debug.Fail("Non-PKCS12 import produced an identity handle");

            identityHandle.Dispose();
            certHandle.Dispose();
            throw new CryptographicException();
        }
コード例 #14
0
        internal static SafeSecIdentityHandle X509MoveToKeychain(
            SafeSecCertificateHandle cert,
            SafeKeychainHandle targetKeychain,
            SafeSecKeyRefHandle privateKey)
        {
            SafeSecIdentityHandle identityHandle;
            int osStatus;

            int result = AppleCryptoNative_X509MoveToKeychain(
                cert,
                targetKeychain,
                privateKey ?? SafeSecKeyRefHandle.InvalidHandle,
                out identityHandle,
                out osStatus);

            if (result == 0)
            {
                identityHandle.Dispose();
                throw CreateExceptionForOSStatus(osStatus);
            }

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

            if (privateKey?.IsInvalid == false)
            {
                // If a PFX has a mismatched association between a private key and the
                // certificate public key then MoveToKeychain will write the NULL SecIdentityRef
                // (after cleaning up the temporary key).
                //
                // When that happens, just treat the import as public-only.
                if (!identityHandle.IsInvalid)
                {
                    return(identityHandle);
                }
            }

            // If the cert in the PFX had no key, but it was imported with PersistKeySet (imports into
            // the default keychain) and a matching private key was already there, then an
            // identityHandle could be found. But that's not desirable, since neither Windows or Linux would
            // do that matching.
            //
            // So dispose the handle, no matter what.
            identityHandle.Dispose();
            return(null);
        }
コード例 #15
0
 private static int AppleCryptoNative_X509ImportCertificate(
     ReadOnlySpan <byte> keyBlob,
     X509ContentType contentType,
     SafeCreateHandle cfPfxPassphrase,
     out SafeSecCertificateHandle pCertOut,
     out SafeSecIdentityHandle pPrivateKeyOut)
 {
     return(AppleCryptoNative_X509ImportCertificate(
                ref MemoryMarshal.GetReference(keyBlob),
                keyBlob.Length,
                contentType,
                cfPfxPassphrase,
                out pCertOut,
                out pPrivateKeyOut));
 }
コード例 #16
0
        public void Dispose()
        {
            _certHandle?.Dispose();
            _identityHandle?.Dispose();

            _certHandle     = null !;
            _identityHandle = null;

            SafeKeychainHandle?tempKeychain = Interlocked.Exchange(ref _tempKeychain, null);

            if (tempKeychain != null)
            {
                tempKeychain.Dispose();
            }
        }
コード例 #17
0
        public static SafeSecIdentityHandle FindIdentity(SafeSecCertificateHandle certificate, bool throwOnError = false)
        {
            if (certificate == null || certificate.IsInvalid)
            {
                throw new ObjectDisposedException(nameof(certificate));
            }
            var identity = FindIdentity(cert => MonoCertificatePal.Equals(certificate, cert)) ?? new SafeSecIdentityHandle();

            if (!throwOnError || identity.IsInvalid)
            {
                return(identity);
            }

            var subject = MonoCertificatePal.GetSubjectSummary(certificate);

            throw new InvalidOperationException($"Could not find SecIdentity for certificate '{subject}' in keychain.");
        }
コード例 #18
0
        internal static ICertificatePal FromDerBlob(
            ReadOnlySpan <byte> rawData,
            X509ContentType contentType,
            SafePasswordHandle password,
            X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            bool ephemeralSpecified = keyStorageFlags.HasFlag(X509KeyStorageFlags.EphemeralKeySet);

            if (contentType == X509ContentType.Pkcs7)
            {
                throw new CryptographicException(
                          SR.Cryptography_X509_PKCS7_Unsupported,
                          new PlatformNotSupportedException(SR.Cryptography_X509_PKCS7_Unsupported));
            }

            if (contentType == X509ContentType.Pkcs12)
            {
                // TODO:
                // We ignore keyStorageFlags which is tracked in https://github.com/dotnet/runtime/issues/52434.
                // The keys are always imported as ephemeral and never persisted. Exportability is ignored for
                // the moment and it needs to be investigated how to map it to iOS keychain primitives.
                return(ImportPkcs12(rawData, password, ephemeralSpecified));
            }

            SafeSecIdentityHandle    identityHandle;
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                rawData,
                contentType,
                password,
                out identityHandle);

            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            Debug.Fail("Non-PKCS12 import produced an identity handle");

            identityHandle.Dispose();
            certHandle.Dispose();
            throw new CryptographicException();
        }
コード例 #19
0
ファイル: MonoCertificatePal.cs プロジェクト: seansaleh/mono
        public static string GetSubjectSummary(SafeSecCertificateHandle certificate)
        {
            if (certificate == null || certificate.IsInvalid)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var subjectSummaryHandle = IntPtr.Zero;

            try {
                subjectSummaryHandle = SecCertificateCopySubjectSummary(certificate.DangerousGetHandle());
                return(CFString.AsString(subjectSummaryHandle));
            } finally {
                if (subjectSummaryHandle != IntPtr.Zero)
                {
                    CFObject.CFRelease(subjectSummaryHandle);
                }
            }
        }
コード例 #20
0
        internal static bool X509DemuxAndRetainHandle(
            IntPtr handle,
            out SafeSecCertificateHandle certHandle,
            out SafeSecIdentityHandle identityHandle)
        {
            int result = AppleCryptoNative_X509DemuxAndRetainHandle(handle, out certHandle, out identityHandle);

            switch (result)
            {
            case 1:
                return(true);

            case 0:
                return(false);

            default:
                Debug.Fail($"AppleCryptoNative_X509DemuxAndRetainHandle returned {result}");
                throw new CryptographicException();
            }
        }
コード例 #21
0
ファイル: Trust.cs プロジェクト: SickheadGames/BRUTE.mono
        public SecStatusCode SetAnchorCertificates(X509CertificateCollection certificates)
        {
            if (handle == IntPtr.Zero)
            {
                throw new ObjectDisposedException("SecTrust");
            }
            if (certificates == null)
            {
                return(SecTrustSetAnchorCertificates(handle, IntPtr.Zero));
            }

            var array = new SafeSecCertificateHandle [certificates.Count];
            int i     = 0;

            foreach (var certificate in certificates)
            {
                array [i++] = MonoCertificatePal.FromOtherCertificate(certificate);
            }
            return(SetAnchorCertificates(array));
        }
コード例 #22
0
        protected override ICertificatePalCore ReadX509Der(ReadOnlyMemory <byte> data)
        {
            SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                data.Span,
                X509ContentType.Cert,
                SafePasswordHandle.InvalidHandle,
                out SafeSecIdentityHandle identityHandle);

            if (identityHandle.IsInvalid)
            {
                identityHandle.Dispose();
                return(new AppleCertificatePal(certHandle));
            }

            Debug.Fail("Non-PKCS12 import produced an identity handle");

            identityHandle.Dispose();
            certHandle.Dispose();
            throw new CryptographicException();
        }
コード例 #23
0
ファイル: MonoCertificatePal.cs プロジェクト: seansaleh/mono
        public static byte[] GetRawData(SafeSecCertificateHandle certificate)
        {
            if (certificate == null || certificate.IsInvalid)
            {
                throw new ArgumentNullException(nameof(certificate));
            }

            var dataPtr = SecCertificateCopyData(certificate.DangerousGetHandle());

            if (dataPtr == IntPtr.Zero)
            {
                throw new ArgumentException("Not a valid certificate");
            }

            using (var data = new CFData(dataPtr, true)) {
                var buffer = new byte[(int)data.Length];
                Marshal.Copy(data.Bytes, buffer, 0, buffer.Length);
                return(buffer);
            }
        }
コード例 #24
0
ファイル: Trust.cs プロジェクト: SickheadGames/BRUTE.mono
        public SecTrust(X509CertificateCollection certificates, SecPolicy policy)
        {
            if (certificates == null)
            {
                throw new ArgumentNullException("certificates");
            }

            var array = new SafeSecCertificateHandle [certificates.Count];
            int i     = 0;

            foreach (var certificate in certificates)
            {
                array [i++] = MonoCertificatePal.FromOtherCertificate(certificate);
            }
            Initialize(array, policy);
            for (i = 0; i < array.Length; i++)
            {
                array [i].Dispose();
            }
        }
コード例 #25
0
ファイル: Interop.X509.cs プロジェクト: mangod9/runtime
        internal static SafeSecKeyRefHandle X509GetPublicKey(SafeSecCertificateHandle cert)
        {
            SafeSecKeyRefHandle publicKey;
            int osStatus;
            int ret = AppleCryptoNative_X509GetPublicKey(cert, out publicKey, out osStatus);

            if (ret == 1)
            {
                return(publicKey);
            }

            publicKey.Dispose();

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

            Debug.Fail($"Unexpected return value {ret}");
            throw new CryptographicException();
        }
コード例 #26
0
        internal static string?X509GetSubjectSummary(SafeSecCertificateHandle cert)
        {
            SafeCFStringHandle subjectSummary;

            int ret = AppleCryptoNative_X509GetSubjectSummary(
                cert,
                out subjectSummary);

            using (subjectSummary)
            {
                if (ret == 1)
                {
                    return(CoreFoundation.CFStringToString(subjectSummary));
                }
            }

            if (ret == 0)
            {
                return(null);
            }

            Debug.Fail($"Unexpected return value {ret}");
            throw new CryptographicException();
        }
コード例 #27
0
ファイル: CertificatePal.cs プロジェクト: stickybun/corefx
        public static ICertificatePal FromBlob(
            byte[] rawData,
            SafePasswordHandle password,
            X509KeyStorageFlags keyStorageFlags)
        {
            Debug.Assert(password != null);

            X509ContentType contentType = X509Certificate2.GetCertContentType(rawData);

            if (contentType == X509ContentType.Pkcs7)
            {
                // In single mode for a PKCS#7 signed or signed-and-enveloped file we're supposed to return
                // the certificate which signed the PKCS#7 file.
                //
                // X509Certificate2Collection::Export(X509ContentType.Pkcs7) claims to be a signed PKCS#7,
                // but doesn't emit a signature block. So this is hard to test.
                //
                // TODO(2910): Figure out how to extract the signing certificate, when it's present.
                throw new CryptographicException(SR.Cryptography_X509_PKCS7_NoSigner);
            }

            bool exportable = true;

            SafeKeychainHandle keychain;

            if (contentType == X509ContentType.Pkcs12)
            {
                if ((keyStorageFlags & X509KeyStorageFlags.EphemeralKeySet) == X509KeyStorageFlags.EphemeralKeySet)
                {
                    throw new PlatformNotSupportedException(SR.Cryptography_X509_NoEphemeralPfx);
                }

                exportable = (keyStorageFlags & X509KeyStorageFlags.Exportable) == X509KeyStorageFlags.Exportable;

                bool persist =
                    (keyStorageFlags & X509KeyStorageFlags.PersistKeySet) == X509KeyStorageFlags.PersistKeySet;

                keychain = persist
                    ? Interop.AppleCrypto.SecKeychainCopyDefault()
                    : Interop.AppleCrypto.CreateTemporaryKeychain();
            }
            else
            {
                keychain = SafeTemporaryKeychainHandle.InvalidHandle;
                password = SafePasswordHandle.InvalidHandle;
            }

            using (keychain)
            {
                SafeSecIdentityHandle    identityHandle;
                SafeSecCertificateHandle certHandle = Interop.AppleCrypto.X509ImportCertificate(
                    rawData,
                    contentType,
                    password,
                    keychain,
                    exportable,
                    out identityHandle);

                if (identityHandle.IsInvalid)
                {
                    identityHandle.Dispose();
                    return(new AppleCertificatePal(certHandle));
                }

                if (contentType != X509ContentType.Pkcs12)
                {
                    Debug.Fail("Non-PKCS12 import produced an identity handle");

                    identityHandle.Dispose();
                    certHandle.Dispose();
                    throw new CryptographicException();
                }

                Debug.Assert(certHandle.IsInvalid);
                certHandle.Dispose();
                return(new AppleCertificatePal(identityHandle));
            }
        }
コード例 #28
0
ファイル: CertificatePal.cs プロジェクト: stickybun/corefx
        internal AppleCertificatePal(SafeSecCertificateHandle certHandle)
        {
            Debug.Assert(!certHandle.IsInvalid);

            _certHandle = certHandle;
        }
コード例 #29
0
ファイル: Interop.X509.cs プロジェクト: mangod9/runtime
 private static extern int AppleCryptoNative_X509DemuxAndRetainHandle(
     IntPtr handle,
     out SafeSecCertificateHandle certHandle,
     out SafeSecIdentityHandle identityHandle);
コード例 #30
0
ファイル: Interop.X509.cs プロジェクト: mangod9/runtime
 private static extern int AppleCryptoNative_X509CopyCertFromIdentity(
     SafeSecIdentityHandle identity,
     out SafeSecCertificateHandle cert);