Skip to content

Commit 26bc8b5

Browse files
author
Lauris Kaplinski
committed
Fixed CDoc1 compilation
1 parent be790ed commit 26bc8b5

File tree

8 files changed

+121
-24
lines changed

8 files changed

+121
-24
lines changed

libcdoc/CDoc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ libcdoc::NetworkBackend::test(std::vector<std::vector<uint8_t>> &dst)
103103
int
104104
libcdoc::CDocReader::getCDocFileVersion(DataSource *src)
105105
{
106-
if (src->seek(0) != libcdoc::OK) return -1;
106+
if (src->seek(0) != libcdoc::OK) return libcdoc::IO_ERROR;
107107
if (CDoc2Reader::isCDoc2File(src)) return 2;
108108
src->seek(0);
109109
if (CDoc1Reader::isCDoc1File(src)) return 1;
110-
return -1;
110+
return libcdoc::NOT_SUPPORTED;
111111
}
112112

113113
int

libcdoc/CDoc1Reader.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ CDoc1Reader::getLocks()
7070
int
7171
CDoc1Reader::getLockForCert(const std::vector<uint8_t>& cert)
7272
{
73-
if (!SUPPORTED_METHODS.contains(d->method)) return false;
73+
if (!SUPPORTED_METHODS.contains(d->method)) return libcdoc::NOT_SUPPORTED;
7474
libcdoc::Certificate cc(cert);
7575
for (size_t i = 0; i < d->locks.size(); i++) {
7676
const libcdoc::Lock *ll = d->locks.at(i);
@@ -81,12 +81,14 @@ CDoc1Reader::getLockForCert(const std::vector<uint8_t>& cert)
8181
if (ll->getString(libcdoc::Lock::Params::METHOD) == libcdoc::Crypto::RSA_MTH) {
8282
return i;
8383
}
84-
} else {
84+
} else if(cc.getAlgorithm() == libcdoc::Certificate::ECC) {
8585
std::vector<uint8_t> eph_key = ll->getBytes(libcdoc::Lock::Params::KEY_MATERIAL);
8686
if(!eph_key.empty() && SUPPORTED_KWAES.contains(ll->getString(libcdoc::Lock::Params::METHOD))) {
8787
return i;
8888
}
89-
}
89+
} else {
90+
return libcdoc::NOT_SUPPORTED;
91+
}
9092
}
9193
return libcdoc::NOT_FOUND;
9294
}
@@ -100,7 +102,7 @@ CDoc1Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
100102
setLastError("Not a CDoc1 key");
101103
return libcdoc::UNSPECIFIED_ERROR;
102104
}
103-
setLastError({});
105+
setLastError({});
104106
std::vector<uint8_t> decrypted_key;
105107
if (lock->isRSA()) {
106108
int result = crypto->decryptRSA(decrypted_key, lock->encrypted_fmk, false, lock_idx);
@@ -160,8 +162,25 @@ CDoc1Reader::decrypt(const std::vector<uint8_t>& fmk, libcdoc::MultiDataConsumer
160162
result = finishDecryption();
161163
return result;
162164
#else
165+
if (fmk.empty()) {
166+
setLastError("FMK is missing");
167+
return libcdoc::WRONG_ARGUMENTS;
168+
}
169+
if (fmk.size() != 16 && fmk.size() != 24 && fmk.size() != 32) {
170+
setLastError("FMK must be AES key with size 128, 192,2 56 bits");
171+
return libcdoc::WRONG_ARGUMENTS;
172+
}
173+
if (!d->files.empty() || (d->f_pos != -1)) {
174+
setLastError("Container is already parsed");
175+
return libcdoc::WORKFLOW_ERROR;
176+
}
163177
std::vector<uint8_t> data = this->decryptData(fmk);
164-
std::string mime = d->mime;
178+
if(data.empty()) {
179+
setLastError("Failed to decrypt data, verify if FMK is correct");
180+
return libcdoc::CRYPTO_ERROR;
181+
}
182+
setLastError({});
183+
std::string mime = d->mime;
165184
if (d->mime == MIME_ZLIB) {
166185
libcdoc::VectorSource vsrc(data);
167186
libcdoc::ZSource zsrc(&vsrc);
@@ -178,13 +197,11 @@ CDoc1Reader::decrypt(const std::vector<uint8_t>& fmk, libcdoc::MultiDataConsumer
178197
setLastError("Failed to parse DDOC file");
179198
return libcdoc::UNSPECIFIED_ERROR;
180199
}
181-
setLastError({});
182200
return libcdoc::OK;
183201
}
184202
dst->open(d->properties["Filename"], data.size());
185203
dst->writeAll(vsrc);
186204
dst->close();
187-
setLastError({});
188205
return libcdoc::OK;
189206
#endif
190207
}

libcdoc/CDoc1Writer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ CDoc1Writer::encrypt(libcdoc::MultiDataSource& src, const std::vector<libcdoc::R
247247
d->_xml->writeEndElement(Private::DENC); // EncryptedData
248248
d->_xml->close();
249249
d->_xml.reset();
250+
result = libcdoc::OK;
250251
if (owned) result = dst->close();
251252
return result;
252253
}

libcdoc/CDocReader.h

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,70 @@ class CDOC_EXPORT CDocReader {
4545
*/
4646
virtual const std::vector<Lock> getLocks() = 0;
4747
/**
48-
* @brief Fetches the lock for certificate
48+
* @brief Finds the lock index for given certificate
4949
*
5050
* Returns the first lock that can be opened by the private key of the certificate holder.
5151
* @param cert a x509 certificate (der)
5252
* @return lock index or error code
5353
*/
5454
virtual int getLockForCert(const std::vector<uint8_t>& cert) = 0;
5555
/**
56-
* @brief Fetches FMK from provided lock
56+
* @brief Fetches FMK from given lock
5757
*
58-
* Fetches FMK (File Master Key) from the provided decryption lock. Depending on the lock type it uses a relevant CryptoBackend and/or
58+
* Fetches FMK (File Master Key) from the lock with given index. Depending on the lock type it uses a relevant CryptoBackend and/or
5959
* NetworkBackend method to either fetch secret and derive key or perform external decryption of encrypted KEK.
6060
* @param fmk The FMK of the document
61-
* @param lock a lock (from document lock list)
61+
* @param lock_idx the index of a lock (in the document lock list)
6262
* @return error code or OK
6363
*/
6464
virtual int getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx) = 0;
6565

6666
// Pull interface
67+
/**
68+
* @brief beginDecryption start decrypting document
69+
*
70+
* Starts decryption of the document. This may involve parsing and decrypting headers, checking
71+
* file and key integrity etc.
72+
* @param fmk File Master Key of the document
73+
* @return error code or OK
74+
*/
6775
virtual int beginDecryption(const std::vector<uint8_t>& fmk) = 0;
76+
/**
77+
* @brief nextFile start decrypting the next file
78+
*
79+
* Begins decrypting the next file in document. On success the file name and size are filled and the
80+
* method returns OK. If there are no more file in the document, END_OF_STREAM is returned.
81+
* It is OK to call nextFile before reading the whole data from the previous one.
82+
* @param name the name of the next file
83+
* @param size the size of the next file
84+
* @return error code, OK or END_OF_STREAM
85+
*/
6886
virtual int nextFile(std::string& name, int64_t& size) = 0;
69-
int nextFile(FileInfo& info) { return nextFile(info.name, info.size); }
87+
/**
88+
* @brief readData read data from the current file
89+
*
90+
* Read bytes from the current file into the buffer. The number of bytes read is always the
91+
* requested number, unless end of file is reached or error occurs. Thus the end of file is marked
92+
* by returning 0.
93+
* @param dst destination byte buffer
94+
* @param size the number of bytes to read
95+
* @return the number of bytes actually read or error code
96+
*/
7097
virtual int64_t readData(uint8_t *dst, size_t size) = 0;
98+
/**
99+
* @brief finishDecryption finish decryption of file
100+
*
101+
* Finishes the decryption of file. This may onvolve releasing buffers, closing hardware keys etc.
102+
* @return error code or OK
103+
*/
71104
virtual int finishDecryption() = 0;
72105

106+
/**
107+
* @brief nextFile start decrypting the next file
108+
* @param info a FileInfo structure
109+
* @return error code, OK or END_OF_STREAM
110+
*/
111+
int nextFile(FileInfo& info) { return nextFile(info.name, info.size); }
73112

74113
// Push interface
75114
/**
@@ -90,12 +129,40 @@ class CDOC_EXPORT CDocReader {
90129
/**
91130
* @brief try to determine the cdoc file version
92131
* @param path a path to file
93-
* @return version, -1 if not a valid CDoc file
132+
* @return version or error code if not a readable CDoc file
94133
*/
95134
static int getCDocFileVersion(const std::string& path);
135+
/**
136+
* @brief try to determine the cdoc file version
137+
* @param src the container source
138+
* @return version or error code if not a readable CDoc file
139+
*/
96140
static int getCDocFileVersion(DataSource *src);
97141

142+
/**
143+
* @brief createReader create CDoc document reader
144+
*
145+
* Creates a new document reader if source is a valid CDoc container (either version 1 or 2).
146+
* The network backend may be null if keyservers are not used.
147+
* @param src the container source
148+
* @param take_ownership if true the source is deleted in reader destructor
149+
* @param conf a configuration object
150+
* @param crypto a cryptographic backend implementation
151+
* @param network a network backend implementation
152+
* @return a new CDocReader or null
153+
*/
98154
static CDocReader *createReader(DataSource *src, bool take_ownership, Configuration *conf, CryptoBackend *crypto, NetworkBackend *network);
155+
/**
156+
* @brief createReader create CDoc document reader
157+
*
158+
* Creates a new document reader if file is a valid CDoc container (either version 1 or 2)
159+
* The network backend may be null if keyservers are not used.
160+
* @param path the path to file
161+
* @param conf a configuration object
162+
* @param crypto a cryptographic backend implementation
163+
* @param network a network backend implementation
164+
* @return a new CDocReader or null
165+
*/
99166
static CDocReader *createReader(const std::string& path, Configuration *conf, CryptoBackend *crypto, NetworkBackend *network);
100167

101168
#if LIBCDOC_TESTING

libcdoc/Crypto.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ Crypto::Cipher::blockSize() const
9797
std::vector<uint8_t> Crypto::AESWrap(const std::vector<uint8_t> &key, const std::vector<uint8_t> &data, bool encrypt)
9898
{
9999
AES_KEY aes;
100-
if (encrypt && SSL_FAILED(AES_set_encrypt_key(key.data(), int(key.size()) * 8, &aes), "AES_set_encrypt_key") ||
101-
!encrypt && SSL_FAILED(AES_set_decrypt_key(key.data(), int(key.size()) * 8, &aes), "AES_set_decrypt_key"))
100+
// fixme: Fix SSL_FAILED, current solution is idiotic
101+
if (encrypt && !SSL_FAILED(AES_set_encrypt_key(key.data(), int(key.size()) * 8, &aes), "AES_set_encrypt_key") ||
102+
!encrypt && !SSL_FAILED(AES_set_decrypt_key(key.data(), int(key.size()) * 8, &aes), "AES_set_decrypt_key"))
102103
return {};
103104

104105
std::vector<uint8_t> result(data.size() + 8);

libcdoc/DDocReader.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "DDocReader.h"
2+
#include "CDoc.h"
23

34
#include "XmlReader.h"
45

@@ -12,11 +13,14 @@ DDOCReader::parse(libcdoc::DataSource *src, libcdoc::MultiDataConsumer *dst)
1213
if(!reader.isElement("DataFile")) continue;
1314
std::string name = reader.attribute("Filename");
1415
std::vector<uint8_t> content = reader.readBase64();
15-
dst->open(name, content.size());
16-
dst->write(content.data(), content.size());
17-
dst->close();
18-
}
19-
return !dst->isError();
16+
int result = dst->open(name, content.size());
17+
if (result != libcdoc::OK) return result;
18+
int64_t n_written = dst->write(content.data(), content.size());
19+
if (n_written < 0) return (int) n_written;
20+
result = dst->close();
21+
if (result != libcdoc::OK) return result;
22+
}
23+
return (dst->isError()) ? libcdoc::IO_ERROR : libcdoc::OK;
2024
}
2125

2226
struct FileListConsumer : public libcdoc::MultiDataConsumer {

libcdoc/Io.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,15 @@ struct CDOC_EXPORT IStreamSource : public DataSource {
199199
IStreamSource(std::istream *ifs, bool take_ownership = false) : _ifs(ifs), _owned(take_ownership) {}
200200
IStreamSource(const std::string& path);
201201
~IStreamSource() {
202-
if (_owned) delete _ifs;
202+
//if (_owned) delete _ifs;
203203
}
204204

205205
int seek(size_t pos) {
206+
if(_ifs->bad()) return INPUT_STREAM_ERROR;
207+
_ifs->clear();
206208
_ifs->seekg(pos);
209+
//std::cerr << "Stream bad:" << _ifs->bad() << " eof:" << _ifs->eof() << " fail:" << _ifs->fail() << std::endl;
210+
//std::cerr << "tell:" << _ifs->tellg() << std::endl;
207211
return bool(_ifs->bad()) ? INPUT_STREAM_ERROR : OK;
208212
}
209213

libcdoc/XmlReader.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ int
3535
XMLReader::Private::xmlInputReadCallback (void *context, char *buffer, int len)
3636
{
3737
XMLReader *reader = reinterpret_cast<XMLReader *>(context);
38-
return reader->d->_src->read((uint8_t *) buffer, len);
38+
int64_t n_read = reader->d->_src->read((uint8_t *) buffer, len);
39+
//std::string str(buffer, len);
40+
//std::cerr << "XML read (" << n_read << "):" << str << std::endl;
41+
return n_read;
3942
}
4043

4144
int

0 commit comments

Comments
 (0)