summary refs log tree commit diff
path: root/Crypto/src/security/WrapperUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/security/WrapperUtilities.cs')
-rw-r--r--Crypto/src/security/WrapperUtilities.cs153
1 files changed, 153 insertions, 0 deletions
diff --git a/Crypto/src/security/WrapperUtilities.cs b/Crypto/src/security/WrapperUtilities.cs
new file mode 100644
index 000000000..33567c51b
--- /dev/null
+++ b/Crypto/src/security/WrapperUtilities.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections;
+using System.Globalization;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Kisa;
+using Org.BouncyCastle.Asn1.Nist;
+using Org.BouncyCastle.Asn1.Ntt;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Security
+{
+	/// <remarks>
+	///  Utility class for creating IWrapper objects from their names/Oids
+	/// </remarks>
+	public sealed class WrapperUtilities
+	{
+		internal enum WrapAlgorithm { AESWRAP, CAMELLIAWRAP, DESEDEWRAP, RC2WRAP, SEEDWRAP,
+			DESEDERFC3211WRAP, AESRFC3211WRAP, CAMELLIARFC3211WRAP };
+
+		private WrapperUtilities()
+		{
+		}
+
+		private static readonly IDictionary algorithms = Platform.CreateHashtable();
+        //private static readonly IDictionary oids = Platform.CreateHashtable();
+
+		static WrapperUtilities()
+		{
+			// Signal to obfuscation tools not to change enum constants
+			((WrapAlgorithm)Enums.GetArbitraryValue(typeof(WrapAlgorithm))).ToString();
+
+			algorithms[NistObjectIdentifiers.IdAes128Wrap.Id] = "AESWRAP";
+			algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP";
+			algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP";
+
+			algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP";
+			algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP";
+			algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP";
+
+			algorithms[PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id] = "DESEDEWRAP";
+
+			algorithms[PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id] = "RC2WRAP";
+
+			algorithms[KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id] = "SEEDWRAP";
+		}
+
+		public static IWrapper GetWrapper(
+			DerObjectIdentifier oid)
+		{
+			return GetWrapper(oid.Id);
+		}
+
+		public static IWrapper GetWrapper(
+			string algorithm)
+		{
+			string upper = algorithm.ToUpperInvariant();
+			string mechanism = (string) algorithms[upper];
+
+			if (mechanism == null)
+			{
+				mechanism = upper;
+			}
+
+			try
+			{
+				WrapAlgorithm wrapAlgorithm = (WrapAlgorithm)Enums.GetEnumValue(
+					typeof(WrapAlgorithm), mechanism);
+
+				switch (wrapAlgorithm)
+				{
+					case WrapAlgorithm.AESWRAP:				return new AesWrapEngine();
+					case WrapAlgorithm.CAMELLIAWRAP:		return new CamelliaWrapEngine();
+					case WrapAlgorithm.DESEDEWRAP:			return new DesEdeWrapEngine();
+					case WrapAlgorithm.RC2WRAP:				return new RC2WrapEngine();
+					case WrapAlgorithm.SEEDWRAP:			return new SeedWrapEngine();
+					case WrapAlgorithm.DESEDERFC3211WRAP:	return new Rfc3211WrapEngine(new DesEdeEngine());
+					case WrapAlgorithm.AESRFC3211WRAP:		return new Rfc3211WrapEngine(new AesFastEngine());
+					case WrapAlgorithm.CAMELLIARFC3211WRAP:	return new Rfc3211WrapEngine(new CamelliaEngine());
+				}
+			}
+			catch (ArgumentException)
+			{
+			}
+
+			// Create an IBufferedCipher and use it as IWrapper (via BufferedCipherWrapper)
+			IBufferedCipher blockCipher = CipherUtilities.GetCipher(algorithm);
+
+			if (blockCipher != null)
+				return new BufferedCipherWrapper(blockCipher);
+
+			throw new SecurityUtilityException("Wrapper " + algorithm + " not recognised.");
+		}
+
+		public static string GetAlgorithmName(
+			DerObjectIdentifier oid)
+		{
+			return (string) algorithms[oid.Id];
+		}
+
+		private class BufferedCipherWrapper
+			: IWrapper
+		{
+			private readonly IBufferedCipher cipher;
+			private bool forWrapping;
+
+			public BufferedCipherWrapper(
+				IBufferedCipher cipher)
+			{
+				this.cipher = cipher;
+			}
+
+			public string AlgorithmName
+			{
+				get { return cipher.AlgorithmName; }
+			}
+
+			public void Init(
+				bool				forWrapping,
+				ICipherParameters	parameters)
+			{
+				this.forWrapping = forWrapping;
+
+				cipher.Init(forWrapping, parameters);
+			}
+
+			public byte[] Wrap(
+				byte[]	input,
+				int		inOff,
+				int		length)
+			{
+				if (!forWrapping)
+					throw new InvalidOperationException("Not initialised for wrapping");
+
+				return cipher.DoFinal(input, inOff, length);
+			}
+
+			public byte[] Unwrap(
+				byte[]	input,
+				int		inOff,
+				int		length)
+			{
+				if (forWrapping)
+					throw new InvalidOperationException("Not initialised for unwrapping");
+
+				return cipher.DoFinal(input, inOff, length);
+			}
+		}
+	}
+}