Bug 32769 - X509Certificate2 Constructor error. "Input data cannot be coded as a valid certificate".
Summary: X509Certificate2 Constructor error. "Input data cannot be coded as a valid ce...
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Security ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-08-04 17:15 UTC by glimbroek
Modified: 2015-08-04 17:15 UTC (History)
1 user (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and 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 Links.

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 for Bug 32769 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEW

Description glimbroek 2015-08-04 17:15:38 UTC
Hello,

I am using BouncyCastle to create some certificates and everything works fine on Windows. On Linux using Mono I am running into some hurdles.

The first was that BouncyCastle uses infinite length encoding for some ASN1 attributes and the Mono decoder does not handle this. Somewhere on the Internet I found a post from someone having the same problem and the solution was to run it through a DEROutputstream to get the right encoding.

Now BouncyCastle has the Pkcs12Utilities.ConvertToDefiniteLength method to convert the stream to a non infinite encoding.

The problem is that this also does not work resulting in the above error.

Is there any way I can fix this? Or is this never going to work? I have quite a lot of time invested in the BouncyCastle code, I also use it for OCSP and the like so it would be nice if mono would just load the certs.

I have made a small test with the following code demonstrating the problem:

using System.Security.Cryptography.X509Certificates;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Pkcs;
using CertificateServer;
using System.Net;
using System.Net.Sockets;
using System.IO;
using Org.BouncyCastle;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.X509.Extension;
using Org.BouncyCastle.Ocsp;

namespace CertTests
{

	public enum CertificateType
	{
		CertificateAuthority,
		ServerCertificate,
		ClientCertificate,
		OcspSigningCertificate
	}

    class Program
    {
		private const string SignatureAlgorithm = "SHA256WithRSA";

        static void Main(string[] args)
        {
            var program = new Program();
            program.Run();
        }

        private void Run()
        {

			GenerateCertificate();
            Console.ReadKey();

            
        }



		public void GenerateCertificate()
		{
			const int keyLength = 2048;
			var random = new SecureRandom(new CryptoApiRandomGenerator());
			var certificateGenerator = new X509V3CertificateGenerator();
			var keyPairGenerator = new RsaKeyPairGenerator();
			keyPairGenerator.Init(new KeyGenerationParameters(random, keyLength));
			var serial = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf (Int64.MaxValue), random);
			certificateGenerator.SetSignatureAlgorithm (SignatureAlgorithm);
			certificateGenerator.SetSerialNumber(serial);
			var subjectDN = new X509Name ("CN=TEST");
			var issuerDN = subjectDN;
			certificateGenerator.SetIssuerDN (issuerDN);
			certificateGenerator.SetSubjectDN (subjectDN);
			var notBefore = DateTime.Now;
			var notAfter = notBefore.AddDays (30);
			certificateGenerator.SetNotBefore (notBefore);
			certificateGenerator.SetNotAfter (notAfter);
			var keyPair = keyPairGenerator.GenerateKeyPair ();
			certificateGenerator.SetPublicKey (keyPair.Public);
			var issuerKeyPair = keyPair;
			var certificate = certificateGenerator.Generate (issuerKeyPair.Private, random);
			WriteCertificateToDisk (certificate, "bla", "bla", issuerKeyPair, random);


		}




		private static void WriteCertificateToDisk(Org.BouncyCastle.X509.X509Certificate certificate, string commonname, string password, AsymmetricCipherKeyPair certificateKeyPair, SecureRandom random)
		{
			var store = new Pkcs12Store();
			string friendlyName = certificate.SubjectDN.ToString();
			var certificateEntry = new X509CertificateEntry(certificate);
			store.SetCertificateEntry(friendlyName, certificateEntry);
			store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(certificateKeyPair.Private), new[] { certificateEntry });
			using (var stream = new MemoryStream())
			{
				store.Save(stream, password.ToCharArray(), random);

				//stream.Position = 0;
				var decodedStore = Pkcs12Utilities.ConvertToDefiniteLength(stream.ToArray(), password.ToCharArray());
				File.WriteAllBytes("test.pfx", decodedStore);
				//var X509Cert = new X509Certificate2(decodedStore, password,X509KeyStorageFlags.Exportable);
				//File.WriteAllBytes(Path.Combine(Environment.CurrentDirectory, "privateFilename.pfx"), X509Cert.Export(X509ContentType.Pkcs12, password));
				//File.WriteAllBytes(Path.Combine(Environment.CurrentDirectory, "publicFileName.cer"), X509Cert.Export(X509ContentType.Cert, password));
				var cert = new X509Certificate2("test.pfx", password);
			}
		}
    }


}

Mono version:
Mono JIT compiler version 4.0.2 (Stable 4.0.2.5/c99aa0c Wed Jun 24 10:04:37 UTC 2015)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

If you need more information please let me know.

Regards,

Kor