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; } }
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; }
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; }
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); }
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]; } }
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()); }
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; } } } }
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); }
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); }
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"); } }
/// <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"); } }
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; } } } }