summary refs log tree commit diff
diff options
context:
space:
mode:
authorbartland <bruce.cartland@pobox.com>2015-04-10 16:48:26 +1000
committerbartland <bruce.cartland@pobox.com>2015-04-10 16:48:26 +1000
commit216d64aab6a4522d35361d9bccae4a079e9bde83 (patch)
treec3f73176faa27bf45ac84c9e835382556ff93d21
parentMerge pull request #1 from bcgit/master (diff)
downloadBouncyCastle.NET-ed25519-216d64aab6a4522d35361d9bccae4a079e9bde83.tar.xz
Support (low-level) for non-default PRFs for PKCS5v2
-rw-r--r--crypto/src/asn1/pkcs/PBKDF2Params.cs72
1 files changed, 59 insertions, 13 deletions
diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs
index 1351b94cf..f629848d8 100644
--- a/crypto/src/asn1/pkcs/PBKDF2Params.cs
+++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs
@@ -1,5 +1,5 @@
 using System;
-
+using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Math;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
@@ -7,9 +7,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 	public class Pbkdf2Params
 		: Asn1Encodable
 	{
+        private static AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdHmacWithSha1, DerNull.Instance);
 		private readonly Asn1OctetString	octStr;
 		private readonly DerInteger			iterationCount;
 		private readonly DerInteger			keyLength;
+        private readonly AlgorithmIdentifier prf;
 
 		public static Pbkdf2Params GetInstance(
 			object obj)
@@ -26,16 +28,27 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 		public Pbkdf2Params(
 			Asn1Sequence seq)
 		{
-			if (seq.Count < 2 || seq.Count > 3)
+            if (seq.Count < 2 || seq.Count > 4)
 				throw new ArgumentException("Wrong number of elements in sequence", "seq");
 
 			octStr = (Asn1OctetString)seq[0];
 			iterationCount = (DerInteger)seq[1];
 
-			if (seq.Count > 2)
+            Asn1Encodable kl = null, d = null;
+            if (seq.Count > 3) 
 			{
-				keyLength = (DerInteger)seq[2];
-			}
+                kl = seq[2];
+                d = seq[3];
+            }
+            else if (seq.Count > 2)
+            {
+                if (seq[2] is DerInteger)
+                    kl = seq[2];
+                else 
+                    d = seq[2];
+            }
+            if (kl != null) keyLength = (DerInteger)kl;
+            if (d != null) prf = AlgorithmIdentifier.GetInstance(d);
 		}
 
 		public Pbkdf2Params(
@@ -55,10 +68,29 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             this.keyLength = new DerInteger(keyLength);
         }
 
-		public byte[] GetSalt()
-		{
-			return octStr.GetOctets();
-		}
+	    public Pbkdf2Params(
+	        byte[] salt,
+	        int iterationCount,
+            int keyLength,
+            AlgorithmIdentifier prf)
+            : this(salt, iterationCount, keyLength)
+        {
+            this.prf = prf;
+	    }
+
+        public Pbkdf2Params(
+            byte[] salt,
+            int iterationCount,
+            AlgorithmIdentifier prf)
+            : this(salt, iterationCount)
+        {
+            this.prf = prf;
+        }
+
+        public byte[] GetSalt()
+        {
+            return octStr.GetOctets();
+        }
 
 		public BigInteger IterationCount
 		{
@@ -70,15 +102,29 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 			get { return keyLength == null ? null : keyLength.Value; }
 		}
 
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				octStr, iterationCount);
+	    public bool IsDefaultPrf() 
+        {
+            return prf == null || prf.Equals(algid_hmacWithSHA1);
+	    }
+
+        public AlgorithmIdentifier Prf
+        {
+            get { return prf ?? algid_hmacWithSHA1; }
+        }
+
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(
+                octStr, iterationCount);
 
 			if (keyLength != null)
 			{
 				v.Add(keyLength);
 			}
+            if (!IsDefaultPrf())
+            {
+                v.Add(prf);
+            }
 
 			return new DerSequence(v);
 		}