Commit ce8f9b6608ebcc3e88fbb1655be3e9363fa671b6

Authored by Jay Berkenbilt
1 parent 5c3e856e

MD5: switch to pluggable crypto

include/qpdf/QPDFCryptoImpl.hh
... ... @@ -23,6 +23,7 @@
23 23 #define QPDFCRYPTOIMPL_HH
24 24  
25 25 #include <qpdf/DLL.h>
  26 +#include <cstring>
26 27  
27 28 // This class is part of qpdf's pluggable crypto provider support.
28 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 40  
40 41 QPDF_DLL
41 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 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 27 //
28 28 /////////////////////////////////////////////////////////////////////////
29 29  
30   -#include <qpdf/MD5.hh>
  30 +#include <qpdf/MD5_native.hh>
31 31 #include <qpdf/QUtil.hh>
32 32 #include <qpdf/QIntC.hh>
33 33  
... ... @@ -72,28 +72,33 @@ static unsigned char PADDING[64] = {
72 72 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
73 73 // Rotation is separate from addition to prevent recomputation.
74 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 76 (a) = ROTATE_LEFT ((a), (s)); \
77 77 (a) += (b); \
78 78 }
79 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 81 (a) = ROTATE_LEFT ((a), (s)); \
82 82 (a) += (b); \
83 83 }
84 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 86 (a) = ROTATE_LEFT ((a), (s)); \
87 87 (a) += (b); \
88 88 }
89 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 91 (a) = ROTATE_LEFT ((a), (s)); \
92 92 (a) += (b); \
93 93 }
94 94  
  95 +MD5_native::MD5_native()
  96 +{
  97 + init();
  98 +}
  99 +
95 100 // MD5 initialization. Begins an MD5 operation, writing a new context.
96   -void MD5::init()
  101 +void MD5_native::init()
97 102 {
98 103 count[0] = count[1] = 0;
99 104 // Load magic initialization constants.
... ... @@ -110,7 +115,7 @@ void MD5::init()
110 115 // operation, processing another message block, and updating the
111 116 // context.
112 117  
113   -void MD5::update(unsigned char *input,
  118 +void MD5_native::update(unsigned char *input,
114 119 size_t inputLen)
115 120 {
116 121 unsigned int i, index, partLen;
... ... @@ -119,10 +124,10 @@ void MD5::update(unsigned char *input,
119 124 index = static_cast<unsigned int>((count[0] >> 3) & 0x3f);
120 125  
121 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 129 count[1]++;
125   - count[1] += (static_cast<UINT4>(inputLen) >> 29);
  130 + count[1] += (static_cast<uint32_t>(inputLen) >> 29);
126 131  
127 132 partLen = 64 - index;
128 133  
... ... @@ -146,7 +151,7 @@ void MD5::update(unsigned char *input,
146 151  
147 152 // MD5 finalization. Ends an MD5 message-digest operation, writing the
148 153 // the message digest and zeroizing the context.
149   -void MD5::final()
  154 +void MD5_native::finalize()
150 155 {
151 156 if (finalized)
152 157 {
... ... @@ -178,10 +183,16 @@ void MD5::final()
178 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 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 197 decode(x, block, 64);
187 198  
... ... @@ -267,9 +278,9 @@ void MD5::transform(UINT4 state[4], unsigned char block[64])
267 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 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 285 unsigned int i, j;
275 286  
... ... @@ -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 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 299 unsigned int i, j;
289 300  
290 301 for (i = 0, j = 0; j < len; i++, j += 4)
291 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 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 16 libqpdf/InsecureRandomDataProvider.cc \
17 17 libqpdf/JSON.cc \
18 18 libqpdf/MD5.cc \
  19 + libqpdf/MD5_native.cc \
19 20 libqpdf/OffsetInputSource.cc \
20 21 libqpdf/Pipeline.cc \
21 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 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 10 public:
18 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 14 void init();
79 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 26 unsigned char buffer[64]; // input buffer
89 27  
90 28 bool finalized;
91 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 3  
4 4 #include <qpdf/DLL.h>
5 5 #include <qpdf/QPDFCryptoImpl.hh>
  6 +#include <qpdf/MD5_native.hh>
  7 +#include <memory>
6 8  
7 9 class QPDFCrypto_native: public QPDFCryptoImpl
8 10 {
... ... @@ -11,6 +13,14 @@ class QPDFCrypto_native: public QPDFCryptoImpl
11 13  
12 14 QPDF_DLL
13 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 26 #endif // QPDFCRYPTO_NATIVE_HH
... ...