public HttpResponseMessage Get(string smsNumber, string code)
        {
            RsaKeyPairGenerator r = new RsaKeyPairGenerator();
            r.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(new Org.BouncyCastle.Security.SecureRandom(), 2048));

            AsymmetricCipherKeyPair keys = r.GenerateKeyPair();

            string publicKeyPath = Path.Combine(Path.GetTempPath(), "publicKey.key");

            if (File.Exists(publicKeyPath))
            {
                File.Delete(publicKeyPath);
            }

            using (TextWriter textWriter = new StreamWriter(publicKeyPath, false))
            {
                PemWriter pemWriter = new PemWriter(textWriter);
                pemWriter.WriteObject(keys.Public);
                pemWriter.Writer.Flush();
            }

            string certSubjectName = "UShadow_RSA";
            var certName = new X509Name("CN=" + certSubjectName);
            var serialNo = BigInteger.ProbablePrime(120, new Random());

            X509V3CertificateGenerator gen2 = new X509V3CertificateGenerator();
            gen2.SetSerialNumber(serialNo);
            gen2.SetSubjectDN(certName);
            gen2.SetIssuerDN(new X509Name(true, "CN=UShadow"));
            gen2.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(30, 0, 0, 0)));
            gen2.SetNotAfter(DateTime.Now.AddYears(2));
            gen2.SetSignatureAlgorithm("sha512WithRSA");

            gen2.SetPublicKey(keys.Public);

            Org.BouncyCastle.X509.X509Certificate newCert = gen2.Generate(keys.Private);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry certEntry = new X509CertificateEntry(newCert);
            store.SetCertificateEntry(newCert.SubjectDN.ToString(), certEntry);

            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private);
            store.SetKeyEntry(newCert.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { certEntry });

            using (MemoryStream ms = new MemoryStream())
            {
                store.Save(ms, "Password".ToCharArray(), new SecureRandom());

                var resp = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(ms.ToArray())
                };

                resp.Content.Headers.Add("Content-Type", "application/x-pkcs12");
                return resp;
            }
        }
Exemple #2
0
        private X509Certificate2 GetAsDotNet(string entryAlias, X509KeyStorageFlags flags)
        {
            Org.BouncyCastle.Pkcs.X509CertificateEntry certificateEntry = store.GetCertificate(entryAlias);
            if (store.IsKeyEntry(entryAlias))
            {
                //Get the org key entry
                AsymmetricKeyEntry orgKeyEntry = store.GetKey(entryAlias);

                //Copy it into a new key attribute with the windows CSP defined
                IDictionary newKeyEntryAttributes = new Hashtable();
                foreach (String attribute in orgKeyEntry.BagAttributeKeys)
                {
                    newKeyEntryAttributes.Add(attribute, orgKeyEntry[attribute]);
                }
                if (!newKeyEntryAttributes.Contains("1.3.6.1.4.1.311.17.1"))
                {
                    newKeyEntryAttributes.Add("1.3.6.1.4.1.311.17.1", new DerBmpString("Microsoft Enhanced RSA and AES Cryptographic Provider"));
                }
                AsymmetricKeyEntry newKeyEntry = new AsymmetricKeyEntry(orgKeyEntry.Key, newKeyEntryAttributes);

                //Make a new P12 in memory
                Pkcs12Store newP12 = new Pkcs12Store();
                newP12.SetKeyEntry(entryAlias, newKeyEntry, store.GetCertificateChain(entryAlias));
                MemoryStream buffer = new MemoryStream();
                newP12.Save(buffer, password.ToCharArray(), new SecureRandom());

                //Read this P12 as X509Certificate with private key
                return(new X509Certificate2(buffer.ToArray(), password, flags));
            }
            else
            {
                return(new X509Certificate2(certificateEntry.Certificate.GetEncoded()));
            }
        }
 public static void WritePkcs12(RsaPrivateCrtKeyParameters privKey,
                                Org.BouncyCastle.X509.X509Certificate certificate,
                                string password, Stream stream)
 {
     Pkcs12Store store = new Pkcs12Store();
     X509CertificateEntry[] chain = new X509CertificateEntry[1];
     chain[0] = new X509CertificateEntry(certificate);
     store.SetKeyEntry("privateKey", new AsymmetricKeyEntry(privKey), chain);
     store.Save(stream, password.ToCharArray(), new SecureRandom());
 }
        /// <summary>
        /// This method takes in a principal name and converts it into a distinguished name for applying to the certificate, also an RSA key pair which is
        /// used to encypt the certificate. This certificate is then returned to the caller.
        /// </summary>
        /// <param name="principalName"></param>
        /// <param name="rsaKeyPair"></param>
        /// <returns></returns>
        public virtual PkcsCertificate MakeCertificate(string principalName, string password)
        {
            //build a key generator
            RsaKeyPairGenerator keyGen = makeRsaGenerator();

            //initialise the keygenerator to produce a large enough key for Azure
            //this may need breaking up for debugging
            keyGen.Init(makeKeyGenParameters());

            //must find out what var this is for type safety
            AsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair();

            //instantiate the generator
            X509V3CertificateGenerator certGen = makeCertificateGenerator();

            //set the values required by the generator to generate a certificate
            //this may need adapting to make this more secure
            certGen.SetSerialNumber(BigInteger.One);
            //magic value
            certGen.SetIssuerDN(new Org.BouncyCastle.Asn1.X509.X509Name("OU=GWydiR"));
            certGen.SetNotBefore(DateTime.Today.AddDays(-1));
            certGen.SetNotAfter(DateTime.Today.AddMonths(3));
            certGen.SetSubjectDN(new Org.BouncyCastle.Asn1.X509.X509Name("cn="+principalName));
            certGen.SetPublicKey(keyPair.Public);
            certGen.SetSignatureAlgorithm("SHA1WithRSA");

            //make a bouncy castle specific x509 certificate to transform into a .net certificate
            Org.BouncyCastle.X509.X509Certificate intermediateCertificate = certGen.Generate(keyPair.Private);

            // make a .pfx from this certificate
            Pkcs12Store store = makePkcsStore();

            // In a pkcs12 (.pfx file) we associate the private key with a certificate via the friendly name
            string friendlyName = intermediateCertificate.SubjectDN.ToString();

            // add the certificate to the store with the friendly name as the entry label
            X509CertificateEntry certEntry = new X509CertificateEntry(intermediateCertificate);
            store.SetCertificateEntry(friendlyName, certEntry);

            // add the private key with the same label/alias and an association with our intermediate certificate
            // it takes an array of entries with which to associate as all of those entries could be certificates
            // signed with that private key.
            store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });

            //make new certificate object
            PkcsCertificate certificate = new PkcsCertificate(password, keyPair, intermediateCertificate, store);

            return certificate;
        }
Exemple #5
0
		public static X509Certificate2 GenerateNewCertificate(string name)
		{
			var kpGen = new RsaKeyPairGenerator();
			kpGen.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 1024));

			AsymmetricCipherKeyPair keyPair = kpGen.GenerateKeyPair();
			var gen = new X509V3CertificateGenerator();
			var certificateName = new X509Name("CN=" + name);
			BigInteger serialNumber = BigInteger.ProbablePrime(120, new Random());
			gen.SetSerialNumber(serialNumber);
			gen.SetSubjectDN(certificateName);
			gen.SetIssuerDN(certificateName);
			gen.SetNotAfter(DateTime.Now.AddYears(100));
			gen.SetNotBefore(DateTime.Now.AddDays(-1));
			gen.SetSignatureAlgorithm("SHA256WithRSAEncryption");
			gen.SetPublicKey(keyPair.Public);

			gen.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
			                 new AuthorityKeyIdentifier(
			                 	SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public),
			                 	new GeneralNames(new GeneralName(certificateName)), serialNumber));

			X509Certificate newCert = gen.Generate(keyPair.Private);

			var newStore = new Pkcs12Store();

			var certEntry = new X509CertificateEntry(newCert);

			newStore.SetCertificateEntry(
				Environment.MachineName,
				certEntry
				);

			newStore.SetKeyEntry(
				Environment.MachineName,
				new AsymmetricKeyEntry(keyPair.Private),
				new[] {certEntry}
				);

			var memoryStream = new MemoryStream();
			newStore.Save(
				memoryStream,
				new char[0],
				new SecureRandom(new CryptoApiRandomGenerator())
				);

			return new X509Certificate2(memoryStream.ToArray());
		}
		/// <summary>
		/// Exports the specified stream and password to a pkcs12 encrypted file.
		/// </summary>
		/// <remarks>
		/// Exports the specified stream and password to a pkcs12 encrypted file.
		/// </remarks>
		/// <param name="stream">The output stream.</param>
		/// <param name="password">The password to use to lock the private keys.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="stream"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="password"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An error occurred while writing to the stream.
		/// </exception>
		public void Export (Stream stream, string password)
		{
			if (stream == null)
				throw new ArgumentNullException ("stream");

			if (password == null)
				throw new ArgumentNullException ("password");

			var store = new Pkcs12Store ();
			foreach (var certificate in certs) {
				if (keys.ContainsKey (certificate))
					continue;

				var alias = certificate.GetCommonName ();

				if (alias == null)
					continue;

				var entry = new X509CertificateEntry (certificate);

				store.SetCertificateEntry (alias, entry);
			}

			foreach (var kvp in keys) {
				var alias = kvp.Key.GetCommonName ();

				if (alias == null)
					continue;

				var entry = new AsymmetricKeyEntry (kvp.Value);
				var cert = new X509CertificateEntry (kvp.Key);
				var chain = new List<X509CertificateEntry> ();

				chain.Add (cert);

				store.SetKeyEntry (alias, entry, chain.ToArray ());
			}

			store.Save (stream, password.ToCharArray (), new SecureRandom ());
		}
		private void basicStoreTest(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain,
			DerObjectIdentifier keyAlgorithm, DerObjectIdentifier certAlgorithm)
		{
			Pkcs12Store store = new Pkcs12StoreBuilder()
				.SetKeyAlgorithm(keyAlgorithm)
				.SetCertAlgorithm(certAlgorithm)
				.Build();

			store.SetKeyEntry("key", privKey, chain);

			MemoryStream bOut = new MemoryStream();

			store.Save(bOut, passwd, new SecureRandom());

			store.Load(new MemoryStream(bOut.ToArray(), false), passwd);

			AsymmetricKeyEntry k = store.GetKey("key");

			if (!k.Equals(privKey))
			{
				Fail("private key didn't match");
			}

			X509CertificateEntry[] c = store.GetCertificateChain("key");

			if (c.Length != chain.Length || !c[0].Equals(chain[0]))
			{
				Fail("certificates didn't match");
			}

			// check attributes
			Pkcs12Entry b1 = k;
			Pkcs12Entry b2 = chain[0];

			if (b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] != null)
			{
				DerBmpString name = (DerBmpString)b1[PkcsObjectIdentifiers.Pkcs9AtFriendlyName];

				if (!name.Equals(new DerBmpString("key")))
				{
					Fail("friendly name wrong");
				}
			}
			else
			{
				Fail("no friendly name found on key");
			}

			if (b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
			{
				Asn1OctetString id = (Asn1OctetString)b1[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID];

				if (!id.Equals(b2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID]))
				{
					Fail("local key id mismatch");
				}
			}
			else
			{
				Fail("no local key id found");
			}

			//
			// check algorithm types.
			//
			Asn1InputStream aIn = new Asn1InputStream(bOut.ToArray());

			Pfx pfx = new Pfx((Asn1Sequence)aIn.ReadObject());

			ContentInfo cInfo = pfx.AuthSafe;

			Asn1OctetString auth = (Asn1OctetString)cInfo.Content;

			aIn = new Asn1InputStream(auth.GetOctets());
			Asn1Sequence s1 = (Asn1Sequence)aIn.ReadObject();

			ContentInfo c1 = ContentInfo.GetInstance(s1[0]);
			ContentInfo c2 = ContentInfo.GetInstance(s1[1]);

			aIn = new Asn1InputStream(((Asn1OctetString)c1.Content).GetOctets());

			SafeBag sb = new SafeBag((Asn1Sequence)(((Asn1Sequence)aIn.ReadObject())[0]));

			EncryptedPrivateKeyInfo encInfo = EncryptedPrivateKeyInfo.GetInstance(sb.BagValue);

			// check the key encryption
            if (!encInfo.EncryptionAlgorithm.Algorithm.Equals(keyAlgorithm))
			{
				Fail("key encryption algorithm wrong");
			}

			// check the certificate encryption
			EncryptedData cb = EncryptedData.GetInstance(c2.Content);

            if (!cb.EncryptionAlgorithm.Algorithm.Equals(certAlgorithm))
			{
				Fail("cert encryption algorithm wrong");
			}
		}
        public X509CertificateEntry[] GetCertificateChain(
            string alias)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }

            if (!IsKeyEntry(alias))
            {
                return(null);
            }

            X509CertificateEntry c = GetCertificate(alias);

            if (c != null)
            {
                ArrayList cs = new ArrayList();

                while (c != null)
                {
                    X509Certificate      x509c = c.Certificate;
                    X509CertificateEntry nextC = null;

                    Asn1OctetString ext = x509c.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
                    if (ext != null)
                    {
                        AuthorityKeyIdentifier id = AuthorityKeyIdentifier.GetInstance(
                            Asn1Object.FromByteArray(ext.GetOctets()));

                        if (id.GetKeyIdentifier() != null)
                        {
                            nextC = (X509CertificateEntry)chainCerts[new CertId(id.GetKeyIdentifier())];
                        }
                    }

                    if (nextC == null)
                    {
                        //
                        // no authority key id, try the Issuer DN
                        //
                        X509Name i = x509c.IssuerDN;
                        X509Name s = x509c.SubjectDN;

                        if (!i.Equivalent(s))
                        {
                            foreach (CertId certId in chainCerts.Keys)
                            {
                                X509CertificateEntry x509CertEntry = (X509CertificateEntry)chainCerts[certId];

                                X509Certificate crt = x509CertEntry.Certificate;

                                X509Name sub = crt.SubjectDN;
                                if (sub.Equivalent(i))
                                {
                                    try
                                    {
                                        x509c.Verify(crt.GetPublicKey());

                                        nextC = x509CertEntry;
                                        break;
                                    }
                                    catch (InvalidKeyException)
                                    {
                                        // TODO What if it doesn't verify?
                                    }
                                }
                            }
                        }
                    }

                    cs.Add(c);
                    if (nextC != c)                     // self signed - end of the chain
                    {
                        c = nextC;
                    }
                    else
                    {
                        c = null;
                    }
                }

                return((X509CertificateEntry[])cs.ToArray(typeof(X509CertificateEntry)));
            }

            return(null);
        }
        public X509CertificateEntry[] GetCertificateChain(
            string alias)
        {
            if (alias == null)
                throw new ArgumentNullException("alias");

            if (!IsKeyEntry(alias))
            {
                return null;
            }

            X509CertificateEntry c = GetCertificate(alias);

            if (c != null)
            {
                IList cs = Platform.CreateArrayList();

                while (c != null)
                {
                    X509Certificate x509c = c.Certificate;
                    X509CertificateEntry nextC = null;

                    Asn1OctetString ext = x509c.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
                    if (ext != null)
                    {
                        AuthorityKeyIdentifier id = AuthorityKeyIdentifier.GetInstance(
                            Asn1Object.FromByteArray(ext.GetOctets()));

                        if (id.GetKeyIdentifier() != null)
                        {
                            nextC = (X509CertificateEntry) chainCerts[new CertId(id.GetKeyIdentifier())];
                        }
                    }

                    if (nextC == null)
                    {
                        //
                        // no authority key id, try the Issuer DN
                        //
                        X509Name i = x509c.IssuerDN;
                        X509Name s = x509c.SubjectDN;

                        if (!i.Equivalent(s))
                        {
                            foreach (CertId certId in chainCerts.Keys)
                            {
                                X509CertificateEntry x509CertEntry = (X509CertificateEntry) chainCerts[certId];

                                X509Certificate crt = x509CertEntry.Certificate;

                                X509Name sub = crt.SubjectDN;
                                if (sub.Equivalent(i))
                                {
                                    try
                                    {
                                        x509c.Verify(crt.GetPublicKey());

                                        nextC = x509CertEntry;
                                        break;
                                    }
                                    catch (InvalidKeyException)
                                    {
                                        // TODO What if it doesn't verify?
                                    }
                                }
                            }
                        }
                    }

                    cs.Add(c);
                    if (nextC != c) // self signed - end of the chain
                    {
                        c = nextC;
                    }
                    else
                    {
                        c = null;
                    }
                }

                X509CertificateEntry[] result = new X509CertificateEntry[cs.Count];
                for (int i = 0; i < cs.Count; ++i)
                {
                    result[i] = (X509CertificateEntry)cs[i];
                }
                return result;
            }

            return null;
        }
        public void Load(
            Stream	input,
            char[]	password)
        {
            if (input == null)
                throw new ArgumentNullException("input");
            if (password == null)
                throw new ArgumentNullException("password");

            Asn1Sequence obj = (Asn1Sequence) Asn1Object.FromStream(input);
            Pfx bag = new Pfx(obj);
            ContentInfo info = bag.AuthSafe;
            bool unmarkedKey = false;
            bool wrongPkcs12Zero = false;

            if (bag.MacData != null) // check the mac code
            {
                MacData mData = bag.MacData;
                DigestInfo dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt = mData.GetSalt();
                int itCount = mData.IterationCount.IntValue;

                byte[] data = ((Asn1OctetString) info.Content).GetOctets();

                byte[] mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, false, data);
                byte[] dig = dInfo.GetDigest();

                if (!Arrays.ConstantTimeAreEqual(mac, dig))
                {
                    if (password.Length > 0)
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");

                    // Try with incorrect zero length password
                    mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, true, data);

                    if (!Arrays.ConstantTimeAreEqual(mac, dig))
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");

                    wrongPkcs12Zero = true;
                }
            }

            keys.Clear();
            localIds.Clear();

            IList chain = Platform.CreateArrayList();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[] octs = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence) Asn1OctetString.FromByteArray(octs));
                ContentInfo[] cis = authSafe.GetContentInfo();

                foreach (ContentInfo ci in cis)
                {
                    DerObjectIdentifier oid = ci.ContentType;

                    if (oid.Equals(PkcsObjectIdentifiers.Data))
                    {
                        byte[] octets = ((Asn1OctetString)ci.Content).GetOctets();
                        Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                IDictionary attributes = Platform.CreateHashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);
                                string alias = null;
                                Asn1OctetString localId = null;

                                if (b.BagAttributes != null)
                                {
                                    foreach (Asn1Sequence sq in b.BagAttributes)
                                    {
                                        DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                        Asn1Set attrSet = (Asn1Set) sq[1];
                                        Asn1Encodable attr = null;

                                        if (attrSet.Count > 0)
                                        {
                                            // TODO We should be adding all attributes in the set
                                            attr = attrSet[0];

                                            // TODO We might want to "merge" attribute sets with
                                            // the same OID - currently, differing values give an error
                                            if (attributes.Contains(aOid.Id))
                                            {
                                                // OK, but the value has to be the same
                                                if (!attributes[aOid.Id].Equals(attr))
                                                {
                                                    throw new IOException("attempt to add existing attribute with different value");
                                                }
                                            }
                                            else
                                            {
                                                attributes.Add(aOid.Id, attr);
                                            }

                                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                            {
                                                alias = ((DerBmpString)attr).GetString();
                                                // TODO Do these in a separate loop, just collect aliases here
                                                keys[alias] = pkcs12Key;
                                            }
                                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                            {
                                                localId = (Asn1OctetString)attr;
                                            }
                                        }
                                    }
                                }

                                if (localId != null)
                                {
                                    string name = Hex.ToHexString(localId.GetOctets());

                                    if (alias == null)
                                    {
                                        keys[name] = pkcs12Key;
                                    }
                                    else
                                    {
                                        // TODO There may have been more than one alias
                                        localIds[alias] = name;
                                    }
                                }
                                else
                                {
                                    unmarkedKey = true;
                                    keys["unmarked"] = pkcs12Key;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else
                            {
                                //TODO: COMENTADO
                                //Console.WriteLine("extra " + b.BagID);
                                //Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        EncryptedData d = EncryptedData.GetInstance(ci.Content);
                        byte[] octets = CryptPbeData(false, d.EncryptionAlgorithm,
                            password, wrongPkcs12Zero, d.Content.GetOctets());
                        Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                IDictionary attributes = Platform.CreateHashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);
                                string alias = null;
                                Asn1OctetString localId = null;

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                    Asn1Set attrSet = (Asn1Set) sq[1];
                                    Asn1Encodable attr = null;

                                    if (attrSet.Count > 0)
                                    {
                                        // TODO We should be adding all attributes in the set
                                        attr = attrSet[0];

                                        // TODO We might want to "merge" attribute sets with
                                        // the same OID - currently, differing values give an error
                                        if (attributes.Contains(aOid.Id))
                                        {
                                            // OK, but the value has to be the same
                                            if (!attributes[aOid.Id].Equals(attr))
                                            {
                                                throw new IOException("attempt to add existing attribute with different value");
                                            }
                                        }
                                        else
                                        {
                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias = ((DerBmpString)attr).GetString();
                                            // TODO Do these in a separate loop, just collect aliases here
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                // TODO Should we be checking localIds != null here
                                // as for PkcsObjectIdentifiers.Data version above?

                                string name = Hex.ToHexString(localId.GetOctets());

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    // TODO There may have been more than one alias
                                    localIds[alias] = name;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                PrivateKeyInfo privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyInfo);

                                //
                                // set the attributes on the key
                                //
                                string alias = null;
                                Asn1OctetString localId = null;
                                IDictionary attributes = Platform.CreateHashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                    Asn1Set attrSet = (Asn1Set) sq[1];
                                    Asn1Encodable attr = null;

                                    if (attrSet.Count > 0)
                                    {
                                        // TODO We should be adding all attributes in the set
                                        attr = attrSet[0];

                                        // TODO We might want to "merge" attribute sets with
                                        // the same OID - currently, differing values give an error
                                        if (attributes.Contains(aOid.Id))
                                        {
                                            // OK, but the value has to be the same
                                            if (!attributes[aOid.Id].Equals(attr))
                                            {
                                                throw new IOException("attempt to add existing attribute with different value");
                                            }
                                        }
                                        else
                                        {
                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias = ((DerBmpString)attr).GetString();
                                            // TODO Do these in a separate loop, just collect aliases here
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                // TODO Should we be checking localIds != null here
                                // as for PkcsObjectIdentifiers.Data version above?

                                string name = Hex.ToHexString(localId.GetOctets());

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    // TODO There may have been more than one alias
                                    localIds[alias] = name;
                                }
                            }
                            else
                            {
                                //TODO: COMENTADO
                                //Console.WriteLine("extra " + b.BagID);
                                //Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        //TODO: COMENTADO
                        //Console.WriteLine("extra " + oid);
                        //Console.WriteLine("extra " + Asn1Dump.DumpAsString(ci.Content));
                    }
                }
            }

            certs.Clear();
            chainCerts.Clear();
            keyCerts.Clear();

            foreach (SafeBag b in chain)
            {
                CertBag cb = new CertBag((Asn1Sequence)b.BagValue);
                byte[] octets = ((Asn1OctetString) cb.CertValue).GetOctets();
                X509Certificate cert = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                IDictionary attributes = Platform.CreateHashtable();
                Asn1OctetString localId = null;
                string alias = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                        Asn1Set attrSet = (Asn1Set) sq[1];

                        if (attrSet.Count > 0)
                        {
                            // TODO We should be adding all attributes in the set
                            Asn1Encodable attr = attrSet[0];

                            // TODO We might want to "merge" attribute sets with
                            // the same OID - currently, differing values give an error
                            if (attributes.Contains(aOid.Id))
                            {
                                // OK, but the value has to be the same
                                if (!attributes[aOid.Id].Equals(attr))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                attributes.Add(aOid.Id, attr);
                            }

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                CertId certId = new CertId(cert.GetPublicKey());
                X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes);

                chainCerts[certId] = pkcs12Cert;

                if (unmarkedKey)
                {
                    if (keyCerts.Count == 0)
                    {
                        string name = Hex.ToHexString(certId.Id);

                        keyCerts[name] = pkcs12Cert;

                        object temp = keys["unmarked"];
                        keys.Remove("unmarked");
                        keys[name] = temp;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        string name = Hex.ToHexString(localId.GetOctets());

                        keyCerts[name] = pkcs12Cert;
                    }

                    if (alias != null)
                    {
                        // TODO There may have been more than one alias
                        certs[alias] = pkcs12Cert;
                    }
                }
            }
        }
        // Only the ctor should be calling with isAuthority = true
        // if isAuthority, value for isMachineCert doesn't matter
        private X509CertificateContainer CreateCertificate(bool isAuthority, bool isMachineCert, X509Certificate signingCertificate, CertificateCreationSettings certificateCreationSettings)
        {
            if (certificateCreationSettings == null)
            {
                if (isAuthority)
                {
                    certificateCreationSettings = new CertificateCreationSettings();
                }
                else
                {
                    throw new Exception("Parameter certificateCreationSettings cannot be null when isAuthority is false");
                }
            }

            // Set to default cert creation settings if not set
            if (certificateCreationSettings.ValidityNotBefore == default(DateTime))
            {
                certificateCreationSettings.ValidityNotBefore = _defaultValidityNotBefore;
            }
            if (certificateCreationSettings.ValidityNotAfter == default(DateTime))
            {
                certificateCreationSettings.ValidityNotAfter = _defaultValidityNotAfter;
            }

            string[] subjects = certificateCreationSettings.Subjects;
            if (!isAuthority ^ (signingCertificate != null))
            {
                throw new ArgumentException("Either isAuthority == true or signingCertificate is not null");
            }

            if (!isAuthority && (subjects == null || subjects.Length == 0))
            {
                throw new ArgumentException("If not creating an authority, must specify at least one Subject", "subjects");
            }

            if (!isAuthority && string.IsNullOrWhiteSpace(subjects[0]))
            {
                throw new ArgumentException("Certificate Subject must not be an empty string or only whitespace", "creationSettings.Subjects");
            }

            EnsureInitialized();

            _certGenerator.Reset();
            _certGenerator.SetSignatureAlgorithm(_signatureAlthorithm);

            X509Name authorityX509Name = CreateX509Name(_authorityCanonicalName);
            
            var keyPair = isAuthority ? _authorityKeyPair : _keyPairGenerator.GenerateKeyPair();
            if (isAuthority)
            {
                _certGenerator.SetIssuerDN(authorityX509Name);
                _certGenerator.SetSubjectDN(authorityX509Name);

                var authorityKeyIdentifier = new AuthorityKeyIdentifier(
                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(_authorityKeyPair.Public),
                    new GeneralNames(new GeneralName(authorityX509Name)),
                    new BigInteger(7, _random).Abs());

                _certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, authorityKeyIdentifier);
                _certGenerator.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyCertSign | X509KeyUsage.KeyEncipherment | X509KeyUsage.CrlSign));

            }
            else
            {
                X509Name subjectName = CreateX509Name(subjects[0]);
                _certGenerator.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(signingCertificate));
                _certGenerator.SetSubjectDN(subjectName);

                _certGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, true, new AuthorityKeyIdentifierStructure(_authorityKeyPair.Public));
                _certGenerator.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(X509KeyUsage.DigitalSignature | X509KeyUsage.KeyAgreement | X509KeyUsage.KeyEncipherment));

            }

            _certGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keyPair.Public));

            _certGenerator.SetSerialNumber(new BigInteger(64 /*sizeInBits*/, _random).Abs());
            _certGenerator.SetNotBefore(certificateCreationSettings.ValidityNotBefore);
            _certGenerator.SetNotAfter(certificateCreationSettings.ValidityNotAfter);
            _certGenerator.SetPublicKey(keyPair.Public);

            _certGenerator.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(isAuthority));
            _certGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth, KeyPurposeID.IdKPClientAuth));

            if (!isAuthority)
            {
                if (isMachineCert)
                {
                    List<Asn1Encodable> subjectAlternativeNames = new List<Asn1Encodable>(); 
                    
                    // All endpoints should also be in the Subject Alt Names 
                    for (int i = 0; i < subjects.Length; i++)
                    {
                        if (!string.IsNullOrWhiteSpace(subjects[i]))
                        {
                            // Machine certs can have additional DNS names
                            subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, subjects[i]));
                        }
                    }

                    _certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNames.ToArray()));
                }
                else
                {
                    if (subjects.Length > 1)
                    {
                        var subjectAlternativeNames = new Asn1EncodableVector();
                    
                        // Only add a SAN for the user if there are any
                        for (int i = 1; i < subjects.Length; i++)
                        {
                            if (!string.IsNullOrWhiteSpace(subjects[i]))
                            {
                                Asn1EncodableVector otherNames = new Asn1EncodableVector();
                                otherNames.Add(new DerObjectIdentifier(_upnObjectId));
                                otherNames.Add(new DerTaggedObject(true, 0, new DerUtf8String(subjects[i])));

                                Asn1Object genName = new DerTaggedObject(false, 0, new DerSequence(otherNames));

                                subjectAlternativeNames.Add(genName);
                            }
                        }
                        _certGenerator.AddExtension(X509Extensions.SubjectAlternativeName, true, new DerSequence(subjectAlternativeNames));
                    }
                }
            }

            var crlDistributionPoints = new DistributionPoint[1] {
                new DistributionPoint(new DistributionPointName(
                    new GeneralNames(new GeneralName(GeneralName.UniformResourceIdentifier, _crlUri))), null, new GeneralNames(new GeneralName(authorityX509Name)))
                };
            var revocationListExtension = new CrlDistPoint(crlDistributionPoints);
            _certGenerator.AddExtension(X509Extensions.CrlDistributionPoints, false, revocationListExtension);

            X509Certificate cert = _certGenerator.Generate(_authorityKeyPair.Private, _random);
            if (certificateCreationSettings.IsValidCert)
            {
                EnsureCertificateValidity(cert);
            }

            // For now, given that we don't know what format to return it in, preserve the formats so we have 
            // the flexibility to do what we need to

            X509CertificateContainer container = new X509CertificateContainer(); 

            X509CertificateEntry[] chain = new X509CertificateEntry[1];
            chain[0] = new X509CertificateEntry(cert);

            Pkcs12Store store = new Pkcs12StoreBuilder().Build();
            store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), chain);

            using (MemoryStream stream = new MemoryStream())
            {
                store.Save(stream, _password.ToCharArray(), _random);
                container.Pfx = stream.ToArray(); 
            }

            X509Certificate2 outputCert;
            if (isAuthority)
            {
                // don't hand out the private key for the cert when it's the authority
                outputCert = new X509Certificate2(cert.GetEncoded()); 
            } 
            else
            {
                // Otherwise, allow encode with the private key. note that X509Certificate2.RawData will not provide the private key
                // you will have to re-export this cert if needed
                outputCert = new X509Certificate2(container.Pfx, _password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
            }

            container.Subject = subjects[0];
            container.InternalCertificate = cert;
            container.Certificate = outputCert;
            container.Thumbprint = outputCert.Thumbprint;

            Trace.WriteLine("[CertificateGenerator] generated a certificate:");
            Trace.WriteLine(string.Format("    {0} = {1}", "isAuthority", isAuthority));
            if (!isAuthority)
            {
                Trace.WriteLine(string.Format("    {0} = {1}", "Signed by", signingCertificate.SubjectDN));
                Trace.WriteLine(string.Format("    {0} = {1}", "Subject (CN) ", subjects[0]));
                Trace.WriteLine(string.Format("    {0} = {1}", "Alt names ", string.Join(", ", subjects)));
            }
            Trace.WriteLine(string.Format("    {0} = {1}", "HasPrivateKey:", outputCert.HasPrivateKey));
            Trace.WriteLine(string.Format("    {0} = {1}", "Thumbprint", outputCert.Thumbprint));

            return container;
        }
Exemple #12
0
        public void Save(Stream stream, char[] password, SecureRandom random)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }
            Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new Asn1Encodable[0]);

            foreach (string text in this.keys.Keys)
            {
                byte[] array = new byte[20];
                random.NextBytes(array);
                AsymmetricKeyEntry  asymmetricKeyEntry = (AsymmetricKeyEntry)this.keys[text];
                DerObjectIdentifier oid;
                Asn1Encodable       asn1Encodable;
                if (password == null)
                {
                    oid           = PkcsObjectIdentifiers.KeyBag;
                    asn1Encodable = PrivateKeyInfoFactory.CreatePrivateKeyInfo(asymmetricKeyEntry.Key);
                }
                else
                {
                    oid           = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
                    asn1Encodable = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(this.keyAlgorithm, password, array, 1024, asymmetricKeyEntry.Key);
                }
                Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(new Asn1Encodable[0]);
                foreach (string text2 in asymmetricKeyEntry.BagAttributeKeys)
                {
                    Asn1Encodable obj = asymmetricKeyEntry[text2];
                    if (!text2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        asn1EncodableVector2.Add(new Asn1Encodable[]
                        {
                            new DerSequence(new Asn1Encodable[]
                            {
                                new DerObjectIdentifier(text2),
                                new DerSet(obj)
                            })
                        });
                    }
                }
                asn1EncodableVector2.Add(new Asn1Encodable[]
                {
                    new DerSequence(new Asn1Encodable[]
                    {
                        PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                        new DerSet(new DerBmpString(text))
                    })
                });
                if (asymmetricKeyEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    X509CertificateEntry   certificate = this.GetCertificate(text);
                    AsymmetricKeyParameter publicKey   = certificate.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   obj2        = Pkcs12Store.CreateSubjectKeyID(publicKey);
                    asn1EncodableVector2.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(obj2)
                        })
                    });
                }
                asn1EncodableVector.Add(new Asn1Encodable[]
                {
                    new SafeBag(oid, asn1Encodable.ToAsn1Object(), new DerSet(asn1EncodableVector2))
                });
            }
            byte[]      derEncoded  = new DerSequence(asn1EncodableVector).GetDerEncoded();
            ContentInfo contentInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded));

            byte[] array2 = new byte[20];
            random.NextBytes(array2);
            Asn1EncodableVector asn1EncodableVector3 = new Asn1EncodableVector(new Asn1Encodable[0]);
            Pkcs12PbeParams     pkcs12PbeParams      = new Pkcs12PbeParams(array2, 1024);
            AlgorithmIdentifier algorithmIdentifier  = new AlgorithmIdentifier(this.certAlgorithm, pkcs12PbeParams.ToAsn1Object());
            ISet set = new HashSet();

            foreach (string text3 in this.keys.Keys)
            {
                X509CertificateEntry certificate2        = this.GetCertificate(text3);
                CertBag             certBag              = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(certificate2.Certificate.GetEncoded()));
                Asn1EncodableVector asn1EncodableVector4 = new Asn1EncodableVector(new Asn1Encodable[0]);
                foreach (string text4 in certificate2.BagAttributeKeys)
                {
                    Asn1Encodable obj3 = certificate2[text4];
                    if (!text4.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        asn1EncodableVector4.Add(new Asn1Encodable[]
                        {
                            new DerSequence(new Asn1Encodable[]
                            {
                                new DerObjectIdentifier(text4),
                                new DerSet(obj3)
                            })
                        });
                    }
                }
                asn1EncodableVector4.Add(new Asn1Encodable[]
                {
                    new DerSequence(new Asn1Encodable[]
                    {
                        PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                        new DerSet(new DerBmpString(text3))
                    })
                });
                if (certificate2[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    AsymmetricKeyParameter publicKey2 = certificate2.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   obj4       = Pkcs12Store.CreateSubjectKeyID(publicKey2);
                    asn1EncodableVector4.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(obj4)
                        })
                    });
                }
                asn1EncodableVector3.Add(new Asn1Encodable[]
                {
                    new SafeBag(PkcsObjectIdentifiers.CertBag, certBag.ToAsn1Object(), new DerSet(asn1EncodableVector4))
                });
                set.Add(certificate2.Certificate);
            }
            foreach (string text5 in this.certs.Keys)
            {
                X509CertificateEntry x509CertificateEntry = (X509CertificateEntry)this.certs[text5];
                if (this.keys[text5] == null)
                {
                    CertBag             certBag2             = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry.Certificate.GetEncoded()));
                    Asn1EncodableVector asn1EncodableVector5 = new Asn1EncodableVector(new Asn1Encodable[0]);
                    foreach (string text6 in x509CertificateEntry.BagAttributeKeys)
                    {
                        if (!text6.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        {
                            Asn1Encodable obj5 = x509CertificateEntry[text6];
                            if (!text6.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                            {
                                asn1EncodableVector5.Add(new Asn1Encodable[]
                                {
                                    new DerSequence(new Asn1Encodable[]
                                    {
                                        new DerObjectIdentifier(text6),
                                        new DerSet(obj5)
                                    })
                                });
                            }
                        }
                    }
                    asn1EncodableVector5.Add(new Asn1Encodable[]
                    {
                        new DerSequence(new Asn1Encodable[]
                        {
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(text5))
                        })
                    });
                    asn1EncodableVector3.Add(new Asn1Encodable[]
                    {
                        new SafeBag(PkcsObjectIdentifiers.CertBag, certBag2.ToAsn1Object(), new DerSet(asn1EncodableVector5))
                    });
                    set.Add(x509CertificateEntry.Certificate);
                }
            }
            foreach (Pkcs12Store.CertId key in this.chainCerts.Keys)
            {
                X509CertificateEntry x509CertificateEntry2 = (X509CertificateEntry)this.chainCerts[key];
                if (!set.Contains(x509CertificateEntry2.Certificate))
                {
                    CertBag             certBag3             = new CertBag(PkcsObjectIdentifiers.X509Certificate, new DerOctetString(x509CertificateEntry2.Certificate.GetEncoded()));
                    Asn1EncodableVector asn1EncodableVector6 = new Asn1EncodableVector(new Asn1Encodable[0]);
                    foreach (string text7 in x509CertificateEntry2.BagAttributeKeys)
                    {
                        if (!text7.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                        {
                            asn1EncodableVector6.Add(new Asn1Encodable[]
                            {
                                new DerSequence(new Asn1Encodable[]
                                {
                                    new DerObjectIdentifier(text7),
                                    new DerSet(x509CertificateEntry2[text7])
                                })
                            });
                        }
                    }
                    asn1EncodableVector3.Add(new Asn1Encodable[]
                    {
                        new SafeBag(PkcsObjectIdentifiers.CertBag, certBag3.ToAsn1Object(), new DerSet(asn1EncodableVector6))
                    });
                }
            }
            byte[]      derEncoded2 = new DerSequence(asn1EncodableVector3).GetDerEncoded();
            ContentInfo contentInfo2;

            if (password == null)
            {
                contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(derEncoded2));
            }
            else
            {
                byte[]        str           = Pkcs12Store.CryptPbeData(true, algorithmIdentifier, password, false, derEncoded2);
                EncryptedData encryptedData = new EncryptedData(PkcsObjectIdentifiers.Data, algorithmIdentifier, new BerOctetString(str));
                contentInfo2 = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, encryptedData.ToAsn1Object());
            }
            ContentInfo[] info = new ContentInfo[]
            {
                contentInfo,
                contentInfo2
            };
            byte[]      encoded      = new AuthenticatedSafe(info).GetEncoded(this.useDerEncoding ? "DER" : "BER");
            ContentInfo contentInfo3 = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(encoded));
            MacData     macData      = null;

            if (password != null)
            {
                byte[] array3 = new byte[20];
                random.NextBytes(array3);
                byte[] digest               = Pkcs12Store.CalculatePbeMac(OiwObjectIdentifiers.IdSha1, array3, 1024, password, false, encoded);
                AlgorithmIdentifier algID   = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
                DigestInfo          digInfo = new DigestInfo(algID, digest);
                macData = new MacData(digInfo, array3, 1024);
            }
            Pfx             obj6 = new Pfx(contentInfo3, macData);
            DerOutputStream derOutputStream;

            if (this.useDerEncoding)
            {
                derOutputStream = new DerOutputStream(stream);
            }
            else
            {
                derOutputStream = new BerOutputStream(stream);
            }
            derOutputStream.WriteObject(obj6);
        }
Exemple #13
0
        public void SetKeyEntry(
            string                   alias,
            AsymmetricKeyEntry       keyEntry,
            X509CertificateEntry[]   chain)
        {
            if (alias == null)
                throw new ArgumentNullException("alias");
            if (keyEntry == null)
                throw new ArgumentNullException("keyEntry");
            if (keyEntry.Key.IsPrivate && (chain == null))
                throw new ArgumentException("No certificate chain for private key");
            if (keys[alias] != null && !keyEntry.Key.Equals(((AsymmetricKeyEntry) keys[alias]).Key))
                throw new ArgumentException("There is already a key with the name " + alias + ".");

            keys[alias] = keyEntry;
            certs[alias] = chain[0];

            for (int i = 0; i != chain.Length; i++)
            {
                chainCerts[new CertId(chain[i].Certificate.GetPublicKey())] = chain[i];
            }
        }
Exemple #14
0
        public Pkcs12Store(
            Stream	input,
            char[]	password)
        {
            if (input == null)
                throw new ArgumentNullException("input");
            if (password == null)
                throw new ArgumentNullException("password");

            Asn1InputStream bIn = new Asn1InputStream(input);
            Asn1Sequence obj = (Asn1Sequence) bIn.ReadObject();
            Pfx bag = new Pfx(obj);
            ContentInfo info = bag.AuthSafe;
            ArrayList chain = new ArrayList();
            bool unmarkedKey = false;
            bool wrongPkcs12Zero = false;

            if (bag.MacData != null)           // check the mac code
            {
                MacData mData = bag.MacData;
                DigestInfo dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt = mData.GetSalt();
                int itCount = mData.IterationCount.IntValue;

                byte[] data = ((Asn1OctetString) info.Content).GetOctets();

                Asn1Encodable parameters = PbeUtilities.GenerateAlgorithmParameters(
                    algId.ObjectID, salt, itCount);
                ICipherParameters keyParameters = PbeUtilities.GenerateCipherParameters(
                    algId.ObjectID, password, parameters);
                IMac mac = (IMac)PbeUtilities.CreateEngine(algId.ObjectID);

                mac.Init(keyParameters);

                mac.BlockUpdate(data, 0, data.Length);

                byte[] res = new byte[mac.GetMacSize()];
                mac.DoFinal(res, 0);

                byte[] dig = dInfo.GetDigest();

                if (!Arrays.AreEqual(res, dig))
                {
                    if (password.Length > 0)
                    {
                        throw new Exception("Pkcs12 key store mac invalid - wrong password or corrupted file.");
                    }

                    //
                    // may be incorrect zero length password
                    //
                    keyParameters = PbeUtilities.GenerateCipherParameters(
                        algId.ObjectID, password, true, parameters);

                    mac.Init(keyParameters);

                    mac.BlockUpdate(data, 0, data.Length);

                    res = new byte[mac.GetMacSize()];
                    mac.DoFinal(res, 0);

                    if (!Arrays.AreEqual(res, dig))
                    {
                        throw new IOException("PKCS12 key store mac invalid - wrong password or corrupted file.");
                    }

                    wrongPkcs12Zero = true;
                }
            }

            keys = new IgnoresCaseHashtable();
            localIds = new Hashtable();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[] octs = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence) Asn1OctetString.FromByteArray(octs));
                ContentInfo[] c = authSafe.GetContentInfo();

                for (int i = 0; i != c.Length; i++)
                {
                    if (c[i].ContentType.Equals(PkcsObjectIdentifiers.Data))
                    {
                        byte[] octets = ((Asn1OctetString)c[i].Content).GetOctets();
                        Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(octets);

                        for (int j = 0; j != seq.Count; j++)
                        {
                            SafeBag b = new SafeBag((Asn1Sequence) seq[j]);
                            if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);
                                string alias = null;
                                Asn1OctetString localId = null;

                                if (b.BagAttributes != null)
                                {
                                    foreach (Asn1Sequence sq in b.BagAttributes)
                                    {
                                        DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                        Asn1Set attrSet = (Asn1Set) sq[1];
                                        Asn1Encodable attr = null;

                                        if (attrSet.Count > 0)
                                        {
                                            attr = attrSet[0];

                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias = ((DerBmpString)attr).GetString();
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                if (localId != null)
                                {
                                    // MASC 20070308. CF compatibility patch
                                    byte[] hex = Hex.Encode(localId.GetOctets());
                                    string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                    if (alias == null)
                                    {
                                        keys[name] = pkcs12Key;
                                    }
                                    else
                                    {
                                        localIds[alias] = name;
                                    }
                                }
                                else
                                {
                                    unmarkedKey = true;
                                    keys["unmarked"] = pkcs12Key;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else if (c[i].ContentType.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        EncryptedData d = EncryptedData.GetInstance(c[i].Content);
                        Asn1Sequence seq = DecryptData(d.EncryptionAlgorithm, d.Content.GetOctets(), password, wrongPkcs12Zero);

                        for (int j = 0; j != seq.Count; j++)
                        {
                            SafeBag b = new SafeBag((Asn1Sequence) seq[j]);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);
                                string alias = null;
                                Asn1OctetString localId = null;

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                    Asn1Set attrSet = (Asn1Set) sq[1];
                                    Asn1Encodable attr = null;

                                    if (attrSet.Count > 0)
                                    {
                                        attr = attrSet[0];

                                        attributes.Add(aOid.Id, attr);
                                    }

                                    if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                    {
                                        alias = ((DerBmpString)attr).GetString();
                                        keys[alias] = pkcs12Key;
                                    }
                                    else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                    {
                                        localId = (Asn1OctetString)attr;
                                    }
                                }

                                // MASC 20070308. CF compatibility patch
                                byte[] hex = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    localIds[alias] = name;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                PrivateKeyInfo privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privKeyInfo);

                                //
                                // set the attributes on the key
                                //
                                string alias = null;
                                Asn1OctetString localId = null;
                                Hashtable attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key = new AsymmetricKeyEntry(privKey, attributes);

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                                    Asn1Set attrSet = (Asn1Set) sq[1];
                                    Asn1Encodable attr = null;

                                    if (attrSet.Count > 0)
                                    {
                                        attr = attrSet[0];

                                        attributes.Add(aOid.Id, attr);
                                    }

                                    if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                    {
                                        alias = ((DerBmpString)attr).GetString();
                                        keys[alias] = pkcs12Key;
                                    }
                                    else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                    {
                                        localId = (Asn1OctetString)attr;
                                    }
                                }

                                // MASC 20070308. CF compatibility patch
                                byte[] hex = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex,0,hex.Length);

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    localIds[alias] = name;
                                }
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("extra " + c[i].ContentType.Id);
                        Console.WriteLine("extra " + Asn1Dump.DumpAsString(c[i].Content));
                    }
                }
            }

            certs = new IgnoresCaseHashtable();
            chainCerts = new Hashtable();
            keyCerts = new Hashtable();

            for (int i = 0; i < chain.Count; ++i)
            {
                SafeBag b = (SafeBag)chain[i];
                CertBag cb = new CertBag((Asn1Sequence)b.BagValue);
                byte[] octets = ((Asn1OctetString) cb.CertValue).GetOctets();
                X509Certificate cert = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                Hashtable attributes = new Hashtable();
                X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes);
                Asn1OctetString localId = null;
                string alias = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid = (DerObjectIdentifier) sq[0];
                        Asn1Set attrSet = (Asn1Set) sq[1];

                        if (attrSet.Count > 0)
                        {
                            Asn1Encodable attr = attrSet[0];

                            attributes.Add(aOid.Id, attr);

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                AsymmetricKeyParameter publicKey = cert.GetPublicKey();
                chainCerts[new CertId(publicKey)] = pkcs12Cert;

                if (unmarkedKey)
                {
                    if (keyCerts.Count == 0)
                    {
                        // MASC 20070308. CF compatibility patch
                        byte[] hex =
                            Hex.Encode(
                                new SubjectKeyIdentifier(
                                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey)).GetKeyIdentifier());

                        string name = Encoding.ASCII.GetString( hex,0,hex.Length );

                        keyCerts[name] = pkcs12Cert;

                        object temp = keys["unmarked"];
                        keys.Remove("unmarked");
                        keys[name] = temp;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        // MASC 20070308. CF compatibility patch
                        byte[] hex = Hex.Encode(localId.GetOctets());
                        string name = Encoding.ASCII.GetString( hex,0,hex.Length );

                        keyCerts[name] = pkcs12Cert;
                    }

                    if (alias != null)
                    {
                        certs[alias] = pkcs12Cert;
                    }
                }
            }
        }
        /// <summary>
        /// Creates new certificate
        /// </summary>
        /// <returns></returns>
        public static void CreateSelfSignedCertificate(string subjectDirName, DateTime startDate, DateTime endDate, int signatureBits, int keyStrength, string password, string fileName)
        {
            string signatureAlgorithm;
            switch (signatureBits)
            {
                case 160:
                    signatureAlgorithm = "SHA1withRSA";
                    break;
                case 224:
                    signatureAlgorithm = "SHA224withRSA";
                    break;
                case 256:
                    signatureAlgorithm = "SHA256withRSA";
                    break;
                case 384:
                    signatureAlgorithm = "SHA384withRSA";
                    break;
                case 512:
                    signatureAlgorithm = "SHA512withRSA";
                    break;
                default:
                    throw new ArgumentException("Invalid signature bit size.", "signatureBits");
            }

            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);

            // Generate public/private keys.
            AsymmetricCipherKeyPair encryptionKeys;

            KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            encryptionKeys = keyPairGenerator.GenerateKeyPair();

            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
            certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random));
            certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);
            certificateGenerator.SetIssuerDN(new X509Name(subjectDirName));
            certificateGenerator.SetSubjectDN(new X509Name(subjectDirName));
            certificateGenerator.SetNotBefore(startDate);
            certificateGenerator.SetNotAfter(endDate);
            certificateGenerator.SetPublicKey(encryptionKeys.Public);

            // self-sign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(encryptionKeys.Private, random);

            var store = new Pkcs12Store();
            string friendlyName = certificate.SubjectDN.ToString();
            var certificateEntry = new X509CertificateEntry(certificate);
            store.SetCertificateEntry(friendlyName, certificateEntry);
            store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(encryptionKeys.Private), new[] { certificateEntry });

            var stream = new MemoryStream();
            store.Save(stream, password.ToCharArray(), random);

            //Verify that the certificate is valid.
            var convertedCertificate = new X509Certificate2(stream.ToArray(), password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

            //Write the file.
            File.WriteAllBytes(fileName, stream.ToArray());

            File.WriteAllBytes(Path.ChangeExtension(fileName, ".cer"), certificate.GetEncoded());
        }
Exemple #16
0
        public void Load(
            Stream input,
            char[]      password)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            Asn1Sequence obj             = (Asn1Sequence)Asn1Object.FromStream(input);
            Pfx          bag             = new Pfx(obj);
            ContentInfo  info            = bag.AuthSafe;
            bool         wrongPkcs12Zero = false;

            if (password != null && bag.MacData != null) // check the mac code
            {
                MacData             mData = bag.MacData;
                DigestInfo          dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt    = mData.GetSalt();
                int    itCount = mData.IterationCount.IntValue;

                byte[] data = ((Asn1OctetString)info.Content).GetOctets();

                byte[] mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, false, data);
                byte[] dig = dInfo.GetDigest();

                if (!Arrays.ConstantTimeAreEqual(mac, dig))
                {
                    if (password.Length > 0)
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }

                    // Try with incorrect zero length password
                    mac = CalculatePbeMac(algId.Algorithm, salt, itCount, password, true, data);

                    if (!Arrays.ConstantTimeAreEqual(mac, dig))
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }

                    wrongPkcs12Zero = true;
                }
            }

            keys.Clear();
            localIds.Clear();
            unmarkedKeyEntry = null;

            IList certBags = Platform.CreateArrayList();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[]            octs     = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence)Asn1OctetString.FromByteArray(octs));
                ContentInfo[] cis = authSafe.GetContentInfo();

                foreach (ContentInfo ci in cis)
                {
                    DerObjectIdentifier oid = ci.ContentType;

                    byte[] octets = null;
                    if (oid.Equals(PkcsObjectIdentifiers.Data))
                    {
                        octets = ((Asn1OctetString)ci.Content).GetOctets();
                    }
                    else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        if (password != null)
                        {
                            EncryptedData d = EncryptedData.GetInstance(ci.Content);
                            octets = CryptPbeData(false, d.EncryptionAlgorithm,
                                                  password, wrongPkcs12Zero, d.Content.GetOctets());
                        }
                    }
                    else
                    {
                        // TODO Other data types
                    }

                    if (octets != null)
                    {
                        Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                certBags.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(b.BagValue),
                                                        b.BagAttributes, password, wrongPkcs12Zero);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                LoadKeyBag(PrivateKeyInfo.GetInstance(b.BagValue), b.BagAttributes);
                            }
                            else
                            {
                                // TODO Other bag types
                            }
                        }
                    }
                }
            }

            certs.Clear();
            chainCerts.Clear();
            keyCerts.Clear();

            foreach (SafeBag b in certBags)
            {
                CertBag         certBag = new CertBag((Asn1Sequence)b.BagValue);
                byte[]          octets  = ((Asn1OctetString)certBag.CertValue).GetOctets();
                X509Certificate cert    = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                IDictionary     attributes = Platform.CreateHashtable();
                Asn1OctetString localId    = null;
                string          alias      = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid    = DerObjectIdentifier.GetInstance(sq[0]);
                        Asn1Set             attrSet = Asn1Set.GetInstance(sq[1]);

                        if (attrSet.Count > 0)
                        {
                            // TODO We should be adding all attributes in the set
                            Asn1Encodable attr = attrSet[0];

                            // TODO We might want to "merge" attribute sets with
                            // the same OID - currently, differing values give an error
                            if (attributes.Contains(aOid.Id))
                            {
                                // OK, but the value has to be the same
                                if (!attributes[aOid.Id].Equals(attr))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                attributes.Add(aOid.Id, attr);
                            }

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                CertId certId = new CertId(cert.GetPublicKey());
                X509CertificateEntry certEntry = new X509CertificateEntry(cert, attributes);

                chainCerts[certId] = certEntry;

                if (unmarkedKeyEntry != null)
                {
                    if (keyCerts.Count == 0)
                    {
                        string name = Hex.ToHexString(certId.Id);

                        keyCerts[name] = certEntry;
                        keys[name]     = unmarkedKeyEntry;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        string name = Hex.ToHexString(localId.GetOctets());

                        keyCerts[name] = certEntry;
                    }

                    if (alias != null)
                    {
                        // TODO There may have been more than one alias
                        certs[alias] = certEntry;
                    }
                }
            }
        }
Exemple #17
0
        public void Save(
            Stream stream,
            char[]                      password,
            SecureRandom random)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (random == null)
            {
                throw new ArgumentNullException("random");
            }

            //
            // handle the keys
            //
            Asn1EncodableVector keyBags = new Asn1EncodableVector();

            foreach (string name in keys.Keys)
            {
                byte[] kSalt = new byte[SaltSize];
                random.NextBytes(kSalt);

                AsymmetricKeyEntry privKey = (AsymmetricKeyEntry)keys[name];

                DerObjectIdentifier bagOid;
                Asn1Encodable       bagData;

                if (password == null)
                {
                    bagOid  = PkcsObjectIdentifiers.KeyBag;
                    bagData = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey.Key);
                }
                else
                {
                    bagOid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
                    if (keyPrfAlgorithm != null)
                    {
                        bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
                            keyAlgorithm, keyPrfAlgorithm, password, kSalt, MinIterations, random, privKey.Key);
                    }
                    else
                    {
                        bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
                            keyAlgorithm, password, kSalt, MinIterations, privKey.Key);
                    }
                }

                Asn1EncodableVector kName = new Asn1EncodableVector();

                foreach (string oid in privKey.BagAttributeKeys)
                {
                    Asn1Encodable entry = privKey[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        continue;
                    }

                    kName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'name'
                //if (privKey[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                //
                // make sure we have a local key-id
                //
                if (privKey[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    X509CertificateEntry   ct           = GetCertificate(name);
                    AsymmetricKeyParameter pubKey       = ct.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   subjectKeyID = CreateSubjectKeyID(pubKey);

                    kName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(subjectKeyID)));
                }

                keyBags.Add(new SafeBag(bagOid, bagData.ToAsn1Object(), new DerSet(kName)));
            }

            byte[]      keyBagsEncoding = new DerSequence(keyBags).GetDerEncoded();
            ContentInfo keysInfo        = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(keyBagsEncoding));

            //
            // certificate processing
            //
            byte[] cSalt = new byte[SaltSize];

            random.NextBytes(cSalt);

            Asn1EncodableVector certBags = new Asn1EncodableVector();
            Pkcs12PbeParams     cParams  = new Pkcs12PbeParams(cSalt, MinIterations);
            AlgorithmIdentifier cAlgId   = new AlgorithmIdentifier(certAlgorithm, cParams.ToAsn1Object());
            ISet doneCerts = new HashSet();

            foreach (string name in keys.Keys)
            {
                X509CertificateEntry certEntry = GetCertificate(name);
                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(certEntry.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in certEntry.BagAttributeKeys)
                {
                    Asn1Encodable entry = certEntry[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        continue;
                    }

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'name'
                //if (certEntry[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(name))));
                }

                //
                // make sure we have a local key-id
                //
                if (certEntry[PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
                {
                    AsymmetricKeyParameter pubKey       = certEntry.Certificate.GetPublicKey();
                    SubjectKeyIdentifier   subjectKeyID = CreateSubjectKeyID(pubKey);

                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtLocalKeyID,
                            new DerSet(subjectKeyID)));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));

                doneCerts.Add(certEntry.Certificate);
            }

            foreach (string certId in certs.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)certs[certId];

                if (keys[certId] != null)
                {
                    continue;
                }

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    // a certificate not immediately linked to a key doesn't require
                    // a localKeyID and will confuse some PKCS12 implementations.
                    //
                    // If we find one, we'll prune it out.
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                    {
                        continue;
                    }

                    Asn1Encodable entry = cert[oid];

                    // NB: Ignore any existing FriendlyName
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id))
                    {
                        continue;
                    }

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(entry)));
                }

                //
                // make sure we are using the local alias on store
                //
                // NB: We always set the FriendlyName based on 'certId'
                //if (cert[PkcsObjectIdentifiers.Pkcs9AtFriendlyName] == null)
                {
                    fName.Add(
                        new DerSequence(
                            PkcsObjectIdentifiers.Pkcs9AtFriendlyName,
                            new DerSet(new DerBmpString(certId))));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));

                doneCerts.Add(cert.Certificate);
            }

            foreach (CertId certId in chainCerts.Keys)
            {
                X509CertificateEntry cert = (X509CertificateEntry)chainCerts[certId];

                if (doneCerts.Contains(cert.Certificate))
                {
                    continue;
                }

                CertBag cBag = new CertBag(
                    PkcsObjectIdentifiers.X509Certificate,
                    new DerOctetString(cert.Certificate.GetEncoded()));

                Asn1EncodableVector fName = new Asn1EncodableVector();

                foreach (string oid in cert.BagAttributeKeys)
                {
                    // a certificate not immediately linked to a key doesn't require
                    // a localKeyID and will confuse some PKCS12 implementations.
                    //
                    // If we find one, we'll prune it out.
                    if (oid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id))
                    {
                        continue;
                    }

                    fName.Add(
                        new DerSequence(
                            new DerObjectIdentifier(oid),
                            new DerSet(cert[oid])));
                }

                certBags.Add(new SafeBag(PkcsObjectIdentifiers.CertBag, cBag.ToAsn1Object(), new DerSet(fName)));
            }

            byte[] certBagsEncoding = new DerSequence(certBags).GetDerEncoded();

            ContentInfo certsInfo;

            if (password == null || certAlgorithm == null)
            {
                certsInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(certBagsEncoding));
            }
            else
            {
                byte[]        certBytes = CryptPbeData(true, cAlgId, password, false, certBagsEncoding);
                EncryptedData cInfo     = new EncryptedData(PkcsObjectIdentifiers.Data, cAlgId, new BerOctetString(certBytes));
                certsInfo = new ContentInfo(PkcsObjectIdentifiers.EncryptedData, cInfo.ToAsn1Object());
            }

            ContentInfo[] info = new ContentInfo[] { keysInfo, certsInfo };

            byte[] data = new AuthenticatedSafe(info).GetEncoded(
                useDerEncoding ? Asn1Encodable.Der : Asn1Encodable.Ber);

            ContentInfo mainInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(data));

            //
            // create the mac
            //
            MacData macData = null;

            if (password != null)
            {
                byte[] mSalt = new byte[20];
                random.NextBytes(mSalt);

                byte[] mac = CalculatePbeMac(OiwObjectIdentifiers.IdSha1,
                                             mSalt, MinIterations, password, false, data);

                AlgorithmIdentifier algId = new AlgorithmIdentifier(
                    OiwObjectIdentifiers.IdSha1, DerNull.Instance);
                DigestInfo dInfo = new DigestInfo(algId, mac);

                macData = new MacData(dInfo, mSalt, MinIterations);
            }

            //
            // output the Pfx
            //
            Pfx pfx = new Pfx(mainInfo, macData);

            DerOutputStream derOut;

            if (useDerEncoding)
            {
                derOut = new DerOutputStream(stream);
            }
            else
            {
                derOut = new BerOutputStream(stream);
            }

            derOut.WriteObject(pfx);
        }
Exemple #18
0
        public X509CertificateEntry[] GetCertificateChain(
            string alias)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }

            if (!IsKeyEntry(alias))
            {
                return(null);
            }

            X509CertificateEntry c = GetCertificate(alias);

            if (c != null)
            {
                IList cs = Platform.CreateArrayList();

                while (c != null)
                {
                    X509Certificate      x509c = c.Certificate;
                    X509CertificateEntry nextC = null;

                    Asn1OctetString akiValue = x509c.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
                    if (akiValue != null)
                    {
                        AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.GetInstance(akiValue.GetOctets());

                        byte[] keyID = aki.GetKeyIdentifier();
                        if (keyID != null)
                        {
                            nextC = (X509CertificateEntry)chainCerts[new CertId(keyID)];
                        }
                    }

                    if (nextC == null)
                    {
                        //
                        // no authority key id, try the Issuer DN
                        //
                        X509Name i = x509c.IssuerDN;
                        X509Name s = x509c.SubjectDN;

                        if (!i.Equivalent(s))
                        {
                            foreach (CertId certId in chainCerts.Keys)
                            {
                                X509CertificateEntry x509CertEntry = (X509CertificateEntry)chainCerts[certId];

                                X509Certificate crt = x509CertEntry.Certificate;

                                X509Name sub = crt.SubjectDN;
                                if (sub.Equivalent(i))
                                {
                                    try
                                    {
                                        x509c.Verify(crt.GetPublicKey());

                                        nextC = x509CertEntry;
                                        break;
                                    }
                                    catch (InvalidKeyException)
                                    {
                                        // TODO What if it doesn't verify?
                                    }
                                }
                            }
                        }
                    }

                    cs.Add(c);
                    if (nextC != c) // self signed - end of the chain
                    {
                        c = nextC;
                    }
                    else
                    {
                        c = null;
                    }
                }

                X509CertificateEntry[] result = new X509CertificateEntry[cs.Count];
                for (int i = 0; i < cs.Count; ++i)
                {
                    result[i] = (X509CertificateEntry)cs[i];
                }
                return(result);
            }

            return(null);
        }
Exemple #19
0
        public X509CertificateEntry[] GetCertificateChain(string alias)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias");
            }
            if (!this.IsKeyEntry(alias))
            {
                return(null);
            }
            X509CertificateEntry x509CertificateEntry = this.GetCertificate(alias);

            if (x509CertificateEntry != null)
            {
                IList list = Platform.CreateArrayList();
                while (x509CertificateEntry != null)
                {
                    X509Certificate      certificate           = x509CertificateEntry.Certificate;
                    X509CertificateEntry x509CertificateEntry2 = null;
                    Asn1OctetString      extensionValue        = certificate.GetExtensionValue(X509Extensions.AuthorityKeyIdentifier);
                    if (extensionValue != null)
                    {
                        AuthorityKeyIdentifier instance = AuthorityKeyIdentifier.GetInstance(Asn1Object.FromByteArray(extensionValue.GetOctets()));
                        if (instance.GetKeyIdentifier() != null)
                        {
                            x509CertificateEntry2 = (X509CertificateEntry)this.chainCerts[new Pkcs12Store.CertId(instance.GetKeyIdentifier())];
                        }
                    }
                    if (x509CertificateEntry2 == null)
                    {
                        X509Name issuerDN  = certificate.IssuerDN;
                        X509Name subjectDN = certificate.SubjectDN;
                        if (!issuerDN.Equivalent(subjectDN))
                        {
                            foreach (Pkcs12Store.CertId key in this.chainCerts.Keys)
                            {
                                X509CertificateEntry x509CertificateEntry3 = (X509CertificateEntry)this.chainCerts[key];
                                X509Certificate      certificate2          = x509CertificateEntry3.Certificate;
                                X509Name             subjectDN2            = certificate2.SubjectDN;
                                if (subjectDN2.Equivalent(issuerDN))
                                {
                                    try
                                    {
                                        certificate.Verify(certificate2.GetPublicKey());
                                        x509CertificateEntry2 = x509CertificateEntry3;
                                        break;
                                    }
                                    catch (InvalidKeyException)
                                    {
                                    }
                                }
                            }
                        }
                    }
                    list.Add(x509CertificateEntry);
                    if (x509CertificateEntry2 != x509CertificateEntry)
                    {
                        x509CertificateEntry = x509CertificateEntry2;
                    }
                    else
                    {
                        x509CertificateEntry = null;
                    }
                }
                X509CertificateEntry[] array = new X509CertificateEntry[list.Count];
                for (int i = 0; i < list.Count; i++)
                {
                    array[i] = (X509CertificateEntry)list[i];
                }
                return(array);
            }
            return(null);
        }
		/// <summary>
		/// Merges a certificate and private key into a single combined certificate
		/// </summary>
		public static X509Certificate2 CombineKeyAndCert(string CertificateFilename, string KeyFilename)
		{
			// Load the certificate
			string CertificatePassword = "";
			X509Certificate2 Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

			// Make sure we have a useful friendly name
			string FriendlyName = Cert.FriendlyName;
			if ((FriendlyName == "") || (FriendlyName == null))
			{
				FriendlyName = GetCommonNameFromCert(Cert);
			}

			// Create a PKCS#12 store with both the certificate and the private key in it
			Pkcs12Store Store = new Pkcs12StoreBuilder().Build();

			X509CertificateEntry[] CertChain = new X509CertificateEntry[1];
			Org.BouncyCastle.X509.X509Certificate BouncyCert = DotNetUtilities.FromX509Certificate(Cert);
			CertChain[0] = new X509CertificateEntry(BouncyCert);

			AsymmetricCipherKeyPair KeyPair = LoadKeyPairFromDiskBouncy(KeyFilename);

			Store.SetKeyEntry(FriendlyName, new AsymmetricKeyEntry(KeyPair.Private), CertChain);

			// Verify the public key from the key pair matches the certificate's public key
			AsymmetricKeyParameter CertPublicKey = BouncyCert.GetPublicKey();
			if (!(KeyPair.Public as RsaKeyParameters).Equals(CertPublicKey as RsaKeyParameters))
			{
				throw new InvalidDataException("The key pair provided does not match the certificate.  Make sure you provide the same key pair that was used to generate the original certificate signing request");
			}

			// Export the merged cert as a .p12
			string TempFileName = Path.GetTempFileName();

			string ReexportedPassword = "******";

			Stream OutStream = File.OpenWrite(TempFileName);
			Store.Save(OutStream, ReexportedPassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
			OutStream.Close();

			// Load it back in and delete the temporary file
			X509Certificate2 Result = new X509Certificate2(TempFileName, ReexportedPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
			FileOperations.DeleteFile(TempFileName);
			return Result;
		}
        public static void SaveToFile(
            X509Certificate newCert,
            AsymmetricCipherKeyPair kp,
            string FilePath,
            string CertAlias,
            string Password)
        {
            var newStore = new Pkcs12Store();

            var certEntry = new X509CertificateEntry(newCert);

            newStore.SetCertificateEntry(
                CertAlias,
                certEntry
                );

            newStore.SetKeyEntry(
                CertAlias,
                new AsymmetricKeyEntry(kp.Private),
                new[] { certEntry }
                );

            using (var certFile = File.Create(FilePath))
            {
                newStore.Save(
                    certFile,
                    Password.ToCharArray(),
                    new SecureRandom(new CryptoApiRandomGenerator())
                    );
            }
        }
        private async Task AddToWinCertStore()
        {
            Pkcs12Store store = new Pkcs12Store();
            string friendlyName = "Limelight-Client";
            var certEntry = new X509CertificateEntry(cert);
            store.SetCertificateEntry(friendlyName, certEntry);

            var keyEntry = new AsymmetricKeyEntry(keyPair.Private);
            store.SetKeyEntry(friendlyName, keyEntry, new[] { certEntry }); 

            // Copy the Pkcs12Store to a stream using an arbitrary password
            const string password = "******";
            var stream = new MemoryStream();
            store.Save(stream, password.ToCharArray(), new SecureRandom());

            // Write to .PFX string
            byte[] arr = stream.ToArray();

            IBuffer buf = arr.AsBuffer();
            string pfx = CryptographicBuffer.EncodeToBase64String(buf);

            await CertificateEnrollmentManager.ImportPfxDataAsync(pfx, password, ExportOption.NotExportable, KeyProtectionLevel.NoConsent, InstallOptions.None, friendlyName);
        }
        public void SetKeyEntry(
            string					alias,
            AsymmetricKeyEntry		keyEntry,
            X509CertificateEntry[]	chain)
        {
            if (alias == null)
                throw new ArgumentNullException("alias");
            if (keyEntry == null)
                throw new ArgumentNullException("keyEntry");
            if (keyEntry.Key.IsPrivate && (chain == null))
                throw new ArgumentException("No certificate chain for private key");

            if (keys[alias] != null)
            {
                DeleteEntry(alias);
            }

            keys[alias] = keyEntry;
            certs[alias] = chain[0];

            for (int i = 0; i != chain.Length; i++)
            {
                chainCerts[new CertId(chain[i].Certificate.GetPublicKey())] = chain[i];
            }
        }
        /// <summary>
        /// Creates a self signed application instance certificate.
        /// </summary>
        /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param>
        /// <param name="storePath">The store path (syntax depends on storeType).</param>
        /// <param name="password">The password to use to protect the certificate.</param>
        /// <param name="applicationUri">The application uri (created if not specified).</param>
        /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param>
        /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param>
        /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param>
        /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="lifetimeInMonths">The lifetime of the key in months.</param>
        /// <param name="hashSizeInBits">The hash size in bits.</param>
        /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param>
        /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param>
        /// <returns>The certificate with a private key.</returns>
        public static X509Certificate2 CreateCertificate(
            string storeType,
            string storePath,
            string password,
            string applicationUri,
            string applicationName,
            string subjectName,
            IList<String> domainNames,
            ushort keySize,
            DateTime startTime,
            ushort lifetimeInMonths,
            ushort hashSizeInBits,
            bool isCA,
            X509Certificate2 issuerCAKeyCert)
        {
            if (!String.IsNullOrEmpty(storeType) &&
                storeType != CertificateStoreType.Directory)
            {
                throw new NotSupportedException("Cannot create a certificate for a non directory store.");
            }

            if (issuerCAKeyCert != null)
            {
                if (!issuerCAKeyCert.HasPrivateKey)
                {
                    throw new NotSupportedException("Cannot sign with a CA certificate without a private key.");
                }

                throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported.");
            }

            // set default values.
            SetSuitableDefaults(
                ref applicationUri,
                ref applicationName,
                ref subjectName,
                ref domainNames,
                ref keySize,
                ref lifetimeInMonths,
                isCA);

            // cert generators
            SecureRandom random = new SecureRandom();
            X509V3CertificateGenerator cg = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            cg.SetSerialNumber(serialNumber);

            // build name attributes
            var nameOids = new ArrayList();
            nameOids.Add(X509Name.DC);
            nameOids.Add(X509Name.CN);

            var nameValues = new ArrayList();
            nameValues.Add(domainNames[0]);
            nameValues.Add(applicationName);

            // self signed 
            X509Name subjectDN = new X509Name(nameOids, nameValues);
            X509Name issuerDN = subjectDN;
            cg.SetIssuerDN(issuerDN);
            cg.SetSubjectDN(subjectDN);

            // valid for
            cg.SetNotBefore(startTime);
            cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths));

            // Private/Public Key
            AsymmetricCipherKeyPair subjectKeyPair;
            var keyGenerationParameters = new KeyGenerationParameters(random, keySize);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            subjectKeyPair = keyPairGenerator.GenerateKeyPair();
            cg.SetPublicKey(subjectKeyPair.Public);

            // add extensions
            // Subject key identifier
            cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false,
                new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));

            // Basic constraints
            cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA));

            // Authority Key identifier
            var issuerKeyPair = subjectKeyPair;
            var issuerSerialNumber = serialNumber;
            cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false,
                new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public),
                    new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber));

            if (!isCA)
            {
                // Key usage 
                cg.AddExtension(X509Extensions.KeyUsage, true,
                    new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature |
                        KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment));

                // Extended Key usage
                cg.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                    new ExtendedKeyUsage(new List<DerObjectIdentifier>() {
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth
                    new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth
                    }));

                // subject alternate name
                cg.AddExtension(X509Extensions.SubjectAlternativeName, false,
                    new GeneralNames(new GeneralName[] {
                    new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri),
                    new GeneralName(GeneralName.DnsName, domainNames[0])}));
            }
            else
            {
                // Key usage CA
                cg.AddExtension(X509Extensions.KeyUsage, true,
                    new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign));
            }

            // sign certificate
            ISignatureFactory signatureFactory = 
                new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random);
            Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory);

            // create pkcs12 store for cert and private key
            X509Certificate2 certificate = null;
            using (MemoryStream pfxData = new MemoryStream())
            {
                Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build();
                X509CertificateEntry[] chain = new X509CertificateEntry[1];
                string passcode = "passcode";
                chain[0] = new X509CertificateEntry(x509);
                pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain);
                pkcsStore.Save(pfxData, passcode.ToCharArray(), random);

                // merge into X509Certificate2
                certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode);
            }

            Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint);

            // add cert to the store.
            if (!String.IsNullOrEmpty(storePath))
            {
                ICertificateStore store = null;
                if (storeType == CertificateStoreType.Directory)
                {
                    using (store = new DirectoryCertificateStore())
                    {
                        store.Open(storePath);
                        store.Add(certificate);
                        store.Close();
                    }
                }
            }

            // note: this cert has a private key!
            return certificate;
        }
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>
        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword, bool addtoStore = false, string exportDirectory = null)
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();
            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;

            // create the CN using the name passed in and create a unique serial number for the cert
            var certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();
            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);
            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] {KeyPurposeID.IdKPServerAuth});
            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??
            x509Generator.SetSignatureAlgorithm("sha1WithRSA");

            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(cerKp.Private);

            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12, userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(10000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();
            store.SetCertificateEntry("Created by Fluent Management", entry);
            store.SetKeyEntry("Created by Fluent Management", keyEntry, new[] { entry });
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

             // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);
            // set up the PEM writer too
            if (exportDirectory != null)
            {
                var textWriter = new StringWriter();
                var pemWriter = new PemWriter(textWriter);
                pemWriter.WriteObject(cerKp.Private, "DESEDE", userPassword.ToCharArray(), new SecureRandom());
                pemWriter.Writer.Flush();
                string privateKeyPem = textWriter.ToString();
                using (var writer = new StreamWriter(Path.Combine(exportDirectory, cert.Thumbprint + ".pem")))
                    {
                        writer.WriteLine(privateKeyPem);
                    }
                // also export the certs - first the .pfx
                byte[] privateKeyBytes = cert.Export(X509ContentType.Pfx, userPassword);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".pfx"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(privateKeyBytes, 0, privateKeyBytes.Length);
                }
                // also export the certs - then the .cer
                byte[] publicKeyBytes = cert.Export(X509ContentType.Cert);
                using (var writer = new FileStream(Path.Combine(exportDirectory, cert.Thumbprint + ".cer"), FileMode.OpenOrCreate, FileAccess.Write))
                {
                    writer.Write(publicKeyBytes, 0, publicKeyBytes.Length);
                }
            }

            // if specified then this add this certificate to the store
            if (addtoStore)
                AddToMyStore(cert);

            return cert;
        }
        public void Load(
            Stream	input,
            char[]	password)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            Asn1Sequence obj = (Asn1Sequence) Asn1Object.FromStream(input);
            Pfx bag = new Pfx(obj);
            ContentInfo info = bag.AuthSafe;
            bool wrongPkcs12Zero = false;

            if (password != null && bag.MacData != null) // check the mac code
            {
                MacData mData = bag.MacData;
                DigestInfo dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt = mData.GetSalt();
                int itCount = mData.IterationCount.IntValue;

                byte[] data = ((Asn1OctetString) info.Content).GetOctets();

                byte[] mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, false, data);
                byte[] dig = dInfo.GetDigest();

                if (!Arrays.ConstantTimeAreEqual(mac, dig))
                {
                    if (password.Length > 0)
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");

                    // Try with incorrect zero length password
                    mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, true, data);

                    if (!Arrays.ConstantTimeAreEqual(mac, dig))
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");

                    wrongPkcs12Zero = true;
                }
            }

            keys.Clear();
            localIds.Clear();
            unmarkedKeyEntry = null;

            IList certBags = Platform.CreateArrayList();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[] octs = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence) Asn1OctetString.FromByteArray(octs));
                ContentInfo[] cis = authSafe.GetContentInfo();

                foreach (ContentInfo ci in cis)
                {
                    DerObjectIdentifier oid = ci.ContentType;

                    byte[] octets = null;
                    if (oid.Equals(PkcsObjectIdentifiers.Data))
                    {
                        octets = ((Asn1OctetString)ci.Content).GetOctets();
                    }
                    else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        if (password != null)
                        {
                            EncryptedData d = EncryptedData.GetInstance(ci.Content);
                            octets = CryptPbeData(false, d.EncryptionAlgorithm,
                                password, wrongPkcs12Zero, d.Content.GetOctets());
                        }
                    }
                    else
                    {
                        // TODO Other data types
                    }

                    if (octets != null)
                    {
                        Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                certBags.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(b.BagValue),
                                    b.BagAttributes, password, wrongPkcs12Zero);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                LoadKeyBag(PrivateKeyInfo.GetInstance(b.BagValue), b.BagAttributes);
                            }
                            else
                            {
                                // TODO Other bag types
                            }
                        }
                    }
                }
            }

            certs.Clear();
            chainCerts.Clear();
            keyCerts.Clear();

            foreach (SafeBag b in certBags)
            {
                CertBag certBag = new CertBag((Asn1Sequence)b.BagValue);
                byte[] octets = ((Asn1OctetString)certBag.CertValue).GetOctets();
                X509Certificate cert = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                IDictionary attributes = Platform.CreateHashtable();
                Asn1OctetString localId = null;
                string alias = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid = DerObjectIdentifier.GetInstance(sq[0]);
                        Asn1Set attrSet = Asn1Set.GetInstance(sq[1]);

                        if (attrSet.Count > 0)
                        {
                            // TODO We should be adding all attributes in the set
                            Asn1Encodable attr = attrSet[0];

                            // TODO We might want to "merge" attribute sets with
                            // the same OID - currently, differing values give an error
                            if (attributes.Contains(aOid.Id))
                            {
                                // OK, but the value has to be the same
                                if (!attributes[aOid.Id].Equals(attr))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                attributes.Add(aOid.Id, attr);
                            }

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                CertId certId = new CertId(cert.GetPublicKey());
                X509CertificateEntry certEntry = new X509CertificateEntry(cert, attributes);

                chainCerts[certId] = certEntry;

                if (unmarkedKeyEntry != null)
                {
                    if (keyCerts.Count == 0)
                    {
                        string name = Hex.ToHexString(certId.Id);

                        keyCerts[name] = certEntry;
                        keys[name] = unmarkedKeyEntry;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        string name = Hex.ToHexString(localId.GetOctets());

                        keyCerts[name] = certEntry;
                    }

                    if (alias != null)
                    {
                        // TODO There may have been more than one alias
                        certs[alias] = certEntry;
                    }
                }
            }
        }
		public void doTestPkcs12Store()
		{
			BigInteger mod = new BigInteger("bb1be8074e4787a8d77967f1575ef72dd7582f9b3347724413c021beafad8f32dba5168e280cbf284df722283dad2fd4abc750e3d6487c2942064e2d8d80641aa5866d1f6f1f83eec26b9b46fecb3b1c9856a303148a5cc899c642fb16f3d9d72f52526c751dc81622c420c82e2cfda70fe8d13f16cc7d6a613a5b2a2b5894d1", 16);

			MemoryStream stream = new MemoryStream(pkcs12, false);
			Pkcs12Store store = new Pkcs12StoreBuilder().Build();
			store.Load(stream, passwd);

			string pName = null;
			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			AsymmetricKeyEntry key = store.GetKey(pName);

			if (!((RsaKeyParameters) key.Key).Modulus.Equals(mod))
			{
				Fail("Modulus doesn't match.");
			}

			X509CertificateEntry[] ch = store.GetCertificateChain(pName);

			if (ch.Length != 3)
			{
				Fail("chain was wrong length");
			}

			if (!ch[0].Certificate.SerialNumber.Equals(new BigInteger("96153094170511488342715101755496684211")))
			{
				Fail("chain[0] wrong certificate.");
			}

			if (!ch[1].Certificate.SerialNumber.Equals(new BigInteger("279751514312356623147411505294772931957")))
			{
				Fail("chain[1] wrong certificate.");
			}

			if (!ch[2].Certificate.SerialNumber.Equals(new BigInteger("11341398017")))
			{
				Fail("chain[2] wrong certificate.");
			}

			//
			// save test
			//
			MemoryStream bOut = new MemoryStream();
			store.Save(bOut, passwd, new SecureRandom());

			stream = new MemoryStream(bOut.ToArray(), false);
			store.Load(stream, passwd);

			key = store.GetKey(pName);

			if (!((RsaKeyParameters)key.Key).Modulus.Equals(mod))
			{
				Fail("Modulus doesn't match.");
			}

			store.DeleteEntry(pName);

			if (store.GetKey(pName) != null)
			{
				Fail("Failed deletion test.");
			}

			//
			// cert chain test
			//
			store.SetCertificateEntry("testCert", ch[2]);

			if (store.GetCertificateChain("testCert") != null)
			{
				Fail("Failed null chain test.");
			}

			//
			// UTF 8 single cert test
			//
			stream = new MemoryStream(certUTF, false);
			store.Load(stream, "user".ToCharArray());

			if (store.GetCertificate("37") == null)
			{
				Fail("Failed to find UTF cert.");
			}

			//
			// try for a self generated certificate
			//
			RsaKeyParameters pubKey = new RsaKeyParameters(
				false,
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16));

			RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
				new BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16),
				new BigInteger("11", 16),
				new BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16),
				new BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16),
				new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16),
				new BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16),
				new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16),
				new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16));

			X509CertificateEntry[] chain = new X509CertificateEntry[] {
				CreateCert(pubKey, privKey, "*****@*****.**", "*****@*****.**")
			};

			store = new Pkcs12StoreBuilder().Build();

			store.SetKeyEntry("privateKey", new AsymmetricKeyEntry(privKey), chain);

			if (!store.ContainsAlias("privateKey") || !store.ContainsAlias("PRIVATEKEY"))
			{
				Fail("couldn't find alias privateKey");
			}

			if (store.IsCertificateEntry("privateKey"))
			{
				Fail("key identified as certificate entry");
			}

			if (!store.IsKeyEntry("privateKey") || !store.IsKeyEntry("PRIVATEKEY"))
			{
				Fail("key not identified as key entry");
			}

			if (!"privateKey".Equals(store.GetCertificateAlias(chain[0].Certificate)))
			{
				Fail("Did not return alias for key certificate privateKey");
			}

			MemoryStream store1Stream = new MemoryStream();
			store.Save(store1Stream, passwd, new SecureRandom());
			testNoExtraLocalKeyID(store1Stream.ToArray());

			//
			// no friendly name test
			//
			stream = new MemoryStream(pkcs12noFriendly, false);
			store.Load(stream, noFriendlyPassword);

			pName = null;

			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			ch = store.GetCertificateChain(pName);

			//for (int i = 0; i != ch.Length; i++)
			//{
			//	Console.WriteLine(ch[i]);
			//}

			if (ch.Length != 1)
			{
				Fail("no cert found in pkcs12noFriendly");
			}

			//
			// failure tests
			//
			ch = store.GetCertificateChain("dummy");

			store.GetCertificateChain("DUMMY");

			store.GetCertificate("dummy");

			store.GetCertificate("DUMMY");

			//
			// storage test
			//
			stream = new MemoryStream(pkcs12StorageIssue, false);
			store.Load(stream, storagePassword);

			pName = null;

			foreach (string n in store.Aliases)
			{
				if (store.IsKeyEntry(n))
				{
					pName = n;
					//break;
				}
			}

			ch = store.GetCertificateChain(pName);
			if (ch.Length != 2)
			{
				Fail("Certificate chain wrong length");
			}

			store.Save(new MemoryStream(), storagePassword, new SecureRandom());

			//
			// basic certificate check
			//
			store.SetCertificateEntry("cert", ch[1]);

			if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT"))
			{
				Fail("couldn't find alias cert");
			}

			if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT"))
			{
				Fail("cert not identified as certificate entry");
			}

			if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT"))
			{
				Fail("cert identified as key entry");
			}

			if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry)))
			{
				Fail("cert not identified as X509CertificateEntry");
			}

			if (!store.IsEntryOfType("CERT", typeof(X509CertificateEntry)))
			{
				Fail("CERT not identified as X509CertificateEntry");
			}

			if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry)))
			{
				Fail("cert identified as key entry via AsymmetricKeyEntry");
			}

			if (!"cert".Equals(store.GetCertificateAlias(ch[1].Certificate)))
			{
				Fail("Did not return alias for certificate entry");
			}

			//
			// test restoring of a certificate with private key originally as a ca certificate
			//
			store = new Pkcs12StoreBuilder().Build();

			store.SetCertificateEntry("cert", ch[0]);

			if (!store.ContainsAlias("cert") || !store.ContainsAlias("CERT"))
			{
				Fail("restore: couldn't find alias cert");
			}

			if (!store.IsCertificateEntry("cert") || !store.IsCertificateEntry("CERT"))
			{
				Fail("restore: cert not identified as certificate entry");
			}

			if (store.IsKeyEntry("cert") || store.IsKeyEntry("CERT"))
			{
				Fail("restore: cert identified as key entry");
			}

			if (store.IsEntryOfType("cert", typeof(AsymmetricKeyEntry)))
			{
				Fail("restore: cert identified as key entry via AsymmetricKeyEntry");
			}

			if (store.IsEntryOfType("CERT", typeof(AsymmetricKeyEntry)))
			{
				Fail("restore: cert identified as key entry via AsymmetricKeyEntry");
			}

			if (!store.IsEntryOfType("cert", typeof(X509CertificateEntry)))
			{
				Fail("restore: cert not identified as X509CertificateEntry");
			}

			//
			// test of reading incorrect zero-length encoding
			//
			stream = new MemoryStream(pkcs12nopass, false);
			store.Load(stream, "".ToCharArray());
		}
        public void SetCertificateEntry(
            string					alias,
            X509CertificateEntry	certEntry)
        {
            if (alias == null)
                throw new ArgumentNullException("alias");
            if (certEntry == null)
                throw new ArgumentNullException("certEntry");
            if (keys[alias] != null)
                throw new ArgumentException("There is a key entry with the name " + alias + ".");

            certs[alias] = certEntry;
            chainCerts[new CertId(certEntry.Certificate.GetPublicKey())] = certEntry;
        }
        public void Load(
            Stream input,
            char[]  password)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }

            Asn1Sequence obj             = (Asn1Sequence)Asn1Object.FromStream(input);
            Pfx          bag             = new Pfx(obj);
            ContentInfo  info            = bag.AuthSafe;
            bool         unmarkedKey     = false;
            bool         wrongPkcs12Zero = false;

            if (bag.MacData != null)             // check the mac code
            {
                MacData             mData = bag.MacData;
                DigestInfo          dInfo = mData.Mac;
                AlgorithmIdentifier algId = dInfo.AlgorithmID;
                byte[] salt    = mData.GetSalt();
                int    itCount = mData.IterationCount.IntValue;

                byte[] data = ((Asn1OctetString)info.Content).GetOctets();

                byte[] mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, false, data);
                byte[] dig = dInfo.GetDigest();

                if (!Arrays.AreEqual(mac, dig))
                {
                    if (password.Length > 0)
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }

                    // Try with incorrect zero length password
                    mac = CalculatePbeMac(algId.ObjectID, salt, itCount, password, true, data);

                    if (!Arrays.AreEqual(mac, dig))
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }

                    wrongPkcs12Zero = true;
                }
            }

            keys.Clear();
            localIds.Clear();

            ArrayList chain = new ArrayList();

            if (info.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[]            octs     = ((Asn1OctetString)info.Content).GetOctets();
                AuthenticatedSafe authSafe = new AuthenticatedSafe(
                    (Asn1Sequence)Asn1OctetString.FromByteArray(octs));
                ContentInfo[] cis = authSafe.GetContentInfo();

                foreach (ContentInfo ci in cis)
                {
                    DerObjectIdentifier oid = ci.ContentType;

                    if (oid.Equals(PkcsObjectIdentifiers.Data))
                    {
                        byte[]       octets = ((Asn1OctetString)ci.Content).GetOctets();
                        Asn1Sequence seq    = (Asn1Sequence)Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);
                                string             alias      = null;
                                Asn1OctetString    localId    = null;

                                if (b.BagAttributes != null)
                                {
                                    foreach (Asn1Sequence sq in b.BagAttributes)
                                    {
                                        DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                        Asn1Set             attrSet = (Asn1Set)sq[1];
                                        Asn1Encodable       attr    = null;

                                        if (attrSet.Count > 0)
                                        {
                                            // TODO We should be adding all attributes in the set
                                            attr = attrSet[0];

                                            // TODO We might want to "merge" attribute sets with
                                            // the same OID - currently, differing values give an error
                                            if (attributes.ContainsKey(aOid.Id))
                                            {
                                                // OK, but the value has to be the same
                                                if (!attributes[aOid.Id].Equals(attr))
                                                {
                                                    throw new IOException("attempt to add existing attribute with different value");
                                                }
                                            }
                                            else
                                            {
                                                attributes.Add(aOid.Id, attr);
                                            }

                                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                            {
                                                alias = ((DerBmpString)attr).GetString();
                                                // TODO Do these in a separate loop, just collect aliases here
                                                keys[alias] = pkcs12Key;
                                            }
                                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                            {
                                                localId = (Asn1OctetString)attr;
                                            }
                                        }
                                    }
                                }

                                if (localId != null)
                                {
                                    byte[] hex  = Hex.Encode(localId.GetOctets());
                                    string name = Encoding.ASCII.GetString(hex, 0, hex.Length);

                                    if (alias == null)
                                    {
                                        keys[name] = pkcs12Key;
                                    }
                                    else
                                    {
                                        // TODO There may have been more than one alias
                                        localIds[alias] = name;
                                    }
                                }
                                else
                                {
                                    unmarkedKey      = true;
                                    keys["unmarked"] = pkcs12Key;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else if (oid.Equals(PkcsObjectIdentifiers.EncryptedData))
                    {
                        EncryptedData d      = EncryptedData.GetInstance(ci.Content);
                        byte[]        octets = CryptPbeData(false, d.EncryptionAlgorithm,
                                                            password, wrongPkcs12Zero, d.Content.GetOctets());
                        Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(octets);

                        foreach (Asn1Sequence subSeq in seq)
                        {
                            SafeBag b = new SafeBag(subSeq);

                            if (b.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                chain.Add(b);
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                EncryptedPrivateKeyInfo eIn      = EncryptedPrivateKeyInfo.GetInstance(b.BagValue);
                                PrivateKeyInfo          privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(
                                    password, wrongPkcs12Zero, eIn);
                                AsymmetricKeyParameter privKey = PrivateKeyFactory.CreateKey(privInfo);

                                //
                                // set the attributes on the key
                                //
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);
                                string             alias      = null;
                                Asn1OctetString    localId    = null;

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                    Asn1Set             attrSet = (Asn1Set)sq[1];
                                    Asn1Encodable       attr    = null;

                                    if (attrSet.Count > 0)
                                    {
                                        // TODO We should be adding all attributes in the set
                                        attr = attrSet[0];

                                        // TODO We might want to "merge" attribute sets with
                                        // the same OID - currently, differing values give an error
                                        if (attributes.ContainsKey(aOid.Id))
                                        {
                                            // OK, but the value has to be the same
                                            if (!attributes[aOid.Id].Equals(attr))
                                            {
                                                throw new IOException("attempt to add existing attribute with different value");
                                            }
                                        }
                                        else
                                        {
                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias = ((DerBmpString)attr).GetString();
                                            // TODO Do these in a separate loop, just collect aliases here
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                // TODO Should we be checking localIds != null here
                                // as for PkcsObjectIdentifiers.Data version above?

                                byte[] hex  = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex, 0, hex.Length);

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    // TODO There may have been more than one alias
                                    localIds[alias] = name;
                                }
                            }
                            else if (b.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                PrivateKeyInfo         privKeyInfo = PrivateKeyInfo.GetInstance(b.BagValue);
                                AsymmetricKeyParameter privKey     = PrivateKeyFactory.CreateKey(privKeyInfo);

                                //
                                // set the attributes on the key
                                //
                                string             alias      = null;
                                Asn1OctetString    localId    = null;
                                Hashtable          attributes = new Hashtable();
                                AsymmetricKeyEntry pkcs12Key  = new AsymmetricKeyEntry(privKey, attributes);

                                foreach (Asn1Sequence sq in b.BagAttributes)
                                {
                                    DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                                    Asn1Set             attrSet = (Asn1Set)sq[1];
                                    Asn1Encodable       attr    = null;

                                    if (attrSet.Count > 0)
                                    {
                                        // TODO We should be adding all attributes in the set
                                        attr = attrSet[0];

                                        // TODO We might want to "merge" attribute sets with
                                        // the same OID - currently, differing values give an error
                                        if (attributes.ContainsKey(aOid.Id))
                                        {
                                            // OK, but the value has to be the same
                                            if (!attributes[aOid.Id].Equals(attr))
                                            {
                                                throw new IOException("attempt to add existing attribute with different value");
                                            }
                                        }
                                        else
                                        {
                                            attributes.Add(aOid.Id, attr);
                                        }

                                        if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                                        {
                                            alias = ((DerBmpString)attr).GetString();
                                            // TODO Do these in a separate loop, just collect aliases here
                                            keys[alias] = pkcs12Key;
                                        }
                                        else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                                        {
                                            localId = (Asn1OctetString)attr;
                                        }
                                    }
                                }

                                // TODO Should we be checking localIds != null here
                                // as for PkcsObjectIdentifiers.Data version above?

                                byte[] hex  = Hex.Encode(localId.GetOctets());
                                string name = Encoding.ASCII.GetString(hex, 0, hex.Length);

                                if (alias == null)
                                {
                                    keys[name] = pkcs12Key;
                                }
                                else
                                {
                                    // TODO There may have been more than one alias
                                    localIds[alias] = name;
                                }
                            }
                            else
                            {
                                Console.WriteLine("extra " + b.BagID);
                                Console.WriteLine("extra " + Asn1Dump.DumpAsString(b));
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("extra " + oid);
                        Console.WriteLine("extra " + Asn1Dump.DumpAsString(ci.Content));
                    }
                }
            }

            certs.Clear();
            chainCerts.Clear();
            keyCerts.Clear();

            foreach (SafeBag b in chain)
            {
                CertBag         cb     = new CertBag((Asn1Sequence)b.BagValue);
                byte[]          octets = ((Asn1OctetString)cb.CertValue).GetOctets();
                X509Certificate cert   = new X509CertificateParser().ReadCertificate(octets);

                //
                // set the attributes
                //
                Hashtable       attributes = new Hashtable();
                Asn1OctetString localId    = null;
                string          alias      = null;

                if (b.BagAttributes != null)
                {
                    foreach (Asn1Sequence sq in b.BagAttributes)
                    {
                        DerObjectIdentifier aOid    = (DerObjectIdentifier)sq[0];
                        Asn1Set             attrSet = (Asn1Set)sq[1];

                        if (attrSet.Count > 0)
                        {
                            // TODO We should be adding all attributes in the set
                            Asn1Encodable attr = attrSet[0];

                            // TODO We might want to "merge" attribute sets with
                            // the same OID - currently, differing values give an error
                            if (attributes.ContainsKey(aOid.Id))
                            {
                                // OK, but the value has to be the same
                                if (!attributes[aOid.Id].Equals(attr))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                attributes.Add(aOid.Id, attr);
                            }

                            if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                alias = ((DerBmpString)attr).GetString();
                            }
                            else if (aOid.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                localId = (Asn1OctetString)attr;
                            }
                        }
                    }
                }

                CertId certId = new CertId(cert.GetPublicKey());
                X509CertificateEntry pkcs12Cert = new X509CertificateEntry(cert, attributes);

                chainCerts[certId] = pkcs12Cert;

                if (unmarkedKey)
                {
                    if (keyCerts.Count == 0)
                    {
                        byte[] hex  = Hex.Encode(certId.Id);
                        string name = Encoding.ASCII.GetString(hex, 0, hex.Length);

                        keyCerts[name] = pkcs12Cert;

                        object temp = keys["unmarked"];
                        keys.Remove("unmarked");
                        keys[name] = temp;
                    }
                }
                else
                {
                    if (localId != null)
                    {
                        byte[] hex  = Hex.Encode(localId.GetOctets());
                        string name = Encoding.ASCII.GetString(hex, 0, hex.Length);

                        keyCerts[name] = pkcs12Cert;
                    }

                    if (alias != null)
                    {
                        // TODO There may have been more than one alias
                        certs[alias] = pkcs12Cert;
                    }
                }
            }
        }
        /// <summary>
        /// Static method used to create a certificate and return as a .net object
        /// </summary>
        public static X509Certificate2 Create(string name, DateTime start, DateTime end, string userPassword,
                                              bool addtoStore = false)
        {
            // generate a key pair using RSA
            var generator = new RsaKeyPairGenerator();
            // keys have to be a minimum of 2048 bits for Azure
            generator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));
            AsymmetricCipherKeyPair cerKp = generator.GenerateKeyPair();
            // get a copy of the private key
            AsymmetricKeyParameter privateKey = cerKp.Private;

            // create the CN using the name passed in and create a unique serial number for the cert
            var certName = new X509Name("CN=" + name);
            BigInteger serialNo = BigInteger.ProbablePrime(120, new Random());

            // start the generator and set CN/DN and serial number and valid period
            var x509Generator = new X509V3CertificateGenerator();
            x509Generator.SetSerialNumber(serialNo);
            x509Generator.SetSubjectDN(certName);
            x509Generator.SetIssuerDN(certName);
            x509Generator.SetNotBefore(start);
            x509Generator.SetNotAfter(end);
            // add the server authentication key usage
            var keyUsage = new KeyUsage(KeyUsage.KeyEncipherment);
            x509Generator.AddExtension(X509Extensions.KeyUsage, false, keyUsage.ToAsn1Object());
            var extendedKeyUsage = new ExtendedKeyUsage(new[] {KeyPurposeID.IdKPServerAuth});
            x509Generator.AddExtension(X509Extensions.ExtendedKeyUsage, true, extendedKeyUsage.ToAsn1Object());
            // algorithm can only be SHA1 ??
            x509Generator.SetSignatureAlgorithm("sha1WithRSA");
            // Set the key pair
            x509Generator.SetPublicKey(cerKp.Public);
            X509Certificate certificate = x509Generator.Generate(cerKp.Private);

            // export the certificate bytes
            byte[] certStream = DotNetUtilities.ToX509Certificate(certificate).Export(X509ContentType.Pkcs12,
                                                                                      userPassword);

            // build the key parameter and the certificate entry
            var keyEntry = new AsymmetricKeyEntry(privateKey);
            var entry = new X509CertificateEntry(certificate);
            // build the PKCS#12 store to encapsulate the certificate
            var builder = new Pkcs12StoreBuilder();
            builder.SetUseDerEncoding(true);
            builder.SetCertAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.SetKeyAlgorithm(PkcsObjectIdentifiers.Sha1WithRsaEncryption);
            builder.Build();
            // create a memorystream to hold the output
            var stream = new MemoryStream(2000);
            // create the individual store and set two entries for cert and key
            var store = new Pkcs12Store();
            store.SetCertificateEntry("Elastacloud Test Certificate", entry);
            store.SetKeyEntry("Elastacloud Test Certificate", keyEntry, new[] {entry});
            store.Save(stream, userPassword.ToCharArray(), new SecureRandom());

            // Create the equivalent C# representation
            var cert = new X509Certificate2(stream.GetBuffer(), userPassword, X509KeyStorageFlags.Exportable);
            // if specified then this add this certificate to the store
            if (addtoStore)
                AddToMyStore(cert);

            return cert;
        }
 public static X509CertificateEntry[] WrapX509Certificates(params X509Certificate[] certs)
 {
     var entries = new X509CertificateEntry[certs.Length];
     for (int i = 0; i < certs.Length; i++)
     {
         entries[i] = new X509CertificateEntry(certs[i]);
     }
     return entries;
 }
        private static byte[] GeneratePkcs12(AsymmetricCipherKeyPair keys, Org.BouncyCastle.X509.X509Certificate cert, string friendlyName, string password,
            Dictionary<string, Org.BouncyCastle.X509.X509Certificate> chain)
        {
            var chainCerts = new List<X509CertificateEntry>();

            // Create the PKCS12 store
            Pkcs12Store store = new Pkcs12StoreBuilder().Build();

            // Add a Certificate entry
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);
            store.SetCertificateEntry(friendlyName, certEntry); // use DN as the Alias.
            //chainCerts.Add(certEntry);

            // Add chain entries
            var additionalCertsAsBytes = new List<byte[]>();
            if (chain != null && chain.Count > 0)
            {
                foreach (var additionalCert in chain)
                {
                    additionalCertsAsBytes.Add(additionalCert.Value.GetEncoded());
                }
            }

            if (chain != null && chain.Count > 0)
            {
                var addicionalCertsAsX09Chain = BuildCertificateChainBC(cert.GetEncoded(), additionalCertsAsBytes);

                foreach (var addCertAsX09 in addicionalCertsAsX09Chain)
                {
                    chainCerts.Add(new X509CertificateEntry(addCertAsX09));
                }
            }

            // Add a key entry
            AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(keys.Private);

            // no chain
            store.SetKeyEntry(friendlyName, keyEntry, new X509CertificateEntry[] { certEntry });

            using (var memoryStream = new MemoryStream())
            {
                store.Save(memoryStream, password.ToCharArray(), new SecureRandom());
                return memoryStream.ToArray();
            }
        }
        public X509Certificate2 CreateSelfSignedCertificate(string subjectName, string issuerName)
        {
            // Generating Random Numbers
            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);

            // The Certificate Generator
            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();

            // Serial Number
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);
            certificateGenerator.SetSerialNumber(serialNumber);

            // Signature Algorithm
            const string signatureAlgorithm = "SHA512withRSA";
            certificateGenerator.SetSignatureAlgorithm(signatureAlgorithm);

            // Issuer and Subject Name
            X509Name subjectDN = new X509Name("CN=" + subjectName);
            X509Name issuerDN = new X509Name("CN=" + issuerName);
            certificateGenerator.SetIssuerDN(issuerDN);
            certificateGenerator.SetSubjectDN(subjectDN);

            // Valid For
            var date = DateTime.Now;
            DateTime notBefore = date.AddDays(-1);
            DateTime notAfter = notBefore.AddYears(2);

            certificateGenerator.SetNotBefore(notBefore);
            certificateGenerator.SetNotAfter(notAfter);

            // Subject Public Key
            const int keyStrength = 2048;
            var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(keyGenerationParameters);
            var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

            certificateGenerator.SetPublicKey(subjectKeyPair.Public);

            // Selfsign certificate
            Org.BouncyCastle.X509.X509Certificate certificate = certificateGenerator.Generate(subjectKeyPair.Private, random);

            // Convert to .NET cert // http://blog.differentpla.net/post/20/how-do-i-convert-a-bouncy-castle-certificate-to-a-net-certificate-
            var store = new Pkcs12Store();
            string friendlyName = certificate.SubjectDN.ToString();
            var certificateEntry = new X509CertificateEntry(certificate);
            store.SetCertificateEntry(friendlyName, certificateEntry);
            store.SetKeyEntry(friendlyName, new AsymmetricKeyEntry(subjectKeyPair.Private), new[] { certificateEntry });
            
            const string password = "******"; // required to export
            byte[] certBytes;
            using (var stream = new MemoryStream())
            {
                store.Save(stream, password.ToCharArray(), random);
                certBytes = stream.ToArray();
            }

            var convertedCertificate =
                new X509Certificate2(certBytes, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            
            return convertedCertificate;
        }
		private void testSupportedTypes(AsymmetricKeyEntry privKey, X509CertificateEntry[] chain)
		{
			basicStoreTest(privKey, chain,
				PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc,
				PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc );
			basicStoreTest(privKey, chain,
				PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc,
				PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc );
		}
        //            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, UnrecoverableKeyException
        private void keyStoreTest(
			IAsymmetricKeyParameter	sKey,
			IAsymmetricKeyParameter	vKey)
        {
            //
            // keystore test
            //
            //			KeyStore ks = KeyStore.GetInstance("JKS");
            //			ks.Load(null, null);
            Pkcs12StoreBuilder ksBuilder = new Pkcs12StoreBuilder();
            Pkcs12Store ks = ksBuilder.Build();

            //
            // create the certificate - version 3
            //
            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

            certGen.SetSerialNumber(BigInteger.One);
            certGen.SetIssuerDN(new X509Name("CN=Test"));
            certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
            certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
            certGen.SetSubjectDN(new X509Name("CN=Test"));
            certGen.SetPublicKey(vKey);
            certGen.SetSignatureAlgorithm("GOST3411withGOST3410");

            X509Certificate cert = certGen.Generate(sKey);
            X509CertificateEntry certEntry = new X509CertificateEntry(cert);

            //	        ks.SetKeyEntry("gost", sKey, "gost".ToCharArray(), new X509Certificate[] { cert });
            ks.SetKeyEntry("gost", new AsymmetricKeyEntry(sKey), new X509CertificateEntry[] { certEntry });

            MemoryStream bOut = new MemoryStream();

            ks.Save(bOut, "gost".ToCharArray(), new SecureRandom());

            //	        ks = KeyStore.getInstance("JKS");
            ks = ksBuilder.Build();

            ks.Load(new MemoryStream(bOut.ToArray(), false), "gost".ToCharArray());

            //	        IAsymmetricKeyParameter gKey = (AsymmetricKeyParameter)ks.GetKey("gost", "gost".ToCharArray());
            //	        AsymmetricKeyEntry gKeyEntry = (AsymmetricKeyEntry)
                ks.GetKey("gost");
        }
		private void testNoExtraLocalKeyID(byte[] store1data)
		{
			IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("RSA");
			kpg.Init(new RsaKeyGenerationParameters(
				BigInteger.ValueOf(0x10001), new SecureRandom(), 512, 25));

			AsymmetricCipherKeyPair newPair =  kpg.GenerateKeyPair();

			Pkcs12Store store1 = new Pkcs12StoreBuilder().Build();
			store1.Load(new MemoryStream(store1data, false), passwd);

			Pkcs12Store store2 = new Pkcs12StoreBuilder().Build();

			AsymmetricKeyEntry k1 = store1.GetKey("privatekey");
			X509CertificateEntry[] chain1 = store1.GetCertificateChain("privatekey");

			X509CertificateEntry[] chain2 = new X509CertificateEntry[chain1.Length + 1];

			Array.Copy(chain1, 0, chain2, 1, chain1.Length);

			chain2[0] = CreateCert(newPair.Public, k1.Key, "*****@*****.**", "*****@*****.**");

			if (chain1[0][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] == null)
			{
				Fail("localKeyID not found initially");
			}

			store2.SetKeyEntry("new", new AsymmetricKeyEntry(newPair.Private), chain2);

			MemoryStream bOut = new MemoryStream();

			store2.Save(bOut, passwd, new SecureRandom());

			store2.Load(new MemoryStream(bOut.ToArray(), false), passwd);

			chain2 = store2.GetCertificateChain("new");

			if (chain2[1][PkcsObjectIdentifiers.Pkcs9AtLocalKeyID] != null)
			{
				Fail("localKeyID found after save");
			}
		}
Exemple #37
0
        /// <summary>
        /// Generates and saves a new certificate to the default CommandServer plx path
        /// </summary>
        public void Generate() {
            RsaKeyPairGenerator rsaKeyPairGenerator = new RsaKeyPairGenerator();
            rsaKeyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()), 2048));

            AsymmetricCipherKeyPair asymmetricCipherKeyPair = rsaKeyPairGenerator.GenerateKeyPair();

            X509Name certificateName = new X509Name("CN=" + Environment.MachineName);
            BigInteger serialNumber = BigInteger.ProbablePrime(120, new SecureRandom());

            X509V3CertificateGenerator certificateGenerator = new X509V3CertificateGenerator();
            certificateGenerator.SetSerialNumber(serialNumber);
            certificateGenerator.SetSubjectDN(certificateName);
            certificateGenerator.SetIssuerDN(certificateName);
            certificateGenerator.SetNotAfter(DateTime.Now.AddYears(1));
            certificateGenerator.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
            certificateGenerator.SetSignatureAlgorithm("Sha1WithRSA");
            certificateGenerator.SetPublicKey(asymmetricCipherKeyPair.Public);

            certificateGenerator.AddExtension(
                X509Extensions.AuthorityKeyIdentifier.Id,
                false,
                new AuthorityKeyIdentifier(
                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(asymmetricCipherKeyPair.Public),
                    new GeneralNames(new GeneralName(certificateName)),
                    serialNumber
                )
            );

            certificateGenerator.AddExtension(
                X509Extensions.ExtendedKeyUsage.Id,
                false,
                new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth)
            );

            X509CertificateEntry certificateEntry = new X509CertificateEntry(certificateGenerator.Generate(asymmetricCipherKeyPair.Private));

            Pkcs12Store store = new Pkcs12Store();
            store.SetCertificateEntry(certificateName.ToString(), certificateEntry);
            store.SetKeyEntry(certificateName.ToString(), new AsymmetricKeyEntry(asymmetricCipherKeyPair.Private), new[] {
                certificateEntry
            });

            // Save to the file system
            using (var filestream = new FileStream(Defines.CertificatesDirectoryCommandServerPfx.FullName, FileMode.Create, FileAccess.ReadWrite)) {
                store.Save(filestream, this.Password.ToCharArray(), new SecureRandom());
            }
        }
		private void doTestParams(
			byte[]	ecParameterEncoded,
			bool	compress)
		{
//			string keyStorePass = "******";
			Asn1Sequence seq = (Asn1Sequence) Asn1Object.FromByteArray(ecParameterEncoded);
			X9ECParameters x9 = new X9ECParameters(seq);
			AsymmetricCipherKeyPair kp = null;
			bool success = false;
			while (!success)
			{
				IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator("ECDSA");
//				kpg.Init(new ECParameterSpec(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()));
				ECDomainParameters ecParams = new ECDomainParameters(
					x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed());
				kpg.Init(new ECKeyGenerationParameters(ecParams, new SecureRandom()));
				kp = kpg.GenerateKeyPair();
				// The very old Problem... we need a certificate chain to
				// save a private key...
				ECPublicKeyParameters pubKey = (ECPublicKeyParameters) kp.Public;

				if (!compress)
				{
					//pubKey.setPointFormat("UNCOMPRESSED");
					pubKey = SetPublicUncompressed(pubKey);
				}

				byte[] x = pubKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned();
				byte[] y = pubKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned();
				if (x.Length == y.Length)
				{
					success = true;
				}
			}

			// The very old Problem... we need a certificate chain to
			// save a private key...

			X509CertificateEntry[] chain = new X509CertificateEntry[] {
				new X509CertificateEntry(GenerateSelfSignedSoftECCert(kp, compress))
			};

//			KeyStore keyStore = KeyStore.getInstance("BKS");
//			keyStore.load(null, keyStorePass.ToCharArray());
			Pkcs12Store keyStore = new Pkcs12StoreBuilder().Build();

			keyStore.SetCertificateEntry("ECCert", chain[0]);

			ECPrivateKeyParameters privateECKey = (ECPrivateKeyParameters) kp.Private;
			keyStore.SetKeyEntry("ECPrivKey", new AsymmetricKeyEntry(privateECKey), chain);

			// Test ec sign / verify
			ECPublicKeyParameters pub = (ECPublicKeyParameters) kp.Public;
//			string oldPrivateKey = new string(Hex.encode(privateECKey.getEncoded()));
			byte[] oldPrivateKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateECKey).GetDerEncoded();
			string oldPrivateKey = Hex.ToHexString(oldPrivateKeyBytes);
//			string oldPublicKey = new string(Hex.encode(pub.getEncoded()));
			byte[] oldPublicKeyBytes = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub).GetDerEncoded();
			string oldPublicKey = Hex.ToHexString(oldPublicKeyBytes);
			ECPrivateKeyParameters newKey = (ECPrivateKeyParameters)
				keyStore.GetKey("ECPrivKey").Key;
			ECPublicKeyParameters newPubKey = (ECPublicKeyParameters)
				keyStore.GetCertificate("ECCert").Certificate.GetPublicKey();

			if (!compress)
			{
				// TODO Private key compression?
				//newKey.setPointFormat("UNCOMPRESSED");
				//newPubKey.setPointFormat("UNCOMPRESSED");
				newPubKey = SetPublicUncompressed(newPubKey);
			}

//			string newPrivateKey = new string(Hex.encode(newKey.getEncoded()));
			byte[] newPrivateKeyBytes = PrivateKeyInfoFactory.CreatePrivateKeyInfo(newKey).GetDerEncoded();
			string newPrivateKey = Hex.ToHexString(newPrivateKeyBytes);
//			string newPublicKey = new string(Hex.encode(newPubKey.getEncoded()));
			byte[] newPublicKeyBytes = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(newPubKey).GetDerEncoded();
			string newPublicKey = Hex.ToHexString(newPublicKeyBytes);

			if (!oldPrivateKey.Equals(newPrivateKey))
//			if (!privateECKey.Equals(newKey))
			{
				Fail("failed private key comparison");
			}

			if (!oldPublicKey.Equals(newPublicKey))
//			if (!pub.Equals(newPubKey))
			{
				Fail("failed public key comparison");
			}
		}
Exemple #39
0
        public void Load(Stream input, char[] password)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            Asn1Sequence seq             = (Asn1Sequence)Asn1Object.FromStream(input);
            Pfx          pfx             = new Pfx(seq);
            ContentInfo  authSafe        = pfx.AuthSafe;
            bool         wrongPkcs12Zero = false;

            if (password != null && pfx.MacData != null)
            {
                MacData             macData     = pfx.MacData;
                DigestInfo          mac         = macData.Mac;
                AlgorithmIdentifier algorithmID = mac.AlgorithmID;
                byte[] salt     = macData.GetSalt();
                int    intValue = macData.IterationCount.IntValue;
                byte[] octets   = ((Asn1OctetString)authSafe.Content).GetOctets();
                byte[] a        = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, false, octets);
                byte[] digest   = mac.GetDigest();
                if (!Arrays.ConstantTimeAreEqual(a, digest))
                {
                    if (password.Length > 0)
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }
                    a = Pkcs12Store.CalculatePbeMac(algorithmID.ObjectID, salt, intValue, password, true, octets);
                    if (!Arrays.ConstantTimeAreEqual(a, digest))
                    {
                        throw new IOException("PKCS12 key store MAC invalid - wrong password or corrupted file.");
                    }
                    wrongPkcs12Zero = true;
                }
            }
            this.keys.Clear();
            this.localIds.Clear();
            this.unmarkedKeyEntry = null;
            IList list = Platform.CreateArrayList();

            if (authSafe.ContentType.Equals(PkcsObjectIdentifiers.Data))
            {
                byte[]            octets2           = ((Asn1OctetString)authSafe.Content).GetOctets();
                AuthenticatedSafe authenticatedSafe = new AuthenticatedSafe((Asn1Sequence)Asn1Object.FromByteArray(octets2));
                ContentInfo[]     contentInfo       = authenticatedSafe.GetContentInfo();
                ContentInfo[]     array             = contentInfo;
                for (int i = 0; i < array.Length; i++)
                {
                    ContentInfo         contentInfo2 = array[i];
                    DerObjectIdentifier contentType  = contentInfo2.ContentType;
                    byte[] array2 = null;
                    if (contentType.Equals(PkcsObjectIdentifiers.Data))
                    {
                        array2 = ((Asn1OctetString)contentInfo2.Content).GetOctets();
                    }
                    else if (contentType.Equals(PkcsObjectIdentifiers.EncryptedData) && password != null)
                    {
                        EncryptedData instance = EncryptedData.GetInstance(contentInfo2.Content);
                        array2 = Pkcs12Store.CryptPbeData(false, instance.EncryptionAlgorithm, password, wrongPkcs12Zero, instance.Content.GetOctets());
                    }
                    if (array2 != null)
                    {
                        Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(array2);
                        foreach (Asn1Sequence seq2 in asn1Sequence)
                        {
                            SafeBag safeBag = new SafeBag(seq2);
                            if (safeBag.BagID.Equals(PkcsObjectIdentifiers.CertBag))
                            {
                                list.Add(safeBag);
                            }
                            else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag))
                            {
                                this.LoadPkcs8ShroudedKeyBag(EncryptedPrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes, password, wrongPkcs12Zero);
                            }
                            else if (safeBag.BagID.Equals(PkcsObjectIdentifiers.KeyBag))
                            {
                                this.LoadKeyBag(PrivateKeyInfo.GetInstance(safeBag.BagValue), safeBag.BagAttributes);
                            }
                        }
                    }
                }
            }
            this.certs.Clear();
            this.chainCerts.Clear();
            this.keyCerts.Clear();
            foreach (SafeBag safeBag2 in list)
            {
                CertBag         certBag         = new CertBag((Asn1Sequence)safeBag2.BagValue);
                byte[]          octets3         = ((Asn1OctetString)certBag.CertValue).GetOctets();
                X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(octets3);
                IDictionary     dictionary      = Platform.CreateHashtable();
                Asn1OctetString asn1OctetString = null;
                string          text            = null;
                if (safeBag2.BagAttributes != null)
                {
                    foreach (Asn1Sequence asn1Sequence2 in safeBag2.BagAttributes)
                    {
                        DerObjectIdentifier instance2 = DerObjectIdentifier.GetInstance(asn1Sequence2[0]);
                        Asn1Set             instance3 = Asn1Set.GetInstance(asn1Sequence2[1]);
                        if (instance3.Count > 0)
                        {
                            Asn1Encodable asn1Encodable = instance3[0];
                            if (dictionary.Contains(instance2.Id))
                            {
                                if (!dictionary[instance2.Id].Equals(asn1Encodable))
                                {
                                    throw new IOException("attempt to add existing attribute with different value");
                                }
                            }
                            else
                            {
                                dictionary.Add(instance2.Id, asn1Encodable);
                            }
                            if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtFriendlyName))
                            {
                                text = ((DerBmpString)asn1Encodable).GetString();
                            }
                            else if (instance2.Equals(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID))
                            {
                                asn1OctetString = (Asn1OctetString)asn1Encodable;
                            }
                        }
                    }
                }
                Pkcs12Store.CertId   certId = new Pkcs12Store.CertId(x509Certificate.GetPublicKey());
                X509CertificateEntry value  = new X509CertificateEntry(x509Certificate, dictionary);
                this.chainCerts[certId] = value;
                if (this.unmarkedKeyEntry != null)
                {
                    if (this.keyCerts.Count == 0)
                    {
                        string text2 = Hex.ToHexString(certId.Id);
                        this.keyCerts[text2] = value;
                        this.keys[text2]     = this.unmarkedKeyEntry;
                    }
                }
                else
                {
                    if (asn1OctetString != null)
                    {
                        string key = Hex.ToHexString(asn1OctetString.GetOctets());
                        this.keyCerts[key] = value;
                    }
                    if (text != null)
                    {
                        this.certs[text] = value;
                    }
                }
            }
        }