How to delete pfx certificate using .net core - c#

I have created code to delete pfx certificate is given below,
X509Store store = new X509Store(
StoreName.Root, StoreLocation.LocalMachine
);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection collection =
(X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection =
(X509Certificate2Collection)collection.Find(
X509FindType.FindBySubjectName,
"CN=AWS IoT Certificate", false
);
foreach (X509Certificate2 x509 in fcollection)
{
byte[] rawdata = x509.RawData;
Console.WriteLine(
"Friendly Name: {0}{1}",
x509.FriendlyName, Environment.NewLine
);
Console.WriteLine(
"Simple Name: {0}{1}",
x509.GetNameInfo(X509NameType.SimpleName, true),
Environment.NewLine
);
store.Remove(x509);
Console.WriteLine(
"X509Certificate2 for localhost removed."
);
}
store.Close();
But in the fcollection variable, didn't get certificate collection with subject name.
Here =>
X509Certificate2Collection fcollection =
(X509Certificate2Collection)collection.Find(
X509FindType.FindBySubjectName,
"CN=AWS IoT Certificate", false
);
How to get certificate collection. collection count getting zero.

X509FindType.FindBySubjectName expects a subject name without RDN attribute: "CN=AWS IoT Certificate" -> "AWS IoT Certificate". And make sure if certificate is indeed in the store.
In addition:
store.Open(OpenFlags.ReadOnly)
you are opening store in read-only mode. You can't modify the store using this flag.

Related

Accessing Certificate Programatically for SAML2

Setup:
I have a .Net Framework WebForms app and just setup SAML2 using Sustainsys.Saml2 setup on Azure. I'm also using Git for version control (VC) and Azure Key Vault for App Settings and Connection Strings.
Question:
What are other ways I can store and access the certificate for SAML2, even if I can access it programmatically (I'm currently accessing/setting the certificate programmatically)?
I want to prevent adding certificates to our VC as well as adding it manually to the Azure directory.
I tried looking into Key Vault Certificates, but I'm unsure if I can even use this.
You can upload your certificate to your Azure App Service --> TSLSSL setting --> Private Key Certificates (.pfx).
Once uploaded there you can retrieve it programmatically via C# with the following:
public static X509Certificate2 GetX509Certificate2(string certThumbprint, bool validOnly = true, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser) {
using (var certStore = new X509Store(storeName, storeLocation)) {
var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, validOnly);
// Get the first cert with the thumbprint
var cert = (X509Certificate2) certCollection.OfType<X509Certificate>().FirstOrDefault();
certStore.Close();
return cert;
}
}
Call it via:
var cert = GetX509Certificate2(certificateThumbprint, false, storeLocation: StoreLocation.LocalMachine);
Personally, so it can work locally, deployed and on any of our devs computers, I use the following code so that it can search different locations where it may be stored:
var cert = GetX509Certificate2(certificateThumbprint, false, storeLocation: StoreLocation.CurrentUser);
if (cert == null) {
cert = GetX509Certificate2(certificateThumbprint, false, storeLocation: StoreLocation.LocalMachine);
}

Certificate found although deleted

I imported a certificate called S0021679776.pfx to a Windows 8 through CERTMGR.MSC.
Then I deleted it (from the certificates manager as well as deleting the file itself).
However, when I run the following code, it still finds the certificate.
Why is that? I searched for certificate by "Issue By" and it is not found.
static void FindCert(string CertificateName)
{
X509Certificate2Collection certificates;
Console.WriteLine("looking for certificate " + CertificateName);
X509Store store = new X509Store("My", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
//FindBySubjectDistinguishedName
certificates = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateName, false);
Console.WriteLine("# of certificates: " + certificates.Count.ToString());
foreach (X509Certificate2 item in certificates)
{
Console.WriteLine(item.GetName());
}
}
}
The output:
looking for certificate S0021679776
# of certificates: 1
C=DE, O=SAP Trust Community, OU=SAP Service Marketplace, CN=S0021679776

.Net program does not get validated server certificate

I have a rather simple LDAP client that works ok when connecting to the 389 port (LDAP) but fails with a "LDAP server unavailable" when I try to connect to the 636 port (LDAPS).
namespace MyNS
{
class ProgramLdap
{
private static LdapConnection CreateConnection(String baseDn, string usuario, string password)
{
LdapConnection ldapConnection = new LdapConnection(
new LdapDirectoryIdentifier("myserver.example", 636, true, false));
ldapConnection.SessionOptions.SecureSocketLayer = true;
ldapConnection.SessionOptions.ProtocolVersion = 3;
// [CODE MODIFICATION HERE]
ldapConnection.Credential = new NetworkCredential(usuario, password);
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.Timeout = new TimeSpan(1, 0, 0);
return ldapConnection;
}
static void Main(string[] args)
{
LdapConnection ldapConnection = CreateConnection("", "myLdapUser", "noneOfYourBusiness");
SearchRequest searchRequest = new SearchRequest(
"ou=usuarios,dc=Dexter,dc=local",
String.Format("(&(objectclass=person)(cn={0}))", user),
SearchScope.Subtree,
new string[0]);
SearchResponse searchResponse =
(SearchResponse) ldapConnection.SendRequest(searchRequest);
System.Diagnostics.Debug.WriteLine("Resultados " + searchResponse.Entries.Count);
}
}
}
If I add the following at [CODE MODIFICATION HERE] to accept all server certificates, it works:
ldapConnection.SessionOptions.VerifyServerCertificate =
new VerifyServerCertificateCallback((conn, certificate) => true);
The certificate is signed by a self-signed CA, I have added the CA public certificate to the Local Computer list of "Trusted Root Certification Authorities"1.
If I check the server certificate with openSSL using that CA's certificate, it validates it. Also, I have tried LdapAdmin and when the CA is in that list, no warning is shown when connecting to the LDAP server.
If I use the VerifyServerCertificateCallback to print the contents of the certificate:
ldapConnection.SessionOptions.VerifyServerCertificate =
new VerifyServerCertificateCallback(
(conn, certificate) => {
X509Certificate2 certificate2 = new X509Certificate2(certificate);
bool verify = certificate2.Verify();
System.Diagnostics.Debug.WriteLine(
String.Format(
"certificate2.Verify {0}; Name {1}; NameOID {2}; FriendlyName {3}; Thumbprint {4}; Algorithm FriendlyName {5}",
verify,
certificate2.SubjectName.Name,
certificate2.SubjectName.Oid,
certificate2.FriendlyName,
certificate2.Thumbprint,
certificate2.SignatureAlgorithm.FriendlyName));
foreach (X509Extension extension in certificate2.Extensions)
{
System.Diagnostics.Debug.WriteLine(extension.ToString() + " " + extension.Oid.FriendlyName + " " + Encoding.UTF8.GetString(extension.RawData));
}
return verify;
});
it shows me the thumbprint of the server certificate but yet verify fails.
What can I be? It seems that I am missing something very basic, but I cannot understand what.
UPDATE:
I checked #FrankNielsen's suggestion and I added this code in the VerifyServerCertificateCallback:
(conn, certificate) => {
X509Chain ch = new X509Chain();
ch.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
ch.Build(new X509Certificate2(certificate));
System.Diagnostics.Debug.WriteLine("Chain Information");
System.Diagnostics.Debug.WriteLine(String.Format("Chain revocation flag: {0}", ch.ChainPolicy.RevocationFlag));
System.Diagnostics.Debug.WriteLine(String.Format("Chain revocation mode: {0}", ch.ChainPolicy.RevocationMode));
System.Diagnostics.Debug.WriteLine(String.Format("Chain verification flag: {0}", ch.ChainPolicy.VerificationFlags));
System.Diagnostics.Debug.WriteLine(String.Format("Chain verification time: {0}", ch.ChainPolicy.VerificationTime));
System.Diagnostics.Debug.WriteLine(String.Format("Chain status length: {0}", ch.ChainStatus.Length));
System.Diagnostics.Debug.WriteLine(String.Format("Chain application policy count: {0}", ch.ChainPolicy.ApplicationPolicy.Count));
System.Diagnostics.Debug.WriteLine(String.Format("Chain certificate policy count: {0} {1}", ch.ChainPolicy.CertificatePolicy.Count, Environment.NewLine));
System.Diagnostics.Debug.WriteLine("Chain Element Information");
System.Diagnostics.Debug.WriteLine(String.Format("Number of chain elements: {0}", ch.ChainElements.Count));
System.Diagnostics.Debug.WriteLine(String.Format("Chain elements synchronized? {0} {1}", ch.ChainElements.IsSynchronized, Environment.NewLine));
foreach (X509ChainElement element in ch.ChainElements)
{
System.Diagnostics.Debug.WriteLine(String.Format("Element issuer name: {0}", element.Certificate.Issuer));
System.Diagnostics.Debug.WriteLine(String.Format("Element certificate valid from: {0}", element.Certificate.NotBefore));
System.Diagnostics.Debug.WriteLine(String.Format("Element certificate valid until: {0}", element.Certificate.NotAfter));
System.Diagnostics.Debug.WriteLine(String.Format("Element certificate is valid: {0}", element.Certificate.Verify()));
System.Diagnostics.Debug.WriteLine(String.Format("Element error status length: {0}", element.ChainElementStatus.Length));
System.Diagnostics.Debug.WriteLine(String.Format("Element information: {0}", element.Information));
System.Diagnostics.Debug.WriteLine(String.Format("Thumbprint: {0}", element.Certificate.Thumbprint));
System.Diagnostics.Debug.WriteLine(String.Format("Number of element extensions: {0}{1}", element.Certificate.Extensions.Count, Environment.NewLine));
if (ch.ChainStatus.Length > 1)
{
for (int index = 0; index < element.ChainElementStatus.Length; index++)
{
System.Diagnostics.Debug.WriteLine(element.ChainElementStatus[index].Status);
System.Diagnostics.Debug.WriteLine(element.ChainElementStatus[index].StatusInformation);
}
}
}
return true;
});
And it returns:
Chain Information
Chain revocation flag: ExcludeRoot
Chain revocation mode: NoCheck
Chain verification flag: NoFlag
Chain verification time: 07/10/2019 15:53:00
Chain status length: 0
Chain application policy count: 0
Chain certificate policy count: 0
Chain Element Information
Number of chain elements: 2
Chain elements synchronized? False
Element issuer name: CN=dexter-SCPDPRDEXTER01V-CA, DC=dexter, DC=local
Element certificate valid from: 02/09/2019 12:24:22
Element certificate valid until: 01/09/2020 12:24:22
Element certificate is valid: False
Element error status length: 0
Element information:
Thumbprint: 63DCF4EFE0C96EF021BCC9CE662E2627A3CDF399
Number of element extensions: 9
Element issuer name: CN=dexter-SCPDPRDEXTER01V-CA, DC=dexter, DC=local
Element certificate valid from: 11/06/2019 7:39:01
Element certificate valid until: 11/06/2069 7:49:01
Element certificate is valid: True
Element error status length: 0
Element information:
Thumbprint: 7BD9C718E336A50FA006CAEF539895C7E3EA5DA0
Number of element extensions: 4
The certificates match what would be expected (the CA is retrieved), the CA return true to Verify() but the server certificate returns false to Verify().
1And for good measure, I also did try adding it to "Intermediate Certification Authorities" to no avail.
Finally the way to properly debug it was inspecting the elements of ChainStatus, as stated in X509Certificate2.Verify() returns false always
That way I did found that my program could not connect to the Certificate Revocation List URL.
The solution (other than opening access to the URL) is to validate the certificate in the callback using the X509Chain class and setting it not to check CRLs:
ldapConnection.SessionOptions.VerifyServerCertificate =
new VerifyServerCertificateCallback(
(conn, certificate) =>
{
X509Chain x509Chain = new X509Chain();
x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
X509Certificate2 cert2 = new X509Certificate2(certificate);
bool buildResult = x509Chain.Build(cert2);
if (!buildResult)
{
foreach (X509ChainStatus chainStatus in x509Chain.ChainStatus)
{
System.Diagnostics.Debug.WriteLine(
String.Format(
"Chain Status {0} : {1}", chainStatus.Status, chainStatus.StatusInformation));
}
}
return buildResult;
});
Please complete this stemps on each Domain Controller to enabel SSL on LDAP.
Go to each Domain Controller, open MMC
Click File, Add Snap-In
Select Certificate
Select Service Account and click Next
Select Local Computer and click Next
Select Active Directory Services and click Finish to complete the dialog
Click on Ok to add the Snap-In to the MMC
In the Certificate Snap-In now add your Certificate to NTDS/Personal and if needed add the CA-Certificate into the NTDS/Trusted Root Certificate Authorities
I'm from german system so I'm sorry if the technical Names mismatches with yours.
Source: https://www.active-directory-faq.de/2012/08/ldap-over-ssl-oder-sercure-ldap-ldaps-mit-server-2008r2/

Find Certificate by hash in Store C#

How to get Certificate by hash in Windows Store using C#?
sha1 example:7a0b021806bffdb826205dac094030f8045d4daa
this loop works but:
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 mCert in store.Certificates)
{
Console.WriteLine( mCert.Thumbprint);
}
store.Close();
Is there a direct method?
var cert = store.Certificates.Find(
X509FindType.FindByThumbprint,
thumbprint,
true
).OfType<X509Certificate>().FirstOrDefault();
Use the Find method on the collection
store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, true)

How to retrieve all certificates in your X509Store

I am using the following code to retrieve all certificates in my PC from an asp.net webapp. The certificates collection is empty, and I can't understand why.
I tried impersonating my own user account and I didn't succeed as well. What am I doing wrong?
var store = new X509Store(StoreLocation.CurrentUser); //StoreLocation.LocalMachine fails too
var certificates = store.Certificates;
foreach (var certificate in certificates)
{
var friendlyName = certificate.FriendlyName;
Console.WriteLine(friendlyName);
}
//original problem: fetch a single certificate by its subject name
X509Certificate2 clientCertificate = CertificateUtility.GetCertificate(StoreName.My, StoreLocation.CurrentUser, "CN=mypc.domainname"); //returns null :(
Add this line of code to the second line and see how it works:
store.Open(OpenFlags.ReadOnly);
and then this at the bottom :):
store.Close();
All in one ...
I have an apache server (xamp) with https. I access through https and c# (vs2010)
to a PHP upload page
Install the certificate from i.e in the personal folder certificate, for example.
To view the certicates run "certmgr.msc" , at least in win7
Listing the personal certificates
var store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates;
foreach (var certificate in certificates)
{
var friendlyName = certificate.FriendlyName;
var xname = certificate.GetName(); //obsolete
Console.WriteLine(friendlyName);
}
store.Close();
Find specific certificate
string certificateName = "CN=localhost"; //name found in the var xname
X509Store storex = new X509Store(StoreName.My, StoreLocation.CurrentUser);
storex.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificatesx =
storex.Certificates.Find(X509FindType.FindBySubjectName,
certificateName,
true);
X509Certificate certificatex = certificates[0];
storex.Close();
I can find certificates by ...
var certificateStore = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine);
certificateStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
var certificateCollection = certificateStore.Certificates.Find(X509FindType.FindBySubjectName, "mycert.me.com",false);
certificateStore.Close();
var certificate = certificateCollection[0];
certificateCollection will have the certificates I care about ... if it is just one then I get first element in the collection.
Look in your certificate store(mmc/add/certificate snap-in/my user account/Certificates - Current User/Personal/Certificates) to see the subject name to make sure "CN=mypc.domainname" is whats actually on the cert.
"CN=mypc.domainname"
vs
"CN = mypc.domainname"
...etc

Categories

Resources