Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
Created attachment 759 [details]
monodroid solution that fails
I’m porting an app that uses a System.Net.HttpWebRequest with client certificates, and I’ve found that I can’t seem to create a System.Security.Cryptography.X509Certificates.X509Certificate2 from a serialized PKCS#12 byte. I’ve created the byte using Bouncycastle’s Pkcs12Store.Save() method, and creating an X509Certifcate2 object from this seems to work fine in windows (using the byte constructor). With monodroid though I get an exception when constructing:
byte bits = …. Pkcs#12 stuff …
X509Certificate2 foo = new X509Certificate2(bits);
System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.NotSupportedException: Undefined length encoding.
I've created minimal example projects using mono for windows, and vs2010+monodroid for android, I'll attach.
Created attachment 760 [details]
mono windows version of the same code, this works
It looks like it works on mono/Windows because mono is using CryptoAPI; If I use it on OSX, I get the same exception that you see on Mono for Android:
Unhandled Exception: System.Security.Cryptography.CryptographicException: Unable to decode certificate. ---> System.Security.Cryptography.CryptographicException: Input data cannot be coded as a valid certificate. ---> System.NotSupportedException: Undefined length encoding.
Jon, the sample code won't work on Mono/Windows (but MS.NET/Windows) since CryptoAPI is not used by Mono.
Nate, the ASN.1 decoder used by Mono does not support undefined length encoding. Sadly it's not a simple fix since it would require to rework everything ASN.1-based in Mono and would break existing APIs.
I suggest you use the classes included in Mono.Security.dll (it's shipped with MonoDroid) if you want to create certificates from managed code. This will ensure the ASN.1 content always have it's length properly calculated (and set) which makes it easier to consume by any tools (including Mono). An alternative is to "fix" (it may already have such option) BouncyCastle not to generated such structures.
You can have a look at 'makecert' to see how you can create certificate using the API provided by Mono.
Thank you Sebastien, to be clear, I need an System.Security.Cryptography.X509Certificates.X509Certificate2 which has both public and private keys that I can provide to the System.Web.HttpWebRequest.
makecert.cs appears to create a Mono.Security flavor X509 certificate structure. Are you suggesting I can serialize this as pkcs12 and de-serialize it again as a System.Security.Cryptography.X509Certificates.X509Certificate2? or that there is a way to create an System.Security.Cryptography.X509Certificates.X509Certificate2 directly? Or am I just reading the namespaces wrong and makecert.cs does exactly what I need? :)
yes, makecert.cs source code (bottom) shows how to create a PKCS#12 file (but you could keep all that into memory).
Once you have the PKCS#12 structure (file or memory) you'll be able to instantiate a X509Certificate2 from it - and it will include both the certificate and the private key.
@Nate: Are you still having this problem after Sebastien's workaround?
To be honest I have not tried it - for other reasons the effort underway was taken up through other means and I have not had a chance to focus on this again. However, in reading the makecert code I am confident this is sufficiently resolved (though I am a bit disappointed that the ASN1 decoder would fail on valid ASN1 :/).
I appreciate your and Sebastien's help, please resolve this bug however necessary.
Closing for now