mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-31 22:11:53 +00:00
AES_PDF: switch to pluggable crypto
This commit is contained in:
parent
bb427bd117
commit
c8cda4f965
@ -73,6 +73,15 @@ class QPDF_DLL_CLASS QPDFCryptoImpl
|
||||
unsigned char* out_data = 0) = 0;
|
||||
QPDF_DLL
|
||||
virtual void RC4_finalize() = 0;
|
||||
|
||||
QPDF_DLL
|
||||
virtual void rijndael_init(
|
||||
bool encrypt, unsigned char const* key_data, size_t key_len) = 0;
|
||||
QPDF_DLL
|
||||
virtual void rijndael_process(
|
||||
unsigned char* in_data, unsigned char* out_data) = 0;
|
||||
QPDF_DLL
|
||||
virtual void rijndael_finalize() = 0;
|
||||
};
|
||||
|
||||
#endif // QPDFCRYPTOIMPL_HH
|
||||
|
55
libqpdf/AES_PDF_native.cc
Normal file
55
libqpdf/AES_PDF_native.cc
Normal file
@ -0,0 +1,55 @@
|
||||
#include <qpdf/AES_PDF_native.hh>
|
||||
#include <qpdf/QUtil.hh>
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <qpdf/rijndael.h>
|
||||
#include <qpdf/QIntC.hh>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
AES_PDF_native::AES_PDF_native(bool encrypt, unsigned char const* key,
|
||||
size_t key_bytes) :
|
||||
encrypt(encrypt),
|
||||
nrounds(0)
|
||||
{
|
||||
size_t keybits = 8 * key_bytes;
|
||||
this->key = std::unique_ptr<unsigned char[]>(
|
||||
new unsigned char[key_bytes],
|
||||
std::default_delete<unsigned char[]>());
|
||||
this->rk = std::unique_ptr<uint32_t[]>(
|
||||
new uint32_t[RKLENGTH(keybits)],
|
||||
std::default_delete<uint32_t[]>());
|
||||
size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t);
|
||||
std::memcpy(this->key.get(), key, key_bytes);
|
||||
std::memset(this->rk.get(), 0, rk_bytes);
|
||||
if (encrypt)
|
||||
{
|
||||
this->nrounds = rijndaelSetupEncrypt(
|
||||
this->rk.get(), this->key.get(), keybits);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->nrounds = rijndaelSetupDecrypt(
|
||||
this->rk.get(), this->key.get(), keybits);
|
||||
}
|
||||
}
|
||||
|
||||
AES_PDF_native::~AES_PDF_native()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AES_PDF_native::update(unsigned char* in_data, unsigned char* out_data)
|
||||
{
|
||||
if (this->encrypt)
|
||||
{
|
||||
rijndaelEncrypt(this->rk.get(),
|
||||
this->nrounds, in_data, out_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
rijndaelDecrypt(this->rk.get(),
|
||||
this->nrounds, in_data, out_data);
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
#include <cstring>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <qpdf/rijndael.h>
|
||||
#include <qpdf/QIntC.hh>
|
||||
#include <qpdf/QPDFCryptoProvider.hh>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -14,38 +14,23 @@ Pl_AES_PDF::Pl_AES_PDF(char const* identifier, Pipeline* next,
|
||||
bool encrypt, unsigned char const* key,
|
||||
size_t key_bytes) :
|
||||
Pipeline(identifier, next),
|
||||
crypto(QPDFCryptoProvider::getImpl()),
|
||||
encrypt(encrypt),
|
||||
cbc_mode(true),
|
||||
first(true),
|
||||
offset(0),
|
||||
nrounds(0),
|
||||
use_zero_iv(false),
|
||||
use_specified_iv(false),
|
||||
disable_padding(false)
|
||||
{
|
||||
size_t keybits = 8 * key_bytes;
|
||||
assert(key_bytes == KEYLENGTH(keybits));
|
||||
this->key = PointerHolder<unsigned char>(
|
||||
true, new unsigned char[key_bytes]);
|
||||
this->rk = PointerHolder<uint32_t>(
|
||||
true, new uint32_t[RKLENGTH(keybits)]);
|
||||
size_t rk_bytes = RKLENGTH(keybits) * sizeof(uint32_t);
|
||||
std::memcpy(this->key.getPointer(), key, key_bytes);
|
||||
std::memset(this->rk.getPointer(), 0, rk_bytes);
|
||||
this->key = std::unique_ptr<unsigned char[]>(
|
||||
new unsigned char[key_bytes],
|
||||
std::default_delete<unsigned char[]>());
|
||||
std::memcpy(this->key.get(), key, key_bytes);
|
||||
std::memset(this->inbuf, 0, this->buf_size);
|
||||
std::memset(this->outbuf, 0, this->buf_size);
|
||||
std::memset(this->cbc_block, 0, this->buf_size);
|
||||
if (encrypt)
|
||||
{
|
||||
this->nrounds = rijndaelSetupEncrypt(
|
||||
this->rk.getPointer(), this->key.getPointer(), keybits);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->nrounds = rijndaelSetupDecrypt(
|
||||
this->rk.getPointer(), this->key.getPointer(), keybits);
|
||||
}
|
||||
assert(this->nrounds == NROUNDS(keybits));
|
||||
this->crypto->rijndael_init(encrypt, this->key.get(), key_bytes);
|
||||
}
|
||||
|
||||
Pl_AES_PDF::~Pl_AES_PDF()
|
||||
@ -148,6 +133,7 @@ Pl_AES_PDF::finish()
|
||||
}
|
||||
flush(! this->disable_padding);
|
||||
}
|
||||
this->crypto->rijndael_finalize();
|
||||
getNext()->finish();
|
||||
}
|
||||
|
||||
@ -224,8 +210,7 @@ Pl_AES_PDF::flush(bool strip_padding)
|
||||
this->inbuf[i] ^= this->cbc_block[i];
|
||||
}
|
||||
}
|
||||
rijndaelEncrypt(this->rk.getPointer(),
|
||||
this->nrounds, this->inbuf, this->outbuf);
|
||||
this->crypto->rijndael_process(this->inbuf, this->outbuf);
|
||||
if (this->cbc_mode)
|
||||
{
|
||||
memcpy(this->cbc_block, this->outbuf, this->buf_size);
|
||||
@ -233,8 +218,7 @@ Pl_AES_PDF::flush(bool strip_padding)
|
||||
}
|
||||
else
|
||||
{
|
||||
rijndaelDecrypt(this->rk.getPointer(),
|
||||
this->nrounds, this->inbuf, this->outbuf);
|
||||
this->crypto->rijndael_process(this->inbuf, this->outbuf);
|
||||
if (this->cbc_mode)
|
||||
{
|
||||
for (unsigned int i = 0; i < this->buf_size; ++i)
|
||||
|
@ -66,3 +66,23 @@ QPDFCrypto_native::SHA2_digest()
|
||||
{
|
||||
return this->sha2->getRawDigest();
|
||||
}
|
||||
|
||||
void
|
||||
QPDFCrypto_native::rijndael_init(
|
||||
bool encrypt, unsigned char const* key_data, size_t key_len)
|
||||
{
|
||||
this->aes_pdf = std::make_shared<AES_PDF_native>(
|
||||
encrypt, key_data, key_len);
|
||||
}
|
||||
|
||||
void
|
||||
QPDFCrypto_native::rijndael_process(unsigned char* in_data,
|
||||
unsigned char* out_data)
|
||||
{
|
||||
this->aes_pdf->update(in_data, out_data);
|
||||
}
|
||||
|
||||
void
|
||||
QPDFCrypto_native::rijndael_finalize()
|
||||
{
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ LDFLAGS_libqpdf = -Llibqpdf/$(OUTPUT_DIR)
|
||||
LIBS_libqpdf = -lqpdf
|
||||
|
||||
SRCS_libqpdf = \
|
||||
libqpdf/AES_PDF_native.cc \
|
||||
libqpdf/BitStream.cc \
|
||||
libqpdf/BitWriter.cc \
|
||||
libqpdf/Buffer.cc \
|
||||
|
25
libqpdf/qpdf/AES_PDF_native.hh
Normal file
25
libqpdf/qpdf/AES_PDF_native.hh
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef AES_PDF_NATIVE_HH
|
||||
#define AES_PDF_NATIVE_HH
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
class AES_PDF_native
|
||||
{
|
||||
public:
|
||||
// key should be a pointer to key_bytes bytes of data
|
||||
AES_PDF_native(bool encrypt, unsigned char const* key,
|
||||
size_t key_bytes);
|
||||
~AES_PDF_native();
|
||||
|
||||
void update(unsigned char* in_data, unsigned char* out_data);
|
||||
|
||||
private:
|
||||
bool encrypt;
|
||||
std::unique_ptr<unsigned char[]> key;
|
||||
std::unique_ptr<uint32_t[]> rk;
|
||||
unsigned int nrounds;
|
||||
};
|
||||
|
||||
#endif // AES_PDF_NATIVE_HH
|
@ -3,9 +3,8 @@
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/qpdf-config.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <qpdf/QPDFCryptoImpl.hh>
|
||||
#include <memory>
|
||||
|
||||
// This pipeline implements AES-128 and AES-256 with CBC and block
|
||||
// padding as specified in the PDF specification.
|
||||
@ -51,17 +50,16 @@ class Pl_AES_PDF: public Pipeline
|
||||
static unsigned int const buf_size = 16;
|
||||
static bool use_static_iv;
|
||||
|
||||
std::shared_ptr<QPDFCryptoImpl> crypto;
|
||||
bool encrypt;
|
||||
bool cbc_mode;
|
||||
bool first;
|
||||
size_t offset; // offset into memory buffer
|
||||
PointerHolder<unsigned char> key;
|
||||
PointerHolder<uint32_t> rk;
|
||||
std::unique_ptr<unsigned char[]> key;
|
||||
unsigned char inbuf[buf_size];
|
||||
unsigned char outbuf[buf_size];
|
||||
unsigned char cbc_block[buf_size];
|
||||
unsigned char specified_iv[buf_size];
|
||||
unsigned int nrounds;
|
||||
bool use_zero_iv;
|
||||
bool use_specified_iv;
|
||||
bool disable_padding;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <qpdf/MD5_native.hh>
|
||||
#include <qpdf/RC4_native.hh>
|
||||
#include <qpdf/SHA2_native.hh>
|
||||
#include <qpdf/AES_PDF_native.hh>
|
||||
#include <memory>
|
||||
|
||||
class QPDFCrypto_native: public QPDFCryptoImpl
|
||||
@ -31,10 +32,17 @@ class QPDFCrypto_native: public QPDFCryptoImpl
|
||||
virtual void SHA2_finalize();
|
||||
virtual std::string SHA2_digest();
|
||||
|
||||
virtual void rijndael_init(
|
||||
bool encrypt, unsigned char const* key_data, size_t key_len);
|
||||
virtual void rijndael_process(
|
||||
unsigned char* in_data, unsigned char* out_data);
|
||||
virtual void rijndael_finalize();
|
||||
|
||||
private:
|
||||
std::shared_ptr<MD5_native> md5;
|
||||
std::shared_ptr<RC4_native> rc4;
|
||||
std::shared_ptr<SHA2_native> sha2;
|
||||
std::shared_ptr<AES_PDF_native> aes_pdf;
|
||||
};
|
||||
|
||||
#endif // QPDFCRYPTO_NATIVE_HH
|
||||
|
Loading…
Reference in New Issue
Block a user