mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2024-12-25 12:58:21 +01:00
Update crypto callback to return the number of output bytes (to account for AES
expansion).
This commit is contained in:
parent
19571d00f2
commit
3af39d5d1f
3
.gitignore
vendored
3
.gitignore
vendored
@ -8,6 +8,5 @@
|
|||||||
/packages
|
/packages
|
||||||
/pdfio.xcodeproj/xcshareddata
|
/pdfio.xcodeproj/xcshareddata
|
||||||
/testpdfio
|
/testpdfio
|
||||||
/testpdfio-out.pdf
|
/testpdfio-*.pdf
|
||||||
/testpdfio-out2.pdf
|
|
||||||
/x64
|
/x64
|
||||||
|
13
pdfio-aes.c
13
pdfio-aes.c
@ -170,7 +170,7 @@ _pdfioCryptoAESInit(
|
|||||||
// multiple of 16 bytes (excess is not decrypted).
|
// multiple of 16 bytes (excess is not decrypted).
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
size_t // O - Number of bytes in output buffer
|
||||||
_pdfioCryptoAESDecrypt(
|
_pdfioCryptoAESDecrypt(
|
||||||
_pdfio_aes_t *ctx, // I - AES context
|
_pdfio_aes_t *ctx, // I - AES context
|
||||||
uint8_t *outbuffer, // I - Output buffer
|
uint8_t *outbuffer, // I - Output buffer
|
||||||
@ -178,6 +178,7 @@ _pdfioCryptoAESDecrypt(
|
|||||||
size_t len) // I - Number of bytes to decrypt
|
size_t len) // I - Number of bytes to decrypt
|
||||||
{
|
{
|
||||||
uint8_t next_iv[16]; // Next IV value
|
uint8_t next_iv[16]; // Next IV value
|
||||||
|
size_t outbytes = 0; // Output bytes
|
||||||
|
|
||||||
|
|
||||||
if (inbuffer != outbuffer)
|
if (inbuffer != outbuffer)
|
||||||
@ -196,7 +197,10 @@ _pdfioCryptoAESDecrypt(
|
|||||||
memcpy(ctx->iv, next_iv, 16);
|
memcpy(ctx->iv, next_iv, 16);
|
||||||
outbuffer += 16;
|
outbuffer += 16;
|
||||||
len -= 16;
|
len -= 16;
|
||||||
|
outbytes += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (outbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -207,7 +211,7 @@ _pdfioCryptoAESDecrypt(
|
|||||||
// be a multiple of 16 bytes.
|
// be a multiple of 16 bytes.
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
size_t // O - Number of bytes in output buffer
|
||||||
_pdfioCryptoAESEncrypt(
|
_pdfioCryptoAESEncrypt(
|
||||||
_pdfio_aes_t *ctx, // I - AES context
|
_pdfio_aes_t *ctx, // I - AES context
|
||||||
uint8_t *outbuffer, // I - Output buffer
|
uint8_t *outbuffer, // I - Output buffer
|
||||||
@ -215,6 +219,7 @@ _pdfioCryptoAESEncrypt(
|
|||||||
size_t len) // I - Number of bytes to decrypt
|
size_t len) // I - Number of bytes to decrypt
|
||||||
{
|
{
|
||||||
uint8_t *iv = ctx->iv; // Current IV for CBC
|
uint8_t *iv = ctx->iv; // Current IV for CBC
|
||||||
|
size_t outbytes = 0; // Output bytes
|
||||||
|
|
||||||
|
|
||||||
if (inbuffer != outbuffer)
|
if (inbuffer != outbuffer)
|
||||||
@ -232,6 +237,7 @@ _pdfioCryptoAESEncrypt(
|
|||||||
iv = outbuffer;
|
iv = outbuffer;
|
||||||
outbuffer += 16;
|
outbuffer += 16;
|
||||||
len -= 16;
|
len -= 16;
|
||||||
|
outbytes += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
@ -242,10 +248,13 @@ _pdfioCryptoAESEncrypt(
|
|||||||
XorWithIv(outbuffer, iv);
|
XorWithIv(outbuffer, iv);
|
||||||
Cipher((state_t*)outbuffer, ctx);
|
Cipher((state_t*)outbuffer, ctx);
|
||||||
iv = outbuffer;
|
iv = outbuffer;
|
||||||
|
outbytes += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store Iv in ctx for next call */
|
/* store Iv in ctx for next call */
|
||||||
memcpy(ctx->iv, iv, 16);
|
memcpy(ctx->iv, iv, 16);
|
||||||
|
|
||||||
|
return (outbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ typedef union _pdfio_crypto_ctx_u // Cryptographic contexts
|
|||||||
_pdfio_aes_t aes; // AES-128/256 context
|
_pdfio_aes_t aes; // AES-128/256 context
|
||||||
_pdfio_rc4_t rc4; // RC4-40/128 context
|
_pdfio_rc4_t rc4; // RC4-40/128 context
|
||||||
} _pdfio_crypto_ctx_t;
|
} _pdfio_crypto_ctx_t;
|
||||||
typedef void (*_pdfio_crypto_cb_t)(_pdfio_crypto_ctx_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len);
|
typedef size_t (*_pdfio_crypto_cb_t)(_pdfio_crypto_ctx_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len);
|
||||||
|
|
||||||
struct _pdfio_array_s
|
struct _pdfio_array_s
|
||||||
{
|
{
|
||||||
@ -342,8 +342,8 @@ extern pdfio_array_t *_pdfioArrayRead(pdfio_file_t *pdf, _pdfio_token_t *ts) _PD
|
|||||||
extern bool _pdfioArrayWrite(pdfio_array_t *a) _PDFIO_INTERNAL;
|
extern bool _pdfioArrayWrite(pdfio_array_t *a) _PDFIO_INTERNAL;
|
||||||
|
|
||||||
extern void _pdfioCryptoAESInit(_pdfio_aes_t *ctx, const uint8_t *key, size_t keylen, const uint8_t *iv) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoAESInit(_pdfio_aes_t *ctx, const uint8_t *key, size_t keylen, const uint8_t *iv) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoAESDecrypt(_pdfio_aes_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
extern size_t _pdfioCryptoAESDecrypt(_pdfio_aes_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoAESEncrypt(_pdfio_aes_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
extern size_t _pdfioCryptoAESEncrypt(_pdfio_aes_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoMakeRandom(uint8_t *buffer, size_t bytes) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoMakeRandom(uint8_t *buffer, size_t bytes) _PDFIO_INTERNAL;
|
||||||
extern _pdfio_crypto_cb_t _pdfioCryptoMakeReader(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_crypto_ctx_t *ctx, uint8_t *iv, size_t *ivlen) _PDFIO_INTERNAL;
|
extern _pdfio_crypto_cb_t _pdfioCryptoMakeReader(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_crypto_ctx_t *ctx, uint8_t *iv, size_t *ivlen) _PDFIO_INTERNAL;
|
||||||
extern _pdfio_crypto_cb_t _pdfioCryptoMakeWriter(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_crypto_ctx_t *ctx, uint8_t *iv, size_t *ivlen) _PDFIO_INTERNAL;
|
extern _pdfio_crypto_cb_t _pdfioCryptoMakeWriter(pdfio_file_t *pdf, pdfio_obj_t *obj, _pdfio_crypto_ctx_t *ctx, uint8_t *iv, size_t *ivlen) _PDFIO_INTERNAL;
|
||||||
@ -351,7 +351,7 @@ extern void _pdfioCryptoMD5Append(_pdfio_md5_t *pms, const uint8_t *data, size_
|
|||||||
extern void _pdfioCryptoMD5Finish(_pdfio_md5_t *pms, uint8_t digest[16]) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoMD5Finish(_pdfio_md5_t *pms, uint8_t digest[16]) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoMD5Init(_pdfio_md5_t *pms) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoMD5Init(_pdfio_md5_t *pms) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoRC4Init(_pdfio_rc4_t *ctx, const uint8_t *key, size_t keylen) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoRC4Init(_pdfio_rc4_t *ctx, const uint8_t *key, size_t keylen) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoRC4Crypt(_pdfio_rc4_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
extern size_t _pdfioCryptoRC4Crypt(_pdfio_rc4_t *ctx, uint8_t *outbuffer, const uint8_t *inbuffer, size_t len) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoSHA256Append(_pdfio_sha256_t *, const uint8_t *bytes, size_t bytecount) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoSHA256Append(_pdfio_sha256_t *, const uint8_t *bytes, size_t bytecount) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoSHA256Init(_pdfio_sha256_t *ctx) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoSHA256Init(_pdfio_sha256_t *ctx) _PDFIO_INTERNAL;
|
||||||
extern void _pdfioCryptoSHA256Finish(_pdfio_sha256_t *ctx, uint8_t *Message_Digest) _PDFIO_INTERNAL;
|
extern void _pdfioCryptoSHA256Finish(_pdfio_sha256_t *ctx, uint8_t *Message_Digest) _PDFIO_INTERNAL;
|
||||||
|
@ -69,7 +69,7 @@ _pdfioCryptoRC4Init(
|
|||||||
// "inbuffer" and "outbuffer" can point to the same memory.
|
// "inbuffer" and "outbuffer" can point to the same memory.
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
size_t // O - Number of output bytes
|
||||||
_pdfioCryptoRC4Crypt(
|
_pdfioCryptoRC4Crypt(
|
||||||
_pdfio_rc4_t *ctx, // I - Context
|
_pdfio_rc4_t *ctx, // I - Context
|
||||||
uint8_t *outbuffer, // I - Output buffer
|
uint8_t *outbuffer, // I - Output buffer
|
||||||
@ -79,6 +79,7 @@ _pdfioCryptoRC4Crypt(
|
|||||||
uint8_t tmp, // Swap variable
|
uint8_t tmp, // Swap variable
|
||||||
i, j, // Looping vars
|
i, j, // Looping vars
|
||||||
t; // Current S box
|
t; // Current S box
|
||||||
|
size_t outbytes = len; // Number of output bytes
|
||||||
|
|
||||||
|
|
||||||
// Loop through the entire buffer...
|
// Loop through the entire buffer...
|
||||||
@ -107,4 +108,6 @@ _pdfioCryptoRC4Crypt(
|
|||||||
// Copy current S box indices back to context...
|
// Copy current S box indices back to context...
|
||||||
ctx->i = i;
|
ctx->i = i;
|
||||||
ctx->j = j;
|
ctx->j = j;
|
||||||
|
|
||||||
|
return (outbytes);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,9 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
|
|||||||
|
|
||||||
while ((status = deflate(&st->flate, Z_FINISH)) != Z_STREAM_END)
|
while ((status = deflate(&st->flate, Z_FINISH)) != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
|
size_t bytes = sizeof(st->cbuffer) - st->flate.avail_out;
|
||||||
|
// Bytes to write
|
||||||
|
|
||||||
if (status < Z_OK && status != Z_BUF_ERROR)
|
if (status < Z_OK && status != Z_BUF_ERROR)
|
||||||
{
|
{
|
||||||
_pdfioFileError(st->pdf, "Flate compression failed: %s", zstrerror(status));
|
_pdfioFileError(st->pdf, "Flate compression failed: %s", zstrerror(status));
|
||||||
@ -64,10 +67,10 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
|
|||||||
if (st->crypto_cb)
|
if (st->crypto_cb)
|
||||||
{
|
{
|
||||||
// Encrypt it first...
|
// Encrypt it first...
|
||||||
(st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out);
|
bytes = (st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_pdfioFileWrite(st->pdf, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out))
|
if (!_pdfioFileWrite(st->pdf, st->cbuffer, bytes))
|
||||||
{
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
goto done;
|
goto done;
|
||||||
@ -80,13 +83,16 @@ pdfioStreamClose(pdfio_stream_t *st) // I - Stream
|
|||||||
if (st->flate.avail_out < (uInt)sizeof(st->cbuffer))
|
if (st->flate.avail_out < (uInt)sizeof(st->cbuffer))
|
||||||
{
|
{
|
||||||
// Write any residuals...
|
// Write any residuals...
|
||||||
|
size_t bytes = sizeof(st->cbuffer) - st->flate.avail_out;
|
||||||
|
// Bytes to write
|
||||||
|
|
||||||
if (st->crypto_cb)
|
if (st->crypto_cb)
|
||||||
{
|
{
|
||||||
// Encrypt it first...
|
// Encrypt it first...
|
||||||
(st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out);
|
bytes = (st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_pdfioFileWrite(st->pdf, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out))
|
if (!_pdfioFileWrite(st->pdf, st->cbuffer, bytes))
|
||||||
{
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
goto done;
|
goto done;
|
||||||
@ -755,7 +761,8 @@ pdfioStreamWrite(
|
|||||||
{
|
{
|
||||||
// Encrypt data before writing...
|
// Encrypt data before writing...
|
||||||
unsigned char temp[8192]; // Temporary buffer
|
unsigned char temp[8192]; // Temporary buffer
|
||||||
size_t cbytes; // Current bytes
|
size_t cbytes, // Current bytes
|
||||||
|
outbytes; // Output bytes
|
||||||
|
|
||||||
bufptr = (const unsigned char *)buffer;
|
bufptr = (const unsigned char *)buffer;
|
||||||
|
|
||||||
@ -764,8 +771,8 @@ pdfioStreamWrite(
|
|||||||
if ((cbytes = bytes) > sizeof(temp))
|
if ((cbytes = bytes) > sizeof(temp))
|
||||||
cbytes = sizeof(temp);
|
cbytes = sizeof(temp);
|
||||||
|
|
||||||
(st->crypto_cb)(&st->crypto_ctx, temp, bufptr, cbytes);
|
outbytes = (st->crypto_cb)(&st->crypto_ctx, temp, bufptr, cbytes);
|
||||||
if (!_pdfioFileWrite(st->pdf, temp, cbytes))
|
if (!_pdfioFileWrite(st->pdf, temp, outbytes))
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
bytes -= cbytes;
|
bytes -= cbytes;
|
||||||
@ -1153,13 +1160,15 @@ stream_write(pdfio_stream_t *st, // I - Stream
|
|||||||
if (st->flate.avail_out < (sizeof(st->cbuffer) / 8))
|
if (st->flate.avail_out < (sizeof(st->cbuffer) / 8))
|
||||||
{
|
{
|
||||||
// Flush the compression buffer...
|
// Flush the compression buffer...
|
||||||
|
size_t bytes = sizeof(st->cbuffer) - st->flate.avail_out;
|
||||||
|
|
||||||
if (st->crypto_cb)
|
if (st->crypto_cb)
|
||||||
{
|
{
|
||||||
// Encrypt it first...
|
// Encrypt it first...
|
||||||
(st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out);
|
bytes = (st->crypto_cb)(&st->crypto_ctx, st->cbuffer, st->cbuffer, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_pdfioFileWrite(st->pdf, st->cbuffer, sizeof(st->cbuffer) - st->flate.avail_out))
|
if (!_pdfioFileWrite(st->pdf, st->cbuffer, bytes))
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
st->flate.next_out = (Bytef *)st->cbuffer;
|
st->flate.next_out = (Bytef *)st->cbuffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user