diff options
author | Jay Berkenbilt <ejb@ql.org> | 2019-11-04 15:55:43 +0100 |
---|---|---|
committer | Jay Berkenbilt <ejb@ql.org> | 2019-11-09 14:18:02 +0100 |
commit | bb427bd11774f47f553257cdc0693f77b559654d (patch) | |
tree | 379100926074a82f81f24d0d6cbe41631b71cc50 /libqpdf/Pl_SHA2.cc | |
parent | eadc222ff9087c8dd41a7afced717a65802e849c (diff) | |
download | qpdf-bb427bd11774f47f553257cdc0693f77b559654d.tar.zst |
SHA2: switch to pluggable crypto
Diffstat (limited to 'libqpdf/Pl_SHA2.cc')
-rw-r--r-- | libqpdf/Pl_SHA2.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/libqpdf/Pl_SHA2.cc b/libqpdf/Pl_SHA2.cc new file mode 100644 index 00000000..3da78773 --- /dev/null +++ b/libqpdf/Pl_SHA2.cc @@ -0,0 +1,92 @@ +#include <qpdf/Pl_SHA2.hh> +#include <stdexcept> +#include <cstdio> +#include <qpdf/PointerHolder.hh> +#include <qpdf/QUtil.hh> +#include <qpdf/QPDFCryptoProvider.hh> + +Pl_SHA2::Pl_SHA2(int bits, Pipeline* next) : + Pipeline("sha2", next), + in_progress(false) +{ + if (bits) + { + resetBits(bits); + } +} + +Pl_SHA2::~Pl_SHA2() +{ +} + +void +Pl_SHA2::write(unsigned char* buf, size_t len) +{ + if (! this->in_progress) + { + this->in_progress = true; + } + + // Write in chunks in case len is too big to fit in an int. + // Assume int is at least 32 bits. + static size_t const max_bytes = 1 << 30; + size_t bytes_left = len; + unsigned char* data = buf; + while (bytes_left > 0) + { + size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); + this->crypto->SHA2_update(data, bytes); + bytes_left -= bytes; + data += bytes; + } + + if (this->getNext(true)) + { + this->getNext()->write(buf, len); + } +} + +void +Pl_SHA2::finish() +{ + if (this->getNext(true)) + { + this->getNext()->finish(); + } + this->crypto->SHA2_finalize(); + this->in_progress = false; +} + +void +Pl_SHA2::resetBits(int bits) +{ + if (this->in_progress) + { + throw std::logic_error( + "bit reset requested for in-progress SHA2 Pipeline"); + } + this->crypto = QPDFCryptoProvider::getImpl(); + this->crypto->SHA2_init(bits); +} + +std::string +Pl_SHA2::getRawDigest() +{ + if (this->in_progress) + { + throw std::logic_error( + "digest requested for in-progress SHA2 Pipeline"); + } + return this->crypto->SHA2_digest(); +} + +std::string +Pl_SHA2::getHexDigest() +{ + if (this->in_progress) + { + throw std::logic_error( + "digest requested for in-progress SHA2 Pipeline"); + } + return QUtil::hex_encode(getRawDigest()); +} |