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.
189 lines
5.2 KiB
189 lines
5.2 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
|
|
using BestHTTP.PlatformSupport.Memory; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.Connections.TLS.Crypto.Impl |
|
{ |
|
public sealed class NoCopyKeyParameter |
|
: ICipherParameters |
|
{ |
|
private readonly byte[] key; |
|
|
|
public NoCopyKeyParameter(byte[] key) |
|
:this(key, 0, key.Length) |
|
{ |
|
} |
|
|
|
public NoCopyKeyParameter( |
|
byte[] key, |
|
int keyOff, |
|
int keyLen) |
|
{ |
|
if (key == null) |
|
throw new ArgumentNullException("key"); |
|
if (keyOff < 0 || keyOff > key.Length) |
|
throw new ArgumentOutOfRangeException("keyOff"); |
|
if (keyLen < 0 || keyLen > (key.Length - keyOff)) |
|
throw new ArgumentOutOfRangeException("keyLen"); |
|
|
|
this.key = new byte[keyLen]; |
|
Array.Copy(key, keyOff, this.key, 0, keyLen); |
|
} |
|
|
|
public byte[] GetKey() |
|
{ |
|
return key;// (byte[])key.Clone(); |
|
} |
|
} |
|
|
|
public sealed class FastAeadParameters |
|
: ICipherParameters |
|
{ |
|
private readonly byte[] associatedText; |
|
private readonly byte[] nonce; |
|
private readonly NoCopyKeyParameter key; |
|
private readonly int macSize; |
|
|
|
/** |
|
* Base constructor. |
|
* |
|
* @param key key to be used by underlying cipher |
|
* @param macSize macSize in bits |
|
* @param nonce nonce to be used |
|
*/ |
|
public FastAeadParameters(NoCopyKeyParameter key, int macSize, byte[] nonce) |
|
: this(key, macSize, nonce, null) |
|
{ |
|
} |
|
|
|
/** |
|
* Base constructor. |
|
* |
|
* @param key key to be used by underlying cipher |
|
* @param macSize macSize in bits |
|
* @param nonce nonce to be used |
|
* @param associatedText associated text, if any |
|
*/ |
|
public FastAeadParameters( |
|
NoCopyKeyParameter key, |
|
int macSize, |
|
byte[] nonce, |
|
byte[] associatedText) |
|
{ |
|
this.key = key; |
|
this.nonce = nonce; |
|
this.macSize = macSize; |
|
this.associatedText = associatedText; |
|
} |
|
|
|
public NoCopyKeyParameter Key |
|
{ |
|
get { return key; } |
|
} |
|
|
|
public int MacSize |
|
{ |
|
get { return macSize; } |
|
} |
|
|
|
public byte[] GetAssociatedText() |
|
{ |
|
return associatedText; |
|
} |
|
|
|
public byte[] GetNonce() |
|
{ |
|
return nonce; |
|
} |
|
} |
|
|
|
public sealed class FastParametersWithIV |
|
: ICipherParameters |
|
{ |
|
private readonly ICipherParameters parameters; |
|
private readonly byte[] iv; |
|
|
|
public FastParametersWithIV(ICipherParameters parameters, |
|
byte[] iv) |
|
: this(parameters, iv, 0, iv.Length) |
|
{ |
|
} |
|
|
|
public FastParametersWithIV(ICipherParameters parameters, |
|
byte[] iv, int ivOff, int ivLen) |
|
{ |
|
// NOTE: 'parameters' may be null to imply key re-use |
|
if (iv == null) |
|
throw new ArgumentNullException("iv"); |
|
|
|
this.parameters = parameters; |
|
this.iv = Arrays.CopyOfRange(iv, ivOff, ivOff + ivLen); |
|
} |
|
|
|
public byte[] GetIV() |
|
{ |
|
return iv; // (byte[])iv.Clone(); |
|
} |
|
|
|
public ICipherParameters Parameters |
|
{ |
|
get { return parameters; } |
|
} |
|
} |
|
|
|
internal sealed class FastTlsAeadCipherImpl |
|
: TlsAeadCipherImpl |
|
{ |
|
private readonly bool m_isEncrypting; |
|
private readonly IAeadBlockCipher m_cipher; |
|
|
|
private NoCopyKeyParameter key; |
|
|
|
internal FastTlsAeadCipherImpl(IAeadBlockCipher cipher, bool isEncrypting) |
|
{ |
|
this.m_cipher = cipher; |
|
this.m_isEncrypting = isEncrypting; |
|
} |
|
|
|
public void SetKey(byte[] key, int keyOff, int keyLen) |
|
{ |
|
this.key = new NoCopyKeyParameter(key, keyOff, keyLen); |
|
} |
|
|
|
public void Init(byte[] nonce, int macSize, byte[] additionalData) |
|
{ |
|
m_cipher.Init(m_isEncrypting, new FastAeadParameters(key, macSize * 8, nonce, additionalData)); |
|
} |
|
|
|
public int GetOutputSize(int inputLength) |
|
{ |
|
return m_cipher.GetOutputSize(inputLength); |
|
} |
|
|
|
public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset) |
|
{ |
|
int len = m_cipher.ProcessBytes(input, inputOffset, inputLength, output, outputOffset); |
|
|
|
try |
|
{ |
|
len += m_cipher.DoFinal(output, outputOffset + len); |
|
} |
|
catch (InvalidCipherTextException e) |
|
{ |
|
throw new TlsFatalAlert(AlertDescription.bad_record_mac, e); |
|
} |
|
|
|
return len; |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|