aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/MD5.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2019-11-04 03:22:03 +0100
committerJay Berkenbilt <ejb@ql.org>2019-11-09 14:18:02 +0100
commitce8f9b6608ebcc3e88fbb1655be3e9363fa671b6 (patch)
tree4585a0a41e624ba5cc2a130a82719eee449f304e /libqpdf/MD5.cc
parent5c3e856e9f0b908494126d1ea7b99c8c32d37039 (diff)
downloadqpdf-ce8f9b6608ebcc3e88fbb1655be3e9363fa671b6.tar.zst
MD5: switch to pluggable crypto
Diffstat (limited to 'libqpdf/MD5.cc')
-rw-r--r--libqpdf/MD5.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/libqpdf/MD5.cc b/libqpdf/MD5.cc
new file mode 100644
index 00000000..95edd3a4
--- /dev/null
+++ b/libqpdf/MD5.cc
@@ -0,0 +1,163 @@
+#include <qpdf/MD5.hh>
+#include <qpdf/QUtil.hh>
+#include <qpdf/QIntC.hh>
+#include <qpdf/QPDFCryptoProvider.hh>
+
+#include <stdio.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+MD5::MD5()
+{
+ init();
+}
+
+void
+MD5::init()
+{
+ this->crypto = QPDFCryptoProvider::getImpl();
+ this->crypto->MD5_init();
+}
+
+void
+MD5::finalize()
+{
+ this->crypto->MD5_finalize();
+}
+
+void MD5::reset()
+{
+ init();
+}
+
+void MD5::encodeString(char const* str)
+{
+ size_t len = strlen(str);
+ crypto->MD5_init();
+ encodeDataIncrementally(str, len);
+ crypto->MD5_finalize();
+}
+
+void MD5::appendString(char const* input_string)
+{
+ encodeDataIncrementally(input_string, strlen(input_string));
+}
+
+void MD5::encodeDataIncrementally(char const* data, size_t len)
+{
+ this->crypto->MD5_update(QUtil::unsigned_char_pointer(data), len);
+}
+
+void MD5::encodeFile(char const *filename, qpdf_offset_t up_to_offset)
+{
+ char buffer[1024];
+
+ FILE *file = QUtil::safe_fopen(filename, "rb");
+ size_t len;
+ size_t so_far = 0;
+ size_t to_try = 1024;
+ size_t up_to_size = 0;
+ if (up_to_offset >= 0)
+ {
+ up_to_size = QIntC::to_size(up_to_offset);
+ }
+ do
+ {
+ if ((up_to_offset >= 0) && ((so_far + to_try) > up_to_size))
+ {
+ to_try = up_to_size - so_far;
+ }
+ len = fread(buffer, 1, to_try, file);
+ if (len > 0)
+ {
+ encodeDataIncrementally(buffer, len);
+ so_far += len;
+ if ((up_to_offset >= 0) && (so_far >= up_to_size))
+ {
+ break;
+ }
+ }
+ } while (len > 0);
+ if (ferror(file))
+ {
+ // Assume, perhaps incorrectly, that errno was set by the
+ // underlying call to read....
+ (void) fclose(file);
+ QUtil::throw_system_error(
+ std::string("MD5: read error on ") + filename);
+ }
+ (void) fclose(file);
+
+ this->crypto->MD5_finalize();
+}
+
+void MD5::digest(Digest result)
+{
+ this->crypto->MD5_finalize();
+ this->crypto->MD5_digest(result);
+}
+
+void MD5::print()
+{
+ Digest digest_val;
+ digest(digest_val);
+
+ unsigned int i;
+ for (i = 0; i < 16; ++i)
+ {
+ printf("%02x", digest_val[i]);
+ }
+ printf("\n");
+}
+
+std::string MD5::unparse()
+{
+ this->crypto->MD5_finalize();
+ Digest digest_val;
+ digest(digest_val);
+ return QUtil::hex_encode(
+ std::string(reinterpret_cast<char*>(digest_val), 16));
+}
+
+std::string
+MD5::getDataChecksum(char const* buf, size_t len)
+{
+ MD5 m;
+ m.encodeDataIncrementally(buf, len);
+ return m.unparse();
+}
+
+std::string
+MD5::getFileChecksum(char const* filename, qpdf_offset_t up_to_offset)
+{
+ MD5 m;
+ m.encodeFile(filename, up_to_offset);
+ return m.unparse();
+}
+
+bool
+MD5::checkDataChecksum(char const* const checksum,
+ char const* buf, size_t len)
+{
+ std::string actual_checksum = getDataChecksum(buf, len);
+ return (checksum == actual_checksum);
+}
+
+bool
+MD5::checkFileChecksum(char const* const checksum,
+ char const* filename, qpdf_offset_t up_to_offset)
+{
+ bool result = false;
+ try
+ {
+ std::string actual_checksum = getFileChecksum(filename, up_to_offset);
+ result = (checksum == actual_checksum);
+ }
+ catch (std::runtime_error const&)
+ {
+ // Ignore -- return false
+ }
+ return result;
+}