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)); } }
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(); } }
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)); }
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); } }
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 }