public void Remove(ICertificatePal certPal) { if (!Directory.Exists(_storePath)) { return; } OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string?currentFilename; do { bool hadCandidates; currentFilename = FindExistingFilename(copy, _storePath, out hadCandidates); if (currentFilename != null) { if (_readOnly) { // Windows compatibility, the readonly check isn't done until after a match is found. throw new CryptographicException(SR.Cryptography_X509_StoreReadOnly); } File.Delete(currentFilename); ChainPal.FlushStores(); } } while (currentFilename != null); } }
public static ICertificatePal FromOtherCert(X509Certificate cert) { Debug.Assert(cert.Pal != null); // Ensure private key is copied OpenSslX509CertificateReader certPal = (OpenSslX509CertificateReader)cert.Pal; return(certPal.DuplicateHandles()); }
private void AddCertToStore(ICertificatePal certPal) { // This may well be the first time that we've added something to this store. Directory.CreateDirectory(_storePath); uint userId = Interop.Sys.GetEUid(); EnsureDirectoryPermissions(_storePath, userId); OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string thumbprint = copy.Thumbprint; bool findOpenSlot; // The odds are low that we'd have a thumbprint collision, but check anyways. string?existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot); if (existingFilename != null) { if (!copy.HasPrivateKey) { return; } try { using (X509Certificate2 fromFile = new X509Certificate2(existingFilename)) { if (fromFile.HasPrivateKey) { // We have a private key, the file has a private key, we're done here. return; } } } catch (CryptographicException) { // We can't read this file anymore, but a moment ago it was this certificate, // so go ahead and overwrite it. } } const UnixFileMode UserReadWrite = UnixFileMode.UserRead | UnixFileMode.UserWrite; string destinationFilename; FileStreamOptions options = new() { Mode = FileMode.CreateNew, UnixCreateMode = UserReadWrite, Access = FileAccess.Write }; if (existingFilename != null) { destinationFilename = existingFilename; options.Mode = FileMode.Create; // Before we open the file for writing the certificate, // ensure it is only accessible to the owner. try { File.SetUnixFileMode(existingFilename, UserReadWrite); } catch (IOException) // Ignore errors. We verify permissions when we've opened the file. { } } else if (findOpenSlot) { destinationFilename = FindOpenSlot(thumbprint); } else { destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension); } using (FileStream stream = new FileStream(destinationFilename, options)) { // Verify the file can only be read/written to by the owner. UnixFileMode actualMode = File.GetUnixFileMode(stream.SafeFileHandle); if (actualMode != UserReadWrite) { throw new CryptographicException(SR.Format(SR.Cryptography_InvalidFilePermissions, stream.Name)); } byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12) !; stream.Write(pkcs12, 0, pkcs12.Length); } } }
private void AddCertToStore(ICertificatePal certPal) { // This may well be the first time that we've added something to this store. Directory.CreateDirectory(_storePath); uint userId = Interop.Sys.GetEUid(); EnsureDirectoryPermissions(_storePath, userId); OpenSslX509CertificateReader cert = (OpenSslX509CertificateReader)certPal; using (X509Certificate2 copy = new X509Certificate2(cert.DuplicateHandles())) { string thumbprint = copy.Thumbprint; bool findOpenSlot; // The odds are low that we'd have a thumbprint collision, but check anyways. string?existingFilename = FindExistingFilename(copy, _storePath, out findOpenSlot); if (existingFilename != null) { if (!copy.HasPrivateKey) { return; } try { using (X509Certificate2 fromFile = new X509Certificate2(existingFilename)) { if (fromFile.HasPrivateKey) { // We have a private key, the file has a private key, we're done here. return; } } } catch (CryptographicException) { // We can't read this file anymore, but a moment ago it was this certificate, // so go ahead and overwrite it. } } string destinationFilename; FileMode mode = FileMode.CreateNew; if (existingFilename != null) { destinationFilename = existingFilename; mode = FileMode.Create; } else if (findOpenSlot) { destinationFilename = FindOpenSlot(thumbprint); } else { destinationFilename = Path.Combine(_storePath, thumbprint + PfxExtension); } using (FileStream stream = new FileStream(destinationFilename, mode)) { EnsureFilePermissions(stream, userId); byte[] pkcs12 = copy.Export(X509ContentType.Pkcs12) !; stream.Write(pkcs12, 0, pkcs12.Length); } } }