summary refs log tree commit diff
path: root/crypto/src/pkcs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/pkcs')
-rw-r--r--crypto/src/pkcs/EncryptedPrivateKeyInfoFactory.cs38
-rw-r--r--crypto/src/pkcs/PKCS12StoreBuilder.cs11
-rw-r--r--crypto/src/pkcs/Pkcs12Store.cs34
3 files changed, 78 insertions, 5 deletions
diff --git a/crypto/src/pkcs/EncryptedPrivateKeyInfoFactory.cs b/crypto/src/pkcs/EncryptedPrivateKeyInfoFactory.cs
index b6b7bac65..000eb7ae5 100644
--- a/crypto/src/pkcs/EncryptedPrivateKeyInfoFactory.cs
+++ b/crypto/src/pkcs/EncryptedPrivateKeyInfoFactory.cs
@@ -60,5 +60,43 @@ namespace Org.BouncyCastle.Pkcs
             AlgorithmIdentifier algID = new AlgorithmIdentifier(oid, pbeParameters);
             return new EncryptedPrivateKeyInfo(algID, encoding);
         }
+
+        public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
+            DerObjectIdentifier cipherAlgorithm,
+            DerObjectIdentifier prfAlgorithm,
+            char[] passPhrase,
+            byte[] salt,
+            int iterationCount,
+            SecureRandom random,
+            AsymmetricKeyParameter key)
+        {
+            return CreateEncryptedPrivateKeyInfo(
+                cipherAlgorithm, prfAlgorithm, passPhrase, salt, iterationCount, random,
+                PrivateKeyInfoFactory.CreatePrivateKeyInfo(key));
+        }
+
+        public static EncryptedPrivateKeyInfo CreateEncryptedPrivateKeyInfo(
+            DerObjectIdentifier cipherAlgorithm,
+            DerObjectIdentifier prfAlgorithm,
+            char[] passPhrase,
+            byte[] salt,
+            int iterationCount,
+            SecureRandom random,
+            PrivateKeyInfo keyInfo)
+        {
+            IBufferedCipher cipher = CipherUtilities.GetCipher(cipherAlgorithm) as IBufferedCipher;
+            if (cipher == null)
+                throw new Exception("Unknown encryption algorithm: " + cipherAlgorithm);
+
+            Asn1Encodable pbeParameters = PbeUtilities.GenerateAlgorithmParameters(
+                cipherAlgorithm, prfAlgorithm, salt, iterationCount, random);
+            ICipherParameters cipherParameters = PbeUtilities.GenerateCipherParameters(
+                PkcsObjectIdentifiers.IdPbeS2, passPhrase, pbeParameters);
+            cipher.Init(true, cipherParameters);
+            byte[] encoding = cipher.DoFinal(keyInfo.GetEncoded());
+
+            AlgorithmIdentifier algID = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPbeS2, pbeParameters);
+            return new EncryptedPrivateKeyInfo(algID, encoding);
+        }
     }
 }
diff --git a/crypto/src/pkcs/PKCS12StoreBuilder.cs b/crypto/src/pkcs/PKCS12StoreBuilder.cs
index c8fa0f603..b61a9ea63 100644
--- a/crypto/src/pkcs/PKCS12StoreBuilder.cs
+++ b/crypto/src/pkcs/PKCS12StoreBuilder.cs
@@ -9,6 +9,8 @@ namespace Org.BouncyCastle.Pkcs
 	{
 		private DerObjectIdentifier	keyAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
 		private DerObjectIdentifier	certAlgorithm = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
+		private DerObjectIdentifier keyPrfAlgorithm = null;
+		private DerObjectIdentifier certPrfAlgorithm = null;
 		private bool useDerEncoding = false;
 
 		public Pkcs12StoreBuilder()
@@ -17,7 +19,7 @@ namespace Org.BouncyCastle.Pkcs
 
 		public Pkcs12Store Build()
 		{
-			return new Pkcs12Store(keyAlgorithm, certAlgorithm, useDerEncoding);
+			return new Pkcs12Store(keyAlgorithm, keyPrfAlgorithm, certAlgorithm, certPrfAlgorithm, useDerEncoding);
 		}
 
 		public Pkcs12StoreBuilder SetCertAlgorithm(DerObjectIdentifier certAlgorithm)
@@ -32,6 +34,13 @@ namespace Org.BouncyCastle.Pkcs
 			return this;
 		}
 
+		// Specify a PKCS#5 Scheme 2 encryption for keys
+		public Pkcs12StoreBuilder SetKeyAlgorithm(DerObjectIdentifier keyAlgorithm, DerObjectIdentifier keyPrfAlgorithm)
+		{
+			this.keyAlgorithm = keyAlgorithm;
+			this.keyPrfAlgorithm = keyPrfAlgorithm;
+			return this;
+		}
 		public Pkcs12StoreBuilder SetUseDerEncoding(bool useDerEncoding)
 		{
 			this.useDerEncoding = useDerEncoding;
diff --git a/crypto/src/pkcs/Pkcs12Store.cs b/crypto/src/pkcs/Pkcs12Store.cs
index 50db14d61..0eff8eb92 100644
--- a/crypto/src/pkcs/Pkcs12Store.cs
+++ b/crypto/src/pkcs/Pkcs12Store.cs
@@ -27,7 +27,9 @@ namespace Org.BouncyCastle.Pkcs
         private readonly IDictionary            chainCerts = Platform.CreateHashtable();
         private readonly IDictionary            keyCerts = Platform.CreateHashtable();
         private readonly DerObjectIdentifier	keyAlgorithm;
+        private readonly DerObjectIdentifier    keyPrfAlgorithm;
         private readonly DerObjectIdentifier	certAlgorithm;
+        private readonly DerObjectIdentifier    certPrfAlgorithm;
         private readonly bool					useDerEncoding;
 
         private AsymmetricKeyEntry unmarkedKeyEntry = null;
@@ -89,12 +91,28 @@ namespace Org.BouncyCastle.Pkcs
             bool				useDerEncoding)
         {
             this.keyAlgorithm = keyAlgorithm;
+            this.keyPrfAlgorithm = null;
             this.certAlgorithm = certAlgorithm;
+            this.certPrfAlgorithm = null;
+            this.useDerEncoding = useDerEncoding;
+        }
+
+        internal Pkcs12Store(
+            DerObjectIdentifier keyAlgorithm,
+            DerObjectIdentifier keyPrfAlgorithm,
+            DerObjectIdentifier certAlgorithm,
+            DerObjectIdentifier certPrfAlgorithm,
+            bool useDerEncoding)
+        {
+            this.keyAlgorithm = keyAlgorithm;
+            this.keyPrfAlgorithm = keyPrfAlgorithm;
+            this.certAlgorithm = certAlgorithm;
+            this.certPrfAlgorithm = certPrfAlgorithm;
             this.useDerEncoding = useDerEncoding;
         }
 
         // TODO Consider making obsolete
-//		[Obsolete("Use 'Pkcs12StoreBuilder' instead")]
+        //		[Obsolete("Use 'Pkcs12StoreBuilder' instead")]
         public Pkcs12Store()
             : this(PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc,
                 PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc, false)
@@ -748,8 +766,16 @@ namespace Org.BouncyCastle.Pkcs
                 else
                 {
                     bagOid = PkcsObjectIdentifiers.Pkcs8ShroudedKeyBag;
-                    bagData = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
-                        keyAlgorithm, password, kSalt, MinIterations, privKey.Key);
+                    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();
@@ -952,7 +978,7 @@ namespace Org.BouncyCastle.Pkcs
             byte[] certBagsEncoding = new DerSequence(certBags).GetDerEncoded();
 
             ContentInfo certsInfo;
-            if (password == null)
+            if (password == null || certAlgorithm == null)
             {
                 certsInfo = new ContentInfo(PkcsObjectIdentifiers.Data, new BerOctetString(certBagsEncoding));
             }