/// <summary> /// When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. /// </summary> /// <param name="buffer">An array of bytes. This method copies <paramref name="count"/> bytes from <paramref name="buffer"/> to the current stream.</param> /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin copying bytes to the current stream.</param> /// <param name="count">The number of bytes to be written to the current stream.</param> /// <exception cref="T:System.ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length. </exception> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="buffer"/> is null. </exception> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="offset"/> or <paramref name="count"/> is negative. </exception> /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> /// <exception cref="T:System.NotSupportedException">The stream does not support writing. </exception> /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> public override void Write(byte[] buffer, int offset, int count) { if (!_init) { if (_encrypt) { _output.Write(_nonce, 0, _nonce.Length); } else { Array.Copy(buffer, 0, _nonce, 0, _nonce.Length); offset = offset + _nonce.Length; count = count - _nonce.Length; } _initFunc(_nonce, _cipher, _header, _encrypt); _init = true; } var outBuffer = new byte[_cipher.GetUpdateOutputSize(count)]; var outLen = _cipher.ProcessBytes(buffer, offset, count, outBuffer, 0); _output.Write(outBuffer, 0, outLen); Secure.Clear(outBuffer); _outLen += outLen; _inLen += count; }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { Flush(); Secure.Clear(_nonce); _nonce = null; Secure.Clear(_header); _header = null; //_cipher.Reset(); _cipher = null; _initFunc = null; _output = null; _outLen = 0; _init = false; _inLen = 0; base.Dispose(disposing); }
/// <summary> /// Finishes this instance. /// </summary> /// <exception cref="InvalidCryptoDataException"></exception> public override void Finish() { try { if (!_init && _encrypt) { _output.Write(_nonce, 0, _nonce.Length); _initFunc(_nonce, _cipher, _header, _encrypt); _init = true; } var buffLen = _cipher.GetOutputSize(_inLen) - _outLen; var buffer = new byte[buffLen]; var writeLen = _cipher.DoFinal(buffer, 0); _output.Write(buffer, 0, writeLen); Secure.Clear(buffer); } catch (InvalidCipherTextException ex) { throw new InvalidCryptoDataException(ex.Message); } }