Merge commit from fork

* Harden serializer deserialization bounds

* Finalize Unix serializer hardening

Validate object types before parsing and release owned objects on failure.
Enforce nesting limits through shared serialization entry points.

Mirror read/write size limits and reject embedded NULs while preserving
the wire format. Add regression tests for bounds, types, and cleanup.

Validated Linux self-tests, C++03 platform tests, and ASan/UBSan with leak
detection.

Co-authored-by: Damian Rickard <damian@rickard.us>

---------

Co-authored-by: Damian Rickard <damian@rickard.us>
Co-authored-by: Mounir IDRASSI <mounir.idrassi@amcrypto.jp>
This commit is contained in:
authored and GitHub committed 2026-09-30 20:12:20 +09:00
1 parent dea8fb0dc0
commit fb9d96c52d
25 files changed
+738 -171

No files matched your search

+8 -8
View File
@@ -136,18 +136,18 @@ namespace VeraCrypt
#ifdef TC_HEADER_Platform_Exception #ifdef TC_HEADER_Platform_Exception
void PCSCException::Deserialize(shared_ptr <Stream> stream) void PCSCException::DeserializeData(shared_ptr <Stream> stream)
{ {
Exception::Deserialize(stream); Exception::DeserializeData(stream);
Serializer sr(stream); Serializer sr(stream);
int64 v; int64 v;
sr.Deserialize("ErrorCode", v); sr.Deserialize("ErrorCode", v);
ErrorCode = (LONG_PCSC)v; ErrorCode = (LONG_PCSC)v;
} }
void PCSCException::Serialize(shared_ptr <Stream> stream) const void PCSCException::SerializeData(shared_ptr <Stream> stream) const
{ {
Exception::Serialize(stream); Exception::SerializeData(stream);
Serializer sr(stream); Serializer sr(stream);
int64 v = (int64)ErrorCode; int64 v = (int64)ErrorCode;
sr.Serialize("ErrorCode", v); sr.Serialize("ErrorCode", v);
@@ -176,17 +176,17 @@ namespace VeraCrypt
#ifdef TC_HEADER_Platform_Exception #ifdef TC_HEADER_Platform_Exception
void CommandAPDUNotValid::Deserialize(shared_ptr <Stream> stream) void CommandAPDUNotValid::DeserializeData(shared_ptr <Stream> stream)
{ {
Exception::Deserialize(stream); Exception::DeserializeData(stream);
Serializer sr(stream); Serializer sr(stream);
sr.Deserialize("SrcPos", SrcPos); sr.Deserialize("SrcPos", SrcPos);
sr.Deserialize("ErrorStr", ErrorStr); sr.Deserialize("ErrorStr", ErrorStr);
} }
void CommandAPDUNotValid::Serialize(shared_ptr <Stream> stream) const void CommandAPDUNotValid::SerializeData(shared_ptr <Stream> stream) const
{ {
Exception::Serialize(stream); Exception::SerializeData(stream);
Serializer sr(stream); Serializer sr(stream);
sr.Serialize("SrcPos", SrcPos); sr.Serialize("SrcPos", SrcPos);
sr.Serialize("ErrorStr", ErrorStr); sr.Serialize("ErrorStr", ErrorStr);
+4 -4
View File
@@ -753,9 +753,9 @@ namespace VeraCrypt
#ifdef TC_HEADER_Platform_Exception #ifdef TC_HEADER_Platform_Exception
void Pkcs11Exception::Deserialize(shared_ptr <Stream> stream) void Pkcs11Exception::DeserializeData(shared_ptr <Stream> stream)
{ {
Exception::Deserialize(stream); Exception::DeserializeData(stream);
Serializer sr(stream); Serializer sr(stream);
uint64 code; uint64 code;
sr.Deserialize("ErrorCode", code); sr.Deserialize("ErrorCode", code);
@@ -764,9 +764,9 @@ namespace VeraCrypt
ErrorCode = (CK_RV)code; ErrorCode = (CK_RV)code;
} }
void Pkcs11Exception::Serialize(shared_ptr <Stream> stream) const void Pkcs11Exception::SerializeData(shared_ptr <Stream> stream) const
{ {
Exception::Serialize(stream); Exception::SerializeData(stream);
Serializer sr(stream); Serializer sr(stream);
sr.Serialize("ErrorCode", (uint64)ErrorCode); sr.Serialize("ErrorCode", (uint64)ErrorCode);
sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid); sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid);
+1
View File
@@ -13,6 +13,7 @@
OBJS := OBJS :=
OBJS += CoreBase.o OBJS += CoreBase.o
OBJS += CoreException.o OBJS += CoreException.o
OBJS += CoreTest.o
OBJS += FatFormatter.o OBJS += FatFormatter.o
OBJS += HostDevice.o OBJS += HostDevice.o
OBJS += MountOptions.o OBJS += MountOptions.o
+8 -8
View File
@@ -15,24 +15,24 @@
namespace VeraCrypt namespace VeraCrypt
{ {
void ElevationFailed::Deserialize (shared_ptr <Stream> stream) void ElevationFailed::DeserializeData (shared_ptr <Stream> stream)
{ {
ExecutedProcessFailed::Deserialize (stream); ExecutedProcessFailed::DeserializeData (stream);
} }
void ElevationFailed::Serialize (shared_ptr <Stream> stream) const void ElevationFailed::SerializeData (shared_ptr <Stream> stream) const
{ {
ExecutedProcessFailed::Serialize (stream); ExecutedProcessFailed::SerializeData (stream);
} }
void FilesystemDismountFailed::Deserialize (shared_ptr <Stream> stream) void FilesystemDismountFailed::DeserializeData (shared_ptr <Stream> stream)
{ {
ExecutedProcessFailed::Deserialize (stream); ExecutedProcessFailed::DeserializeData (stream);
} }
void FilesystemDismountFailed::Serialize (shared_ptr <Stream> stream) const void FilesystemDismountFailed::SerializeData (shared_ptr <Stream> stream) const
{ {
ExecutedProcessFailed::Serialize (stream); ExecutedProcessFailed::SerializeData (stream);
} }
#define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) #define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
+126
View File
@@ -0,0 +1,126 @@
/*
Copyright (c) 2026 AM Crypto. All rights reserved.
Governed by the Apache License 2.0, the full text of which is contained in
the file License.txt included in VeraCrypt binary and source distributions.
*/
#include "CoreTest.h"
#include "HostDevice.h"
#include "Platform/MemoryStream.h"
#include "Unix/CoreServiceRequest.h"
#include "Volume/VolumePassword.h"
namespace VeraCrypt
{
void CoreTest::HostDeviceTest ()
{
HostDevice device;
device.Name = L"Device";
device.SystemNumber = 0;
shared_ptr <HostDevice> partition (new HostDevice);
partition->Name = L"Partition";
partition->SystemNumber = 1;
device.Partitions.push_back (partition);
// Exercise real parent/child serialization at the nesting boundary using a
// shallow tree and reserved scopes, without constructing a deep input tree.
for (int attempt = 0; attempt < 2; ++attempt)
{
shared_ptr <Stream> stream (new MemoryStream);
vector < shared_ptr <SerializationScope> > scopes;
if (attempt != 0)
{
for (unsigned int i = 0; i < Serializer::MaxNestingDepth - 2; ++i)
scopes.push_back (shared_ptr <SerializationScope> (new SerializationScope (stream)));
}
device.Serialize (stream);
shared_ptr <HostDevice> result = Serializable::DeserializeNew <HostDevice> (stream);
if (result->Name != device.Name || result->Partitions.size() != 1
|| result->Partitions.front()->Name != partition->Name
|| result->Partitions.front()->SystemNumber != partition->SystemNumber)
throw TestFailed (SRC_POS);
}
for (int direction = 0; direction < 2; ++direction)
{
shared_ptr <Stream> stream (new MemoryStream);
device.Serialize (stream);
vector < shared_ptr <SerializationScope> > scopes;
for (unsigned int i = 0; i < Serializer::MaxNestingDepth - 1; ++i)
scopes.push_back (shared_ptr <SerializationScope> (new SerializationScope (stream)));
try
{
if (direction == 0)
Serializable::DeserializeNew <HostDevice> (stream);
else
device.Serialize (stream);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
scopes.clear();
SerializationScope reusable (stream);
}
device.Partitions.assign ((size_t) Serializer::MaxCollectionSize + 1, partition);
try
{
shared_ptr <Stream> stream (new MemoryStream);
device.Serialize (stream);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
}
void CoreTest::VolumePasswordTest ()
{
SecureBuffer password (VolumePassword::MaxSize);
for (size_t i = 0; i < password.Size(); ++i)
password[i] = (uint8) i;
const size_t sizes[] = { 0, VolumePassword::MaxLegacySize, VolumePassword::MaxSize };
for (size_t i = 0; i < array_capacity (sizes); ++i)
{
shared_ptr <Stream> stream (new MemoryStream);
VolumePassword original (password.Ptr(), sizes[i]);
original.Serialize (stream);
shared_ptr <VolumePassword> result = Serializable::DeserializeNew <VolumePassword> (stream);
if (*result != original)
throw TestFailed (SRC_POS);
}
shared_ptr <Stream> stream (new MemoryStream);
Serializer sr (stream);
Serializable::SerializeHeader (sr, "VolumePassword");
sr.Serialize ("PasswordSize", (uint64) VolumePassword::MaxSize + 1);
try
{
Serializable::DeserializeNew <VolumePassword> (stream);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
VolumePassword invalid (password.Ptr(), VolumePassword::MaxSize + 1);
throw TestFailed (SRC_POS);
}
catch (PasswordTooLong &) { }
}
void CoreTest::ServiceRequestTest ()
{
shared_ptr <Stream> stream (new MemoryStream);
GetDeviceSizeRequest request (DevicePath (L"/dev/test"));
request.Serialize (stream);
shared_ptr <CoreServiceRequest> result = Serializable::DeserializeNew <CoreServiceRequest> (stream);
GetDeviceSizeRequest *deviceRequest = dynamic_cast <GetDeviceSizeRequest *> (result.get());
if (!deviceRequest || deviceRequest->Path != request.Path)
throw TestFailed (SRC_POS);
}
void CoreTest::TestAll ()
{
HostDeviceTest();
VolumePasswordTest();
ServiceRequestTest();
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
Copyright (c) 2026 AM Crypto. All rights reserved.
Governed by the Apache License 2.0, the full text of which is contained in
the file License.txt included in VeraCrypt binary and source distributions.
*/
#ifndef TC_HEADER_Core_CoreTest
#define TC_HEADER_Core_CoreTest
namespace VeraCrypt
{
class CoreTest
{
public:
static void TestAll ();
private:
CoreTest ();
static void HostDeviceTest ();
static void VolumePasswordTest ();
static void ServiceRequestTest ();
};
}
#endif // TC_HEADER_Core_CoreTest
+7 -4
View File
@@ -15,7 +15,7 @@
namespace VeraCrypt namespace VeraCrypt
{ {
void HostDevice::Deserialize (shared_ptr <Stream> stream) void HostDevice::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
MountPoint = sr.DeserializeWString ("MountPoint"); MountPoint = sr.DeserializeWString ("MountPoint");
@@ -27,13 +27,16 @@ namespace VeraCrypt
uint32 partitionCount; uint32 partitionCount;
sr.Deserialize ("Partitions", partitionCount); sr.Deserialize ("Partitions", partitionCount);
Serializer::ValidateCollectionSize (partitionCount);
HostDeviceList partitions;
for (uint32 i = 0; i < partitionCount; i++) for (uint32 i = 0; i < partitionCount; i++)
Partitions.push_back (Serializable::DeserializeNew <HostDevice> (stream)); partitions.push_back (Serializable::DeserializeNew <HostDevice> (stream));
Partitions.swap (partitions);
} }
void HostDevice::Serialize (shared_ptr <Stream> stream) const void HostDevice::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream); Serializer::ValidateCollectionSize (Partitions.size());
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("MountPoint", wstring (MountPoint)); sr.Serialize ("MountPoint", wstring (MountPoint));
sr.Serialize ("Name", Name); sr.Serialize ("Name", Name);
+2 -3
View File
@@ -58,7 +58,7 @@ namespace VeraCrypt
TC_CLONE (EMVSupportEnabled); TC_CLONE (EMVSupportEnabled);
} }
void MountOptions::Deserialize (shared_ptr <Stream> stream) void MountOptions::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
wstring nameValue; wstring nameValue;
@@ -132,9 +132,8 @@ namespace VeraCrypt
sr.Deserialize ("ProtectionPim", ProtectionPim); sr.Deserialize ("ProtectionPim", ProtectionPim);
} }
void MountOptions::Serialize (shared_ptr <Stream> stream) const void MountOptions::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("CachePassword", CachePassword); sr.Serialize ("CachePassword", CachePassword);
+19 -9
View File
@@ -574,14 +574,12 @@ namespace VeraCrypt
if (errOutput.empty()) if (errOutput.empty())
return; return;
unique_ptr <Serializable> deserializedObject; shared_ptr <Exception> deserializedException;
Exception *deserializedException = nullptr;
try try
{ {
shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &errOutput[0], errOutput.size()))); shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &errOutput[0], errOutput.size())));
deserializedObject.reset (Serializable::DeserializeNew (stream)); deserializedException = Serializable::DeserializeNew <Exception> (stream);
deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
} }
catch (...) { } catch (...) { }
@@ -1076,9 +1074,21 @@ namespace VeraCrypt
} }
#endif #endif
unique_ptr <Serializable> CoreService::GetResponseObject () template <class T>
static bool IsResponseType (const Serializable &object)
{ {
unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream)); return Serializable::IsType <T> (object) || Serializable::IsType <Exception> (object);
}
template <class T>
static bool IsInitialResponseType (const Serializable &object)
{
return IsResponseType <T> (object) || Serializable::IsType <ElevatedServiceStartedResponse> (object);
}
unique_ptr <Serializable> CoreService::GetResponseObject (Serializable::TypeValidator isExpectedType)
{
unique_ptr <Serializable> deserializedObject (Serializable::DeserializeNew (ServiceOutputStream, isExpectedType));
Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get()); Exception *deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
if (deserializedException) if (deserializedException)
@@ -1090,7 +1100,7 @@ namespace VeraCrypt
template <class T> template <class T>
unique_ptr <T> CoreService::GetResponse () unique_ptr <T> CoreService::GetResponse ()
{ {
unique_ptr <Serializable> deserializedObject (GetResponseObject()); unique_ptr <Serializable> deserializedObject (GetResponseObject (&IsResponseType <T>));
if (dynamic_cast <T *> (deserializedObject.get()) == nullptr) if (dynamic_cast <T *> (deserializedObject.get()) == nullptr)
throw ParameterIncorrect (SRC_POS); throw ParameterIncorrect (SRC_POS);
@@ -1206,7 +1216,7 @@ namespace VeraCrypt
ElevatedServiceStartedResponse().Serialize (outputStream); ElevatedServiceStartedResponse().Serialize (outputStream);
request->Serialize (ServiceInputStream); request->Serialize (ServiceInputStream);
GetResponse <Serializable>()->Serialize (outputStream); GetResponse <CoreServiceResponse>()->Serialize (outputStream);
continue; continue;
} }
@@ -1500,7 +1510,7 @@ namespace VeraCrypt
{ {
request.Serialize (ServiceInputStream); request.Serialize (ServiceInputStream);
unique_ptr <Serializable> response (GetResponseObject()); unique_ptr <Serializable> response (GetResponseObject (&IsInitialResponseType <T>));
if (dynamic_cast <ElevatedServiceStartedResponse *> (response.get()) != nullptr) if (dynamic_cast <ElevatedServiceStartedResponse *> (response.get()) != nullptr)
{ {
// The elevated channel is usable even if the forwarded request fails. // The elevated channel is usable even if the forwarded request fails.
+1 -1
View File
@@ -50,7 +50,7 @@ namespace VeraCrypt
static void Stop (); static void Stop ();
protected: protected:
static unique_ptr <Serializable> GetResponseObject (); static unique_ptr <Serializable> GetResponseObject (Serializable::TypeValidator isExpectedType);
template <class T> static unique_ptr <T> GetResponse (); template <class T> static unique_ptr <T> GetResponse ();
template <class T> static unique_ptr <T> SendRequest (CoreServiceRequest &request); template <class T> static unique_ptr <T> SendRequest (CoreServiceRequest &request);
static void StartElevated (const CoreServiceRequest &request); static void StartElevated (const CoreServiceRequest &request);
+50 -51
View File
@@ -16,7 +16,7 @@
namespace VeraCrypt namespace VeraCrypt
{ {
void CoreServiceRequest::Deserialize (shared_ptr <Stream> stream) void CoreServiceRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("AdminPassword", AdminPassword); sr.Deserialize ("AdminPassword", AdminPassword);
@@ -28,9 +28,8 @@ namespace VeraCrypt
sr.Deserialize ("AllowInsecureMount", AllowInsecureMount); sr.Deserialize ("AllowInsecureMount", AllowInsecureMount);
} }
void CoreServiceRequest::Serialize (shared_ptr <Stream> stream) const void CoreServiceRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("AdminPassword", AdminPassword); sr.Serialize ("AdminPassword", AdminPassword);
sr.Serialize ("ApplicationExecutablePath", wstring (ApplicationExecutablePath)); sr.Serialize ("ApplicationExecutablePath", wstring (ApplicationExecutablePath));
@@ -42,9 +41,9 @@ namespace VeraCrypt
} }
// CheckFilesystemRequest // CheckFilesystemRequest
void CheckFilesystemRequest::Deserialize (shared_ptr <Stream> stream) void CheckFilesystemRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream); MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
sr.Deserialize ("Repair", Repair); sr.Deserialize ("Repair", Repair);
@@ -58,18 +57,18 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void CheckFilesystemRequest::Serialize (shared_ptr <Stream> stream) const void CheckFilesystemRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
MountedVolumeInfo->Serialize (stream); MountedVolumeInfo->Serialize (stream);
sr.Serialize ("Repair", Repair); sr.Serialize ("Repair", Repair);
} }
// DismountFilesystemRequest // DismountFilesystemRequest
void DismountFilesystemRequest::Deserialize (shared_ptr <Stream> stream) void DismountFilesystemRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("Force", Force); sr.Deserialize ("Force", Force);
MountPoint = sr.DeserializeWString ("MountPoint"); MountPoint = sr.DeserializeWString ("MountPoint");
@@ -80,18 +79,18 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void DismountFilesystemRequest::Serialize (shared_ptr <Stream> stream) const void DismountFilesystemRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Force", Force); sr.Serialize ("Force", Force);
sr.Serialize ("MountPoint", wstring (MountPoint)); sr.Serialize ("MountPoint", wstring (MountPoint));
} }
// DismountVolumeRequest // DismountVolumeRequest
void DismountVolumeRequest::Deserialize (shared_ptr <Stream> stream) void DismountVolumeRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("IgnoreOpenFiles", IgnoreOpenFiles); sr.Deserialize ("IgnoreOpenFiles", IgnoreOpenFiles);
sr.Deserialize ("SyncVolumeInfo", SyncVolumeInfo); sr.Deserialize ("SyncVolumeInfo", SyncVolumeInfo);
@@ -119,9 +118,9 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void DismountVolumeRequest::Serialize (shared_ptr <Stream> stream) const void DismountVolumeRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("IgnoreOpenFiles", IgnoreOpenFiles); sr.Serialize ("IgnoreOpenFiles", IgnoreOpenFiles);
sr.Serialize ("SyncVolumeInfo", SyncVolumeInfo); sr.Serialize ("SyncVolumeInfo", SyncVolumeInfo);
@@ -130,9 +129,9 @@ namespace VeraCrypt
#ifdef TC_LINUX #ifdef TC_LINUX
// EmergencyDismountVolumeRequest // EmergencyDismountVolumeRequest
void EmergencyDismountVolumeRequest::Deserialize (shared_ptr <Stream> stream) void EmergencyDismountVolumeRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream); MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
} }
@@ -141,17 +140,17 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void EmergencyDismountVolumeRequest::Serialize (shared_ptr <Stream> stream) const void EmergencyDismountVolumeRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
MountedVolumeInfo->Serialize (stream); MountedVolumeInfo->Serialize (stream);
} }
#endif #endif
// GetDeviceSectorSizeRequest // GetDeviceSectorSizeRequest
void GetDeviceSectorSizeRequest::Deserialize (shared_ptr <Stream> stream) void GetDeviceSectorSizeRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
Path = sr.DeserializeWString ("Path"); Path = sr.DeserializeWString ("Path");
} }
@@ -161,17 +160,17 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void GetDeviceSectorSizeRequest::Serialize (shared_ptr <Stream> stream) const void GetDeviceSectorSizeRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Path", wstring (Path)); sr.Serialize ("Path", wstring (Path));
} }
// GetDeviceSizeRequest // GetDeviceSizeRequest
void GetDeviceSizeRequest::Deserialize (shared_ptr <Stream> stream) void GetDeviceSizeRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
Path = sr.DeserializeWString ("Path"); Path = sr.DeserializeWString ("Path");
} }
@@ -181,17 +180,17 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void GetDeviceSizeRequest::Serialize (shared_ptr <Stream> stream) const void GetDeviceSizeRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Path", wstring (Path)); sr.Serialize ("Path", wstring (Path));
} }
// GetHostDevicesRequest // GetHostDevicesRequest
void GetHostDevicesRequest::Deserialize (shared_ptr <Stream> stream) void GetHostDevicesRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("PathListOnly", PathListOnly); sr.Deserialize ("PathListOnly", PathListOnly);
} }
@@ -201,29 +200,29 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void GetHostDevicesRequest::Serialize (shared_ptr <Stream> stream) const void GetHostDevicesRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("PathListOnly", PathListOnly); sr.Serialize ("PathListOnly", PathListOnly);
} }
// ExitRequest // ExitRequest
void ExitRequest::Deserialize (shared_ptr <Stream> stream) void ExitRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
} }
void ExitRequest::Serialize (shared_ptr <Stream> stream) const void ExitRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
} }
#ifdef TC_MACOSX #ifdef TC_MACOSX
// ExecuteMacOSXAPFSFormatterRequest // ExecuteMacOSXAPFSFormatterRequest
void ExecuteMacOSXAPFSFormatterRequest::Deserialize (shared_ptr <Stream> stream) void ExecuteMacOSXAPFSFormatterRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
Device = sr.DeserializeWString ("Device"); Device = sr.DeserializeWString ("Device");
sr.Deserialize ("OwnerGroupId", OwnerGroupId); sr.Deserialize ("OwnerGroupId", OwnerGroupId);
@@ -235,9 +234,9 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void ExecuteMacOSXAPFSFormatterRequest::Serialize (shared_ptr <Stream> stream) const void ExecuteMacOSXAPFSFormatterRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Device", wstring (Device)); sr.Serialize ("Device", wstring (Device));
sr.Serialize ("OwnerGroupId", OwnerGroupId); sr.Serialize ("OwnerGroupId", OwnerGroupId);
@@ -247,9 +246,9 @@ namespace VeraCrypt
#ifdef TC_OPENBSD #ifdef TC_OPENBSD
// ExecuteOpenBSDFFSFormatterRequest // ExecuteOpenBSDFFSFormatterRequest
void ExecuteOpenBSDFFSFormatterRequest::Deserialize (shared_ptr <Stream> stream) void ExecuteOpenBSDFFSFormatterRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
Device = sr.DeserializeWString ("Device"); Device = sr.DeserializeWString ("Device");
sr.Deserialize ("OwnerGroupId", OwnerGroupId); sr.Deserialize ("OwnerGroupId", OwnerGroupId);
@@ -261,9 +260,9 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void ExecuteOpenBSDFFSFormatterRequest::Serialize (shared_ptr <Stream> stream) const void ExecuteOpenBSDFFSFormatterRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Device", wstring (Device)); sr.Serialize ("Device", wstring (Device));
sr.Serialize ("OwnerGroupId", OwnerGroupId); sr.Serialize ("OwnerGroupId", OwnerGroupId);
@@ -272,9 +271,9 @@ namespace VeraCrypt
#endif #endif
// MountVolumeRequest // MountVolumeRequest
void MountVolumeRequest::Deserialize (shared_ptr <Stream> stream) void MountVolumeRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
DeserializedOptions = Serializable::DeserializeNew <MountOptions> (stream); DeserializedOptions = Serializable::DeserializeNew <MountOptions> (stream);
Options = DeserializedOptions.get(); Options = DeserializedOptions.get();
@@ -301,17 +300,17 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void MountVolumeRequest::Serialize (shared_ptr <Stream> stream) const void MountVolumeRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
Options->Serialize (stream); Options->Serialize (stream);
} }
// SetFileOwnerRequest // SetFileOwnerRequest
void SetFileOwnerRequest::Deserialize (shared_ptr <Stream> stream) void SetFileOwnerRequest::DeserializeData (shared_ptr <Stream> stream)
{ {
CoreServiceRequest::Deserialize (stream); CoreServiceRequest::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
uint64 owner; uint64 owner;
@@ -326,9 +325,9 @@ namespace VeraCrypt
return !Core->HasAdminPrivileges(); return !Core->HasAdminPrivileges();
} }
void SetFileOwnerRequest::Serialize (shared_ptr <Stream> stream) const void SetFileOwnerRequest::SerializeData (shared_ptr <Stream> stream) const
{ {
CoreServiceRequest::Serialize (stream); CoreServiceRequest::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
uint64 owner = Owner.SystemId; uint64 owner = Owner.SystemId;
+22 -33
View File
@@ -16,134 +16,123 @@
namespace VeraCrypt namespace VeraCrypt
{ {
// ElevatedServiceStartedResponse // ElevatedServiceStartedResponse
void ElevatedServiceStartedResponse::Deserialize (shared_ptr <Stream> stream) void ElevatedServiceStartedResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void ElevatedServiceStartedResponse::Serialize (shared_ptr <Stream> stream) const void ElevatedServiceStartedResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
// CheckFilesystemResponse // CheckFilesystemResponse
void CheckFilesystemResponse::Deserialize (shared_ptr <Stream> stream) void CheckFilesystemResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void CheckFilesystemResponse::Serialize (shared_ptr <Stream> stream) const void CheckFilesystemResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
// DismountFilesystemResponse // DismountFilesystemResponse
void DismountFilesystemResponse::Deserialize (shared_ptr <Stream> stream) void DismountFilesystemResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void DismountFilesystemResponse::Serialize (shared_ptr <Stream> stream) const void DismountFilesystemResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
// DismountVolumeResponse // DismountVolumeResponse
void DismountVolumeResponse::Deserialize (shared_ptr <Stream> stream) void DismountVolumeResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
DismountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream); DismountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
} }
void DismountVolumeResponse::Serialize (shared_ptr <Stream> stream) const void DismountVolumeResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
DismountedVolumeInfo->Serialize (stream); DismountedVolumeInfo->Serialize (stream);
} }
// GetDeviceSectorSizeResponse // GetDeviceSectorSizeResponse
void GetDeviceSectorSizeResponse::Deserialize (shared_ptr <Stream> stream) void GetDeviceSectorSizeResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("Size", Size); sr.Deserialize ("Size", Size);
} }
void GetDeviceSectorSizeResponse::Serialize (shared_ptr <Stream> stream) const void GetDeviceSectorSizeResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Size", Size); sr.Serialize ("Size", Size);
} }
// GetDeviceSizeResponse // GetDeviceSizeResponse
void GetDeviceSizeResponse::Deserialize (shared_ptr <Stream> stream) void GetDeviceSizeResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("Size", Size); sr.Deserialize ("Size", Size);
} }
void GetDeviceSizeResponse::Serialize (shared_ptr <Stream> stream) const void GetDeviceSizeResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Size", Size); sr.Serialize ("Size", Size);
} }
// GetHostDevicesResponse // GetHostDevicesResponse
void GetHostDevicesResponse::Deserialize (shared_ptr <Stream> stream) void GetHostDevicesResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializable::DeserializeList (stream, HostDevices); Serializable::DeserializeList (stream, HostDevices);
} }
void GetHostDevicesResponse::Serialize (shared_ptr <Stream> stream) const void GetHostDevicesResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializable::SerializeList (stream, HostDevices); Serializable::SerializeList (stream, HostDevices);
} }
#ifdef TC_MACOSX #ifdef TC_MACOSX
// ExecuteMacOSXAPFSFormatterResponse // ExecuteMacOSXAPFSFormatterResponse
void ExecuteMacOSXAPFSFormatterResponse::Deserialize (shared_ptr <Stream> stream) void ExecuteMacOSXAPFSFormatterResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void ExecuteMacOSXAPFSFormatterResponse::Serialize (shared_ptr <Stream> stream) const void ExecuteMacOSXAPFSFormatterResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
#endif #endif
#ifdef TC_OPENBSD #ifdef TC_OPENBSD
// ExecuteOpenBSDFFSFormatterResponse // ExecuteOpenBSDFFSFormatterResponse
void ExecuteOpenBSDFFSFormatterResponse::Deserialize (shared_ptr <Stream> stream) void ExecuteOpenBSDFFSFormatterResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void ExecuteOpenBSDFFSFormatterResponse::Serialize (shared_ptr <Stream> stream) const void ExecuteOpenBSDFFSFormatterResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
#endif #endif
// MountVolumeResponse // MountVolumeResponse
void MountVolumeResponse::Deserialize (shared_ptr <Stream> stream) void MountVolumeResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream); MountedVolumeInfo = Serializable::DeserializeNew <VolumeInfo> (stream);
} }
void MountVolumeResponse::Serialize (shared_ptr <Stream> stream) const void MountVolumeResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
MountedVolumeInfo->Serialize (stream); MountedVolumeInfo->Serialize (stream);
} }
// SetFileOwnerResponse // SetFileOwnerResponse
void SetFileOwnerResponse::Deserialize (shared_ptr <Stream> stream) void SetFileOwnerResponse::DeserializeData (shared_ptr <Stream> stream)
{ {
} }
void SetFileOwnerResponse::Serialize (shared_ptr <Stream> stream) const void SetFileOwnerResponse::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
} }
TC_SERIALIZER_FACTORY_ADD_CLASS (ElevatedServiceStartedResponse); TC_SERIALIZER_FACTORY_ADD_CLASS (ElevatedServiceStartedResponse);
+2
View File
@@ -19,6 +19,7 @@
#include <wx/apptrait.h> #include <wx/apptrait.h>
#include <wx/cmdline.h> #include <wx/cmdline.h>
#include "Crypto/cpu.h" #include "Crypto/cpu.h"
#include "Core/CoreTest.h"
#include "Platform/PlatformTest.h" #include "Platform/PlatformTest.h"
#include "Common/PCSCException.h" #include "Common/PCSCException.h"
#ifdef TC_UNIX #ifdef TC_UNIX
@@ -1829,6 +1830,7 @@ const FileManager fileManagers[] = {
if (!PlatformTest::TestAll()) if (!PlatformTest::TestAll())
throw TestFailed (SRC_POS); throw TestFailed (SRC_POS);
CoreTest::TestAll();
EncryptionTest::TestAll(); EncryptionTest::TestAll();
// StringFormatter // StringFormatter
+6 -7
View File
@@ -15,33 +15,32 @@
namespace VeraCrypt namespace VeraCrypt
{ {
void Exception::Deserialize (shared_ptr <Stream> stream) void Exception::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("Message", Message); sr.Deserialize ("Message", Message);
sr.Deserialize ("Subject", Subject); sr.Deserialize ("Subject", Subject);
} }
void Exception::Serialize (shared_ptr <Stream> stream) const void Exception::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Message", Message); sr.Serialize ("Message", Message);
sr.Serialize ("Subject", Subject); sr.Serialize ("Subject", Subject);
} }
void ExecutedProcessFailed::Deserialize (shared_ptr <Stream> stream) void ExecutedProcessFailed::DeserializeData (shared_ptr <Stream> stream)
{ {
Exception::Deserialize (stream); Exception::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("Command", Command); sr.Deserialize ("Command", Command);
sr.Deserialize ("ExitCode", ExitCode); sr.Deserialize ("ExitCode", ExitCode);
sr.Deserialize ("ErrorOutput", ErrorOutput); sr.Deserialize ("ErrorOutput", ErrorOutput);
} }
void ExecutedProcessFailed::Serialize (shared_ptr <Stream> stream) const void ExecutedProcessFailed::SerializeData (shared_ptr <Stream> stream) const
{ {
Exception::Serialize (stream); Exception::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("Command", Command); sr.Serialize ("Command", Command);
sr.Serialize ("ExitCode", ExitCode); sr.Serialize ("ExitCode", ExitCode);
+311
View File
@@ -26,6 +26,312 @@
namespace VeraCrypt namespace VeraCrypt
{ {
class TestSerializer : public Serializer
{
public:
TestSerializer (shared_ptr <Stream> stream) : Serializer (stream) { }
string ReadString () { return DeserializeString (); }
wstring ReadWString () { return DeserializeWString (); }
};
static shared_ptr <Stream> CreateStringTestStream (uint64 declaredSize, const ConstBufferPtr &data)
{
shared_ptr <Stream> stream (new MemoryStream);
uint64 fieldSize = Endian::Big (uint64 (sizeof (declaredSize)));
uint64 size = Endian::Big (declaredSize);
stream->Write (ConstBufferPtr ((uint8 *) &fieldSize, sizeof (fieldSize)));
stream->Write (ConstBufferPtr ((uint8 *) &size, sizeof (size)));
if (data.Size() > 0)
stream->Write (data);
return stream;
}
static void SerializerFailureTest ()
{
bool exceptionThrown = false;
try
{
TestSerializer ser (CreateStringTestStream (0, ConstBufferPtr()));
ser.ReadString ();
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
exceptionThrown = false;
try
{
TestSerializer ser (CreateStringTestStream (1024 * 1024 + 1, ConstBufferPtr()));
ser.ReadString ();
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
uint8 unterminatedString = 'x';
exceptionThrown = false;
try
{
TestSerializer ser (CreateStringTestStream (1, ConstBufferPtr (&unterminatedString, 1)));
ser.ReadString ();
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
exceptionThrown = false;
try
{
TestSerializer ser (CreateStringTestStream (sizeof (wchar_t) - 1, ConstBufferPtr()));
ser.ReadWString ();
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
wchar_t unterminatedWString = L'x';
exceptionThrown = false;
try
{
TestSerializer ser (CreateStringTestStream (sizeof (unterminatedWString), ConstBufferPtr ((uint8 *) &unterminatedWString, sizeof (unterminatedWString))));
ser.ReadWString ();
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
exceptionThrown = false;
try
{
Serializer::ValidateCollectionSize (65537);
}
catch (ParameterIncorrect &) { exceptionThrown = true; }
if (!exceptionThrown)
throw TestFailed (SRC_POS);
}
static void SerializerStringPolicyTest ()
{
shared_ptr <Stream> stream (new MemoryStream);
Serializer sr (stream);
const string strings[] = { "", "text", string ((size_t) Serializer::MaxStringSize - 1, 'x') };
const wstring wstrings[] = { L"", L"text", wstring ((size_t) Serializer::MaxStringSize / sizeof (wchar_t) - 1, L'x') };
for (size_t i = 0; i < array_capacity (strings); ++i)
{
sr.Serialize ("String", strings[i]);
sr.Serialize ("WString", wstrings[i]);
if (sr.DeserializeString ("String") != strings[i] || sr.DeserializeWString ("WString") != wstrings[i])
throw TestFailed (SRC_POS);
}
const string invalidStrings[] = { string ("x\0y", 3), string (1, '\0'), string ((size_t) Serializer::MaxStringSize, 'x') };
const wstring invalidWStrings[] = { wstring (L"x\0y", 3), wstring (1, L'\0'), wstring ((size_t) Serializer::MaxStringSize / sizeof (wchar_t), L'x') };
for (size_t i = 0; i < array_capacity (invalidStrings); ++i)
{
try
{
sr.Serialize ("String", invalidStrings[i]);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
sr.Serialize ("WString", invalidWStrings[i]);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
TestSerializer reader (CreateStringTestStream (invalidStrings[i].size() + 1,
ConstBufferPtr ((const uint8 *) invalidStrings[i].c_str(), invalidStrings[i].size() + 1)));
reader.ReadString();
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
size_t size = (invalidWStrings[i].size() + 1) * sizeof (wchar_t);
TestSerializer reader (CreateStringTestStream (size, ConstBufferPtr ((const uint8 *) invalidWStrings[i].c_str(), size)));
reader.ReadWString();
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
}
try
{
TestSerializer reader (CreateStringTestStream (0, ConstBufferPtr()));
reader.ReadWString();
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
}
static void SerializerCollectionTest ()
{
shared_ptr <Stream> stream (new MemoryStream);
Serializer sr (stream);
list <string> strings ((size_t) Serializer::MaxCollectionSize + 1);
list <wstring> wstrings ((size_t) Serializer::MaxCollectionSize + 1);
list < shared_ptr <Exception> > objects ((size_t) Serializer::MaxCollectionSize + 1);
try
{
sr.Serialize ("Strings", strings);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
sr.Serialize ("WStrings", wstrings);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
try
{
Serializable::SerializeList (stream, objects);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
strings.pop_back();
wstrings.pop_back();
sr.Serialize ("Strings", strings);
sr.Serialize ("WStrings", wstrings);
if (sr.DeserializeStringList ("Strings") != strings || sr.DeserializeWStringList ("WStrings") != wstrings)
throw TestFailed (SRC_POS);
sr.Serialize ("Strings", Serializer::MaxCollectionSize + 1);
try
{
sr.DeserializeStringList ("Strings");
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
sr.Serialize ("WStrings", Serializer::MaxCollectionSize + 1);
try
{
sr.DeserializeWStringList ("WStrings");
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
Serializable::SerializeHeader (sr, "list<Exception>");
sr.Serialize ("ListSize", Serializer::MaxCollectionSize + 1);
objects.clear();
try
{
Serializable::DeserializeList (stream, objects);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
}
// Registered only for this test; counters check that rejection happens before parsing
// and that failed reads release the object, including through the raw-pointer API.
class SerializerTestObject : public Serializable
{
public:
SerializerTestObject () { ++LiveCount; }
virtual ~SerializerTestObject () { --LiveCount; }
static Serializable *GetNewSerializable () { return new SerializerTestObject; }
virtual void DeserializeData (shared_ptr <Stream> stream)
{
++ParseCount;
Serializer sr (stream);
sr.DeserializeUInt32 ("Value");
}
static int LiveCount;
static int ParseCount;
};
int SerializerTestObject::LiveCount = 0;
int SerializerTestObject::ParseCount = 0;
static void SerializableTypeTest ()
{
TC_SERIALIZER_FACTORY_ADD (SerializerTestObject);
finally_do ({
SerializerFactory::NameToTypeMap->erase ("SerializerTestObject");
SerializerFactory::TypeToNameMap->erase (StringConverter::GetTypeName (typeid (SerializerTestObject)));
});
SerializerTestObject::ParseCount = 0;
shared_ptr <Stream> stream (new MemoryStream);
Serializer sr (stream);
Serializable::SerializeHeader (sr, "SerializerTestObject");
try
{
Serializable::DeserializeNew <Exception> (stream);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
if (SerializerTestObject::LiveCount != 0 || SerializerTestObject::ParseCount != 0)
throw TestFailed (SRC_POS);
Serializable::SerializeHeader (sr, "list<Exception>");
sr.Serialize ("ListSize", uint64 (1));
Serializable::SerializeHeader (sr, "SerializerTestObject");
list < shared_ptr <Exception> > objects;
try
{
Serializable::DeserializeList (stream, objects);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
if (SerializerTestObject::LiveCount != 0 || SerializerTestObject::ParseCount != 0 || !objects.empty())
throw TestFailed (SRC_POS);
for (int i = 0; i < 2; ++i)
{
Serializable::SerializeHeader (sr, "SerializerTestObject");
try
{
if (i == 0)
{
unique_ptr <Serializable> object (Serializable::DeserializeNew (stream));
}
else
Serializable::DeserializeNew <SerializerTestObject> (stream);
throw TestFailed (SRC_POS);
}
catch (InsufficientData &) { }
if (SerializerTestObject::LiveCount != 0 || SerializerTestObject::ParseCount != i + 1)
throw TestFailed (SRC_POS);
}
ExecutedProcessFailed exception ("message", "command", 1, "output");
exception.Serialize (stream);
shared_ptr <Exception> result = Serializable::DeserializeNew <Exception> (stream);
if (!dynamic_cast <ExecutedProcessFailed *> (result.get()))
throw TestFailed (SRC_POS);
}
static void SerializerNestingTest ()
{
shared_ptr <Stream> stream (new MemoryStream);
for (int attempt = 0; attempt < 2; ++attempt)
{
vector < shared_ptr <SerializationScope> > scopes;
for (unsigned int i = 0; i < Serializer::MaxNestingDepth; ++i)
scopes.push_back (shared_ptr <SerializationScope> (new SerializationScope (stream)));
try
{
SerializationScope excess (stream);
throw TestFailed (SRC_POS);
}
catch (ParameterIncorrect &) { }
// Nesting is local to a stream and is restored when scopes unwind.
shared_ptr <Stream> otherStream (new MemoryStream);
SerializationScope other (otherStream);
scopes.clear();
Serializer sr (stream);
sr.Serialize ("Value", uint32 (7));
if (sr.DeserializeUInt32 ("Value") != 7)
throw TestFailed (SRC_POS);
}
}
// make_shared_auto, File, Stream, MemoryStream, Endian, Serializer, Serializable // make_shared_auto, File, Stream, MemoryStream, Endian, Serializer, Serializable
void PlatformTest::SerializerTest () void PlatformTest::SerializerTest ()
{ {
@@ -345,6 +651,11 @@ namespace VeraCrypt
} }
SerializerTest(); SerializerTest();
SerializerFailureTest();
SerializerStringPolicyTest();
SerializerCollectionTest();
SerializableTypeTest();
SerializerNestingTest();
ThreadTest(); ThreadTest();
return true; return true;
+15 -3
View File
@@ -10,30 +10,42 @@
code distribution packages. code distribution packages.
*/ */
#include "Exception.h"
#include "Serializable.h" #include "Serializable.h"
#include "SerializerFactory.h" #include "SerializerFactory.h"
namespace VeraCrypt namespace VeraCrypt
{ {
void Serializable::Deserialize (shared_ptr <Stream> stream)
{
SerializationScope scope (stream);
DeserializeData (stream);
}
string Serializable::DeserializeHeader (shared_ptr <Stream> stream) string Serializable::DeserializeHeader (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
return sr.DeserializeString ("SerializableName"); return sr.DeserializeString ("SerializableName");
} }
Serializable *Serializable::DeserializeNew (shared_ptr <Stream> stream) Serializable *Serializable::DeserializeNew (shared_ptr <Stream> stream, TypeValidator isExpectedType)
{ {
string name = Serializable::DeserializeHeader (stream); string name = Serializable::DeserializeHeader (stream);
Serializable *serializable = SerializerFactory::GetNewSerializable (name); unique_ptr <Serializable> serializable (SerializerFactory::GetNewSerializable (name));
// Allow legitimate subtypes, but never run an unexpected object's parser.
if (isExpectedType && !isExpectedType (*serializable))
throw ParameterIncorrect (SRC_POS);
serializable->Deserialize (stream); serializable->Deserialize (stream);
return serializable; return serializable.release();
} }
void Serializable::Serialize (shared_ptr <Stream> stream) const void Serializable::Serialize (shared_ptr <Stream> stream) const
{ {
SerializationScope scope (stream);
Serializer sr (stream); Serializer sr (stream);
Serializable::SerializeHeader (sr, SerializerFactory::GetName (typeid (*this))); Serializable::SerializeHeader (sr, SerializerFactory::GetName (typeid (*this)));
SerializeData (stream);
} }
void Serializable::SerializeHeader (Serializer &serializer, const string &name) void Serializable::SerializeHeader (Serializer &serializer, const string &name)
+28 -16
View File
@@ -26,43 +26,50 @@ namespace VeraCrypt
public: public:
virtual ~Serializable () { } virtual ~Serializable () { }
virtual void Deserialize (shared_ptr <Stream> stream) = 0; // Non-virtual entry points enforce nesting limits for every object. Derived
// classes implement only the field operations below; Serialize owns the header.
void Deserialize (shared_ptr <Stream> stream);
static string DeserializeHeader (shared_ptr <Stream> stream); static string DeserializeHeader (shared_ptr <Stream> stream);
static Serializable *DeserializeNew (shared_ptr <Stream> stream); typedef bool (*TypeValidator) (const Serializable &object);
static Serializable *DeserializeNew (shared_ptr <Stream> stream, TypeValidator isExpectedType = nullptr);
template <class T>
static bool IsType (const Serializable &object)
{
return dynamic_cast <const T *> (&object) != nullptr;
}
template <class T> template <class T>
static shared_ptr <T> DeserializeNew (shared_ptr <Stream> stream) static shared_ptr <T> DeserializeNew (shared_ptr <Stream> stream)
{ {
shared_ptr <T> p (dynamic_cast <T *> (DeserializeNew (stream))); return shared_ptr <T> (dynamic_cast <T *> (DeserializeNew (stream, &IsType <T>)));
if (!p)
throw std::runtime_error (SRC_POS);
return p;
} }
template <class T> template <class T>
static void DeserializeList (shared_ptr <Stream> stream, list < shared_ptr <T> > &dataList) static void DeserializeList (shared_ptr <Stream> stream, list < shared_ptr <T> > &dataList)
{ {
SerializationScope scope (stream);
if (DeserializeHeader (stream) != string ("list<") + SerializerFactory::GetName (typeid (T)) + ">") if (DeserializeHeader (stream) != string ("list<") + SerializerFactory::GetName (typeid (T)) + ">")
throw std::runtime_error (SRC_POS); throw std::runtime_error (SRC_POS);
Serializer sr (stream); Serializer sr (stream);
uint64 listSize; uint64 listSize;
sr.Deserialize ("ListSize", listSize); sr.Deserialize ("ListSize", listSize);
Serializer::ValidateCollectionSize (listSize);
for (size_t i = 0; i < listSize; i++) list < shared_ptr <T> > deserializedList;
{ for (uint64 i = 0; i < listSize; i++)
shared_ptr <T> p (dynamic_cast <T *> (DeserializeNew (stream))); deserializedList.push_back (DeserializeNew <T> (stream));
if (!p) dataList.splice (dataList.end(), deserializedList);
throw std::runtime_error (SRC_POS);
dataList.push_back (p);
}
} }
virtual void Serialize (shared_ptr <Stream> stream) const; void Serialize (shared_ptr <Stream> stream) const;
template <class T> template <class T>
static void SerializeList (shared_ptr <Stream> stream, const list < shared_ptr <T> > &dataList) static void SerializeList (shared_ptr <Stream> stream, const list < shared_ptr <T> > &dataList)
{ {
Serializer::ValidateCollectionSize (dataList.size());
SerializationScope scope (stream);
Serializer sr (stream); Serializer sr (stream);
SerializeHeader (sr, string ("list<") + SerializerFactory::GetName (typeid (T)) + ">"); SerializeHeader (sr, string ("list<") + SerializerFactory::GetName (typeid (T)) + ">");
@@ -75,12 +82,17 @@ namespace VeraCrypt
protected: protected:
Serializable () { } Serializable () { }
// Call base-class field operations here, never their public entry points.
virtual void DeserializeData (shared_ptr <Stream> stream) = 0;
virtual void SerializeData (shared_ptr <Stream> stream) const { }
}; };
} }
#define TC_SERIALIZABLE(TYPE) \ #define TC_SERIALIZABLE(TYPE) \
static Serializable *GetNewSerializable () { return new TYPE(); } \ static Serializable *GetNewSerializable () { return new TYPE(); } \
virtual void Deserialize (shared_ptr <Stream> stream); \ protected: \
virtual void Serialize (shared_ptr <Stream> stream) const virtual void DeserializeData (shared_ptr <Stream> stream); \
virtual void SerializeData (shared_ptr <Stream> stream) const; \
public:
#endif // TC_HEADER_Platform_Serializable #endif // TC_HEADER_Platform_Serializable
+51 -7
View File
@@ -10,6 +10,7 @@
code distribution packages. code distribution packages.
*/ */
#include <algorithm>
#include "Exception.h" #include "Exception.h"
#include "ForEach.h" #include "ForEach.h"
#include "Memory.h" #include "Memory.h"
@@ -17,6 +18,24 @@
namespace VeraCrypt namespace VeraCrypt
{ {
SerializationScope::SerializationScope (shared_ptr <Stream> stream) : DataStream (stream)
{
if (!DataStream || DataStream->SerializationDepth >= Serializer::MaxNestingDepth)
throw ParameterIncorrect (SRC_POS);
++DataStream->SerializationDepth;
}
SerializationScope::~SerializationScope ()
{
--DataStream->SerializationDepth;
}
Serializer::Serializer (shared_ptr <Stream> stream) : DataStream (stream)
{
if (!DataStream)
throw ParameterIncorrect (SRC_POS);
}
template <typename T> template <typename T>
T Serializer::Deserialize () T Serializer::Deserialize ()
{ {
@@ -125,11 +144,15 @@ namespace VeraCrypt
string Serializer::DeserializeString () string Serializer::DeserializeString ()
{ {
uint64 size = Deserialize <uint64> (); uint64 size = Deserialize <uint64> ();
if (size == 0 || size > MaxStringSize)
throw ParameterIncorrect (SRC_POS);
vector <char> data ((size_t) size); vector <char> data ((size_t) size);
DataStream->ReadCompleteBuffer (BufferPtr ((uint8 *) &data[0], (size_t) size)); DataStream->ReadCompleteBuffer (BufferPtr ((uint8 *) &data[0], (size_t) size));
if (data.back() != 0 || find (data.begin(), data.end() - 1, '\0') != data.end() - 1)
throw ParameterIncorrect (SRC_POS);
return string (&data[0]); return string (&data[0], data.size() - 1);
} }
string Serializer::DeserializeString (const string &name) string Serializer::DeserializeString (const string &name)
@@ -143,8 +166,9 @@ namespace VeraCrypt
ValidateName (name); ValidateName (name);
list <string> deserializedList; list <string> deserializedList;
uint64 listSize = Deserialize <uint64> (); uint64 listSize = Deserialize <uint64> ();
ValidateCollectionSize (listSize);
for (size_t i = 0; i < listSize; i++) for (uint64 i = 0; i < listSize; i++)
deserializedList.push_back (DeserializeString ()); deserializedList.push_back (DeserializeString ());
return deserializedList; return deserializedList;
@@ -153,11 +177,15 @@ namespace VeraCrypt
wstring Serializer::DeserializeWString () wstring Serializer::DeserializeWString ()
{ {
uint64 size = Deserialize <uint64> (); uint64 size = Deserialize <uint64> ();
if (size == 0 || size > MaxStringSize || size % sizeof (wchar_t) != 0)
throw ParameterIncorrect (SRC_POS);
vector <wchar_t> data ((size_t) size / sizeof (wchar_t)); vector <wchar_t> data ((size_t) size / sizeof (wchar_t));
DataStream->ReadCompleteBuffer (BufferPtr ((uint8 *) &data[0], (size_t) size)); DataStream->ReadCompleteBuffer (BufferPtr ((uint8 *) &data[0], (size_t) size));
if (data.back() != 0 || find (data.begin(), data.end() - 1, L'\0') != data.end() - 1)
throw ParameterIncorrect (SRC_POS);
return wstring (&data[0]); return wstring (&data[0], data.size() - 1);
} }
list <wstring> Serializer::DeserializeWStringList (const string &name) list <wstring> Serializer::DeserializeWStringList (const string &name)
@@ -165,8 +193,9 @@ namespace VeraCrypt
ValidateName (name); ValidateName (name);
list <wstring> deserializedList; list <wstring> deserializedList;
uint64 listSize = Deserialize <uint64> (); uint64 listSize = Deserialize <uint64> ();
ValidateCollectionSize (listSize);
for (size_t i = 0; i < listSize; i++) for (uint64 i = 0; i < listSize; i++)
deserializedList.push_back (DeserializeWString ()); deserializedList.push_back (DeserializeWString ());
return deserializedList; return deserializedList;
@@ -178,6 +207,12 @@ namespace VeraCrypt
return DeserializeWString (); return DeserializeWString ();
} }
void Serializer::ValidateCollectionSize (uint64 size)
{
if (size > MaxCollectionSize)
throw ParameterIncorrect (SRC_POS);
}
template <typename T> template <typename T>
void Serializer::Serialize (T data) void Serializer::Serialize (T data)
{ {
@@ -249,6 +284,7 @@ namespace VeraCrypt
void Serializer::Serialize (const string &name, const list <string> &stringList) void Serializer::Serialize (const string &name, const list <string> &stringList)
{ {
ValidateCollectionSize (stringList.size());
SerializeString (name); SerializeString (name);
uint64 listSize = stringList.size(); uint64 listSize = stringList.size();
@@ -260,6 +296,7 @@ namespace VeraCrypt
void Serializer::Serialize (const string &name, const list <wstring> &stringList) void Serializer::Serialize (const string &name, const list <wstring> &stringList)
{ {
ValidateCollectionSize (stringList.size());
SerializeString (name); SerializeString (name);
uint64 listSize = stringList.size(); uint64 listSize = stringList.size();
@@ -281,15 +318,22 @@ namespace VeraCrypt
void Serializer::SerializeString (const string &data) void Serializer::SerializeString (const string &data)
{ {
// Embedded NULs would be interpreted differently by C-string consumers.
if (data.size() >= MaxStringSize || data.find ('\0') != string::npos)
throw ParameterIncorrect (SRC_POS);
Serialize ((uint64) data.size() + 1); Serialize ((uint64) data.size() + 1);
DataStream->Write (ConstBufferPtr ((uint8 *) (data.data() ? data.data() : data.c_str()), data.size() + 1)); DataStream->Write (ConstBufferPtr ((const uint8 *) data.c_str(), data.size() + 1));
} }
void Serializer::SerializeWString (const wstring &data) void Serializer::SerializeWString (const wstring &data)
{ {
uint64 size = (data.size() + 1) * sizeof (wchar_t); if (data.size() >= MaxStringSize / sizeof (wchar_t) || data.find (L'\0') != wstring::npos)
throw ParameterIncorrect (SRC_POS);
uint64 size = ((uint64) data.size() + 1) * sizeof (wchar_t);
Serialize (size); Serialize (size);
DataStream->Write (ConstBufferPtr ((uint8 *) (data.data() ? data.data() : data.c_str()), (size_t) size)); DataStream->Write (ConstBufferPtr ((const uint8 *) data.c_str(), (size_t) size));
} }
void Serializer::ValidateName (const string &name) void Serializer::ValidateName (const string &name)
+21 -1
View File
@@ -20,12 +20,31 @@
namespace VeraCrypt namespace VeraCrypt
{ {
// An object or object-list operation retains this scope across all its fields.
// Sibling operations and separate streams have independent nesting limits.
class SerializationScope
{
public:
explicit SerializationScope (shared_ptr <Stream> stream);
~SerializationScope ();
private:
shared_ptr <Stream> DataStream;
SerializationScope (const SerializationScope &);
SerializationScope &operator= (const SerializationScope &);
};
class Serializer class Serializer
{ {
public: public:
Serializer (shared_ptr <Stream> stream) : DataStream (stream) { } Serializer (shared_ptr <Stream> stream);
virtual ~Serializer () { } virtual ~Serializer () { }
// Wire sizes include the terminating NUL. The same limits apply in both directions.
static const uint64 MaxCollectionSize = 65536;
static const uint64 MaxStringSize = 1024 * 1024;
static const unsigned int MaxNestingDepth = 64;
void Deserialize (const string &name, bool &data); void Deserialize (const string &name, bool &data);
void Deserialize (const string &name, uint8 &data); void Deserialize (const string &name, uint8 &data);
void Deserialize (const string &name, int32 &data); void Deserialize (const string &name, int32 &data);
@@ -44,6 +63,7 @@ namespace VeraCrypt
list <string> DeserializeStringList (const string &name); list <string> DeserializeStringList (const string &name);
wstring DeserializeWString (const string &name); wstring DeserializeWString (const string &name);
list <wstring> DeserializeWStringList (const string &name); list <wstring> DeserializeWStringList (const string &name);
static void ValidateCollectionSize (uint64 size);
void Serialize (const string &name, bool data); void Serialize (const string &name, bool data);
void Serialize (const string &name, uint8 data); void Serialize (const string &name, uint8 data);
void Serialize (const string &name, const char *data); void Serialize (const string &name, const char *data);
+12 -1
View File
@@ -41,7 +41,18 @@ namespace VeraCrypt
: Pointer (nullptr), UseCount (nullptr) { } : Pointer (nullptr), UseCount (nullptr) { }
explicit SharedPtr (T *pointer) explicit SharedPtr (T *pointer)
: Pointer (pointer), UseCount (new SharedVal <uint64> (1)) { } : Pointer (pointer), UseCount (nullptr)
{
try
{
UseCount = new SharedVal <uint64> (1);
}
catch (...)
{
delete Pointer;
throw;
}
}
SharedPtr (const SharedPtr &source) SharedPtr (const SharedPtr &source)
{ {
+4 -1
View File
@@ -27,9 +27,12 @@ namespace VeraCrypt
virtual void Write (const ConstBufferPtr &data) = 0; virtual void Write (const ConstBufferPtr &data) = 0;
protected: protected:
Stream () { }; Stream () : SerializationDepth (0) { }
private: private:
friend class SerializationScope;
unsigned int SerializationDepth;
Stream (const Stream &); Stream (const Stream &);
Stream &operator= (const Stream &); Stream &operator= (const Stream &);
}; };
+2 -4
View File
@@ -412,14 +412,12 @@ namespace VeraCrypt
if (!exOutput.empty()) if (!exOutput.empty())
{ {
unique_ptr <Serializable> deserializedObject; shared_ptr <Exception> deserializedException;
Exception *deserializedException = nullptr;
try try
{ {
shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &exOutput[0], exOutput.size()))); shared_ptr <Stream> stream (new MemoryStream (ConstBufferPtr ((uint8 *) &exOutput[0], exOutput.size())));
deserializedObject.reset (Serializable::DeserializeNew (stream)); deserializedException = Serializable::DeserializeNew <Exception> (stream);
deserializedException = dynamic_cast <Exception*> (deserializedObject.get());
} }
catch (...) { } catch (...) { }
+4 -4
View File
@@ -38,9 +38,9 @@ namespace VeraCrypt
{ {
} }
void SystemException::Deserialize (shared_ptr <Stream> stream) void SystemException::DeserializeData (shared_ptr <Stream> stream)
{ {
Exception::Deserialize (stream); Exception::DeserializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Deserialize ("ErrorCode", ErrorCode); sr.Deserialize ("ErrorCode", ErrorCode);
} }
@@ -50,9 +50,9 @@ namespace VeraCrypt
return ErrorCode != 0; return ErrorCode != 0;
} }
void SystemException::Serialize (shared_ptr <Stream> stream) const void SystemException::SerializeData (shared_ptr <Stream> stream) const
{ {
Exception::Serialize (stream); Exception::SerializeData (stream);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("ErrorCode", ErrorCode); sr.Serialize ("ErrorCode", ErrorCode);
} }
+2 -3
View File
@@ -16,7 +16,7 @@
namespace VeraCrypt namespace VeraCrypt
{ {
void VolumeInfo::Deserialize (shared_ptr <Stream> stream) void VolumeInfo::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
@@ -63,9 +63,8 @@ namespace VeraCrypt
return first->SerialInstanceNumber > second->SerialInstanceNumber; return first->SerialInstanceNumber > second->SerialInstanceNumber;
} }
void VolumeInfo::Serialize (shared_ptr <Stream> stream) const void VolumeInfo::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream);
Serializer sr (stream); Serializer sr (stream);
const uint32 version = VERSION_NUM; const uint32 version = VERSION_NUM;
+6 -3
View File
@@ -36,11 +36,13 @@ namespace VeraCrypt
PasswordBuffer.Allocate (MaxSize); PasswordBuffer.Allocate (MaxSize);
} }
void VolumePassword::Deserialize (shared_ptr <Stream> stream) void VolumePassword::DeserializeData (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
uint64 passwordSize; uint64 passwordSize;
sr.Deserialize ("PasswordSize", passwordSize); sr.Deserialize ("PasswordSize", passwordSize);
if (passwordSize > MaxSize)
throw ParameterIncorrect (SRC_POS);
PasswordSize = static_cast <size_t> (passwordSize); PasswordSize = static_cast <size_t> (passwordSize);
sr.Deserialize ("PasswordBuffer", BufferPtr (PasswordBuffer)); sr.Deserialize ("PasswordBuffer", BufferPtr (PasswordBuffer));
@@ -48,9 +50,10 @@ namespace VeraCrypt
sr.Deserialize ("WipeData", wipeBuffer); sr.Deserialize ("WipeData", wipeBuffer);
} }
void VolumePassword::Serialize (shared_ptr <Stream> stream) const void VolumePassword::SerializeData (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream); if (PasswordSize > MaxSize)
throw ParameterIncorrect (SRC_POS);
Serializer sr (stream); Serializer sr (stream);
sr.Serialize ("PasswordSize", static_cast <uint64> (PasswordSize)); sr.Serialize ("PasswordSize", static_cast <uint64> (PasswordSize));
sr.Serialize ("PasswordBuffer", ConstBufferPtr (PasswordBuffer)); sr.Serialize ("PasswordBuffer", ConstBufferPtr (PasswordBuffer));