Beispiel #1
0
        public static SecIdentity Import(byte[] data, string password, ImportOptions options = null)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (string.IsNullOrEmpty(password))              // SecPKCS12Import() doesn't allow empty passwords.
            {
                throw new ArgumentException("password");
            }
            using (var pwstring = CFString.Create(password))
                using (var optionDict = CreateImportOptions(pwstring, options)) {
                    CFDictionary [] array;
                    SecStatusCode   result = SecImportExport.ImportPkcs12(data, optionDict, out array);
                    if (result != SecStatusCode.Success)
                    {
                        throw new InvalidOperationException(result.ToString());
                    }

                    return(new SecIdentity(array [0].GetValue(ImportItemIdentity.Handle)));
                }
        }
Beispiel #2
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
        }