Commit ce8f9b6608ebcc3e88fbb1655be3e9363fa671b6
1 parent
5c3e856e
MD5: switch to pluggable crypto
Showing
8 changed files
with
328 additions
and
237 deletions
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 |