1 //**********************************************************************************
2 //EncryptPad Copyright 2016 Evgeny Pokhilko
3 //<http://www.evpo.net/encryptpad>
4 //
5 //This file is part of EncryptPad
6 //
7 //EncryptPad is free software: you can redistribute it and/or modify
8 //it under the terms of the GNU General Public License as published by
9 //the Free Software Foundation, either version 2 of the License, or
10 //(at your option) any later version.
11 //
12 //EncryptPad is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with EncryptPad. If not, see <http://www.gnu.org/licenses/>.
19 //**********************************************************************************
20 #include "encryptor.h"
21 #include <string>
22 #include "file_encryption.h"
23 #include "file_helper.h"
24 #include "plog/Log.h"
25
26 using namespace std;
27 using namespace EncryptPadEncryptor;
28 using namespace EncryptPad;
29 using namespace Botan;
30
SetLibcurlParams(const std::string & params)31 void Encryptor::SetLibcurlParams(const std::string ¶ms)
32 {
33 mLibcurlParams = params;
34 }
35
SetLibcurlPath(const std::string & path)36 void Encryptor::SetLibcurlPath(const std::string &path)
37 {
38 mLibcurlPath = path;
39 }
40
SetEncryptedPlainSwitchFunctor(EncryptedPlainSwitchFunctor * functor)41 void Encryptor::SetEncryptedPlainSwitchFunctor(EncryptedPlainSwitchFunctor *functor)
42 {
43 mEncryptedPlainSwitchFunctor = functor;
44 }
45
ClearKFPassphrase()46 void Encryptor::ClearKFPassphrase()
47 {
48 kf_key_service_.Clear();
49 }
50
HasKFPassphrase() const51 bool Encryptor::HasKFPassphrase() const
52 {
53 return kf_key_service_.IsPassphraseSet();
54 }
55
SetIsPlainText()56 void Encryptor::SetIsPlainText()
57 {
58 key_service_.Clear();
59 mPlainText = true;
60 if (mEncryptedPlainSwitchFunctor)
61 mEncryptedPlainSwitchFunctor->EncryptedPlainSwitchChange(false);
62 }
63
GetIsPlainText()64 bool Encryptor::GetIsPlainText()
65 {
66 return this->mPlainText;
67 }
68
UnusedKeysExist()69 bool Encryptor::UnusedKeysExist()
70 {
71 return key_service_.UnusedKeysExist();
72 }
73
GetX2KeyLocation() const74 const string &Encryptor::GetX2KeyLocation() const
75 {
76 return this->mX2KeyLocation;
77 }
78
SetPassphrase(const char * pwd,EncryptPad::PacketMetadata * metadata)79 void Encryptor::SetPassphrase(const char *pwd, EncryptPad::PacketMetadata *metadata)
80 {
81 assert(metadata);
82 key_service_.Clear();
83 if(metadata)
84 {
85 std::string passphrase(pwd);
86 key_service_.ChangePassphrase(
87 passphrase,
88 metadata->hash_algo,
89 GetAlgoSpec(metadata->cipher_algo).key_size,
90 metadata->iterations);
91 std::fill(std::begin(passphrase), std::end(passphrase), '0');
92
93 // if there was key_only before, switch it off
94 metadata->key_only = false;
95 }
96
97 mPlainText = false;
98
99 if (mEncryptedPlainSwitchFunctor)
100 mEncryptedPlainSwitchFunctor->EncryptedPlainSwitchChange(true);
101 }
102
Save(const string & fileName,const SecureVector<byte> & content,const string & x2KeyLocation,bool persistX2KeyLocation,PacketMetadata * metadata,const std::string * kf_passphrase)103 EpadResult Encryptor::Save(const string &fileName, const SecureVector<byte> &content,
104 const string &x2KeyLocation, bool persistX2KeyLocation,
105 PacketMetadata *metadata, const std::string *kf_passphrase)
106 {
107 using namespace EncryptPad;
108
109 bool is_protected = !GetIsPlainText() || !x2KeyLocation.empty();
110
111 if(!is_protected)
112 {
113 LOG_INFO << "the file is not protected";
114 OutPacketStreamFile file;
115 if (OpenFile(fileName, file) != OpenFileResult::OK)
116 {
117 return EpadResult::IOErrorOutput;
118 }
119 LOG_INFO << "unprotected file opened";
120
121 if(!file.Write(content.data(), content.size()))
122 {
123 return EpadResult::IOErrorOutput;
124 }
125 LOG_INFO << "unprotected file written";
126
127 return EpadResult::Success;
128 }
129
130 assert(metadata);
131 mX2KeyLocation = x2KeyLocation;
132 metadata->key_file = mX2KeyLocation;
133
134 if(GetIsPlainText())
135 metadata->key_only = true;
136
137 metadata->persist_key_path = persistX2KeyLocation;
138
139 EncryptParams enc_params = {};
140 enc_params.key_service = &key_service_;
141 enc_params.libcurl_path = &mLibcurlPath;
142 enc_params.libcurl_parameters = &mLibcurlParams;
143
144 EncryptParams kf_encrypt_params = {};
145
146 if(kf_passphrase || kf_key_service_.IsPassphraseSet())
147 {
148 kf_encrypt_params.key_service = &kf_key_service_;
149 kf_encrypt_params.passphrase = kf_passphrase;
150 enc_params.key_file_encrypt_params = &kf_encrypt_params;
151 }
152
153 LOG_INFO << "calling EncryptPacketFile";
154 EpadResult result = EncryptPacketFile(content, fileName, enc_params, *metadata);
155
156 if(result != EpadResult::Success)
157 {
158 LOG_ERROR << "EncryptPacketFile failed";
159 return result;
160 }
161
162 if(metadata->key_only)
163 this->SetIsPlainText();
164
165 LOG_INFO << "EncryptPacketFile succeeded";
166 return result;
167 }
168
169 // Loads file, decrypts into content
Load(const std::string & fileName,SecureVector<byte> & content,const string & x2KeyLocation,const string * passphrase,EncryptPad::PacketMetadata * metadata,const string * kf_passphrase)170 EpadResult Encryptor::Load(const std::string &fileName, SecureVector<byte> &content,
171 const string &x2KeyLocation, const string *passphrase,
172 EncryptPad::PacketMetadata *metadata, const string *kf_passphrase)
173 {
174 using namespace EncryptPad;
175
176 bool is_protected = !GetIsPlainText() || !x2KeyLocation.empty();
177 if(!is_protected)
178 {
179 InPacketStreamFile file;
180 if (OpenFile(fileName, file) != OpenFileResult::OK)
181 {
182 return EpadResult::IOErrorInput;
183 }
184
185 content.resize(file.GetCount());
186 stream_length_type length = file.Read(content.data(), content.size());
187 if(length != static_cast<stream_length_type>(content.size()))
188 return EpadResult::IOErrorInput;
189
190 mX2KeyLocation = x2KeyLocation;
191 return EpadResult::Success;
192 }
193
194 assert(metadata);
195 mX2KeyLocation = x2KeyLocation;
196 metadata->key_file = mX2KeyLocation;
197
198 EncryptParams enc_params = {};
199 enc_params.passphrase = passphrase;
200 enc_params.key_service = &key_service_;
201 enc_params.libcurl_path = &mLibcurlPath;
202 enc_params.libcurl_parameters = &mLibcurlParams;
203
204 EncryptParams kf_encrypt_params = {};
205
206 if(kf_passphrase || kf_key_service_.IsPassphraseSet())
207 {
208 kf_encrypt_params.key_service = &kf_key_service_;
209 kf_encrypt_params.passphrase = kf_passphrase;
210 enc_params.key_file_encrypt_params = &kf_encrypt_params;
211 }
212
213 EpadResult result = DecryptPacketFile(fileName, enc_params, content, *metadata);
214 if(result != EpadResult::Success)
215 return result;
216 mX2KeyLocation = metadata->key_file;
217 if(metadata->key_only)
218 this->SetIsPlainText();
219
220 return result;
221 }
222
223