Loading Root Certificate on Compact Framework .NET - compact-framework

I am trying to load an x509 certificate from file in CF.NET. The certificate I am trying to load can be downloaded here (it's a GoDaddy root cert).
My code looks like this:
byte[] bytes = null;
using (var certFile = new FileStream("\\gdroot-g2.crt", FileMode.Open, FileAccess.Read))
using (var br = new BinaryReader(certFile))
{
bytes = new byte[(int)certFile.Length];
br.Read(bytes, 0, bytes.Length);
}
//This line throws the error.
var cert = new X509Certificate2(bytes);
When I try loading the cert, I get the following error:
Creating certificate object failed. The data passed in is either
incorrect or is not supported by .NET Compact Framework. .NET Compact
Framework does not support reading from pfx files.
I've verified that the .CRT file I am using is Base-64 encoded. Also - when I run this same code on the desktop (using a mobile simulator that we've built) it parses the cert successfully.
Am I missing something basic here?

I too had the same problem and I resolved it by following the below steps.
Convert the certificate file to DER encoded binary X.509 format and then use it in the compact framework.
Steps for conversion:
Open the .cer file in the computer
Go to "Details" tab and click "Copy to File..." button
Certificate Export Wizard appears in which click Next and choose "DER encoded binary X.509(.CER)"
Click Next and specify the desired location and file name and click Finish
This will generate a .cer file in the chosen location
Use the certificate file (generated by the above process) in the compact framework and access the information programmatically as follows.
Read the contents of certificate file using BinaryReader which results in byte[] value
X509Certificate2 cert = new X509Certificate2(byte value returned by the above step)
Get the issuer name or any details required through built-in methods like cert.GetIssuerName();
When I followed this procedure, I didn't get any exception and it worked fine.

You might find it easier to interact with the certificate via the X509Store class. You can either add the root certificate by hand or programmatically.
Once you've added your certificate to the store you can retrieve an enumeration of the X509Certificate2 from the store and use LINQ to filter down to the specific GoDaddy certificate.
The linked MSDN page has some sample code showing this in action. Hope this helps.

The X509 namespace in the CF is effectively useless. I'm not sure why they bothered including it at all. I ended up wrapping the certificate APIs manually and creating a separate set of X509 classes that provide the functionality the BCL should have provided. The code is too long for a post here on SO, but those methods are part of the SDF.

Related

PKIX path building Failed error while establishing SSL connection

I was trying to establish a ssl connection to the sever in my application. for this, I generated self-signed certificates and added them to the keystore as well as the java cacerts which is the trust store.
But When I launch my application, I keep getting PKIX path building failed validatorException: unable to find valid path to requested target error
Hence unable to login to my java application.I use java1.8.0_144 version.
Try to login to the website which IDE is complaining about, and see if you are able to access it through the browser.
If so, then check for the certificate being used in the browser and check that certificate is present in your java cacerts.
Hi i usually generated the root CA with openssl and never worked importing that into the cacerts with keytools. You can instead generate it with this application i made out of desperation (it's a Java 11 app):
https://github.com/kendarorg/JavaCaCertGenerator
Its only purpose is to replace the generation of the private key and the root certificate, in a form "fit" for cacerts. From there you can produce the various certificates for the addresses

.Net Standard 2.0 RSA.ExportParameters(bool) not working on Linux

Have implemented some https support infrastructure. In one place need to Convert RSA to pem format. Here found the solution, that works fine on Windows, but as soon as run it in docker with linux, after the construction
var parameters = rsa.ExportParameters(true); have got next error
System.Security.Cryptography.CryptographicException Cannot open an invalid handle. Void CheckInvalidKey(Microsoft.Win32.SafeHandles.SafeRsaHandle)
Is there any alternative to export RSA in pem format ? If not is there any alternative way to get parameters from RSA ?

How are people authenticated in their ASP.NET Core Web APIs on Ubuntu/Docker given the bug described below?

I have come across what I think is a bug preventing me from loading an X509Certificate2 on Ubuntu or the Debian-based docker image provided by Microsoft. This means that I can't initialise JwtAuthentication in my web API on these platforms, and I'm looking for help:
Are you successfully using JwtAuthentication on Linux?
If so, how are you initialising an X509Certificate for the JwtBearerOptions?
Can you see a problem with what I'm doing, or suggest a work-around or solution?
I have logged the issue with the corefx team and you can see the full discussion here, but below is the main description of the problem:
I have a Web API running in a docker container. The container is built from the provided 1.1.0 package:
FROM microsoft/aspnetcore:1.1.0
and the Web API binaries are copied in. The API runs fine and returns data as expected until I turn on authentication, at which point it needs an X509SecurityKey to set the TokenValidationParameters.IssuerSigningKey value. It throws an exception when it attempts to initialise an X509Certificate2 from a string value:
string certValue = certificate.Value;
byte[] byteCert = Encoding.ASCII.GetBytes(certValue);
return new X509Certificate2(byteCert);
throws an OpenSslCryptographicException:
Unhandled Exception: System.Exception: Failed to extract the Token Signing certificate from the Federation metadata. --->
Interop+Crypto+OpenSslCryptographicException: error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error
at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] data)
at Mercury.Shared.Rest.Authentication.AdfsFederationMetadata.GetSigningCertificate()
The string value from which the X509Certificate2 is being initialised is:
MIIC4jCCAcqgAwIBAgIQHWt3kGySgJxPtsalC0EoKzANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJBREZTIFNpZ25pbmcgLSBzdHMuYWxsYW5ncmF5LmNvLnphMB4XDTE2MDkwNzA5MDQyM1oXDTE3MDkwNzA5MDQyM1owLTErMCkGA1UEAxMiQURGUyBTaWduaW5nIC0gc3RzLmFsbGFuZ3JheS5jby56YTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANdq9BEuBRPsTdpngeFyXbfH5lBg5WyENQW0qz2FtDw3AvZhiPdFyvTPZIeZDc4vhg+gPuG8pCxhFa6hPqNIwnLSVuyhUi4/CtZrLghF2wVVcyriijvirzdVp2m56nO31NB5HXbSerTmey1gJsgumr+MiaM2CEI9z5ctwAp66jqM9jVv7kzqIwB33irSck+X97jUa9XVa0/0QPBdrSVUR0i4rmfZ9orRdTKC3IA13bD9duk2Kc9V7t8t/woo80Kbbb3ZseYk5N8AI+7RRw9+oSAm8zZQzBYkNkAMeI1mto1faXsm9Aea4HXbyCbvVOx/JGj5Ki7YK/BtzWAyCgRu0TkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAd9rdJ1V9te8njMHiEuvr1DLVUBt2YdpZ8qGFC2rWDKeEW8iARrMfbtrlQovvE1radxoZ2gWR1AaaoEqzmLvF9fEAZ7xjR2P2UlT+ZgntfMn/c+3j7gWnfGNHIjosaYiyF72q4k6bgOx1TV8X08kD2AMBH27utXeeUQTZTd0bUWaWpr76NrDB95k4P6d0t5bkYsguiQjV+2t5/dSvrbTPVbXQmWGyC53IS2OI37AI2bIaeCCDkRHDoxu+L/DtgH8N60k2CLfa+pf0/cxQCR39p4Z+tquVKfYgJIsdZLD6bbrqK9VdpSR2vyUcDLMTGnO0tuDuzBd/xdhJ0GKbnBv3+g==
The same code runs with no problem on Windows, building a certificate from the same string.
Edit: Note that while I initially encountered this problem running a docker image, subsequent testing has shown that it also occurs using Ubuntu 14.04 + .NET Core 1.1
The problem here is that what is being passed to the constructor are the bytes of the base64 representation of the key, and not the bytes of the key itself.
If this code works on Windows then maybe it's a good idea to create an issue in the .net core github referencing this problem.
Thanks for the answer. For those who would like to copy and paste:
var certificateWithoutHeaderAndFooter = certificateString
.Replace("\\n","")
.Replace("-----BEGIN CERTIFICATE-----", "")
.Replace("-----END CERTIFICATE-----", "");
var certificateBytes = Convert.FromBase64String(certificateWithoutHeaderAndFooter);
var certificate = new X509Certificate2(certificateBase64Bytes);

handshake_failure trying to access file on same server

My code is trying to access a template file on the same server as the application.
It all worked fine until we switched on SSL.
Now when connecting to the file I get a SSLHandshakeException: handshake_failure with not much information on the actual cause of the issue.
If I try to access the file through the browser I get a warning page asking if I want to proceed at my own risk.
Is it a problem with the certificate? Can I bypass it?
Edit: The server is JBoss EAP 6.1 with Java 1.7. It's configured to use TLS1.2.
The bit retrieving the template is:
URL url;
URLConnection urlConnection;
try {
url = new URL(templateUrl);
urlConnection = url.openConnection();
urlConnection.setConnectTimeout(connectionTimeout);
urlConnection.setReadTimeout(connectionTimeout);
BufferedReader breader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = breader.readLine()) != null) {
strHtmlContent.append(line);
}
}
Handshake error is usually not a problem with the certificate, at least not with the validation of the certificate. It can have several other reasons, typically wrong protocol version, no cipher overlap, missing use of SNI... .
Unfortunately it is impossible to say what the problem is in your specific case but you might narrow it down by trying to access the site with different clients (i.e. browser, curl, ...). If not even a browser can access the site it is probably a misconfiguration of the server.

Opening an SSL web-browser connection in HtmlUnit library

I've searched through web for couple hours on this issue, and none of the answers I found didn't really fit into my problem, so here's me, asking my first-ever question in SOF.
So, I'm trying to open a web-browser from a java program using the htmlunit library. The web site I need to connect requires SSL connection, and the certificate is stored in a USB key. Its iKey2023 product.
The system used to work(I did not write it), but one of the certificates in the USB key expired, so it automatically moved on to the next one (there were 4 certificates in total), and it suddenly stopped working.
It is giving me javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated error.
I'm back home now and I forgot the exact name of the method, but I remember the following.
Browser instance is created, using IE8
browser.setWebConnection method was called. This method, according to the API, is an internal API.
Make connection to the website by passing the URL as parameter
It's throwing the exception at step 3.
Some more details. The little details might be incorrect but I'm trying to describe a big picture.
At step 2, the method requites WebConnection object as a parameter, and there is a implementation of that interface. Within this implementation, a keystore is created using sun.security.pkcs11.SunPKCS11(configFileInputStream) (did I spell that correctly?)
It was sth like this.
Provider p = new sun.security.pkcs11.SunPKCS11(configFileInputStream);
Security.addProvider(p);
And create a keystore from this provider.
Using this keystore, within the WebConnection implementation, it creates a SSLSocket.
So, after the certificate has been switched to a new one, it's not picking up the certificate correctly.
Here's what I've tried.
I've tried to use different methods in the htmlunit library, something like setSecurityProvider, and I tried to put the Provider object created in above code snippet. I got class cast exception.
I tried to manually set the system properties(trustStore, trustStorePassword, keyStore, etc). In order to do this, I wanted to export the certificate out of the USB key, but it did not let me export the private key out from it, so I could not really create a valid PKCS12 file out of it (openSSL wanted a private key file along with .pem file for conversion, and I did not have that key file).
They did not work, and I'm so stuck right now.
I have a similar issue. In my case, an admin changed the certificate and I began encountering the same SSLPeerUnverifiedException.
I found that I can set the WebClient to use insecureSSL (prior to calling getPage())and I will no longer get the exception.
webClient.setUseInsecureSSL(true);
This however, doesn't resolve the issue as the server basically doesn't authenticate the client.
Its as if the WebClient is storing something that doesn't work with the new certificate.