You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
7.6 KiB
250 lines
7.6 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto |
|
{ |
|
/** |
|
* The AEAD ciphers already handle buffering internally, so this class |
|
* just takes care of implementing IBufferedCipher methods. |
|
*/ |
|
public class BufferedAeadCipher |
|
: BufferedCipherBase |
|
{ |
|
private readonly IAeadCipher cipher; |
|
|
|
public BufferedAeadCipher(IAeadCipher cipher) |
|
{ |
|
if (cipher == null) |
|
throw new ArgumentNullException("cipher"); |
|
|
|
this.cipher = cipher; |
|
} |
|
|
|
public override string AlgorithmName |
|
{ |
|
get { return cipher.AlgorithmName; } |
|
} |
|
|
|
/** |
|
* initialise the cipher. |
|
* |
|
* @param forEncryption if true the cipher is initialised for |
|
* encryption, if false for decryption. |
|
* @param param the key and other data required by the cipher. |
|
* @exception ArgumentException if the parameters argument is |
|
* inappropriate. |
|
*/ |
|
public override void Init( |
|
bool forEncryption, |
|
ICipherParameters parameters) |
|
{ |
|
if (parameters is ParametersWithRandom) |
|
{ |
|
parameters = ((ParametersWithRandom)parameters).Parameters; |
|
} |
|
|
|
cipher.Init(forEncryption, parameters); |
|
} |
|
|
|
/** |
|
* return the blocksize for the underlying cipher. |
|
* |
|
* @return the blocksize for the underlying cipher. |
|
*/ |
|
public override int GetBlockSize() |
|
{ |
|
return 0; |
|
} |
|
|
|
/** |
|
* return the size of the output buffer required for an update |
|
* an input of len bytes. |
|
* |
|
* @param len the length of the input. |
|
* @return the space required to accommodate a call to update |
|
* with len bytes of input. |
|
*/ |
|
public override int GetUpdateOutputSize( |
|
int length) |
|
{ |
|
return cipher.GetUpdateOutputSize(length); |
|
} |
|
|
|
/** |
|
* return the size of the output buffer required for an update plus a |
|
* doFinal with an input of len bytes. |
|
* |
|
* @param len the length of the input. |
|
* @return the space required to accommodate a call to update and doFinal |
|
* with len bytes of input. |
|
*/ |
|
public override int GetOutputSize( |
|
int length) |
|
{ |
|
return cipher.GetOutputSize(length); |
|
} |
|
|
|
/** |
|
* process a single byte, producing an output block if necessary. |
|
* |
|
* @param in the input byte. |
|
* @param out the space for any output that might be produced. |
|
* @param outOff the offset from which the output will be copied. |
|
* @return the number of output bytes copied to out. |
|
* @exception DataLengthException if there isn't enough space in out. |
|
* @exception InvalidOperationException if the cipher isn't initialised. |
|
*/ |
|
public override int ProcessByte( |
|
byte input, |
|
byte[] output, |
|
int outOff) |
|
{ |
|
return cipher.ProcessByte(input, output, outOff); |
|
} |
|
|
|
public override byte[] ProcessByte( |
|
byte input) |
|
{ |
|
int outLength = GetUpdateOutputSize(1); |
|
|
|
byte[] outBytes = outLength > 0 ? new byte[outLength] : null; |
|
|
|
int pos = ProcessByte(input, outBytes, 0); |
|
|
|
if (outLength > 0 && pos < outLength) |
|
{ |
|
byte[] tmp = new byte[pos]; |
|
Array.Copy(outBytes, 0, tmp, 0, pos); |
|
outBytes = tmp; |
|
} |
|
|
|
return outBytes; |
|
} |
|
|
|
public override byte[] ProcessBytes( |
|
byte[] input, |
|
int inOff, |
|
int length) |
|
{ |
|
if (input == null) |
|
throw new ArgumentNullException("input"); |
|
if (length < 1) |
|
return null; |
|
|
|
int outLength = GetUpdateOutputSize(length); |
|
|
|
byte[] outBytes = outLength > 0 ? new byte[outLength] : null; |
|
|
|
int pos = ProcessBytes(input, inOff, length, outBytes, 0); |
|
|
|
if (outLength > 0 && pos < outLength) |
|
{ |
|
byte[] tmp = new byte[pos]; |
|
Array.Copy(outBytes, 0, tmp, 0, pos); |
|
outBytes = tmp; |
|
} |
|
|
|
return outBytes; |
|
} |
|
|
|
/** |
|
* process an array of bytes, producing output if necessary. |
|
* |
|
* @param in the input byte array. |
|
* @param inOff the offset at which the input data starts. |
|
* @param len the number of bytes to be copied out of the input array. |
|
* @param out the space for any output that might be produced. |
|
* @param outOff the offset from which the output will be copied. |
|
* @return the number of output bytes copied to out. |
|
* @exception DataLengthException if there isn't enough space in out. |
|
* @exception InvalidOperationException if the cipher isn't initialised. |
|
*/ |
|
public override int ProcessBytes( |
|
byte[] input, |
|
int inOff, |
|
int length, |
|
byte[] output, |
|
int outOff) |
|
{ |
|
return cipher.ProcessBytes(input, inOff, length, output, outOff); |
|
} |
|
|
|
public override byte[] DoFinal() |
|
{ |
|
byte[] outBytes = new byte[GetOutputSize(0)]; |
|
|
|
int pos = DoFinal(outBytes, 0); |
|
|
|
if (pos < outBytes.Length) |
|
{ |
|
byte[] tmp = new byte[pos]; |
|
Array.Copy(outBytes, 0, tmp, 0, pos); |
|
outBytes = tmp; |
|
} |
|
|
|
return outBytes; |
|
} |
|
|
|
public override byte[] DoFinal( |
|
byte[] input, |
|
int inOff, |
|
int inLen) |
|
{ |
|
if (input == null) |
|
throw new ArgumentNullException("input"); |
|
|
|
byte[] outBytes = new byte[GetOutputSize(inLen)]; |
|
|
|
int pos = (inLen > 0) |
|
? ProcessBytes(input, inOff, inLen, outBytes, 0) |
|
: 0; |
|
|
|
pos += DoFinal(outBytes, pos); |
|
|
|
if (pos < outBytes.Length) |
|
{ |
|
byte[] tmp = new byte[pos]; |
|
Array.Copy(outBytes, 0, tmp, 0, pos); |
|
outBytes = tmp; |
|
} |
|
|
|
return outBytes; |
|
} |
|
|
|
/** |
|
* Process the last block in the buffer. |
|
* |
|
* @param out the array the block currently being held is copied into. |
|
* @param outOff the offset at which the copying starts. |
|
* @return the number of output bytes copied to out. |
|
* @exception DataLengthException if there is insufficient space in out for |
|
* the output, or the input is not block size aligned and should be. |
|
* @exception InvalidOperationException if the underlying cipher is not |
|
* initialised. |
|
* @exception InvalidCipherTextException if padding is expected and not found. |
|
* @exception DataLengthException if the input is not block size |
|
* aligned. |
|
*/ |
|
public override int DoFinal( |
|
byte[] output, |
|
int outOff) |
|
{ |
|
return cipher.DoFinal(output, outOff); |
|
} |
|
|
|
/** |
|
* Reset the buffer and cipher. After resetting the object is in the same |
|
* state as it was after the last init (if there was one). |
|
*/ |
|
public override void Reset() |
|
{ |
|
cipher.Reset(); |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|