I want to use the Windows Azure Management API to scale my webservice programmatically. First I try to get my Management Certificate.
I created a new self signed cert using the makecert.exe. Its described here.
makecert -sky exchange -r -n "CN=<CertificateName>" -pe -a sha1 -len 2048 -ss My "<CertificateName>.cer"
Then I uploaded my cert to my azure subscription (this way).
I really see my uploaded certificate in the new and in the previous admin portal.
Now I add the following code to my webservice
private X509Certificate2 GetX509Certificate2()
{
// The thumbprint value of the management certificate.
// You must replace the string with the thumbprint of a
// management certificate associated with your subscription.
string certThumbprint = "mythumprint...";
// Create a reference to the My certificate store.
X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
// Try to open the store.
try
{
certStore.Open(OpenFlags.ReadOnly);
}
catch (Exception e)
{
if (e is CryptographicException)
{
Console.WriteLine("Error: The store is unreadable.");
debugTable.persist("Error: The store is unreadable.");
}
else if (e is SecurityException)
{
Console.WriteLine("Error: You don't have the required permission.");
debugTable.persist("Error: You don't have the required permission.");
}
else if (e is ArgumentException)
{
Console.WriteLine("Error: Invalid values in the store.");
debugTable.persist("Error: Invalid values in the store.");
}
else
{
debugTable.persist("Something got wrong with certificate");
return null;
}
}
// Find the certificate that matches the thumbprint.
X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false);
certStore.Close();
// Check to see if our certificate was added to the collection. If no, throw an error, if yes, create a certificate using it.
if (0 == certCollection.Count)
{
Console.WriteLine("Error: No certificate found containing thumbprint " + certThumbprint);
debugTable.persist("Error: No certificate found containing thumbprint " + certThumbprint);
return null;
}
debugTable.persist("found cert");
// Create an X509Certificate2 object using our matching certificate.
X509Certificate2 certificate = certCollection[0];
return certificate;
}
The debugtable.persists() method writes the debug message into a table storage.
At the end I only find these entries in my table:
"Error: No certificate found containing thumbprint " + certThumbprint
So whats wrong with my code?
So you uploaded your certificate in the portal. This means the certificate can be used to authenticate to the Service Management API.
Now if you want to use this certificate from within a WCF Service / Web Service which is hosted in a Web/Worker Role you'll also need to upload that certificate in the Cloud Service:
Then you'll need to open the settings of your Web/Worker Role and add a new certificate here by specifying the Location, the Store Name and the Thumbprint:
If you redeploy the appliction the certificate will be available and your WCF Service will be able to use it (if the service has sufficient permissions to access it).
Related
I have an asp.net mvc website deployed to iis. A self signed SSL certificate is used in order to secure the traffic. I would like to access this self signed certificate from my asp.net, probably in the startup class or something, in order to get the validity of the self signed certificate (i need this metric for something else).
How could i do that?
I would gladly post some code, or what I've tried so far, but sadly i have no clue where to start from!
I would really appreciate any help.
Edit
To rephrase my question, lets say i have an asp.net web service deployed to IIS, how do i access the certificates in that IIS, and retrieve their validity period (from with in the web service using c# code)
You can do this by opening the cert store and finding certs based upon search criteria. If it's a self signed cert that you created you should know something about it.
object value = "AcmeOrganization";
X509FindType findType = X509FindType.FindByIssuerName;
StoreName storeName = StoreName.My;
StoreLocation storeLocation = StoreLocation.CurrentUser;
var store = new X509Store(storeName, storeLocation);
try
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(findType, value, true);
if (certs.Count > 0)
{
return certs[0];
}
}
finally
{
store.Close();
store = null;
}
This will get you the cert you're looking for then you can call Verify which does chain validation. Other properties along with expiration will be available with the X509Certificate2 object.
certs[0].Verify()
As I understand if someone doesn't want to use a custom domain name and instead plans on using *.azurewebsite.net domain assigned to the website by Azure, then HTTPS is already enabled with a certificate from Microsoft(I know this is not as secure as using a custom domain name). How would be I able to load this certificate programmatically. Currently I use the following method to load a certificate from local machine or Azure :
public static X509Certificate2 LoadFromStore(string certificateThumbprint,bool hostedOnAzure)
{
var s = certificateThumbprint;
var thumbprint = Regex.Replace(s, #"[^\da-zA-z]", string.Empty).ToUpper();
var store = hostedOnAzure ? new X509Store(StoreName.My, StoreLocation.CurrentUser) : new X509Store(StoreName.Root, StoreLocation.LocalMachine);
try
{
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates;
var signingCert = certCollection.Find(X509FindType.FindByThumbprint, thumbprint, false);
if (signingCert.Count == 0)
{
throw new FileNotFoundException(string.Format("Cert with thumbprint: '{0}' not found in certificate store. Also number of certificates in the sotre was {1}", thumbprint, store.Certificates.Count));
}
return signingCert[0];
}
finally
{
store.Close();
}
}
I assume the culprit is the following line of code :
new X509Store(StoreName.My, StoreLocation.CurrentUser)
because when I get an exception it tells me there is no certificate in the store although I pass the correct certificate Thumbprint(I grab the thumbprint from Chrome manually).
You will not be able to access this certificate programmatically in your WebApp as this certificate is not really installed on the Azure WebApp. Azure WebApps have a front-end server which does a "kind of" SSL Offloading so the WebApp actually never has access to this particular certificate. Why exactly you want to read this certificate though ?
Typically if there is a need for certificates in WebApps, you would install client certificates and pass them to services for Authentication as mentioned in https://azure.microsoft.com/en-us/blog/using-certificates-in-azure-websites-applications/ and those certificates you can access programmatically (code snippet mentioned in the same article)
But I am not sure what exactly you want to achieve by reading the server certificate
How can we install the Fiddler root certificate in the machine root store using Fiddler Core ?
We can do it with certmgr, but it would be great to do it using FiddlerCore. It seems it has methods to test and install everything except for the machine root store :( !?
FiddlerCore Has the following methods:
Fiddler.CertMaker.rootCertExists() to "Determine if the self-signed root certificate exists "
if it returns false we can call Fiddler.CertMaker.createRootCert() to install the certificate.
Fiddler.CertMaker.rootCertIsTrusted() to test if Fiddler's root certificate is in the Root store.
if it returns false we can call Fiddler.CertMaker.trustRootCert() to trust the certificate.
Fiddler.CertMaker.rootCertIsMachineTrusted() checks "Is Fiddler's root certificate in the Machine Root store? "
if it returns false ??? what do we do to solve this ???
This topic is well-covered in the Fiddler book, which is a helpful reference to programming with FiddlerCore.
To machine-trust a root, your code must be running as Administrator and must use the .NET APIs:
private static bool setMachineTrust(X509Certificate2 oRootCert)
{
try
{
X509Store certStore = new X509Store(StoreName.Root,
StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadWrite);
try
{
certStore.Add(oRootCert);
}
finally
{
certStore.Close();
}
return true;
}
catch (Exception eX)
{
return false;
}
}
My IIS (web server) requires client certificate and I need to check for certificate validity and read some information from and record in database (Audit)
I have following code
using System.Security.Cryptography.X509Certificates;
...
HttpClientCertificate cert = Request.ClientCertificate;
if (cert.IsPresent && cert.IsValid) {
X509Certificate2 cer = new X509Certificate2(cert.Certificate);
bool verified = cer.Verify();
...
AuditLog( ... );
}
cert.IsValid shows that certificate is valid. Do I need to instantiate X509Certificate2 object and re-check the validity of certificate (Why)?
If the certificate wasn't valid you wouldn't get this far. IIS should check that during the handshake, and abort the connection if invalid. All you need to do is verify that the identity represented by the Subject DN is authorized to be a client of this application.
Is there any way to check in C# if the PKI end user certificate is installed in the user windows keystore (Personal)? (An exception would do?) I would be passing some attribute like Name.
You can use the X509Store class to search for certificates on the system. Below code sample finds a certificate by subject name of "XYZ" in the Current User's Personal Store.
System.Security.Cryptography.X509Certificates.X509Store store = new System.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly); // Dont forget. otherwise u will get an exception.
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName,"XYZ",true);
if(certs.Count > 0)
{
// Certificate is found.
}
else
{
// No Certificate found by that subject name.
}