Installing a pfx file with C# seems different to manually installing it - c#

I have a c# program which installs a pfx file (Code below)
X509Certificate2 cert;
cert = new X509Certificate2(#"myCert.pfx", "password");
if (cert != null)
{
var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
if (!store.Certificates.Contains(cert))
{
store.Add(cert);
}
}
This seems to add the cert into the correct place when I view it in the management console. However I have a websocket server in c# that will pick it out of the store and use it for its ssl connections to the browser however the browsers all fail due to not having authentication to the cert.
However if I were to install it manually (clicking the cert) and installing it to the same location everything works fine.
NOTE:It is Self-Signed
How would I fix this problem

If the certificate is self-signed, you have to use it as well for the HTTPS page that holds the javascript code connecting to the websocket, so the browser can prompt you to accept the certificate.
You can retrieve the certificate using for example:
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificate = store.Certificates[1];
store.Close();
And then use it for your WebSocket server. I don't know which .NET WebSocket server are you using, but in WebSocketListener is done this way.

Related

How to get Azure Cloud Service details from App service via Code, .NET

Running the following code in Azure App service, which try to get details of a cloud service in the same Azure subscription, and get the exception about Certificate is is not associated with the subscription.
Although, under the subscription blade, under "Management certificates"
the certificate does exists and authorized.
X509Store certStore = new X509Store(StoreName.My, storeLocation);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, prodThumbprint, false);
if (certCollection.Count > 0)
CredentialsProd = new CertificateCloudCredentials(DBConstants.AZURE_SUBSCRIPTION_ID_PROD, certCollection[0]);
using (var client = new ComputeManagementClient(Credentials))
{
var t = client.HostedServices.GetDetailedAsync(serviceName, CancellationToken);
}
The exception:
ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.
The certificate in the subscription:
The certificate in the App service
To use a certificate that is uploaded to or imported into App Service, first make it accessible to your application code. You do this with the WEBSITE_LOAD_CERTIFICATES app setting. For more detail information, please refer to Use an SSL certificate in your application code in Azure App Service.
Add an app setting called WEBSITE_LOAD_CERTIFICATES and set its value to the thumbprint of the certificate. To make multiple certificates accessible, use comma-separated thumbprint values. To make all certificates accessible, set the value to *.

Unity SSLStream AuthenticateAsClient gives SslPolicyErrors.RemoteCertificateNotAvailable

I'm developing an application using Secure Sockets in Unity5 (in C#) to allow a server to push information to clients. I want to use Socket and SSLStream for this, to keep the communications secure.
I have an elastic beanstalk environment setup with a certificate provided by the AWS certificate service.
I've written a client class that can connect to this environment with a RemoteCertificateValidationCallback below:
public static bool RemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors write them out
if (sslPolicyErrors != SslPolicyErrors.None)
{
//Debug.Log(sslPolicyErrors.ToString());
Console.WriteLine(sslPolicyErrors.ToString());
return false;
}
return isOk;
}
When I run this code from a Console application created in Visual Studio 2017 I get sslPolicyErrors.None as expected.
Running the exact same code from within Unity5 (minus Console references) gives me sslPolicyErrors.RemoteCertificateNotAvailable.
I've tried importing the certificates to the Mono trust store using mozroots -import --machine which gives the following output:
Issuer: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon
Serial number: 66-xx-xx-xx-xx-xx-xx-xx-xx-xx-46-xx-xx-xx-xx-0D
Valid from 05/05/2017 00:00:00 to 05/06/2018 12:00:00
I've been hunting around but can find nothing that would suggest why this works as a standalone console program, but not when run from Unity. If I ignore this sslPolicyError specifically, everything works just fine, communication between the client and server happens as expected. But I don't want to be randomly ignoring an error that could mean the communications could be compromised.
I'm really hoping someone here has some idea!
why this works as a standalone console program, but not when run from Unity?
As Mono official said, Mono doesn’t include root certificates while standalone program using system certs.
There is one solution that install the cert via X509Store.
string cert = "BASE64 ENCODED CERT(PEM), NOT HEADER AND FOOTER, BASICALLY EXPORTED BY OPENSSL";
byte[] certBytes = Convert.FromBase64String(cert);
X509Certificate2 certificate = new X509Certificate2(cert);
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
You can use openssl to export a pem, like openssl x509 -inform DER -in YOUR_CER.cer -out YOUR_PEM.pem.
Once the proper cert is installed, RemoteCertificateValidationCallback won't return RemoteCertificateNotAvailable anymore if connecting to trusted sites.

Netsh error 1312 after programatically adding certificate to the store

I'm trying to add a certificate to the store programatically using the following code:
var certPath = string.Format("{0}//{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"fileName.pfx");
var cert = new X509Certificate2(certPath, "Password");
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
I check in MMC and the certificate is added.
If I now run in a command prompt with admin privileged:
netsh http add sslcert ipport=0.0.0.0:<port> certhash=<Thumbnail> appid={00000000-0000-0000-0000-000000000000}
Then it throws a 1312 error, "A specified log-on session does not exist. It may already have been terminated."
If I add the certificate via the import function in MMC, then the above command works.
Can anyone please help?
The issue is the way in which windows is storing the private key.
To do this programatically in .Net, change the following line of code:
X509Certificate2 cert = new X509Certificate2(path, "password",
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
As per this question: Inserting Certificate (with privatekey) in Root, LocalMachine certificate store fails in .NET 4
We ended up using WIX to inject the certificate into the store on installation. It seemed to work nicely.

Installing client certificates in Windows Store XAML apps

I would like to use client certificate authentication in Windows Store XAML app. Using makecert i have created a self-signed CA and client certificates, the authentication works in IIS/ASP.NET + browser (IE10,Chrome, etc.) fine.
Now I wanted to use it in Windows Store app, but am unsure on how to actually install the certificate. I have a cert.pfx file that i imported to IE10.
Here is the code I use to consume HTTP service over SSL.
HttpClientHandler handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
HttpClient client = new HttpClient(handler);
Not sure whats the difference between ClientCertificateOption.Automatic and ClientCertificateOption.Manual.
When I try to connect the certificate is not being presented to the server and i get 401 error I am guessing that the certificate is not present in app cert store and thus nothing is being sent to the server. How do I install the cert then?
Should I use CertificateEnrollmentManager.ImportPfxDataAsync() method? if so how can i convert .pfx to 'Base64-encoded PFX message'
Should pfx contain private key?
Or maybe I should use Certificates extension as described here: http://msdn.microsoft.com/en-us/library/windows/apps/hh464981.aspx#certificates_extension_content
The following code will load a pfx file and create a base64 encoded string that can be used by ImportPfxDataAsync method:
StorageFolder packageLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFolder certificateFolder = await packageLocation.GetFolderAsync("Certificates");
StorageFile certificate = await certificateFolder.GetFileAsync("YourCert.pfx");
IBuffer buffer = await Windows.Storage.FileIO.ReadBufferAsync(certificate);
string encodedString = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(buffer);
This assumes that you put your certificate in 'Certificates' folder.
You may want to have a look at http://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/ this walks through end-to-end scenario of using client certificates in windows 8 app to communicate with asp.net web api.

How to create personal certificate

i am using this code for certificate generation o local machine.
X509Certificate2 certificate = new X509Certificate2(cerFilePath,password);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
output shows it's created but it is not in the personal tab of certmanager but if i use Store Name other than My (example: Trusted Publisher ) in same program, certificate is available in cert manager under that storename.
but i need certificate for personal use.
what is going wrong?
If you use the "LocalMachine" context, you must have "Elevated Privileges" (Run the application as an administrator if needed).
Both "LocalMachine" and "CurrentUser" have a store named "Personal" (My) !
You can browse the "LocalMachine" store with "certlm.msc", and use "certmgr.msc" to browse "CurrentUser" store.

Categories

Resources