summary refs log tree commit diff
path: root/crypto/src/pkcs/Pkcs12Utilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/pkcs/Pkcs12Utilities.cs')
-rw-r--r--crypto/src/pkcs/Pkcs12Utilities.cs77
1 files changed, 77 insertions, 0 deletions
diff --git a/crypto/src/pkcs/Pkcs12Utilities.cs b/crypto/src/pkcs/Pkcs12Utilities.cs
new file mode 100644
index 000000000..d35c8b6a2
--- /dev/null
+++ b/crypto/src/pkcs/Pkcs12Utilities.cs
@@ -0,0 +1,77 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Pkcs
+{
+	/**
+	 * Utility class for reencoding PKCS#12 files to definite length.
+	 */
+	public class Pkcs12Utilities
+	{
+		/**
+		 * Just re-encode the outer layer of the PKCS#12 file to definite length encoding.
+		 *
+		 * @param berPKCS12File - original PKCS#12 file
+		 * @return a byte array representing the DER encoding of the PFX structure
+		 * @throws IOException
+		 */
+		public static byte[] ConvertToDefiniteLength(
+			byte[] berPkcs12File)
+		{
+			Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));
+
+			return pfx.GetEncoded(Asn1Encodable.Der);
+		}
+
+		/**
+		* Re-encode the PKCS#12 structure to definite length encoding at the inner layer
+		* as well, recomputing the MAC accordingly.
+		*
+		* @param berPKCS12File - original PKCS12 file.
+		* @param provider - provider to use for MAC calculation.
+		* @return a byte array representing the DER encoding of the PFX structure.
+		* @throws IOException on parsing, encoding errors.
+		*/
+		public static byte[] ConvertToDefiniteLength(
+			byte[]	berPkcs12File,
+			char[]	passwd)
+		{
+			Pfx pfx = new Pfx(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(berPkcs12File)));
+
+			ContentInfo info = pfx.AuthSafe;
+
+			Asn1OctetString content = Asn1OctetString.GetInstance(info.Content);
+			Asn1Object obj = Asn1Object.FromByteArray(content.GetOctets());
+
+			info = new ContentInfo(info.ContentType, new DerOctetString(obj.GetEncoded(Asn1Encodable.Der)));
+
+			MacData mData = pfx.MacData;
+
+			try
+			{
+				int itCount = mData.IterationCount.IntValue;
+				byte[] data = Asn1OctetString.GetInstance(info.Content).GetOctets();
+				byte[] res = Pkcs12Store.CalculatePbeMac(
+					mData.Mac.AlgorithmID.ObjectID, mData.GetSalt(), itCount, passwd, false, data);
+
+				AlgorithmIdentifier algId = new AlgorithmIdentifier(
+					mData.Mac.AlgorithmID.ObjectID, DerNull.Instance);
+				DigestInfo dInfo = new DigestInfo(algId, res);
+
+				mData = new MacData(dInfo, mData.GetSalt(), itCount);
+			}
+			catch (Exception e)
+			{
+				throw new IOException("error constructing MAC: " + e.ToString());
+			}
+
+			pfx = new Pfx(info, mData);
+
+			return pfx.GetEncoded(Asn1Encodable.Der);
+		}
+	}
+}
\ No newline at end of file