// Author:
// Sergey Chaban (serge@wildwestsoftware.com)
//
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
-using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
namespace System.Security.Cryptography {
[Serializable]
+#if NET_2_0
+ [ComVisible (true)]
+#endif
public enum FromBase64TransformMode : int {
IgnoreWhiteSpaces,
DoNotIgnoreWhiteSpaces
}
+#if NET_2_0
+ [ComVisible (true)]
+#endif
public class FromBase64Transform : ICryptoTransform {
private FromBase64TransformMode mode;
- private byte [] accumulator;
- private byte [] filterBuffer;
+ private byte[] accumulator;
+ private byte[] filterBuffer;
private int accPtr;
private bool m_disposed;
-
- /// <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;
Dispose (false);
}
-
- /// <summary>
- /// </summary>
public bool CanTransformMultipleBlocks {
- get {
- return false;
- }
+ get { return false; }
}
public virtual bool CanReuseTransform {
- get { return false; }
+ get { return true; }
}
- /// <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 int InputBlockSize {
- get {
- return 1;
- }
+ 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 int OutputBlockSize {
- get {
- return 3;
- }
+ get { return 3; }
}
public void Clear()
protected virtual void Dispose (bool disposing)
{
if (!m_disposed) {
+ // zeroize data
+ if (accumulator != null)
+ Array.Clear (accumulator, 0, accumulator.Length);
+ if (filterBuffer != null)
+ Array.Clear (filterBuffer, 0, filterBuffer.Length);
+
// dispose unmanaged objects
if (disposing) {
// dispose managed objects
+ accumulator = null;
+ filterBuffer = null;
}
m_disposed = true;
}
int end = offset + count;
int len = filterBuffer.Length;
int ptr = 0;
- byte [] filter = this.filterBuffer;
+ byte[] filter = this.filterBuffer;
for (int i = offset; i < end; i++) {
byte b = buffer [i];
if (ptr >= len) {
len <<= 1;
this.filterBuffer = new byte [len];
- Array.Copy(filter, 0, this.filterBuffer, 0, len >> 1);
+ Buffer.BlockCopy (filter, 0, this.filterBuffer, 0, len >> 1);
filter = this.filterBuffer;
}
filter [ptr++] = b;
return ptr;
}
+ private byte[] lookupTable;
+
+ private byte lookup (byte input)
+ {
+ if (input >= lookupTable.Length) {
+ throw new FormatException (
+ Locale.GetText ("Invalid character in a Base-64 string."));
+ }
+
+ byte ret = lookupTable [input];
+ if (ret == Byte.MaxValue) {
+ throw new FormatException (
+ Locale.GetText ("Invalid character in a Base-64 string."));
+ }
- private int DoTransform (byte [] inputBuffer,
- int inputOffset,
- int inputCount,
- byte [] outputBuffer,
- int outputOffset)
+ return ret;
+ }
+
+ private int DoTransform (byte [] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
int full = inputCount >> 2;
- if (full == 0) return 0;
+ if (full == 0)
+ return 0;
int rem = 0;
--full;
}
- if (inputBuffer[inputCount - 2] == (byte)'=') ++rem;
+ if (inputBuffer[inputCount - 2] == (byte)'=')
+ ++rem;
- byte [] lookup = Base64Table.DecodeTable;
+ lookupTable = Base64Constants.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++]];
+ 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));
case 0:
break;
case 1:
- b0 = lookup [inputBuffer [inputOffset++]];
- b1 = lookup [inputBuffer [inputOffset++]];
- b2 = lookup [inputBuffer [inputOffset++]];
+ 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++]];
+ b0 = lookup (inputBuffer [inputOffset++]);
+ b1 = lookup (inputBuffer [inputOffset++]);
outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
++res;
break;
- default:
- break;
}
return res;
}
+ private void CheckInputParameters (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (inputBuffer == null)
+ throw new ArgumentNullException ("inputBuffer");
+ if (inputOffset < 0)
+ throw new ArgumentOutOfRangeException ("inputOffset", "< 0");
+ if (inputCount > inputBuffer.Length)
+ throw new OutOfMemoryException ("inputCount " + Locale.GetText ("Overflow"));
+ if (inputOffset > inputBuffer.Length - inputCount)
+ throw new ArgumentException ("inputOffset", Locale.GetText ("Overflow"));
+ if (inputCount < 0)
+ throw new OverflowException ("inputCount < 0");
+ }
- /// <summary>
- /// </summary>
- public int TransformBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount,
- byte [] outputBuffer,
- int outputOffset)
+ public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
+ if (m_disposed)
+ throw new ObjectDisposedException ("FromBase64Transform");
+ // LAMESPEC: undocumented exceptions
+ CheckInputParameters (inputBuffer, inputOffset, inputCount);
+ if ((outputBuffer == null) || (outputOffset < 0) || (inputCount > outputBuffer.Length - outputOffset))
+ throw new FormatException ("outputBuffer");
+
int n;
byte [] src;
int srcOff;
n = Filter (inputBuffer, inputOffset, inputCount);
src = filterBuffer;
srcOff = 0;
- } else {
+ }
+ else {
n = inputCount;
src = inputBuffer;
srcOff = inputOffset;
}
-
int count = accPtr + n;
if (count < 4) {
- Array.Copy (src, srcOff, accumulator, accPtr, n);
+ Buffer.BlockCopy (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);
+ }
+ else {
+ byte[] tmpBuff = new byte [count];
+ Buffer.BlockCopy (accumulator, 0, tmpBuff, 0, accPtr);
+ Buffer.BlockCopy (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);
+ Buffer.BlockCopy (src, srcOff + (n - accPtr), accumulator, 0, accPtr);
+ res = DoTransform (tmpBuff, 0, count & (~3), outputBuffer, outputOffset) ;
}
-
return res;
}
-
- /// <summary>
- /// </summary>
- public byte [] TransformFinalBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount)
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
{
- byte [] src;
+ if (m_disposed)
+ throw new ObjectDisposedException ("FromBase64Transform");
+ // LAMESPEC: undocumented exceptions
+ CheckInputParameters (inputBuffer, inputOffset, inputCount);
+
+ byte[] src;
int srcOff;
int n;
n = Filter (inputBuffer, inputOffset, inputCount);
src = filterBuffer;
srcOff = 0;
- } else {
+ }
+ else {
n = inputCount;
src = inputBuffer;
srcOff = inputOffset;
}
-
int dataLen = accPtr + n;
- byte [] tmpBuf = new byte [dataLen];
+ 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);
+ byte[] res = new byte [resLen];
+ Buffer.BlockCopy (accumulator, 0, tmpBuf, 0, accPtr);
+ Buffer.BlockCopy (src, srcOff, tmpBuf, accPtr, n);
+
int actLen = DoTransform (tmpBuf, 0, dataLen, res, 0);
-
accPtr = 0;
if (actLen < resLen) {
- byte [] newres = new byte [actLen];
+ byte[] newres = new byte [actLen];
- Array.Copy (res, newres, actLen);
+ Buffer.BlockCopy (res, 0, newres, 0, actLen);
return newres;
- } else
- return res;
+ }
+ else
+ return res;
}
-
- } // FromBase64Transform
-
-} // System.Security.Cryptography
+ }
+}