Commit ce8f9b6608ebcc3e88fbb1655be3e9363fa671b6

Authored by Jay Berkenbilt
1 parent 5c3e856e

MD5: switch to pluggable crypto

include/qpdf/QPDFCryptoImpl.hh
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #define QPDFCRYPTOIMPL_HH 23 #define QPDFCRYPTOIMPL_HH
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
  26 +#include <cstring>
26 27
27 // This class is part of qpdf's pluggable crypto provider support. 28 // This class is part of qpdf's pluggable crypto provider support.
28 // Most users won't need to know or care about this class, but you can 29 // Most users won't need to know or care about this class, but you can
@@ -39,6 +40,16 @@ class QPDF_DLL_CLASS QPDFCryptoImpl @@ -39,6 +40,16 @@ class QPDF_DLL_CLASS QPDFCryptoImpl
39 40
40 QPDF_DLL 41 QPDF_DLL
41 virtual ~QPDFCryptoImpl() = default; 42 virtual ~QPDFCryptoImpl() = default;
  43 +
  44 + typedef unsigned char MD5_Digest[16];
  45 + QPDF_DLL
  46 + virtual void MD5_init() = 0;
  47 + QPDF_DLL
  48 + virtual void MD5_update(unsigned char const* data, size_t len) = 0;
  49 + QPDF_DLL
  50 + virtual void MD5_finalize() = 0;
  51 + QPDF_DLL
  52 + virtual void MD5_digest(MD5_Digest) = 0;
42 }; 53 };
43 54
44 #endif // QPDFCRYPTOIMPL_HH 55 #endif // QPDFCRYPTOIMPL_HH
libqpdf/MD5.cc 0 → 100644
  1 +#include <qpdf/MD5.hh>
  2 +#include <qpdf/QUtil.hh>
  3 +#include <qpdf/QIntC.hh>
  4 +#include <qpdf/QPDFCryptoProvider.hh>
  5 +
  6 +#include <stdio.h>
  7 +#include <memory.h>
  8 +#include <stdlib.h>
  9 +#include <string.h>
  10 +#include <errno.h>
  11 +
  12 +MD5::MD5()
  13 +{
  14 + init();
  15 +}
  16 +
  17 +void
  18 +MD5::init()
  19 +{
  20 + this->crypto = QPDFCryptoProvider::getImpl();
  21 + this->crypto->MD5_init();
  22 +}
  23 +
  24 +void
  25 +MD5::finalize()
  26 +{
  27 + this->crypto->MD5_finalize();
  28 +}
  29 +
  30 +void MD5::reset()
  31 +{
  32 + init();
  33 +}
  34 +
  35 +void MD5::encodeString(char const* str)
  36 +{
  37 + size_t len = strlen(str);
  38 + crypto->MD5_init();
  39 + encodeDataIncrementally(str, len);
  40 + crypto->MD5_finalize();
  41 +}
  42 +
  43 +void MD5::appendString(char const* input_string)
  44 +{
  45 + encodeDataIncrementally(input_string, strlen(input_string));
  46 +}
  47 +
  48 +void MD5::encodeDataIncrementally(char const* data, size_t len)
  49 +{
  50 + this->crypto->MD5_update(QUtil::unsigned_char_pointer(data), len);
  51 +}
  52 +
  53 +void MD5::encodeFile(char const *filename, qpdf_offset_t up_to_offset)
  54 +{
  55 + char buffer[1024];
  56 +
  57 + FILE *file = QUtil::safe_fopen(filename, "rb");
  58 + size_t len;
  59 + size_t so_far = 0;
  60 + size_t to_try = 1024;
  61 + size_t up_to_size = 0;
  62 + if (up_to_offset >= 0)
  63 + {
  64 + up_to_size = QIntC::to_size(up_to_offset);
  65 + }
  66 + do
  67 + {
  68 + if ((up_to_offset >= 0) && ((so_far + to_try) > up_to_size))
  69 + {
  70 + to_try = up_to_size - so_far;
  71 + }
  72 + len = fread(buffer, 1, to_try, file);
  73 + if (len > 0)
  74 + {
  75 + encodeDataIncrementally(buffer, len);
  76 + so_far += len;
  77 + if ((up_to_offset >= 0) && (so_far >= up_to_size))
  78 + {
  79 + break;
  80 + }
  81 + }
  82 + } while (len > 0);
  83 + if (ferror(file))
  84 + {
  85 + // Assume, perhaps incorrectly, that errno was set by the
  86 + // underlying call to read....
  87 + (void) fclose(file);
  88 + QUtil::throw_system_error(
  89 + std::string("MD5: read error on ") + filename);
  90 + }
  91 + (void) fclose(file);
  92 +
  93 + this->crypto->MD5_finalize();
  94 +}
  95 +
  96 +void MD5::digest(Digest result)
  97 +{
  98 + this->crypto->MD5_finalize();
  99 + this->crypto->MD5_digest(result);
  100 +}
  101 +
  102 +void MD5::print()
  103 +{
  104 + Digest digest_val;
  105 + digest(digest_val);
  106 +
  107 + unsigned int i;
  108 + for (i = 0; i < 16; ++i)
  109 + {
  110 + printf("%02x", digest_val[i]);
  111 + }
  112 + printf("\n");
  113 +}
  114 +
  115 +std::string MD5::unparse()
  116 +{
  117 + this->crypto->MD5_finalize();
  118 + Digest digest_val;
  119 + digest(digest_val);
  120 + return QUtil::hex_encode(
  121 + std::string(reinterpret_cast<char*>(digest_val), 16));
  122 +}
  123 +
  124 +std::string
  125 +MD5::getDataChecksum(char const* buf, size_t len)
  126 +{
  127 + MD5 m;
  128 + m.encodeDataIncrementally(buf, len);
  129 + return m.unparse();
  130 +}
  131 +
  132 +std::string
  133 +MD5::getFileChecksum(char const* filename, qpdf_offset_t up_to_offset)
  134 +{
  135 + MD5 m;
  136 + m.encodeFile(filename, up_to_offset);
  137 + return m.unparse();
  138 +}
  139 +
  140 +bool
  141 +MD5::checkDataChecksum(char const* const checksum,
  142 + char const* buf, size_t len)
  143 +{
  144 + std::string actual_checksum = getDataChecksum(buf, len);
  145 + return (checksum == actual_checksum);
  146 +}
  147 +
  148 +bool
  149 +MD5::checkFileChecksum(char const* const checksum,
  150 + char const* filename, qpdf_offset_t up_to_offset)
  151 +{
  152 + bool result = false;
  153 + try
  154 + {
  155 + std::string actual_checksum = getFileChecksum(filename, up_to_offset);
  156 + result = (checksum == actual_checksum);
  157 + }
  158 + catch (std::runtime_error const&)
  159 + {
  160 + // Ignore -- return false
  161 + }
  162 + return result;
  163 +}
libqpdf/MD5_native.cc
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 // 27 //
28 ///////////////////////////////////////////////////////////////////////// 28 /////////////////////////////////////////////////////////////////////////
29 29
30 -#include <qpdf/MD5.hh> 30 +#include <qpdf/MD5_native.hh>
31 #include <qpdf/QUtil.hh> 31 #include <qpdf/QUtil.hh>
32 #include <qpdf/QIntC.hh> 32 #include <qpdf/QIntC.hh>
33 33
@@ -72,28 +72,33 @@ static unsigned char PADDING[64] = { @@ -72,28 +72,33 @@ static unsigned char PADDING[64] = {
72 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 72 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
73 // Rotation is separate from addition to prevent recomputation. 73 // Rotation is separate from addition to prevent recomputation.
74 #define FF(a, b, c, d, x, s, ac) { \ 74 #define FF(a, b, c, d, x, s, ac) { \
75 - (a) += F ((b), (c), (d)) + (x) + static_cast<UINT4>(ac); \ 75 + (a) += F ((b), (c), (d)) + (x) + static_cast<uint32_t>(ac); \
76 (a) = ROTATE_LEFT ((a), (s)); \ 76 (a) = ROTATE_LEFT ((a), (s)); \
77 (a) += (b); \ 77 (a) += (b); \
78 } 78 }
79 #define GG(a, b, c, d, x, s, ac) { \ 79 #define GG(a, b, c, d, x, s, ac) { \
80 - (a) += G ((b), (c), (d)) + (x) + static_cast<UINT4>(ac); \ 80 + (a) += G ((b), (c), (d)) + (x) + static_cast<uint32_t>(ac); \
81 (a) = ROTATE_LEFT ((a), (s)); \ 81 (a) = ROTATE_LEFT ((a), (s)); \
82 (a) += (b); \ 82 (a) += (b); \
83 } 83 }
84 #define HH(a, b, c, d, x, s, ac) { \ 84 #define HH(a, b, c, d, x, s, ac) { \
85 - (a) += H ((b), (c), (d)) + (x) + static_cast<UINT4>(ac); \ 85 + (a) += H ((b), (c), (d)) + (x) + static_cast<uint32_t>(ac); \
86 (a) = ROTATE_LEFT ((a), (s)); \ 86 (a) = ROTATE_LEFT ((a), (s)); \
87 (a) += (b); \ 87 (a) += (b); \
88 } 88 }
89 #define II(a, b, c, d, x, s, ac) { \ 89 #define II(a, b, c, d, x, s, ac) { \
90 - (a) += I ((b), (c), (d)) + (x) + static_cast<UINT4>(ac); \ 90 + (a) += I ((b), (c), (d)) + (x) + static_cast<uint32_t>(ac); \
91 (a) = ROTATE_LEFT ((a), (s)); \ 91 (a) = ROTATE_LEFT ((a), (s)); \
92 (a) += (b); \ 92 (a) += (b); \
93 } 93 }
94 94
  95 +MD5_native::MD5_native()
  96 +{
  97 + init();
  98 +}
  99 +
95 // MD5 initialization. Begins an MD5 operation, writing a new context. 100 // MD5 initialization. Begins an MD5 operation, writing a new context.
96 -void MD5::init() 101 +void MD5_native::init()
97 { 102 {
98 count[0] = count[1] = 0; 103 count[0] = count[1] = 0;
99 // Load magic initialization constants. 104 // Load magic initialization constants.
@@ -110,7 +115,7 @@ void MD5::init() @@ -110,7 +115,7 @@ void MD5::init()
110 // operation, processing another message block, and updating the 115 // operation, processing another message block, and updating the
111 // context. 116 // context.
112 117
113 -void MD5::update(unsigned char *input, 118 +void MD5_native::update(unsigned char *input,
114 size_t inputLen) 119 size_t inputLen)
115 { 120 {
116 unsigned int i, index, partLen; 121 unsigned int i, index, partLen;
@@ -119,10 +124,10 @@ void MD5::update(unsigned char *input, @@ -119,10 +124,10 @@ void MD5::update(unsigned char *input,
119 index = static_cast<unsigned int>((count[0] >> 3) & 0x3f); 124 index = static_cast<unsigned int>((count[0] >> 3) & 0x3f);
120 125
121 // Update number of bits 126 // Update number of bits
122 - if ((count[0] += (static_cast<UINT4>(inputLen) << 3)) <  
123 - (static_cast<UINT4>(inputLen) << 3)) 127 + if ((count[0] += (static_cast<uint32_t>(inputLen) << 3)) <
  128 + (static_cast<uint32_t>(inputLen) << 3))
124 count[1]++; 129 count[1]++;
125 - count[1] += (static_cast<UINT4>(inputLen) >> 29); 130 + count[1] += (static_cast<uint32_t>(inputLen) >> 29);
126 131
127 partLen = 64 - index; 132 partLen = 64 - index;
128 133
@@ -146,7 +151,7 @@ void MD5::update(unsigned char *input, @@ -146,7 +151,7 @@ void MD5::update(unsigned char *input,
146 151
147 // MD5 finalization. Ends an MD5 message-digest operation, writing the 152 // MD5 finalization. Ends an MD5 message-digest operation, writing the
148 // the message digest and zeroizing the context. 153 // the message digest and zeroizing the context.
149 -void MD5::final() 154 +void MD5_native::finalize()
150 { 155 {
151 if (finalized) 156 if (finalized)
152 { 157 {
@@ -178,10 +183,16 @@ void MD5::final() @@ -178,10 +183,16 @@ void MD5::final()
178 finalized = true; 183 finalized = true;
179 } 184 }
180 185
  186 +void
  187 +MD5_native::digest(Digest result)
  188 +{
  189 + memcpy(result, digest_val, sizeof(digest_val));
  190 +}
  191 +
181 // MD5 basic transformation. Transforms state based on block. 192 // MD5 basic transformation. Transforms state based on block.
182 -void MD5::transform(UINT4 state[4], unsigned char block[64]) 193 +void MD5_native::transform(uint32_t state[4], unsigned char block[64])
183 { 194 {
184 - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 195 + uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
185 196
186 decode(x, block, 64); 197 decode(x, block, 64);
187 198
@@ -267,9 +278,9 @@ void MD5::transform(UINT4 state[4], unsigned char block[64]) @@ -267,9 +278,9 @@ void MD5::transform(UINT4 state[4], unsigned char block[64])
267 memset (x, 0, sizeof (x)); 278 memset (x, 0, sizeof (x));
268 } 279 }
269 280
270 -// Encodes input (UINT4) into output (unsigned char). Assumes len is a 281 +// Encodes input (uint32_t) into output (unsigned char). Assumes len is a
271 // multiple of 4. 282 // multiple of 4.
272 -void MD5::encode(unsigned char *output, UINT4 *input, size_t len) 283 +void MD5_native::encode(unsigned char *output, uint32_t *input, size_t len)
273 { 284 {
274 unsigned int i, j; 285 unsigned int i, j;
275 286
@@ -281,155 +292,16 @@ void MD5::encode(unsigned char *output, UINT4 *input, size_t len) @@ -281,155 +292,16 @@ void MD5::encode(unsigned char *output, UINT4 *input, size_t len)
281 } 292 }
282 } 293 }
283 294
284 -// Decodes input (unsigned char) into output (UINT4). Assumes len is a 295 +// Decodes input (unsigned char) into output (uint32_t). Assumes len is a
285 // multiple of 4. 296 // multiple of 4.
286 -void MD5::decode(UINT4 *output, unsigned char *input, size_t len) 297 +void MD5_native::decode(uint32_t *output, unsigned char *input, size_t len)
287 { 298 {
288 unsigned int i, j; 299 unsigned int i, j;
289 300
290 for (i = 0, j = 0; j < len; i++, j += 4) 301 for (i = 0, j = 0; j < len; i++, j += 4)
291 output[i] = 302 output[i] =
292 - static_cast<UINT4>(input[j]) |  
293 - (static_cast<UINT4>(input[j+1]) << 8) |  
294 - (static_cast<UINT4>(input[j+2]) << 16) |  
295 - (static_cast<UINT4>(input[j+3]) << 24);  
296 -}  
297 -  
298 -// Public functions  
299 -  
300 -MD5::MD5()  
301 -{  
302 - init();  
303 -}  
304 -  
305 -void MD5::reset()  
306 -{  
307 - init();  
308 -}  
309 -  
310 -void MD5::encodeString(char const* str)  
311 -{  
312 - size_t len = strlen(str);  
313 -  
314 - update(QUtil::unsigned_char_pointer(str), len);  
315 - final();  
316 -}  
317 -  
318 -void MD5::appendString(char const* input_string)  
319 -{  
320 - update(QUtil::unsigned_char_pointer(input_string), strlen(input_string));  
321 -}  
322 -  
323 -void MD5::encodeDataIncrementally(char const* data, size_t len)  
324 -{  
325 - update(QUtil::unsigned_char_pointer(data), len);  
326 -}  
327 -  
328 -void MD5::encodeFile(char const *filename, qpdf_offset_t up_to_offset)  
329 -{  
330 - unsigned char buffer[1024];  
331 -  
332 - FILE *file = QUtil::safe_fopen(filename, "rb");  
333 - size_t len;  
334 - size_t so_far = 0;  
335 - size_t to_try = 1024;  
336 - size_t up_to_size = 0;  
337 - if (up_to_offset >= 0)  
338 - {  
339 - up_to_size = QIntC::to_size(up_to_offset);  
340 - }  
341 - do  
342 - {  
343 - if ((up_to_offset >= 0) && ((so_far + to_try) > up_to_size))  
344 - {  
345 - to_try = up_to_size - so_far;  
346 - }  
347 - len = fread(buffer, 1, to_try, file);  
348 - if (len > 0)  
349 - {  
350 - update(buffer, len);  
351 - so_far += len;  
352 - if ((up_to_offset >= 0) && (so_far >= up_to_size))  
353 - {  
354 - break;  
355 - }  
356 - }  
357 - } while (len > 0);  
358 - if (ferror(file))  
359 - {  
360 - // Assume, perhaps incorrectly, that errno was set by the  
361 - // underlying call to read....  
362 - (void) fclose(file);  
363 - QUtil::throw_system_error(  
364 - std::string("MD5: read error on ") + filename);  
365 - }  
366 - (void) fclose(file);  
367 -  
368 - final();  
369 -}  
370 -  
371 -void MD5::digest(Digest result)  
372 -{  
373 - final();  
374 - memcpy(result, digest_val, sizeof(digest_val));  
375 -}  
376 -  
377 -void MD5::print()  
378 -{  
379 - final();  
380 -  
381 - unsigned int i;  
382 - for (i = 0; i < 16; ++i)  
383 - {  
384 - printf("%02x", digest_val[i]);  
385 - }  
386 - printf("\n");  
387 -}  
388 -  
389 -std::string MD5::unparse()  
390 -{  
391 - final();  
392 - return QUtil::hex_encode(  
393 - std::string(reinterpret_cast<char*>(digest_val), 16));  
394 -}  
395 -  
396 -std::string  
397 -MD5::getDataChecksum(char const* buf, size_t len)  
398 -{  
399 - MD5 m;  
400 - m.encodeDataIncrementally(buf, len);  
401 - return m.unparse();  
402 -}  
403 -  
404 -std::string  
405 -MD5::getFileChecksum(char const* filename, qpdf_offset_t up_to_offset)  
406 -{  
407 - MD5 m;  
408 - m.encodeFile(filename, up_to_offset);  
409 - return m.unparse();  
410 -}  
411 -  
412 -bool  
413 -MD5::checkDataChecksum(char const* const checksum,  
414 - char const* buf, size_t len)  
415 -{  
416 - std::string actual_checksum = getDataChecksum(buf, len);  
417 - return (checksum == actual_checksum);  
418 -}  
419 -  
420 -bool  
421 -MD5::checkFileChecksum(char const* const checksum,  
422 - char const* filename, qpdf_offset_t up_to_offset)  
423 -{  
424 - bool result = false;  
425 - try  
426 - {  
427 - std::string actual_checksum = getFileChecksum(filename, up_to_offset);  
428 - result = (checksum == actual_checksum);  
429 - }  
430 - catch (std::runtime_error const&)  
431 - {  
432 - // Ignore -- return false  
433 - }  
434 - return result; 303 + static_cast<uint32_t>(input[j]) |
  304 + (static_cast<uint32_t>(input[j+1]) << 8) |
  305 + (static_cast<uint32_t>(input[j+2]) << 16) |
  306 + (static_cast<uint32_t>(input[j+3]) << 24);
435 } 307 }
libqpdf/QPDFCrypto_native.cc
1 #include <qpdf/QPDFCrypto_native.hh> 1 #include <qpdf/QPDFCrypto_native.hh>
  2 +#include <qpdf/QUtil.hh>
  3 +
  4 +void
  5 +QPDFCrypto_native::MD5_init()
  6 +{
  7 + this->md5 = std::make_shared<MD5_native>();
  8 +}
  9 +
  10 +void
  11 +QPDFCrypto_native::MD5_update(unsigned char const* data, size_t len)
  12 +{
  13 + this->md5->update(const_cast<unsigned char*>(data), len);
  14 +}
  15 +
  16 +void
  17 +QPDFCrypto_native::MD5_finalize()
  18 +{
  19 + this->md5->finalize();
  20 +}
  21 +
  22 +void
  23 +QPDFCrypto_native::MD5_digest(MD5_Digest d)
  24 +{
  25 + this->md5->digest(d);
  26 +}
  27 +
libqpdf/build.mk
@@ -16,6 +16,7 @@ SRCS_libqpdf = \ @@ -16,6 +16,7 @@ SRCS_libqpdf = \
16 libqpdf/InsecureRandomDataProvider.cc \ 16 libqpdf/InsecureRandomDataProvider.cc \
17 libqpdf/JSON.cc \ 17 libqpdf/JSON.cc \
18 libqpdf/MD5.cc \ 18 libqpdf/MD5.cc \
  19 + libqpdf/MD5_native.cc \
19 libqpdf/OffsetInputSource.cc \ 20 libqpdf/OffsetInputSource.cc \
20 libqpdf/Pipeline.cc \ 21 libqpdf/Pipeline.cc \
21 libqpdf/Pl_AES_PDF.cc \ 22 libqpdf/Pl_AES_PDF.cc \
libqpdf/qpdf/MD5.hh 0 → 100644
  1 +#ifndef MD5_HH
  2 +#define MD5_HH
  3 +
  4 +#include <qpdf/DLL.h>
  5 +#include <qpdf/Types.h>
  6 +#include <qpdf/QPDFCryptoImpl.hh>
  7 +#include <string>
  8 +#include <memory>
  9 +
  10 +class MD5
  11 +{
  12 + public:
  13 + typedef unsigned char Digest[16];
  14 +
  15 + QPDF_DLL
  16 + MD5();
  17 + QPDF_DLL
  18 + void reset();
  19 +
  20 + // encodes string and finalizes
  21 + QPDF_DLL
  22 + void encodeString(char const* input_string);
  23 +
  24 + // encodes file and finalizes; offset < 0 reads whole file
  25 + QPDF_DLL
  26 + void encodeFile(char const* filename, qpdf_offset_t up_to_offset = -1);
  27 +
  28 + // appends string to current md5 object
  29 + QPDF_DLL
  30 + void appendString(char const* input_string);
  31 +
  32 + // appends arbitrary data to current md5 object
  33 + QPDF_DLL
  34 + void encodeDataIncrementally(char const* input_data, size_t len);
  35 +
  36 + // computes a raw digest
  37 + QPDF_DLL
  38 + void digest(Digest);
  39 +
  40 + // prints the digest to stdout terminated with \r\n (primarily for
  41 + // testing)
  42 + QPDF_DLL
  43 + void print();
  44 +
  45 + // returns the digest as a hexadecimal string
  46 + QPDF_DLL
  47 + std::string unparse();
  48 +
  49 + // Convenience functions
  50 + QPDF_DLL
  51 + static std::string getDataChecksum(char const* buf, size_t len);
  52 + QPDF_DLL
  53 + static std::string getFileChecksum(char const* filename,
  54 + qpdf_offset_t up_to_offset = -1);
  55 + QPDF_DLL
  56 + static bool checkDataChecksum(char const* const checksum,
  57 + char const* buf, size_t len);
  58 + QPDF_DLL
  59 + static bool checkFileChecksum(char const* const checksum,
  60 + char const* filename,
  61 + qpdf_offset_t up_to_offset = -1);
  62 +
  63 + private:
  64 + void init();
  65 + void finalize();
  66 +
  67 + std::shared_ptr<QPDFCryptoImpl> crypto;
  68 +};
  69 +
  70 +#endif // MD5_HH
libqpdf/qpdf/MD5_native.hh
1 -#ifndef MD5_HH  
2 -#define MD5_HH 1 +#ifndef MD5_NATIVE_HH
  2 +#define MD5_NATIVE_HH
3 3
4 -#include <qpdf/DLL.h>  
5 #include <qpdf/qpdf-config.h> 4 #include <qpdf/qpdf-config.h>
6 -#include <qpdf/Types.h>  
7 -#ifdef HAVE_INTTYPES_H  
8 -# include <inttypes.h>  
9 -#endif  
10 -#ifdef HAVE_STDINT_H  
11 -# include <stdint.h>  
12 -#endif  
13 -#include <string> 5 +#include <cstdint>
  6 +#include <cstring>
14 7
15 -class MD5 8 +class MD5_native
16 { 9 {
17 public: 10 public:
18 typedef unsigned char Digest[16]; 11 typedef unsigned char Digest[16];
19 12
20 - QPDF_DLL  
21 - MD5();  
22 - QPDF_DLL  
23 - void reset();  
24 -  
25 - // encodes string and finalizes  
26 - QPDF_DLL  
27 - void encodeString(char const* input_string);  
28 -  
29 - // encodes file and finalizes; offset < 0 reads whole file  
30 - QPDF_DLL  
31 - void encodeFile(char const* filename, qpdf_offset_t up_to_offset = -1);  
32 -  
33 - // appends string to current md5 object  
34 - QPDF_DLL  
35 - void appendString(char const* input_string);  
36 -  
37 - // appends arbitrary data to current md5 object  
38 - QPDF_DLL  
39 - void encodeDataIncrementally(char const* input_data, size_t len);  
40 -  
41 - // computes a raw digest  
42 - QPDF_DLL  
43 - void digest(Digest);  
44 -  
45 - // prints the digest to stdout terminated with \r\n (primarily for  
46 - // testing)  
47 - QPDF_DLL  
48 - void print();  
49 -  
50 - // returns the digest as a hexadecimal string  
51 - QPDF_DLL  
52 - std::string unparse();  
53 -  
54 - // Convenience functions  
55 - QPDF_DLL  
56 - static std::string getDataChecksum(char const* buf, size_t len);  
57 - QPDF_DLL  
58 - static std::string getFileChecksum(char const* filename,  
59 - qpdf_offset_t up_to_offset = -1);  
60 - QPDF_DLL  
61 - static bool checkDataChecksum(char const* const checksum,  
62 - char const* buf, size_t len);  
63 - QPDF_DLL  
64 - static bool checkFileChecksum(char const* const checksum,  
65 - char const* filename,  
66 - qpdf_offset_t up_to_offset = -1);  
67 -  
68 - private:  
69 - // POINTER defines a generic pointer type  
70 - typedef void *POINTER;  
71 -  
72 - // UINT2 defines a two byte word  
73 - typedef uint16_t UINT2;  
74 -  
75 - // UINT4 defines a four byte word  
76 - typedef uint32_t UINT4;  
77 - 13 + MD5_native();
78 void init(); 14 void init();
79 void update(unsigned char *, size_t); 15 void update(unsigned char *, size_t);
80 - void final(); 16 + void finalize();
  17 + void digest(Digest);
81 18
82 - static void transform(UINT4 [4], unsigned char [64]);  
83 - static void encode(unsigned char *, UINT4 *, size_t);  
84 - static void decode(UINT4 *, unsigned char *, size_t); 19 + private:
  20 + static void transform(uint32_t[4], unsigned char[64]);
  21 + static void encode(unsigned char *, uint32_t *, size_t);
  22 + static void decode(uint32_t *, unsigned char *, size_t);
85 23
86 - UINT4 state[4]; // state (ABCD)  
87 - UINT4 count[2]; // number of bits, modulo 2^64 (lsb first) 24 + uint32_t state[4]; // state (ABCD)
  25 + uint32_t count[2]; // number of bits, modulo 2^64 (lsb first)
88 unsigned char buffer[64]; // input buffer 26 unsigned char buffer[64]; // input buffer
89 27
90 bool finalized; 28 bool finalized;
91 Digest digest_val; 29 Digest digest_val;
92 }; 30 };
93 31
94 -#endif // MD5_HH 32 +#endif // MD5_NATIVE_HH
libqpdf/qpdf/QPDFCrypto_native.hh
@@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
3 3
4 #include <qpdf/DLL.h> 4 #include <qpdf/DLL.h>
5 #include <qpdf/QPDFCryptoImpl.hh> 5 #include <qpdf/QPDFCryptoImpl.hh>
  6 +#include <qpdf/MD5_native.hh>
  7 +#include <memory>
6 8
7 class QPDFCrypto_native: public QPDFCryptoImpl 9 class QPDFCrypto_native: public QPDFCryptoImpl
8 { 10 {
@@ -11,6 +13,14 @@ class QPDFCrypto_native: public QPDFCryptoImpl @@ -11,6 +13,14 @@ class QPDFCrypto_native: public QPDFCryptoImpl
11 13
12 QPDF_DLL 14 QPDF_DLL
13 virtual ~QPDFCrypto_native() = default; 15 virtual ~QPDFCrypto_native() = default;
  16 +
  17 + virtual void MD5_init();
  18 + virtual void MD5_update(unsigned char const* data, size_t len);
  19 + virtual void MD5_finalize();
  20 + virtual void MD5_digest(MD5_Digest);
  21 +
  22 + private:
  23 + std::shared_ptr<MD5_native> md5;
14 }; 24 };
15 25
16 #endif // QPDFCRYPTO_NATIVE_HH 26 #endif // QPDFCRYPTO_NATIVE_HH