// Adds the given certificate to the given keychain unless it is // already present. Returns the certificate either already in // the store or the one requested. public static X509Certificate2 AddToOSXKeyChainIfNeeded(SafeKeychainHandle keychain, X509Certificate2 certificate) { X509Certificate2 resultCert = null; lock (s_certificateLock) { using (X509Store store = new X509Store(keychain.DangerousGetHandle())) { // No need to open X509Store as it is already opened with mode of MaxAllowed resultCert = CertificateFromThumbprint(store, certificate.Thumbprint, validOnly: false); // Not already in store. We need to add it. if (resultCert == null) { try { // We don't need the private key and the X509Certificate2 instance wasn't created as exportable. // This creates a new certificate instance with only the public key so that it can be added to keychain. var publicOnly = new X509Certificate2(certificate.RawData); store.Add(publicOnly); resultCert = publicOnly; } catch (CryptographicException inner) { throw new InvalidOperationException($"Error while attempting to install cert with thumbprint '{certificate.Thumbprint}' into OSX custom keychain.", inner); } } } } return(resultCert); }
private static X509Certificate2 KeychainCertificateFromThumbprint(string thumbprint, bool validOnly) { X509Certificate2 resultCert = null; using (SafeKeychainHandle handle = SafeKeychainHandle.Open(CertificateManager.OSXCustomKeychainFilePath, CertificateManager.OSXCustomKeychainPassword)) { using (X509Store store = new X509Store(handle.DangerousGetHandle())) { resultCert = CertificateFromThumbprint(store, thumbprint, validOnly); } } return(resultCert); }