Browse Source

Implement CSecureDataStream for streaming CKeyingMaterial

pull/4/head
Jack Grigg 8 years ago
parent
commit
6bffc46a87
  1. 81
      src/streams.h
  2. 8
      src/wallet/crypter.cpp
  3. 13
      src/wallet/crypter.h

81
src/streams.h

@ -27,54 +27,55 @@
* >> and << read and write unformatted data using the above serialization templates.
* Fills with data in linear time; some stringstream implementations take N^2 time.
*/
class CDataStream
template<typename SerializeType>
class CBaseDataStream
{
protected:
typedef CSerializeData vector_type;
typedef SerializeType vector_type;
vector_type vch;
unsigned int nReadPos;
public:
int nType;
int nVersion;
typedef vector_type::allocator_type allocator_type;
typedef vector_type::size_type size_type;
typedef vector_type::difference_type difference_type;
typedef vector_type::reference reference;
typedef vector_type::const_reference const_reference;
typedef vector_type::value_type value_type;
typedef vector_type::iterator iterator;
typedef vector_type::const_iterator const_iterator;
typedef vector_type::reverse_iterator reverse_iterator;
typedef typename vector_type::allocator_type allocator_type;
typedef typename vector_type::size_type size_type;
typedef typename vector_type::difference_type difference_type;
typedef typename vector_type::reference reference;
typedef typename vector_type::const_reference const_reference;
typedef typename vector_type::value_type value_type;
typedef typename vector_type::iterator iterator;
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::reverse_iterator reverse_iterator;
explicit CDataStream(int nTypeIn, int nVersionIn)
explicit CBaseDataStream(int nTypeIn, int nVersionIn)
{
Init(nTypeIn, nVersionIn);
}
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
CBaseDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
{
Init(nTypeIn, nVersionIn);
}
#if !defined(_MSC_VER) || _MSC_VER >= 1300
CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
CBaseDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend)
{
Init(nTypeIn, nVersionIn);
}
#endif
CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
CBaseDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
CBaseDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
CBaseDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end())
{
Init(nTypeIn, nVersionIn);
}
@ -86,15 +87,15 @@ public:
nVersion = nVersionIn;
}
CDataStream& operator+=(const CDataStream& b)
CBaseDataStream& operator+=(const CBaseDataStream& b)
{
vch.insert(vch.end(), b.begin(), b.end());
return *this;
}
friend CDataStream operator+(const CDataStream& a, const CDataStream& b)
friend CBaseDataStream operator+(const CBaseDataStream& a, const CBaseDataStream& b)
{
CDataStream ret = a;
CBaseDataStream ret = a;
ret += b;
return (ret);
}
@ -207,7 +208,7 @@ public:
// Stream subset
//
bool eof() const { return size() == 0; }
CDataStream* rdbuf() { return this; }
CBaseDataStream* rdbuf() { return this; }
int in_avail() { return size(); }
void SetType(int n) { nType = n; }
@ -217,7 +218,7 @@ public:
void ReadVersion() { *this >> nVersion; }
void WriteVersion() { *this << nVersion; }
CDataStream& read(char* pch, size_t nSize)
CBaseDataStream& read(char* pch, size_t nSize)
{
// Read from the beginning of the buffer
unsigned int nReadPosNext = nReadPos + nSize;
@ -225,7 +226,7 @@ public:
{
if (nReadPosNext > vch.size())
{
throw std::ios_base::failure("CDataStream::read(): end of data");
throw std::ios_base::failure("CBaseDataStream::read(): end of data");
}
memcpy(pch, &vch[nReadPos], nSize);
nReadPos = 0;
@ -237,7 +238,7 @@ public:
return (*this);
}
CDataStream& ignore(int nSize)
CBaseDataStream& ignore(int nSize)
{
// Ignore from the beginning of the buffer
assert(nSize >= 0);
@ -245,7 +246,7 @@ public:
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
throw std::ios_base::failure("CDataStream::ignore(): end of data");
throw std::ios_base::failure("CBaseDataStream::ignore(): end of data");
nReadPos = 0;
vch.clear();
return (*this);
@ -254,7 +255,7 @@ public:
return (*this);
}
CDataStream& write(const char* pch, size_t nSize)
CBaseDataStream& write(const char* pch, size_t nSize)
{
// Write to the end of the buffer
vch.insert(vch.end(), pch, pch + nSize);
@ -277,7 +278,7 @@ public:
}
template<typename T>
CDataStream& operator<<(const T& obj)
CBaseDataStream& operator<<(const T& obj)
{
// Serialize to this stream
::Serialize(*this, obj, nType, nVersion);
@ -285,7 +286,7 @@ public:
}
template<typename T>
CDataStream& operator>>(T& obj)
CBaseDataStream& operator>>(T& obj)
{
// Unserialize from this stream
::Unserialize(*this, obj, nType, nVersion);
@ -298,6 +299,30 @@ public:
}
};
class CDataStream : public CBaseDataStream<CSerializeData>
{
public:
explicit CDataStream(int nTypeIn, int nVersionIn) : CBaseDataStream(nTypeIn, nVersionIn) { }
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) :
CBaseDataStream(pbegin, pend, nTypeIn, nVersionIn) { }
#if !defined(_MSC_VER) || _MSC_VER >= 1300
CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) :
CBaseDataStream(pbegin, pend, nTypeIn, nVersionIn) { }
#endif
CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
};

8
src/wallet/crypter.cpp

@ -148,9 +148,7 @@ static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey,
if (vchSecret.size() != libzcash::SerializedSpendingKeySize)
return false;
// TODO does this undo the benefits of using CKeyingMaterial?
std::vector<unsigned char> serialized(vchSecret.begin(), vchSecret.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION);
ss >> sk;
return sk.address() == address;
}
@ -313,7 +311,7 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
return false;
std::vector<unsigned char> vchCryptedSecret;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end());
auto address = sk.address();
@ -378,7 +376,7 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys)
{
const libzcash::SpendingKey &sk = mSpendingKey.second;
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << sk;
CKeyingMaterial vchSecret(ss.begin(), ss.end());
libzcash::PaymentAddress address = sk.address();

13
src/wallet/crypter.h

@ -7,6 +7,7 @@
#include "keystore.h"
#include "serialize.h"
#include "streams.h"
#include "support/allocators/secure.h"
#include "zcash/Address.hpp"
@ -67,6 +68,18 @@ public:
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
class CSecureDataStream : public CBaseDataStream<CKeyingMaterial>
{
public:
explicit CSecureDataStream(int nTypeIn, int nVersionIn) : CBaseDataStream(nTypeIn, nVersionIn) { }
CSecureDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) :
CBaseDataStream(pbegin, pend, nTypeIn, nVersionIn) { }
CSecureDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) :
CBaseDataStream(vchIn, nTypeIn, nVersionIn) { }
};
/** Encryption/decryption context with key information */
class CCrypter
{

Loading…
Cancel
Save