Certificate found although deleted - c#

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

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

How to delete pfx certificate using .net core

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.

Create a Certificate Revocation List (CRL) with makecert and then bundle it to a .pfx with pvk2pfx

To authenticate an application internally with client certification I have created a Root Certificate and the client certificate using the makecert application.
Everything works well but when I use the X509Certificate2 Verify method I get the following error:
The revocation function was unable to check revocation for the
certificate
X509Certificate2 cert = actionContext.Request.GetClientCertificate();
cert.Verify();
I can get around this by creating a X509Chain and then set X509ChainPolicy to RevocationMode = X509RevocationMode.NoCheck.
X509Certificate2 cert = actionContext.Request.GetClientCertificate();
if (cert == null)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized)
{
ReasonPhrase = "Client Certificate Required"
};
}
else
{
X509Chain chain = new X509Chain();
//Needed because the error "The revocation function was unable to check revocation for the certificate" will happen otherwise
chain.ChainPolicy = new X509ChainPolicy()
{
RevocationMode = X509RevocationMode.NoCheck,
};
try
{
var chainBuilt = chain.Build(cert);
Debug.WriteLine(string.Format("Chain building status: {0}", chainBuilt));
if (chainBuilt == false)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized)
{
ReasonPhrase = "Client Certificate not valid"
};
foreach (X509ChainStatus chainStatus in chain.ChainStatus)
{
Debug.WriteLine(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation));
}
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
However this got me interested. Is there someway that I can create a Certificate Revocation List (CRL) with makecert and then bundle it to a .pfx with pvk2pfx that will be accepted by X509Certificate2 Verify?
Found a solution on msdn.
https://msdn.microsoft.com/en-us/library/ff648732.aspx
After you have created your Root Certificate run the following command:
makecert -crl -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.crl
Install the CRL file on both the server and client machines. Use MMC to install RootCATes.crl on the client and server machines in the Trusted Root Certification Authorities store.
MMC -> File -> Add or Remove Snap-ins -> Certificates -> My user account
Trusted Root Certification Authorities -> Certificates -> Right click -> All tasks -> Import -> RootCATest.crl
I did not manage to bundle it with pvk2pfx but after doing this I could run Verify.

Find certificate location on box/server

I am trying to find where the certificate is stored on my local machine and then as well as our dev servers. I can go Run -> MMC -> File - > Add/Remove SnapIns and select certificates and Current User and see my personal certificates. However, I am trying to utilize this code for an HttpWebRequest and I cannot find the url.
string certPath = #"e:\mycertificate.cer"; //This Value
X509Certificate myCert = X509Certificate.CreateFromCertFile(certPath);
request.ClientCertificates.Add(myCert);
In another area we set up a proxy and do it like this.
proxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, CertificateName);
So obviously a little different implementation and I am unsure as to where/how to find the location to fill in for the first example.
Solution that worked for me
public WebRequest GetWebRequest(string address)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
X509Certificate myCert = null;
X509Store store = new X509Store("My");
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.FriendlyName.Contains("certname"))
{
myCert = mCert;
}
}
if (myCert != null) { request.ClientCertificates.Add(myCert); }
return request;
}
Assuming like you want to pick a certificate somehow and not really care if it is from file or not. In this case you can use certificate store object and find one you need (i.e. by thumbprint). Check out this Get list of certificates from the certificate store in C# and MSDN article on X509Store.Certificates which contains sample too:
X509Store store = new X509Store("My");
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 mCert in store.Certificates){
//TODO's
}

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