Beispiel #1
0
        public static SecIdentity GetIdentity(X509Certificate certificate)
        {
            /*
             * If we got an 'X509Certificate2', then we require it to have a private key
             * and import it.
             */
            var certificate2 = certificate as X509Certificate2;

            if (certificate2 != null)
            {
                return(SecIdentity.Import(certificate2));
            }

            /*
             * Otherwise, we require the private key to be in the keychain.
             */
            using (var secCert = new SecCertificate(certificate)) {
                return(SecKeyChain.FindIdentity(secCert, true));
            }
        }
Beispiel #2
0
        public SecTrust(X509CertificateCollection certificates, SecPolicy policy)
        {
            if (certificates == null)
            {
                throw new ArgumentNullException("certificates");
            }

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

            foreach (var certificate in certificates)
            {
                array [i++] = new SecCertificate(certificate);
            }
            Initialize(array, policy);
            for (i = 0; i < array.Length; i++)
            {
                array [i].Dispose();
            }
        }
Beispiel #3
0
        public SecStatusCode SetAnchorCertificates(X509CertificateCollection certificates)
        {
            if (handle == IntPtr.Zero)
            {
                throw new ObjectDisposedException("SecTrust");
            }
            if (certificates == null)
            {
                return(SecTrustSetAnchorCertificates(handle, IntPtr.Zero));
            }

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

            foreach (var certificate in certificates)
            {
                array [i++] = new SecCertificate(certificate);
            }
            return(SetAnchorCertificates(array));
        }
Beispiel #4
0
        public static INativeObject[] QueryAsReference(SecRecord query, int max, out SecStatusCode result)
        {
            if (query == null)
            {
                result = SecStatusCode.Param;
                return(null);
            }

            using (var copy = query.queryDict.MutableCopy()) {
                copy.SetValue(CFBoolean.True.Handle, SecItem.ReturnRef);
                SetLimit(copy, max);

                IntPtr ptr;
                result = SecItem.SecItemCopyMatching(copy.Handle, out ptr);
                if ((result == SecStatusCode.Success) && (ptr != IntPtr.Zero))
                {
                    var array = CFArray.ArrayFromHandle <INativeObject> (ptr, p => {
                        IntPtr cfType = CFType.GetTypeID(p);
                        if (cfType == SecCertificate.GetTypeID())
                        {
                            return(new SecCertificate(p, true));
                        }
                        else if (cfType == SecKey.GetTypeID())
                        {
                            return(new SecKey(p, true));
                        }
                        else if (cfType == SecIdentity.GetTypeID())
                        {
                            return(new SecIdentity(p, true));
                        }
                        else
                        {
                            throw new Exception(String.Format("Unexpected type: 0x{0:x}", cfType));
                        }
                    });
                    return(array);
                }
                return(null);
            }
        }
Beispiel #5
0
        public static SecIdentity GetIdentity(X509Certificate certificate)
        {
            /*
             * If we got an 'X509Certificate2', then we require it to have a private key
             * and import it.
             */
            var certificate2 = certificate as X509Certificate2;

            if (certificate2 != null)
#if MONOTOUCH
            { return(SecIdentity.Import(certificate2)); }
#else
            { return(SecImportExport.ItemImport(certificate2)); }
#endif

            /*
             * Reading Certificates from the Mac Keychain
             * ==========================================
             *
             * Reading the private key from the keychain is a new feature introduced with
             * AppleTls on XamMac and iOS. On Desktop Mono, this new feature has several
             * known issues and it also did not received any testing yet. We go back to the old
             * way of doing things, which is to explicitly provide an X509Certificate2 with a
             * private key.
             *
             * Keychain Dialog Popups
             * ======================
             *
             * When using Xamarin.Mac or Xamarin.iOS, we try to search the keychain
             * for the certificate and private key.
             *
             * On Xamarin.iOS, this is easy because each app has its own keychain.
             *
             * On Xamarin.Mac, the .app package needs to be trusted via code-sign
             * to get permission to access the user's keychain. [FIXME: I still have to
             * research how to actually do that.] Without this, you will get a popup
             * message each time, asking you whether you want to allow the app to access
             * the keychain, but you can make these go away by selecting "Trust always".
             *
             * On Desktop Mono, this is problematic because selecting "Trust always"
             * give the 'mono' binary (and thus everything you'll ever run with Mono)
             * permission to retrieve the private key from the keychain.
             *
             * This code would also trigger constant keychain popup messages,
             * which could only be suppressed by granting full trust. It also makes it
             * impossible to run Mono in headless mode.
             *
             * SecIdentityCreate
             * =================
             *
             * To avoid these problems, we are currently using an undocumented API
             * called SecIdentityRef() to avoid using the Mac keychain whenever a
             * X509Certificate2 with a private key is used.
             *
             * On iOS and XamMac, you can still provide the X509Certificate without
             * a private key - in this case, a keychain search will be performed (and you
             * may get a popup message on XamMac).
             */

#if MOBILE
            using (var secCert = new SecCertificate(certificate)) {
                return(SecKeyChain.FindIdentity(secCert, true));
            }
#else
            return(null);
#endif
        }