@@ -22,89 +22,89 @@ namespace cpputils {
2222template <size_t KeySize>
2323class EncryptionKey final {
2424private:
25- struct EncryptionKeyData final {
26- public:
27- constexpr static size_t BINARY_LENGTH = FixedSizeData<KeySize>::BINARY_LENGTH ;
28- constexpr static size_t STRING_LENGTH = FixedSizeData<KeySize>::STRING_LENGTH ;
29-
30- EncryptionKeyData (const FixedSizeData<KeySize>& keyData);
31- ~EncryptionKeyData ();
25+ explicit EncryptionKey (std::shared_ptr<Data> keyData)
26+ : _keyData(std::move(keyData)) {
27+ ASSERT (_keyData->size () == KeySize, " Wrong key data size" );
28+ }
29+ template <size_t OtherKeySize> friend class EncryptionKey ;
3230
33- // Disallow copying and moving
34- EncryptionKeyData (const EncryptionKeyData &rhs) = delete ;
35- EncryptionKeyData (EncryptionKeyData &&rhs) = delete ;
36- EncryptionKeyData &operator =(const EncryptionKeyData &rhs) = delete ;
37- EncryptionKeyData &operator =(EncryptionKeyData &&rhs) = delete ;
31+ public:
32+ EncryptionKey (const EncryptionKey& rhs) = default ;
33+ EncryptionKey (EncryptionKey&& rhs) = default ;
34+ EncryptionKey& operator =(const EncryptionKey& rhs) = default ;
35+ EncryptionKey& operator =(EncryptionKey&& rhs) = default ;
36+
37+ static constexpr size_t BINARY_LENGTH = KeySize;
38+ static constexpr size_t STRING_LENGTH = 2 * BINARY_LENGTH ;
39+
40+ static EncryptionKey Null () {
41+ auto data = std::make_shared<Data>(
42+ KeySize,
43+ make_unique_ref<UnswappableAllocator>()
44+ );
45+ data->FillWithZeroes ();
46+ return EncryptionKey (std::move (data));
47+ }
3848
39- FixedSizeData<KeySize> key;
40- DontSwapMemoryRAII memoryProtector; // this makes sure that the key data isn't swapped to disk
41- };
49+ static EncryptionKey FromString (const std::string& keyData) {
50+ ASSERT (keyData.size () == STRING_LENGTH , " Wrong input size or EncryptionKey::FromString()" );
4251
43- public:
44- constexpr static size_t BINARY_LENGTH = EncryptionKeyData::BINARY_LENGTH ;
45- constexpr static size_t STRING_LENGTH = EncryptionKeyData::STRING_LENGTH ;
52+ auto data = std::make_shared<Data>(
53+ Data::FromString (keyData, make_unique_ref<UnswappableAllocator>())
54+ );
55+ ASSERT (data->size () == KeySize, " Wrong input size for EncryptionKey::FromString()" );
4656
47- EncryptionKey (const FixedSizeData<KeySize>& keyData);
57+ return EncryptionKey (std::move (data));
58+ }
4859
49- static EncryptionKey FromBinary (const void *source);
50- static EncryptionKey FromString (const std::string& keyData);
51- std::string ToString () const ;
60+ std::string ToString () const {
61+ auto result = _keyData->ToString ();
62+ ASSERT (result.size () == STRING_LENGTH , " Wrong string length" );
63+ return result;
64+ }
5265
5366 static EncryptionKey CreateKey (RandomGenerator &randomGenerator) {
54- EncryptionKey result (FixedSizeData<BINARY_LENGTH >::Null ());
55- randomGenerator.write (result._key ->key .data (), BINARY_LENGTH );
67+ EncryptionKey result (std::make_shared<Data>(
68+ KeySize,
69+ make_unique_ref<UnswappableAllocator>() // the allocator makes sure key data is never swapped to disk
70+ ));
71+ randomGenerator.write (result._keyData ->data (), KeySize);
5672 return result;
5773 }
5874
5975 const void *data () const {
60- return _key-> key . data ();
76+ return _keyData-> data ();
6177 }
6278
6379 void *data () {
6480 return const_cast <void *>(const_cast <const EncryptionKey*>(this )->data ());
6581 }
6682
67- private:
83+ // TODO Test take/drop
84+
85+ template <size_t NumTaken>
86+ EncryptionKey<NumTaken> take () const {
87+ static_assert (NumTaken <= KeySize, " Out of bounds" );
88+ auto result = std::make_shared<Data>(NumTaken, make_unique_ref<UnswappableAllocator>());
89+ std::memcpy (result->data (), _keyData->data (), NumTaken);
90+ return EncryptionKey<NumTaken>(std::move (result));
91+ }
92+
93+ template <size_t NumDropped>
94+ EncryptionKey<KeySize - NumDropped> drop () const {
95+ static_assert (NumDropped <= KeySize, " Out of bounds" );
96+ auto result = std::make_shared<Data>(KeySize - NumDropped, make_unique_ref<UnswappableAllocator>());
97+ std::memcpy (result->data (), _keyData->dataOffset (NumDropped), KeySize - NumDropped);
98+ return EncryptionKey<KeySize - NumDropped>(std::move (result));
99+ }
68100
69- std::shared_ptr<EncryptionKeyData> _key;
101+ private:
102+ std::shared_ptr<Data> _keyData;
70103};
71104
72105template <size_t KeySize> constexpr size_t EncryptionKey<KeySize>::BINARY_LENGTH ;
73106template <size_t KeySize> constexpr size_t EncryptionKey<KeySize>::STRING_LENGTH ;
74107
75- template <size_t KeySize>
76- inline EncryptionKey<KeySize>::EncryptionKeyData::EncryptionKeyData(const FixedSizeData<KeySize>& keyData)
77- : key(keyData)
78- , memoryProtector(&key, sizeof (key)) {
79- }
80-
81- template <size_t KeySize>
82- inline EncryptionKey<KeySize>::EncryptionKeyData::~EncryptionKeyData () {
83- // After destruction, the swap-protection is lifted, but we also don't need the key data anymore.
84- // Overwrite it with zeroes.
85- std::memset (key.data (), 0 , KeySize);
86- }
87-
88- template <size_t KeySize>
89- inline EncryptionKey<KeySize>::EncryptionKey(const FixedSizeData<KeySize>& keyData)
90- : _key(std::make_shared<EncryptionKeyData>(keyData)) {
91- }
92-
93- template <size_t KeySize>
94- EncryptionKey<KeySize> EncryptionKey<KeySize>::FromBinary(const void *source) {
95- return EncryptionKey (FixedSizeData<KeySize>::FromBinary (source));
96- }
97-
98- template <size_t KeySize>
99- EncryptionKey<KeySize> EncryptionKey<KeySize>::FromString(const std::string& keyData) {
100- return EncryptionKey (FixedSizeData<KeySize>::FromString (keyData));
101- }
102-
103- template <size_t KeySize>
104- std::string EncryptionKey<KeySize>::ToString() const {
105- return _key->key .ToString ();
106- }
107-
108108}
109109
110110#endif
0 commit comments