Przeglądaj źródła

Initial check-in.

svn path=/trunk/mcs/; revision=447
Sergey Chaban 24 lat temu
rodzic
commit
ce0d4534ee

+ 236 - 0
mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs

@@ -0,0 +1,236 @@
+//
+// System.Security.Cryptography.DESCryptoServiceProvider
+//
+// Author:
+//   Sergey Chaban ([email protected])
+//
+
+
+
+using System;
+using System.Security.Cryptography;
+
+
+namespace System.Security.Cryptography {
+
+
+	internal class DESTransformBase : ICryptoTransform {
+
+		internal enum Mode : int {
+			ENCRYPTOR = 0,
+			DECRYPTOR = 1
+		}
+
+		protected delegate void Filter (byte [] workBuff);
+
+		private DESCore core;
+
+		private DESCore.DESCall cryptFn;
+		private Filter preprocess;
+		private Filter postprocess;
+
+		private byte [] iv;
+		private byte [] tmpBlock;
+
+		protected DESTransformBase (Mode mode, byte [] key, byte [] iv)
+		{
+			core = new DESCore ();
+
+			if (mode == Mode.ENCRYPTOR) {
+				cryptFn = new DESCore.DESCall (core.Encrypt);
+				preprocess = new Filter (this.EncPreprocess);
+				postprocess = new Filter (this.EncPostprocess);
+			} else {
+				cryptFn = new DESCore.DESCall (core.Decrypt);
+				preprocess = new Filter (this.DecPreprocess);
+				postprocess = new Filter (this.DecPostprocess);
+			}
+
+			core.SetKey (key);
+			this.iv = new byte [DESCore.BLOCK_BYTE_SIZE];
+			Array.Copy (iv, 0, this.iv, 0, DESCore.BLOCK_BYTE_SIZE);
+
+			tmpBlock = new byte [DESCore.BLOCK_BYTE_SIZE];
+		}
+
+
+		public virtual bool CanTransformMultipleBlocks {
+			get {
+				return true;
+			}
+		}
+
+
+		public virtual int InputBlockSize {
+			get {
+				return DESCore.BLOCK_BYTE_SIZE;
+			}
+		}
+
+		public virtual int OutputBlockSize {
+			get {
+				return DESCore.BLOCK_BYTE_SIZE;
+			}
+		}
+
+		private void EncPreprocess (byte [] workBuff)
+		{
+			byte [] iv = this.iv;
+			for (int i = 0; i < DESCore.BLOCK_BYTE_SIZE; i++) {
+				workBuff [i] ^= iv [i];
+			}
+		}
+
+		private void EncPostprocess (byte [] workBuff)
+		{
+			Array.Copy (workBuff, 0, iv, 0, DESCore.BLOCK_BYTE_SIZE);
+		}
+
+
+		private void DecPreprocess (byte [] workBuff)
+		{
+			Array.Copy (workBuff, 0, tmpBlock, 0, DESCore.BLOCK_BYTE_SIZE);
+		}
+
+		private void DecPostprocess (byte [] workBuff)
+		{
+			EncPreprocess (workBuff);
+			Array.Copy (tmpBlock, 0, iv, 0, DESCore.BLOCK_BYTE_SIZE);
+		}
+
+
+
+		private void Transform (byte [] workBuff)
+		{
+			preprocess (workBuff);
+			cryptFn (workBuff, null);
+			postprocess (workBuff);
+		}
+
+
+		public virtual int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
+		{
+			if ((inputCount & (DESCore.BLOCK_BYTE_SIZE-1)) != 0)
+				throw new CryptographicException ("Invalid input block size.");
+
+			if (outputOffset + inputCount > outputBuffer.Length)
+				throw new CryptographicException ("Insufficient output buffer size.");
+
+			int step = InputBlockSize;
+			int offs = inputOffset;
+			int full = inputCount / step;
+
+			byte [] workBuff = new byte [step];
+
+			for (int i = 0; i < full; i++) {
+				Array.Copy (inputBuffer, offs, workBuff, 0, step);
+				Transform (workBuff);
+				Array.Copy (workBuff, 0, outputBuffer, outputOffset, step);
+				offs += step;
+				outputOffset += step;
+			}
+
+			return (full * step);
+		}
+
+
+		public virtual byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
+		{
+			// TODO: add decryption support
+			// FIXME: use compatible padding mode
+
+			int num = (inputCount + DESCore.BLOCK_BYTE_SIZE) & (~(DESCore.BLOCK_BYTE_SIZE-1));
+			byte [] res = new byte [num];
+			int full = num - DESCore.BLOCK_BYTE_SIZE;
+
+			TransformBlock (inputBuffer, inputOffset, full, res, 0);
+
+			int rem = inputCount & (DESCore.BLOCK_BYTE_SIZE-1);
+			res [num - 1] = (byte) rem;
+			Array.Copy (inputBuffer, inputOffset + full, res, full, rem);
+
+			// the last padded block will be transformed in-place
+			TransformBlock (res, full, DESCore.BLOCK_BYTE_SIZE, res, full);
+
+			return res;
+		}
+
+
+	} // DESTransformBase
+
+
+	internal sealed class DESEncryptor : DESTransformBase {
+		internal DESEncryptor (byte [] key, byte [] iv)
+		: base (DESTransformBase.Mode.ENCRYPTOR, key, iv)
+		{
+		}
+	} // DESEncryptor
+
+
+	internal sealed class DESDecryptor : DESTransformBase {
+		internal DESDecryptor (byte [] key, byte [] iv)
+		: base (DESTransformBase.Mode.DECRYPTOR, key, iv)
+		{
+		}
+	} // DESDecryptor
+
+
+	public class DESCryptoServiceProvider {
+		private byte [] iv;
+		private byte [] key;
+
+		public DESCryptoServiceProvider ()
+		{
+		}
+
+
+		//
+		// Factories
+		//
+
+		public virtual ICryptoTransform CreateEncryptor()
+		{
+			return new DESEncryptor (key, iv);
+		}
+
+		public virtual ICryptoTransform CreateDecryptor()
+		{
+			return new DESDecryptor (key, iv);
+		}
+
+
+
+		// FIXME: Ought to be in DES.cs
+
+		public /*override*/ byte[] Key {
+			get {
+				return this.key;
+			}
+			set {
+				this.key = new byte [DESCore.KEY_BYTE_SIZE];
+				Array.Copy (value, 0, this.key, 0, DESCore.KEY_BYTE_SIZE);
+			}
+		}
+
+		public virtual byte[] IV {
+			get {
+				return this.iv;
+			}
+			set {
+				this.iv = new byte [DESCore.KEY_BYTE_SIZE];
+				Array.Copy (value, 0, this.iv, 0, DESCore.KEY_BYTE_SIZE);
+			}
+		}
+
+
+
+
+
+		public override string ToString ()
+		{
+			return "mono::System.Security.Cryptography.DESCryptoServiceProvider";
+		}
+
+	} // DESCryptoServiceProvider
+
+} // System.Security.Cryptography

+ 264 - 0
mcs/class/corlib/System.Security.Cryptography/FromBase64Transform.cs

@@ -0,0 +1,264 @@
+//
+// System.Security.Cryptography.FromBase64Transform
+//
+// Author:
+//   Sergey Chaban ([email protected])
+//
+
+using System;
+using System.Security.Cryptography;
+
+
+namespace System.Security.Cryptography {
+
+	public enum FromBase64TransformMode : int {
+		IgnoreWhiteSpaces,
+		DoNotIgnoreWhiteSpaces
+	}
+
+	public class FromBase64Transform : ICryptoTransform {
+
+		private FromBase64TransformMode mode;
+		private byte [] accumulator;
+		private byte [] filterBuffer;
+		private int accPtr;
+
+
+		/// <summary>
+		///  Creates a new instance of the decoder
+		///  with the default transformation mode (IgnoreWhiteSpaces).
+		/// </summary>
+		public FromBase64Transform ()
+		: this (FromBase64TransformMode.IgnoreWhiteSpaces)
+		{
+		}
+
+
+		/// <summary>
+		///  Creates a new instance of the decoder
+		///  with the specified transformation mode.
+		/// </summary>
+		public FromBase64Transform (FromBase64TransformMode mode)
+		{
+			this.mode = mode;
+			accumulator = new byte [4];
+			filterBuffer = new byte [4];
+			accPtr = 0;
+		}
+
+
+		/// <summary>
+		/// </summary>
+		public virtual bool CanTransformMultipleBlocks {
+			get {
+				return false;
+			}
+		}
+
+
+		/// <summary>
+		///  Returns the input block size for the Base64 decoder.
+		/// </summary>
+		/// <remarks>
+		///  The input block size for Base64 decoder is always 1 byte.
+		/// </remarks>
+		public virtual int InputBlockSize {
+			get {
+				return 1;
+			}
+		}
+
+
+		/// <summary>
+		///  Returns the output block size for the Base64 decoder.
+		/// </summary>
+		/// <remarks>
+		///  The value returned by this property is always 3.
+		/// </remarks>
+		public virtual int OutputBlockSize {
+			get {
+				return 3;
+			}
+		}
+
+
+
+		private int Filter (byte [] buffer, int offset, int count)
+		{
+			int end = offset + count;
+			int len = filterBuffer.Length;
+			int ptr = 0;
+			byte [] filter = this.filterBuffer;
+
+			for (int i = offset; i < end; i++) {
+				byte b = buffer [i];
+				if (!Char.IsWhiteSpace ((char) b)) {
+					if (ptr >= len) {
+						len <<= 1;
+						this.filterBuffer = new byte [len];
+						Array.Copy(filter, 0, this.filterBuffer, 0, len >> 1);
+						filter = this.filterBuffer;
+					}
+					filter [ptr++] = b;
+				}
+			}
+
+			return ptr;
+		}
+
+
+
+
+		private int DoTransform (byte [] inputBuffer,
+		                         int inputOffset,
+		                         int inputCount,
+		                         byte [] outputBuffer,
+		                         int outputOffset)
+		{
+			int full = inputCount >> 2;
+			if (full == 0) return 0;
+
+			int rem = 0;
+
+			if (inputBuffer[inputCount - 1] == (byte)'=') {
+				++rem;
+				--full;
+			}
+
+			if (inputBuffer[inputCount - 2] == (byte)'=') ++rem;
+
+			byte [] lookup = Base64Table.DecodeTable;
+			int b0,b1,b2,b3;
+
+			for (int i = 0; i < full; i++) {
+				b0 = lookup [inputBuffer [inputOffset++]];
+				b1 = lookup [inputBuffer [inputOffset++]];
+				b2 = lookup [inputBuffer [inputOffset++]];
+				b3 = lookup [inputBuffer [inputOffset++]];
+
+				outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+				outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
+				outputBuffer [outputOffset++] = (byte) ((b2 << 6) | b3);
+			}
+
+			int res = full * 3;
+
+			switch (rem) {
+			case 0:
+				break;
+			case 1:
+				b0 = lookup [inputBuffer [inputOffset++]];
+				b1 = lookup [inputBuffer [inputOffset++]];
+				b2 = lookup [inputBuffer [inputOffset++]];
+				outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+				outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
+				res += 2;
+				break;
+			case 2:
+				b0 = lookup [inputBuffer [inputOffset++]];
+				b1 = lookup [inputBuffer [inputOffset++]];
+				outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+				++res;
+				break;
+			default:
+				break;
+			}
+
+			return res;
+		}
+
+
+		/// <summary>
+		/// </summary>
+		public virtual int TransformBlock (byte [] inputBuffer,
+		                                   int inputOffset,
+		                                   int inputCount,
+		                                   byte [] outputBuffer,
+		                                   int outputOffset)
+		{
+			int n;
+			byte [] src;
+			int srcOff;
+			int res = 0;
+
+			if (mode == FromBase64TransformMode.IgnoreWhiteSpaces) {
+				n = Filter (inputBuffer, inputOffset, inputCount);
+				src = filterBuffer;
+				srcOff = 0;
+			} else {
+				n = inputCount;
+				src = inputBuffer;
+				srcOff = inputOffset;
+			}
+
+
+			int count = accPtr + n;
+
+			if (count < 4) {
+				Array.Copy (src, srcOff, accumulator, accPtr, n);
+				accPtr = count;
+			} else {
+				byte [] tmpBuff = new byte [count];
+				Array.Copy (accumulator, 0, tmpBuff, 0, accPtr);
+				Array.Copy (src, srcOff, tmpBuff, accPtr, n);
+				accPtr = count & 3;
+				Array.Copy (src, srcOff + (n - accPtr), accumulator, 0, accPtr);
+				res = DoTransform (tmpBuff, 0, count & (~3), outputBuffer, outputOffset);
+			}
+
+
+			return res;
+		}
+
+
+
+
+
+		/// <summary>
+		/// </summary>
+		public virtual byte [] TransformFinalBlock (byte [] inputBuffer,
+		                                            int inputOffset,
+		                                            int inputCount)
+		{
+			byte [] src;
+			int srcOff;
+			int n;
+
+			if (mode == FromBase64TransformMode.IgnoreWhiteSpaces) {
+				n = Filter (inputBuffer, inputOffset, inputCount);
+				src = filterBuffer;
+				srcOff = 0;
+			} else {
+				n = inputCount;
+				src = inputBuffer;
+				srcOff = inputOffset;
+			}
+
+
+			int dataLen = accPtr + n;
+			byte [] tmpBuf = new byte [dataLen];
+
+			int resLen = ((dataLen) >> 2) * 3;
+			byte [] res = new byte [resLen];
+
+			Array.Copy (accumulator, 0, tmpBuf, 0, accPtr);
+			Array.Copy (src, srcOff, tmpBuf, accPtr, n);
+
+			DoTransform (tmpBuf, 0, dataLen, res, 0);
+
+			accPtr = 0;
+			return res;
+		}
+
+
+
+		/// <summary>
+		/// </summary>
+		public override string ToString ()
+		{
+			return "mono::System.Security.Cryptography.FromBase64Transform";
+		}
+
+	} // FromBase64Transform
+
+} // System.Security.Cryptography