Files
modernkeepass/ModernKeePassLib/Serialization/CryptoStream.cs

140 lines
4.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
namespace ModernKeePassLib.Serialization
{
// An adaptor function to provide a stream interface from an IBuffer.
class CryptoStream : Stream
{
private int m_blockSize = 16 ;
private byte[] m_decoded;
private IEnumerator<byte> m_enumerator = null;
public CryptoStream(Stream s, String strAlgName, bool bEncrypt, byte[] pbKey, byte[] pbIV)
{
IBuffer iv = CryptographicBuffer.CreateFromByteArray(pbIV);
SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(strAlgName);
CryptographicKey key = objAlg.CreateSymmetricKey( CryptographicBuffer.CreateFromByteArray(pbKey) );
2017-09-20 18:45:37 +02:00
/*if (bEncrypt)
{
Debug.Assert(false, "Not implemented yet");
}
else
2017-09-20 18:45:37 +02:00
{*/
// For the time being, WinRT CryptographicEngine doesn't support stream decoding. Bummer.
// Copy the file to a memory buffer, then decode all at once.
byte[] block = new byte[s.Length]; // We are not at the beginning of the stream
// There is always less than s.Lenght bytes remaining to be read.
int readItemCount = s.Read(block, 0, (int) s.Length);
Array.Resize(ref block, readItemCount);
IBuffer input = CryptographicBuffer.CreateFromByteArray(block);
IBuffer decoded = null;
try
{
decoded = CryptographicEngine.Decrypt(key, input, iv);
} catch (System.Exception)
{
throw new Keys.InvalidCompositeKeyException();
}
CryptographicBuffer.CopyToByteArray(decoded, out m_decoded);
m_enumerator = m_decoded.AsEnumerable().GetEnumerator();
2017-09-20 18:45:37 +02:00
//}
}
public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return false; } }
public override bool CanTimeout { get { return false; } }
public override bool CanWrite { get { return false; } }
public override long Length
{
get
{
throw new System.NotSupportedException();
}
}
public override long Position {
get
{
throw new System.NotSupportedException();
}
set
{
throw new System.NotSupportedException();
}
}
public override void Flush()
{
Debug.Assert(false, "Not yet implemented");
}
public override int Read(byte[] buffer, int offset, int count)
{
// Exceptions:
// System.ArgumentException:
// The sum of offset and count is larger than the buffer length.
//
// System.ArgumentNullException:
// buffer is null.
//
// System.ArgumentOutOfRangeException:
// offset or count is negative.
//
// System.IO.IOException:
// An I/O error occurs.
//
// System.NotSupportedException:
// The stream does not support reading.
//
// System.ObjectDisposedException:
// Methods were called after the stream was closed.
if ((count <0) || (offset <0))
throw new System.ArgumentOutOfRangeException();
if (buffer == null)
throw new System.ArgumentNullException();
if (m_enumerator == null)
throw new System.ArgumentNullException();
for (int i = 0; i < count; i++)
{
if (!m_enumerator.MoveNext())
return i;
buffer[i + offset] = m_enumerator.Current;
}
return count;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new System.NotSupportedException();
}
public override void SetLength(long value)
{
throw new System.NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new System.NotSupportedException();
}
}
}