1 | /*␊ |
2 | Copyright 2021 Grégory Soutadé␊ |
3 | ␊ |
4 | This file is part of libgourou.␊ |
5 | ␊ |
6 | libgourou is free software: you can redistribute it and/or modify␊ |
7 | it under the terms of the GNU Lesser General Public License as published by␊ |
8 | the Free Software Foundation, either version 3 of the License, or␊ |
9 | (at your option) any later version.␊ |
10 | ␊ |
11 | libgourou is distributed in the hope that it will be useful,␊ |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of␊ |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the␊ |
14 | GNU Lesser General Public License for more details.␊ |
15 | ␊ |
16 | You should have received a copy of the GNU Lesser General Public License␊ |
17 | along with libgourou. If not, see <http://www.gnu.org/licenses/>.␊ |
18 | */␊ |
19 | ␊ |
20 | #ifndef _DRMPROCESSORCLIENT_H_␊ |
21 | #define _DRMPROCESSORCLIENT_H_␊ |
22 | ␊ |
23 | #include <string>␊ |
24 | #include <bytearray.h>␊ |
25 | ␊ |
26 | namespace gourou␊ |
27 | {␊ |
28 | /**␊ |
29 | * @brief All fucntions that must be implemented by a client␊ |
30 | * This allow libgourou to have only few external libraries dependencies␊ |
31 | * and improve code portability␊ |
32 | */␊ |
33 | ␊ |
34 | class DigestInterface␊ |
35 | {␊ |
36 | public:␊ |
37 | ␉/**␊ |
38 | ␉ * @brief Create a digest handler␊ |
39 | ␉ *␊ |
40 | ␉ * @param digestName Digest name to instanciate␊ |
41 | ␉ */␊ |
42 | ␉virtual void* createDigest(const std::string& digestName) = 0;␊ |
43 | ␊ |
44 | ␉/**␊ |
45 | ␉ * @brief Update digest engine with new data␊ |
46 | ␉ *␊ |
47 | ␉ * @param handler Digest handler␊ |
48 | ␉ * @param data Data to digest␊ |
49 | ␉ * @param length Length of data␊ |
50 | ␉ */␊ |
51 | ␉virtual void digestUpdate(void* handler, unsigned char* data, unsigned int length) = 0;␊ |
52 | ␊ |
53 | ␉/**␊ |
54 | ␉ * @brief Finalize digest with remained buffered data and destroy handler␊ |
55 | ␉ *␊ |
56 | ␉ * @param handler Digest handler␊ |
57 | ␉ * @param digestOut Digest result (buffer must be pre allocated with right size)␊ |
58 | ␉ */␊ |
59 | ␉virtual void digestFinalize(void* handler, unsigned char* digestOut) = 0;␊ |
60 | ␊ |
61 | ␉/**␊ |
62 | ␉ * @brief Global digest function␊ |
63 | ␉ *␊ |
64 | ␉ * @param digestName Digest name to instanciate␊ |
65 | ␉ * @param data Data to digest␊ |
66 | ␉ * @param length Length of data␊ |
67 | ␉ * @param digestOut Digest result (buffer must be pre allocated with right size)␊ |
68 | ␉ */␊ |
69 | ␉virtual void digest(const std::string& digestName, unsigned char* data, unsigned int length, unsigned char* digestOut) = 0;␊ |
70 | };␊ |
71 | ␊ |
72 | class RandomInterface␊ |
73 | {␊ |
74 | public:␊ |
75 | ␉/**␊ |
76 | ␉ * @brief Generate random bytes␊ |
77 | ␉ *␊ |
78 | ␉ * @param bytesOut Buffer to fill with random bytes␊ |
79 | ␉ * @param length Length of bytesOut␊ |
80 | ␉ */␊ |
81 | ␉virtual void randBytes(unsigned char* bytesOut, unsigned int length) = 0;␊ |
82 | };␊ |
83 | ␊ |
84 | class HTTPInterface␊ |
85 | {␊ |
86 | public:␊ |
87 | ␉␊ |
88 | ␉/**␊ |
89 | ␉ * @brief Send HTTP (GET or POST) request␊ |
90 | ␉ *␊ |
91 | ␉ * @param URL HTTP URL␊ |
92 | ␉ * @param POSTData POST data if needed, if not set, a GET request is done␊ |
93 | ␉ * @param contentType Optional content type of POST Data␊ |
94 | ␉ * @param responseHeaders Optional Response headers of HTTP request␊ |
95 | ␉ * @param fd Optional file descriptor to write request result␊ |
96 | ␉ * @param resume false if target file should be truncated, true to try resume download (works only in combination with a valid fd)␊ |
97 | ␉ *␊ |
98 | ␉ * @return data of HTTP response␊ |
99 | ␉ */␊ |
100 | ␉virtual std::string sendHTTPRequest(const std::string& URL, const std::string& POSTData=std::string(""), const std::string& contentType=std::string(""), std::map<std::string, std::string>* responseHeaders=0, int fd=0, bool resume=false) = 0;␊ |
101 | };␊ |
102 | ␊ |
103 | class RSAInterface␊ |
104 | {␊ |
105 | public:␊ |
106 | ␉enum RSA_KEY_TYPE {␊ |
107 | ␉ RSA_KEY_PKCS12 = 0,␊ |
108 | ␉ RSA_KEY_PKCS8,␊ |
109 | ␉ RSA_KEY_X509␊ |
110 | ␉};␊ |
111 | ␊ |
112 | ␉/**␊ |
113 | ␉ * @brief Encrypt data with RSA private key. Data is padded using PKCS1.5␊ |
114 | ␉ *␊ |
115 | ␉ * @param RSAKey RSA key in binary form␊ |
116 | ␉ * @param RSAKeyLength RSA key length␊ |
117 | ␉ * @param keyType Key type␊ |
118 | ␉ * @param password Optional password for RSA PKCS12 certificate␊ |
119 | ␉ * @param data Data to encrypt␊ |
120 | ␉ * @param dataLength Data length␊ |
121 | ␉ * @param res Encryption result (pre allocated buffer)␊ |
122 | ␉ */␊ |
123 | ␉virtual void RSAPrivateEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,␊ |
124 | ␉␉␉␉ const RSA_KEY_TYPE keyType, const std::string& password,␊ |
125 | ␉␉␉␉ const unsigned char* data, unsigned dataLength,␊ |
126 | ␉␉␉␉ unsigned char* res) = 0;␊ |
127 | ␉␉␉ ␊ |
128 | ␉/**␊ |
129 | ␉ * @brief Decrypt data with RSA private key. Data is padded using PKCS1.5␊ |
130 | ␉ *␊ |
131 | ␉ * @param RSAKey RSA key in binary form␊ |
132 | ␉ * @param RSAKeyLength RSA key length␊ |
133 | ␉ * @param keyType Key type␊ |
134 | ␉ * @param password Optional password for RSA PKCS12 certificate␊ |
135 | ␉ * @param data Data to encrypt␊ |
136 | ␉ * @param dataLength Data length␊ |
137 | ␉ * @param res Encryption result (pre allocated buffer)␊ |
138 | ␉ */␊ |
139 | ␉virtual void RSAPrivateDecrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,␊ |
140 | ␉␉␉␉ const RSA_KEY_TYPE keyType, const std::string& password,␊ |
141 | ␉␉␉␉ const unsigned char* data, unsigned dataLength,␊ |
142 | ␉␉␉␉ unsigned char* res) = 0;␊ |
143 | ␊ |
144 | ␉/**␊ |
145 | ␉ * @brief Encrypt data with RSA public key. Data is padded using PKCS1.5␊ |
146 | ␉ *␊ |
147 | ␉ * @param RSAKey RSA key in binary form␊ |
148 | ␉ * @param RSAKeyLength RSA key length␊ |
149 | ␉ * @param keyType Key type␊ |
150 | ␉ * @param password Optional password for RSA PKCS12 certificate␊ |
151 | ␉ * @param data Data to encrypt␊ |
152 | ␉ * @param dataLength Data length␊ |
153 | ␉ * @param res Encryption result (pre allocated buffer)␊ |
154 | ␉ */␊ |
155 | ␉virtual void RSAPublicEncrypt(const unsigned char* RSAKey, unsigned int RSAKeyLength,␊ |
156 | ␉␉␉␉ const RSA_KEY_TYPE keyType,␊ |
157 | ␉␉␉␉ const unsigned char* data, unsigned dataLength,␊ |
158 | ␉␉␉␉ unsigned char* res) = 0;␊ |
159 | ␊ |
160 | ␉/**␊ |
161 | ␉ * @brief Generate RSA key. Expnonent is fixed (65537 / 0x10001)␊ |
162 | ␉ *␊ |
163 | ␉ * @param keyLengthBits Length of key (in bits) to generate␊ |
164 | ␉ *␊ |
165 | ␉ * @return generatedKey␊ |
166 | ␉ */␊ |
167 | ␉virtual void* generateRSAKey(int keyLengthBits) = 0;␊ |
168 | ␊ |
169 | ␉/**␊ |
170 | ␉ * @brief Destroy key previously generated␊ |
171 | ␉ *␊ |
172 | ␉ * @param handler Key to destroy␊ |
173 | ␉ */␊ |
174 | ␉virtual void destroyRSAHandler(void* handler) = 0;␊ |
175 | ␊ |
176 | ␉/**␊ |
177 | ␉ * @brief Extract public key (big number) from RSA handler␊ |
178 | ␉ *␊ |
179 | ␉ * @param handler RSA handler (generated key)␊ |
180 | ␉ * @param keyOut Pre allocated buffer (if *keyOut != 0). If *keyOut is 0, memory is internally allocated (must be freed)␊ |
181 | ␉ * @param keyOutLength Length of result␊ |
182 | ␉ */␊ |
183 | ␉virtual void extractRSAPublicKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength) = 0;␊ |
184 | ␊ |
185 | ␉/**␊ |
186 | ␉ * @brief Extract private key (big number) from RSA handler␊ |
187 | ␉ *␊ |
188 | ␉ * @param handler RSA handler (generated key)␊ |
189 | ␉ * @param keyOut Pre allocated buffer (if *keyOut != 0). If *keyOut is 0, memory is internally allocated (must be freed)␊ |
190 | ␉ * @param keyOutLength Length of result␊ |
191 | ␉ */␊ |
192 | ␉virtual void extractRSAPrivateKey(void* handler, unsigned char** keyOut, unsigned int* keyOutLength) = 0;␊ |
193 | ␊ |
194 | ␉/**␊ |
195 | ␉ * @brief Extract certificate from PKCS12 blob␊ |
196 | ␉ *␊ |
197 | ␉ * @param RSAKey RSA key in binary form␊ |
198 | ␉ * @param RSAKeyLength RSA key length␊ |
199 | ␉ * @param keyType Key type␊ |
200 | ␉ * @param password Optional password for RSA PKCS12 certificate␊ |
201 | ␉ * @param certOut Result certificate␊ |
202 | ␉ * @param certOutLength Result certificate length␊ |
203 | ␉ */␊ |
204 | ␉virtual void extractCertificate(const unsigned char* RSAKey, unsigned int RSAKeyLength,␊ |
205 | ␉␉␉␉␉const RSA_KEY_TYPE keyType, const std::string& password,␊ |
206 | ␉␉␉␉␉unsigned char** certOut, unsigned int* certOutLength) = 0;␊ |
207 | };␊ |
208 | ␊ |
209 | class CryptoInterface␊ |
210 | {␊ |
211 | public:␊ |
212 | ␉enum CRYPTO_ALGO {␊ |
213 | ␉ ALGO_AES=0,␊ |
214 | ␉ ALGO_RC4␊ |
215 | ␉};␊ |
216 | ␊ |
217 | ␉enum CHAINING_MODE {␊ |
218 | ␉ CHAIN_ECB=0,␊ |
219 | ␉ CHAIN_CBC␊ |
220 | ␉};␊ |
221 | ␉␊ |
222 | ␉/**␊ |
223 | ␉ * @brief Do encryption. If length of data is not multiple of block size, PKCS#5 padding is done␊ |
224 | ␉ *␊ |
225 | ␉ * @param algo Algorithm to use␊ |
226 | ␉ * @param chaining Chaining mode␊ |
227 | ␉ * @param key AES key␊ |
228 | ␉ * @param keyLength AES key length␊ |
229 | ␉ * @param iv IV key␊ |
230 | ␉ * @param ivLength IV key length␊ |
231 | ␉ * @param dataIn Data to encrypt␊ |
232 | ␉ * @param dataInLength Data length␊ |
233 | ␉ * @param dataOut Encrypted data␊ |
234 | ␉ * @param dataOutLength Length of encrypted data␊ |
235 | ␉ */␊ |
236 | ␉virtual void encrypt(CRYPTO_ALGO algo, CHAINING_MODE chaining,␊ |
237 | ␉␉␉ const unsigned char* key, unsigned int keyLength,␊ |
238 | ␉␉␉ const unsigned char* iv, unsigned int ivLength,␊ |
239 | ␉␉␉ const unsigned char* dataIn, unsigned int dataInLength,␊ |
240 | ␉␉␉ unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
241 | ␊ |
242 | ␉/**␊ |
243 | ␉ * @brief Init encryption␊ |
244 | ␉ *␊ |
245 | ␉ * @param chaining Chaining mode␊ |
246 | ␉ * @param key Key␊ |
247 | ␉ * @param keyLength Key length␊ |
248 | ␉ * @param iv Optional IV key␊ |
249 | ␉ * @param ivLength Optional IV key length␊ |
250 | ␉ *␊ |
251 | ␉ * @return AES handler␊ |
252 | ␉ */␊ |
253 | ␉virtual void* encryptInit(CRYPTO_ALGO algo, CHAINING_MODE chaining,␊ |
254 | ␉␉␉␉ const unsigned char* key, unsigned int keyLength,␊ |
255 | ␉␉␉␉ const unsigned char* iv=0, unsigned int ivLength=0) = 0;␊ |
256 | ␊ |
257 | ␉/**␊ |
258 | ␉ * @brief Encrypt data␊ |
259 | ␉ *␊ |
260 | ␉ * @param handler Crypto handler␊ |
261 | ␉ * @param dataIn Data to encrypt␊ |
262 | ␉ * @param dataInLength Data length␊ |
263 | ␉ * @param dataOut Encrypted data␊ |
264 | ␉ * @param dataOutLength Length of encrypted data␊ |
265 | ␉ */␊ |
266 | ␉virtual void encryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,␊ |
267 | ␉␉␉␉ unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
268 | ␊ |
269 | ␉/**␊ |
270 | ␉ * @brief Finalize encryption (pad and encrypt last block if needed)␊ |
271 | ␉ * Destroy handler at the end␊ |
272 | ␉ *␊ |
273 | ␉ * @param handler Crypto handler␊ |
274 | ␉ * @param dataOut Last block of encrypted data␊ |
275 | ␉ * @param dataOutLength Length of encrypted data␊ |
276 | ␉ */␊ |
277 | ␉virtual void encryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
278 | ␊ |
279 | ␉/**␊ |
280 | ␉ * @brief Do decryption. If length of data is not multiple of block size, PKCS#5 padding is done␊ |
281 | ␉ *␊ |
282 | ␉ * @param algo Algorithm to use␊ |
283 | ␉ * @param chaining Chaining mode␊ |
284 | ␉ * @param key AES key␊ |
285 | ␉ * @param keyLength AES key length␊ |
286 | ␉ * @param iv IV key␊ |
287 | ␉ * @param ivLength IV key length␊ |
288 | ␉ * @param dataIn Data to encrypt␊ |
289 | ␉ * @param dataInLength Data length␊ |
290 | ␉ * @param dataOut Encrypted data␊ |
291 | ␉ * @param dataOutLength Length of encrypted data␊ |
292 | ␉ */␊ |
293 | ␉virtual void decrypt(CRYPTO_ALGO algo, CHAINING_MODE chaining,␊ |
294 | ␉␉␉ const unsigned char* key, unsigned int keyLength,␊ |
295 | ␉␉␉ const unsigned char* iv, unsigned int ivLength,␊ |
296 | ␉␉␉ const unsigned char* dataIn, unsigned int dataInLength,␊ |
297 | ␉␉␉ unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
298 | ␊ |
299 | ␉/**␊ |
300 | ␉ * @brief Init decryption␊ |
301 | ␉ *␊ |
302 | ␉ * @param chaining Chaining mode␊ |
303 | ␉ * @param key Key␊ |
304 | ␉ * @param keyLength Key length␊ |
305 | ␉ * @param iv IV key␊ |
306 | ␉ * @param ivLength IV key length␊ |
307 | ␉ *␊ |
308 | ␉ * @return AES handler␊ |
309 | ␉ */␊ |
310 | ␉virtual void* decryptInit(CRYPTO_ALGO algo, CHAINING_MODE chaining,␊ |
311 | ␉␉␉␉ const unsigned char* key, unsigned int keyLength,␊ |
312 | ␉␉␉␉ const unsigned char* iv=0, unsigned int ivLength=0) = 0;␊ |
313 | ␊ |
314 | ␉/**␊ |
315 | ␉ * @brief Decrypt data␊ |
316 | ␉ *␊ |
317 | ␉ * @param handler Crypto handler␊ |
318 | ␉ * @param dataIn Data to decrypt␊ |
319 | ␉ * @param dataInLength Data length␊ |
320 | ␉ * @param dataOut Decrypted data␊ |
321 | ␉ * @param dataOutLength Length of decrypted data␊ |
322 | ␉ */␊ |
323 | ␉virtual void decryptUpdate(void* handler, const unsigned char* dataIn, unsigned int dataInLength,␊ |
324 | ␉␉␉␉ unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
325 | ␉/**␊ |
326 | ␉ * @brief Finalize decryption (decrypt last block and remove padding if it is set).␊ |
327 | ␉ * Destroy handler at the end␊ |
328 | ␉ *␊ |
329 | ␉ * @param handler Crypto handler␊ |
330 | ␉ * @param dataOut Last block decrypted data␊ |
331 | ␉ * @param dataOutLength Length of decrypted data␊ |
332 | ␉ */␊ |
333 | ␉virtual void decryptFinalize(void* handler, unsigned char* dataOut, unsigned int* dataOutLength) = 0;␊ |
334 | };␊ |
335 | ␊ |
336 | ␊ |
337 | class ZIPInterface␊ |
338 | {␊ |
339 | public:␊ |
340 | ␉/**␊ |
341 | ␉ * @brief Open a zip file and return an handler␊ |
342 | ␉ *␊ |
343 | ␉ * @param path Path of zip file␊ |
344 | ␉ *␊ |
345 | ␉ * @return ZIP file handler␊ |
346 | ␉ */␊ |
347 | ␉virtual void* zipOpen(const std::string& path) = 0;␊ |
348 | ␉␊ |
349 | ␉/**␊ |
350 | ␉ * @brief Read zip internal file␊ |
351 | ␉ *␊ |
352 | ␉ * @param handler ZIP file handler␊ |
353 | ␉ * @param path Internal path inside zip file␊ |
354 | ␉ * @param result Result buffer␊ |
355 | ␉ * @param decompress If false, don't decompress read data␊ |
356 | ␉ */␊ |
357 | ␉virtual void zipReadFile(void* handler, const std::string& path, ByteArray& result, bool decompress=true) = 0;␊ |
358 | ␉␊ |
359 | ␉/**␊ |
360 | ␉ * @brief Write zip internal file␊ |
361 | ␉ *␊ |
362 | ␉ * @param handler ZIP file handler␊ |
363 | ␉ * @param path Internal path inside zip file␊ |
364 | ␉ * @param content File content␊ |
365 | ␉ */␊ |
366 | ␉virtual void zipWriteFile(void* handler, const std::string& path, ByteArray& content) = 0;␊ |
367 | ␊ |
368 | ␉/**␊ |
369 | ␉ * @brief Delete zip internal file␊ |
370 | ␉ *␊ |
371 | ␉ * @param handler ZIP file handler␊ |
372 | ␉ * @param path Internal path inside zip file␊ |
373 | ␉ */␊ |
374 | ␉virtual void zipDeleteFile(void* handler, const std::string& path) = 0;␊ |
375 | ␊ |
376 | ␉/**␊ |
377 | ␉ * @brief Close ZIP file handler␊ |
378 | ␉ *␊ |
379 | ␉ * @param handler ZIP file handler␊ |
380 | ␉ */␊ |
381 | ␉virtual void zipClose(void* handler) = 0;␊ |
382 | ␊ |
383 | ␉/**␊ |
384 | ␉ * @brief Inflate algorithm␊ |
385 | ␉ *␊ |
386 | ␉ * @param data Data to inflate␊ |
387 | ␉ * @param result Zipped data␊ |
388 | ␉ * @param wbits Window bits value for libz␊ |
389 | ␉ */␊ |
390 | ␉virtual void inflate(gourou::ByteArray& data, gourou::ByteArray& result,␊ |
391 | ␉␉␉ int wbits=-15) = 0;␊ |
392 | ␉␊ |
393 | ␉/**␊ |
394 | ␉ * @brief Deflate algorithm␊ |
395 | ␉ *␊ |
396 | ␉ * @param data Data to deflate␊ |
397 | ␉ * @param result Unzipped data␊ |
398 | ␉ * @param wbits Window bits value for libz␊ |
399 | ␉ * @param compressionLevel Compression level for libz␊ |
400 | ␉ */␊ |
401 | ␉virtual void deflate(gourou::ByteArray& data, gourou::ByteArray& result,␊ |
402 | ␉␉␉ int wbits=-15, int compressionLevel=8) = 0;␊ |
403 | };␊ |
404 | ␊ |
405 | class DRMProcessorClient: public DigestInterface, public RandomInterface, public HTTPInterface, \␊ |
406 | ␉␉␉ public RSAInterface, public CryptoInterface, public ZIPInterface␊ |
407 | {};␊ |
408 | }␊ |
409 | #endif␊ |