Implement CSecureDataStream for streaming CKeyingMaterial
This commit is contained in:
parent
3bbf2c1422
commit
6bffc46a87
|
@ -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) { }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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…
Reference in New Issue